diff options
author | Stig Bakken <ssb@php.net> | 2000-07-06 08:38:12 +0000 |
---|---|---|
committer | Stig Bakken <ssb@php.net> | 2000-07-06 08:38:12 +0000 |
commit | 81ded022e06add76d3f00c2eba4e19bce5bd2b65 (patch) | |
tree | 0540db56129c160033396ba0a8938553796ac0e6 /ext/odbc | |
parent | 6fd156b481f14f4b9eead88f74ac73503095b1c6 (diff) | |
download | php-git-81ded022e06add76d3f00c2eba4e19bce5bd2b65.tar.gz |
Applied DBMaker patch by Jeffrey Lin <clin@lion.syscom.com.tw>
Diffstat (limited to 'ext/odbc')
-rw-r--r-- | ext/odbc/Makefile.in | 2 | ||||
-rw-r--r-- | ext/odbc/config.m4 | 65 | ||||
-rw-r--r-- | ext/odbc/php_odbc.c | 187 | ||||
-rw-r--r-- | ext/odbc/php_odbc.h | 6 |
4 files changed, 235 insertions, 25 deletions
diff --git a/ext/odbc/Makefile.in b/ext/odbc/Makefile.in index 46f8b827e4..16822de011 100644 --- a/ext/odbc/Makefile.in +++ b/ext/odbc/Makefile.in @@ -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 diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4 index e0b6093655..e5edee78e0 100644 --- a/ext/odbc/config.m4 +++ b/ext/odbc/config.m4 @@ -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 diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 5ea0a584ac..d187614c38 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -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, ¶ms[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) diff --git a/ext/odbc/php_odbc.h b/ext/odbc/php_odbc.h index e3bd5f6b3a..4a7ff022dd 100644 --- a/ext/odbc/php_odbc.h +++ b/ext/odbc/php_odbc.h @@ -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); |