]> granicus.if.org Git - php/commitdiff
Applied DBMaker patch by Jeffrey Lin <clin@lion.syscom.com.tw>
authorStig Bakken <ssb@php.net>
Thu, 6 Jul 2000 08:38:12 +0000 (08:38 +0000)
committerStig Bakken <ssb@php.net>
Thu, 6 Jul 2000 08:38:12 +0000 (08:38 +0000)
ext/odbc/Makefile.in
ext/odbc/config.m4
ext/odbc/php_odbc.c
ext/odbc/php_odbc.h

index 46f8b827e4d2dc2ef218e4eeaab2b5c58b6275d1..16822de011f335c5fa2b0927b3b7b90190e5c086 100644 (file)
@@ -1,5 +1,7 @@
 
 LTLIBRARY_NAME    = libodbc.la
 LTLIBRARY_SOURCES = php_odbc.c velocis.c
+LTLIBRARY_SHARED_NAME      = odbc.la
+LTLIBRARY_SHARED_LIBADD    = $(ODBC_LFLAGS) $(ODBC_LIBS)
 
 include $(top_srcdir)/build/dynlib.mk
index e0b60936551ca083a7cc0b7d7b8ad30a389cbaa5..e5edee78e085011fd55725b5cc6030c121053a57 100644 (file)
@@ -80,27 +80,6 @@ AC_DEFUN(AC_FIND_EMPRESS_LIBS,[
   AC_MSG_RESULT(`echo $ODBC_LIBS | sed -e 's!.*/!!'`)
 ])
 
-dnl
-dnl Figure out the path where the newest DBMaker is installed.
-dnl
-AC_DEFUN(AC_FIND_DBMAKER_PATH,[
-  AC_MSG_CHECKING([DBMaker version])
-  if [ test -d "$1/4.0" ]; then
-    DBMAKER_PATH=$1/4.0
-  elif [ test -d "$1/3.6" ]; then
-    DBMAKER_PATH=$1/3.6
-  elif [ test -d "$1/3.5" ]; then
-    DBMAKER_PATH=$1/3.5
-  elif [ test -d "$1/3.01" ]; then
-    DBMAKER_PATH=$1/3.01
-  elif [ test -d "$1/3.0" ]; then
-    DBMAKER_PATH=$1/3.0
-  else
-    DBMAKER_PATH=$1
-  fi
-  AC_MSG_RESULT(`echo $DBMAKER_PATH | sed -e 's!.*/!!'`)
-])
-
 if test -z "$ODBC_TYPE"; then
 AC_MSG_CHECKING(for Adabas support)
 AC_ARG_WITH(adabas,
@@ -396,12 +375,32 @@ AC_ARG_WITH(dbmaker,
                           version of DBMaker is installed (such as
                           /home/dbmaker/3.6).],
 [
+  PHP_WITH_SHARED
   if test "$withval" = "yes"; then
     # find dbmaker's home directory
     DBMAKER_HOME=`grep "^dbmaker:" /etc/passwd | awk -F: '{print $6}'`
-    AC_FIND_DBMAKER_PATH($DBMAKER_HOME)
+
+    # check DBMaker version (from 5.0 to 2.0)
+    DBMAKER_VERSION=5.0
+
+    while [ test ! -d $DBMAKER_HOME/$DBMAKER_VERSION -a \
+                 "$DBMAKER_VERSION" != "2.9" ]; do
+        DM_VER=`echo $DBMAKER_VERSION | sed -e 's/\.//' | awk '{ print $1-1;}'`
+        MAJOR_V=`echo $DM_VER | awk '{ print $1/10; }' \
+                 | awk  -F. '{ print $1; }'`
+        MINOR_V=`echo $DM_VER | awk '{ print $1%10; }'`
+        DBMAKER_VERSION=$MAJOR_V.$MINOR_V
+    done
+
+    if [ "$DBMAKER_VERSION" = "2.9" ]; then
+        withval=$DBMAKER_HOME
+    else
+        DBMAKER_PATH=$DBMAKER_HOME/$DBMAKER_VERSION
+    fi
+
     withval=$DBMAKER_PATH
   fi
+
   if test "$withval" != "no"; then
     ODBC_INCDIR=$withval/include
     ODBC_LIBDIR=$withval/lib
@@ -410,7 +409,21 @@ AC_ARG_WITH(dbmaker,
     ODBC_INCLUDE=-I$ODBC_INCDIR
     ODBC_LIBS="-ldmapic -lc"
     ODBC_TYPE=dbmaker
-    AC_DEFINE(HAVE_DBMAKER,1,[ ])
+
+    AC_DEFINE(HAVE_DBMAKER,1,[Whether you want DBMaker])
+
+    if test "$shared" = "yes"; then
+        AC_MSG_RESULT(yes (shared))
+        ODBC_LFLAGS="-L$withval/driver/JDBC"
+        ODBC_LIBS="-ldmjdbc -lc -lm"
+        ODBC_SHARED="odbc.la"
+    else
+        AC_MSG_RESULT(yes (static))
+        AC_ADD_LIBRARY_WITH_PATH(dmapic, $ODBC_LIBDIR)
+        AC_ADD_INCLUDE($ODBC_INCDIR)
+        ODBC_STATIC="libphpext_odbc.la"
+    fi
+
     AC_MSG_RESULT(yes)
   else
     AC_MSG_RESULT(no)
@@ -422,7 +435,9 @@ fi
 
 if test -n "$ODBC_TYPE"; then
   INCLUDES="$INCLUDES $ODBC_INCLUDE"
-  EXTRA_LIBS="$EXTRA_LIBS $ODBC_LFLAGS $ODBC_LIBS"
+  if test "$ODBC_TYPE" != "dbmaker"; then
+    EXTRA_LIBS="$EXTRA_LIBS $ODBC_LFLAGS $ODBC_LIBS"
+  fi
   AC_DEFINE(HAVE_UODBC,1,[ ])
   PHP_SUBST(ODBC_INCDIR)
   PHP_SUBST(ODBC_INCLUDE)
@@ -430,5 +445,5 @@ if test -n "$ODBC_TYPE"; then
   PHP_SUBST(ODBC_LIBS)
   PHP_SUBST(ODBC_LFLAGS)
   PHP_SUBST(ODBC_TYPE)
-  PHP_EXTENSION(odbc)
+  PHP_EXTENSION(odbc, $shared)
 fi
index 5ea0a584ac8b66bd3d2b700d5c9f4a36f8a3e144..d187614c386c02cce1813d152a3f242697ba6ddc 100644 (file)
@@ -74,6 +74,10 @@ function_entry odbc_functions[] = {
        PHP_FE(odbc_connect, NULL)
        PHP_FE(odbc_pconnect, NULL)
        PHP_FE(odbc_cursor, NULL)
+#ifdef HAVE_DBMAKER
+    PHP_FE(odbc_fetch_array, NULL)
+    PHP_FE(odbc_fetch_object, NULL)
+#endif
        PHP_FE(odbc_exec, NULL)
        PHP_FE(odbc_prepare, NULL)
        PHP_FE(odbc_execute, NULL)
@@ -701,6 +705,9 @@ PHP_FUNCTION(odbc_prepare)
        odbc_result *result = NULL;
        odbc_connection *conn;
        RETCODE rc;
+#ifdef HAVE_SQL_EXTENDED_FETCH
+       UDWORD      scrollopts;
+#endif
 
        if (zend_get_parameters_ex(2, &pv_conn, &pv_query) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -732,6 +739,28 @@ PHP_FUNCTION(odbc_prepare)
                RETURN_FALSE;
        }
 
+#ifdef HAVE_SQL_EXTENDED_FETCH
+       /* Solid doesn't have ExtendedFetch, if DriverManager is used, get Info,
+          whether Driver supports ExtendedFetch */
+       rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL);
+       if (rc == SQL_SUCCESS) {
+               if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) {
+                       /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other
+                          type if not possible.
+                       */
+                       if (SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC)
+                               == SQL_ERROR) {
+                               odbc_sql_error(conn->henv, conn->hdbc, result->stmt, " SQLSetStmtOption");
+                               SQLFreeStmt(result->stmt, SQL_DROP);
+                               efree(result);
+                               RETURN_FALSE;
+                       }
+               }
+       } else {
+               result->fetch_abs = 0;
+       }
+#endif
+
        if ((rc = SQLPrepare(result->stmt, query, SQL_NTS)) != SQL_SUCCESS) {
                odbc_sql_error(conn->henv, conn->hdbc, result->stmt, "SQLPrepare");
                SQLFreeStmt(result->stmt, SQL_DROP);
@@ -859,6 +888,9 @@ PHP_FUNCTION(odbc_execute)
                                                                          (void *)params[i-1].fp, 0,
                                                                          &params[i-1].vallen);
                        } else {
+#ifdef HAVE_DBMAKER
+                precision = params[i-1].vallen;
+#endif
                                rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
                                                                          ctype, sqltype, precision, scale,
                                                                          (*tmp)->value.str.val, 0,
@@ -1087,6 +1119,161 @@ PHP_FUNCTION(odbc_exec)
 }
 /* }}} */
 
+#ifdef HAVE_DBMAKER
+#define ODBC_NUM  1
+#define ODBC_OBJECT  2
+
+static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type)
+{
+ int i;
+ odbc_result *result;
+ RETCODE rc;
+    SWORD sql_c_type;
+ char *buf = NULL;
+#ifdef HAVE_SQL_EXTENDED_FETCH
+ UDWORD crow;
+ UWORD  RowStatus[1];
+ SDWORD rownum = -1;
+ pval **pv_res, **pv_row, *tmp;
+
+ switch(ZEND_NUM_ARGS()) {
+  case 1:
+   if (zend_get_parameters_ex(1, &pv_res) == FAILURE)
+    WRONG_PARAM_COUNT;
+   break;
+  case 2:
+   if (zend_get_parameters_ex(2, &pv_res, &pv_row) == FAILURE)
+    WRONG_PARAM_COUNT;
+   convert_to_long_ex(pv_row);
+   rownum = (*pv_row)->value.lval;
+   break;
+  default:
+   WRONG_PARAM_COUNT;
+ }
+
+#else
+ pval **pv_res, *tmp;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pv_res) == FAILURE) {
+  WRONG_PARAM_COUNT;
+ }
+#endif
+
+ ZEND_FETCH_RESOURCE(result, odbc_result *, pv_res, -1, "ODBC result", le_result);
+
+ if (result->numcols == 0) {
+  php_error(E_WARNING, "No tuples available at this result index");
+  RETURN_FALSE;
+ }
+
+ if (array_init(return_value)==FAILURE) {
+  RETURN_FALSE;
+ }
+
+#ifdef HAVE_SQL_EXTENDED_FETCH
+ if (result->fetch_abs) {
+  if (rownum > 0)
+   rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus);
+  else
+   rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
+ } else
+#endif
+  rc = SQLFetch(result->stmt);
+
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
+  RETURN_FALSE;
+
+#ifdef HAVE_SQL_EXTENDED_FETCH
+ if (rownum > 0 && result->fetch_abs)
+  result->fetched = rownum;
+ else
+#endif
+  result->fetched++;
+
+ for(i = 0; i < result->numcols; i++) {
+  ALLOC_ZVAL(tmp);
+  tmp->refcount = 1;
+  tmp->type = IS_STRING;
+  tmp->value.str.len = 0;
+        sql_c_type = SQL_C_CHAR;
+
+        switch(result->values[i].coltype) {
+            case SQL_BINARY:
+            case SQL_VARBINARY:
+            case SQL_LONGVARBINARY:
+                if (result->binmode <= 0) {
+                    tmp->value.str.val = empty_string;
+                    break;
+                }
+                if (result->binmode == 1) sql_c_type = SQL_C_BINARY;
+            case SQL_LONGVARCHAR:
+                if (IS_SQL_LONG(result->values[i].coltype) &&
+                   result->longreadlen <= 0) {
+                    tmp->value.str.val = empty_string;
+                    break;
+                }
+
+                if (buf == NULL) buf = emalloc(result->longreadlen + 1);
+                rc = SQLGetData(result->stmt, (UWORD)(i + 1),sql_c_type,
+        buf, result->longreadlen + 1, &result->values[i].vallen);
+
+     if (rc == SQL_ERROR) {
+     odbc_sql_error(result->conn_ptr->henv, result->conn_ptr->hdbc, result->stmt, "SQLGetData");
+     efree(buf);
+     RETURN_FALSE;
+    }
+    if (rc == SQL_SUCCESS_WITH_INFO) {
+     tmp->value.str.len = result->longreadlen;
+    } else if (result->values[i].vallen == SQL_NULL_DATA) {
+     tmp->value.str.val = empty_string;
+     break;
+    } else {
+     tmp->value.str.len = result->values[i].vallen;
+    }
+    tmp->value.str.val = estrndup(buf, tmp->value.str.len);
+    break;
+
+   default:
+    if (result->values[i].vallen == SQL_NULL_DATA) {
+     tmp->value.str.val = empty_string;
+     break;
+    }
+    tmp->value.str.len = result->values[i].vallen;
+    tmp->value.str.val = estrndup(result->values[i].value,tmp->value.str.len);
+    break;
+  }
+  if (result_type & ODBC_NUM) {
+   zend_hash_index_update(return_value->value.ht, i, &tmp, sizeof(pval *), NULL);
+  } else {
+   zend_hash_update(return_value->value.ht, result->values[i].name, strlen(result->values[i].name)+1, &tmp, sizeof(pval *), NULL);
+  }
+ }
+ if (buf) efree(buf);
+}
+
+
+/* {{{ proto object odbc_fetch_object(int result [, int rownumber])
+   Fetch a result row as an object */
+PHP_FUNCTION(odbc_fetch_object)
+{
+ php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT);
+ if (return_value->type==IS_ARRAY) {
+  return_value->type=IS_OBJECT;
+  return_value->value.obj.properties = return_value->value.ht;
+  return_value->value.obj.ce = &zend_standard_class_def;
+ }
+}
+/* }}} */
+
+/* {{{ proto array odbc_fetch_array(int result [, int rownumber])
+   Fetch a result row as an associative array */
+PHP_FUNCTION(odbc_fetch_array)
+{
+        php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT);
+}
+/* }}} */
+#endif
+
 /* {{{ proto int odbc_fetch_into(int result_id [, int rownumber], array result_array)
    Fetch one result row into an array */ 
 PHP_FUNCTION(odbc_fetch_into)
index e3bd5f6b3acec6246d0dc3eb1698eaec3e961111..4a7ff022ddd757f71afe8f59d51fd6cdb0968c75 100644 (file)
@@ -139,6 +139,8 @@ PHP_FUNCTION(solid_fetch_prev);
 #elif defined(HAVE_DBMAKER) /* DBMaker */
 
 #define ODBC_TYPE "DBMaker"
+#undef ODBCVER
+#define ODBCVER 0x0300
 #define HAVE_SQL_EXTENDED_FETCH 1
 #include <odbc.h>
 
@@ -189,6 +191,10 @@ PHP_FUNCTION(odbc_cursor);
 PHP_FUNCTION(odbc_exec);
 PHP_FUNCTION(odbc_do);
 PHP_FUNCTION(odbc_execute);
+#ifdef HAVE_DBMAKER
+PHP_FUNCTION(odbc_fetch_array);
+PHP_FUNCTION(odbc_fetch_object);
+#endif
 PHP_FUNCTION(odbc_fetch_into);
 PHP_FUNCTION(odbc_fetch_row);
 PHP_FUNCTION(odbc_field_len);