mirror of
https://github.com/php/php-src.git
synced 2026-04-21 23:18:13 +02:00
Applied DBMaker patch by Jeffrey Lin <clin@lion.syscom.com.tw>
This commit is contained 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
|
||||
|
||||
+40
-25
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user