summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStig Bakken <ssb@php.net>1999-04-19 15:04:11 +0000
committerStig Bakken <ssb@php.net>1999-04-19 15:04:11 +0000
commit7dee737fb448b0ab2d35debd358b3c10f01508a8 (patch)
tree9b2bb34e9b65d2d244f19f631e1b5e6629d47b11
parentaac5a431237c60bc14204d5697e81bcfb9395d4d (diff)
downloadphp-git-7dee737fb448b0ab2d35debd358b3c10f01508a8.tar.gz
moved odbc into ext/
-rw-r--r--Makefile.in9
-rw-r--r--configure.in.in278
-rw-r--r--ext/odbc/Makefile.am4
-rw-r--r--ext/odbc/config.m4217
-rw-r--r--ext/odbc/odbc.c2312
-rw-r--r--ext/odbc/php3_odbc.h729
-rw-r--r--ext/odbc/php3_velocis.h108
-rw-r--r--ext/odbc/setup.stub76
-rw-r--r--ext/odbc/velocis.c646
-rw-r--r--internal_functions.c8
-rw-r--r--setup56
11 files changed, 4097 insertions, 346 deletions
diff --git a/Makefile.in b/Makefile.in
index 526b8cd2cf..07dd3f5687 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -68,22 +68,21 @@ OBJS = main.o internal_functions.o snprintf.o php3_sprintf.o \
safe_mode.o fopen-wrappers.o php3_realpath.o alloca.o output.o \
php_ini.o
-FUNCTIONS_SOURCE = functions/adabasd.c functions/apache.c functions/fhttpd.c \
+FUNCTIONS_SOURCE = functions/apache.c functions/fhttpd.c \
functions/crypt.c functions/db.c functions/dl.c functions/filepro.c \
functions/head.c functions/imap.c functions/mime.c \
functions/msql.c functions/mysql.c \
functions/oracle.c functions/oci8.c functions/pgsql.c \
- functions/post.c functions/solid.c functions/sybase.c \
+ functions/post.c functions/sybase.c \
functions/sybase-ct.c @BCMATH_SRC@ functions/xml.c \
- functions/unified_odbc.c functions/ldap.c functions/velocis.c \
- functions/zlib.c functions/COM.c functions/ifx.c \
+ functions/ldap.c functions/zlib.c functions/COM.c functions/ifx.c \
functions/pdf.c functions/hw.c functions/hg_comm.c functions/dlist.c \
functions/fdf.c functions/snmp.c functions/interbase.c \
functions/sysvsem.c functions/sysvshm.c functions/dav.c
FUNCTIONS = $(FUNCTIONS_SOURCE:.c=.o)
PHPLIBS = -L@top_srcdir@/libzend -lzend -Lext -lphpext
-LIBS = $(PHPLIBS) $(EXTRA_LIBS) @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @FHTTPD_LIB@ @REGEX_LIB@ @DBM_LIB@ @ORACLE_LFLAGS@ @ORACLE_LIBS@ @IODBC_LFLAGS@ @IODBC_LIBS@ @SYBASE_LFLAGS@ @SYBASE_LIBS@ @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @MYSQL_LFLAGS@ @MYSQL_LIBS@ @MSQL_LFLAGS@ @MSQL_LIBS@ @ADA_LFLAGS@ @ADA_LIBS@ @SOLID_LIBS@ @EMPRESS_LIBS@ @OPENLINK_LFLAGS@ @OPENLINK_LIBS@ @PGSQL_LFLAGS@ @PGSQL_LIBS@ @LDAP_LFLAGS@ @LDAP_LIBS@ @VELOCIS_LIBS@ @CODBC_LFLAGS@ @CODBC_LIBS@ @IMAP_LIBS@ @ZLIB_LIBS@ @PDFLIB_LIBS@ @FDFLIB_LIBS@ @IFX_LFLAGS@ @IFX_LIBS@ @SNMP_LFLAGS@ @SNMP_LIBS@ @IBASE_LFLAGS@ @IBASE_LIBS@ @XML_LIBS@ @LIBS@
+LIBS = $(PHPLIBS) $(EXTRA_LIBS) @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @FHTTPD_LIB@ @REGEX_LIB@ @DBM_LIB@ @ORACLE_LFLAGS@ @ORACLE_LIBS@ @SYBASE_LFLAGS@ @SYBASE_LIBS@ @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @MYSQL_LFLAGS@ @MYSQL_LIBS@ @MSQL_LFLAGS@ @MSQL_LIBS@ @PGSQL_LFLAGS@ @PGSQL_LIBS@ @LDAP_LFLAGS@ @LDAP_LIBS@ @IMAP_LIBS@ @ZLIB_LIBS@ @PDFLIB_LIBS@ @FDFLIB_LIBS@ @IFX_LFLAGS@ @IFX_LIBS@ @SNMP_LFLAGS@ @SNMP_LIBS@ @IBASE_LFLAGS@ @IBASE_LIBS@ @XML_LIBS@ @LIBS@
all: $(BINNAME)
diff --git a/configure.in.in b/configure.in.in
index af10ae83c4..40c409180c 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -1023,99 +1023,6 @@ AC_SUBST(ORACLE_HOME)
AC_SUBST(ORACLE_VERSION)
-AC_MSG_CHECKING(for iODBC support)
-AC_ARG_WITH(iodbc,
-[ --with-iodbc[=DIR] Include iODBC support. DIR is the iODBC base
- install directory, defaults to /usr/local.],
-[
- if test "$withval" = "yes"; then
- withval=/usr/local
- fi
- if test "$withval" != "no"; then
-
- IODBC_INCDIR=$withval/include
- IODBC_LIBDIR=$withval/lib
- IODBC_LFLAGS=-L$IODBC_LIBDIR
- IODBC_INCLUDE=-I$IODBC_INCDIR
- IODBC_LIBS=-liodbc
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_IODBC)
-
- AC_MSG_RESULT(yes)
-
- fi
-],[
- AC_MSG_RESULT(no)
-])
-AC_SUBST(IODBC_LIBS)
-AC_SUBST(IODBC_LFLAGS)
-dnl## AC_SUBST(IODBC_INCLUDE)
-INCLUDES="$INCLUDES $IODBC_INCLUDE"
-
-
-AC_MSG_CHECKING(for OpenLink ODBC support)
-AC_ARG_WITH(openlink,
-[ --with-openlink[=DIR] Include OpenLink ODBC support. DIR is the
- OpenLink base install directory, defaults to
- /usr/local/openlink.],
-[
- if test "$withval" = "yes"; then
- withval=/usr/local/openlink
- fi
- if test "$withval" != "no"; then
-
- OPENLINK_INCDIR=$withval/odbcsdk/include
- OPENLINK_LIBDIR=$withval/odbcsdk/lib
- OPENLINK_LFLAGS=-L$OPENLINK_LIBDIR
- OPENLINK_INCLUDE=-I$OPENLINK_INCDIR
- OPENLINK_LIBS=-liodbc
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_OPENLINK)
-
- AC_MSG_RESULT(yes)
-
- fi
-],[
- AC_MSG_RESULT(no)
-])
-AC_SUBST(OPENLINK_LIBS)
-AC_SUBST(OPENLINK_LFLAGS)
-dnl## AC_SUBST(OPENLINK_INCLUDE)
-INCLUDES="$INCLUDES $OPENLINK_INCLUDE"
-
-
-AC_MSG_CHECKING(for Adabas support)
-AC_ARG_WITH(adabas,
-[ --with-adabas[=DIR] Include Adabas D support. DIR is the Adabas base
- install directory, defaults to /usr/local.],
-[
- if test "$withval" = "yes"; then
- withval=/usr/local
- fi
- if test "$withval" != "no"; then
- ADA_INCDIR=$withval/incl
- ADA_LIBDIR=$withval/lib
- ADA_LFLAGS=-L$ADA_LIBDIR
- ADA_INCLUDE=-I$ADA_INCDIR
- ADA_LIBS="${ADA_LIBDIR}/odbclib.a -lsqlrte -lsqlptc"
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_ADABAS)
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-],[
- AC_MSG_RESULT(no)
-])
-AC_SUBST(ADA_LIBS)
-AC_SUBST(ADA_LFLAGS)
-dnl## AC_SUBST(ADA_INCLUDE)
-INCLUDES="$INCLUDES $ADA_INCLUDE"
-
-
AC_MSG_CHECKING(for Sybase support)
AC_ARG_WITH(sybase,
[ --with-sybase[=DIR] Include Sybase-DB support. DIR is the Sybase home
@@ -1309,72 +1216,6 @@ dnl## AC_SUBST(PGSQL_INCLUDE)
INCLUDES="$INCLUDES $PGSQL_INCLUDE"
-AC_MSG_CHECKING(for Solid support)
-AC_ARG_WITH(solid,
-[ --with-solid[=DIR] Include Solid support. DIR is the Solid base
- install directory, defaults to /usr/local/solid],
-[
- if test "$withval" != "no"; then
- if test "$withval" = "yes"; then
- SOLID_INCDIR=/usr/local/solid/include
- SOLID_LIBDIR=/usr/local/solid/lib
- else
- SOLID_INCDIR=$withval/include
- SOLID_LIBDIR=$withval/lib
- fi
- SOLID_INCLUDE=-I$SOLID_INCDIR
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_SOLID)
-
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-],[
- AC_MSG_RESULT(no)
-])
-if test "$SOLID_LIBDIR" != ""; then
- AC_FIND_SOLID_LIBS($SOLID_LIBDIR)
-fi
-dnl## AC_SUBST(SOLID_INCLUDE)
-AC_SUBST(SOLID_LIBS)
-INCLUDES="$INCLUDES $SOLID_INCLUDE"
-
-
-AC_MSG_CHECKING(for Empress support)
-AC_ARG_WITH(empress,
-[ --with-empress[=DIR] Include Empress support. DIR is the Empress base
- install directory, defaults to \$EMPRESSPATH],
-[
- if test "$withval" != "no"; then
- if test "$withval" = "yes"; then
- EMPRESS_INCDIR=$EMPRESSPATH/odbccl/include
- EMPRESS_LIBDIR=$EMPRESSPATH/odbccl/lib
- else
- EMPRESS_INCDIR=$withval/include
- EMPRESS_LIBDIR=$withval/lib
- fi
- EMPRESS_INCLUDE=-I$EMPRESS_INCDIR
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_EMPRESS)
-
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-],[
- AC_MSG_RESULT(no)
-])
-if test "$EMPRESS_LIBDIR" != ""; then
- AC_FIND_EMPRESS_LIBS($EMPRESS_LIBDIR)
-fi
-AC_SUBST(EMPRESS_LIBS)
-dnl## AC_SUBST(EMPRESS_INCLUDE)
-INCLUDES="$INCLUDES $EMPRESS_INCLUDE"
-
-
AC_MSG_CHECKING(for LDAP support)
AC_ARG_WITH(ldap,
[ --with-ldap[=DIR] Include LDAP support. DIR is the LDAP base
@@ -1441,48 +1282,6 @@ dnl## AC_SUBST(SNMP_INCLUDE)
INCLUDES="$INCLUDES $SNMP_INCLUDE"
-AC_MSG_CHECKING(for Velocis support)
-AC_ARG_WITH(velocis,
-[ --with-velocis[=DIR] Include Velocis support. DIR is the Velocis
- base install directory, defaults to /usr/local/velocis.],
-[
- if test "$withval" != "no"; then
- VELOCIS_OS=`uname`
- if test "$withval" = "yes"; then
- VELOCIS_INCDIR=/usr/local/velocis/include
- VELOCIS_LIBDIR=/usr/local/velocis
- else
- VELOCIS_INCDIR=$withval/include
- VELOCIS_LIBDIR=$withval
- fi
- VELOCIS_INCLUDE=-I$VELOCIS_INCDIR
- VELOCIS_LIBDIR="$VELOCIS_LIBDIR/bin"
- VELOCIS_LIBS="-l_rdbc -l_sql"
- if test $VELOCIS_OS = "FreeBSD"; then
- VELOCIS_LIBS="$VELOCIS_LIBDIR/../lib/rdscli.a -lcompat"
- fi
- if test $VELOCIS_OS = "BSD/OS"; then
- VELOCIS_LIBS="$VELOCIS_LIBDIR/../lib/rdscli.a -lcompat"
- fi
- old_CFLAGS=$CFLAGS; old_LDFLAGS=$LDFLAGS
- CFLAGS="$CFLAGS $VELOCIS_INCLUDE"
- LDFLAGS="$LDFLAGS $VELOCIS_LIBS"
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_VELOCIS)
- AC_MSG_RESULT(yes)
- else
- AC_MSG_RESULT(no)
- fi
-],[
- AC_MSG_RESULT(no)
-])
-AC_SUBST(VELOCIS_LIBS)
-AC_SUBST(VELOCIS_LFLAGS)
-dnl## AC_SUBST(VELOCIS_INCLUDE)
-INCLUDES="$INCLUDES $VELOCIS_INCLUDE"
-
-
AC_MSG_CHECKING(for Informix support)
AC_ARG_WITH(informix,
[ --with-informix[=DIR] Include Informix support. DIR is the Informix base
@@ -1587,46 +1386,6 @@ dnl## AC_SUBST(IBASE_INCLUDE)
INCLUDES="$INCLUDES $IBASE_INCLUDE"
-AC_MSG_CHECKING(for a custom ODBC support)
-AC_ARG_WITH(custom-odbc,
-[ --with-custom-odbc[=DIR] Include a user defined ODBC support.
- The DIR is ODBC install base directory,
- which defaults to /usr/local.
- Make sure to define CUSTOM_ODBC_LIBS and
- have some odbc.h in your include dirs.
- E.g., you should define following for
- Sybase SQL Anywhere 5.5.00 on QNX, prior to
- run configure script:
- CFLAGS=\"-DODBC_QNX -DSQLANY_BUG\"
- LDFLAGS=-lunix
- CUSTOM_ODBC_LIBS=\"-ldblib -lodbc\".],
-[
- if test "$withval" = "yes"; then
- withval=/usr/local
- fi
- if test "$withval" != "no"; then
-
- CODBC_INCDIR=$withval/include
- CODBC_LIBDIR=$withval/lib
- CODBC_LFLAGS=-L$CODBC_LIBDIR
- CODBC_INCLUDE=-I$CODBC_INCDIR
- CODBC_LIBS=$CUSTOM_ODBC_LIBS
- UODBC_DEFAULT=yes
-
- AC_DEFINE(HAVE_CODBC)
-
- AC_MSG_RESULT(yes)
-
- fi
-],[
- AC_MSG_RESULT(no)
-])
-AC_SUBST(CODBC_LIBS)
-AC_SUBST(CODBC_LFLAGS)
-dnl## AC_SUBST(CODBC_INCLUDE)
-INCLUDES="$INCLUDES $CODBC_INCLUDE"
-
-
AC_MSG_CHECKING(for Hyperwave support)
AC_ARG_WITH(hyperwave,
[ --with-hyperwave Include Hyperwave support],
@@ -1805,43 +1564,6 @@ AC_ARG_WITH(mod-dav,
AC_SUBST(MOD_DAV_CFLAGS)
-AC_MSG_CHECKING(whether to enable unified ODBC support)
-AC_ARG_ENABLE(unified-odbc,
-[ --disable-unified-odbc Disable unified ODBC support. Only applicable if
- iODBC, Adabas, Solid, Velocis or a custom ODBC
- interface is enabled.],
-[
- if test "$enableval" = "no"; then
- AC_DEFINE(HAVE_UODBC, 0)
- AC_MSG_RESULT(no)
- else
- if test "$with_solid" != ""; then
- UODBC_TYPE=solid
- elif test "$with_iodbc" != ""; then
- UODBC_TYPE=iodbc
- elif test "$with_adabas" != ""; then
- UODBC_TYPE=adabas
- elif test "$with_velocis" != ""; then
- UODBC_TYPE=velocis
- elif test "$with_custom_odbc" != ""; then
- UODBC_TYPE=custom
- else
- AC_MSG_ERROR([no ODBC library! Include Solid, iODBC, Velocis, Adabas D or a custom ODBC support.])
- fi
- AC_DEFINE(HAVE_UODBC, 1)
- AC_MSG_RESULT([yes, using $UODBC_TYPE])
- fi
-],[
- if test "$UODBC_DEFAULT" = "yes"; then
- AC_DEFINE(HAVE_UODBC, 1)
- AC_MSG_RESULT(yes)
- else
- AC_DEFINE(HAVE_UODBC, 0)
- AC_MSG_RESULT(no)
- fi
-])
-
-
AC_MSG_CHECKING(whether to enable System V semaphore support)
AC_ARG_ENABLE(sysvsem,
[ --enable-sysvsem Enable System V semaphore support.],
diff --git a/ext/odbc/Makefile.am b/ext/odbc/Makefile.am
new file mode 100644
index 0000000000..9f78717c5d
--- /dev/null
+++ b/ext/odbc/Makefile.am
@@ -0,0 +1,4 @@
+## Process this file with automake to produce Makefile.in
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_odbc.a
+libphpext_odbc_a_SOURCES=odbc.c velocis.c
diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4
new file mode 100644
index 0000000000..8fee81c8cf
--- /dev/null
+++ b/ext/odbc/config.m4
@@ -0,0 +1,217 @@
+dnl ODBC_INCDIR
+dnl ODBC_INCLUDE
+dnl ODBC_LIBDIR
+dnl ODBC_LIBS
+dnl ODBC_LFLAGS
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for Adabas support)
+AC_ARG_WITH(adabas,
+[ --with-adabas[=DIR] Include Adabas D support. DIR is the Adabas base
+ install directory, defaults to /usr/local.],
+[
+ if test "$withval" = "yes"; then
+ withval=/usr/local
+ fi
+ if test "$withval" != "no"; then
+ ODBC_INCDIR=$withval/incl
+ ODBC_LIBDIR=$withval/lib
+ ODBC_LFLAGS=-L$ADA_LIBDIR
+ ODBC_INCLUDE=-I$ADA_INCDIR
+ ODBC_LIBS="${ADA_LIBDIR}/odbclib.a -lsqlrte -lsqlptc"
+ ODBC_TYPE=adabas
+ AC_DEFINE(HAVE_ADABAS)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for Solid support)
+AC_ARG_WITH(solid,
+[ --with-solid[=DIR] Include Solid support. DIR is the Solid base
+ install directory, defaults to /usr/local/solid],
+[
+ if test "$withval" = "yes"; then
+ withval=/usr/local/solid
+ fi
+ if test "$withval" != "no"; then
+ ODBC_INCDIR=$withval/include
+ ODBC_LIBDIR=$withval/lib
+ ODBC_INCLUDE=-I$ODBC_INCDIR
+ ODBC_TYPE=solid
+ AC_DEFINE(HAVE_SOLID)
+ AC_MSG_RESULT(yes)
+ AC_FIND_SOLID_LIBS($SOLID_LIBDIR)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for Empress support)
+AC_ARG_WITH(empress,
+[ --with-empress[=DIR] Include Empress support. DIR is the Empress base
+ install directory, defaults to \$EMPRESSPATH],
+[
+ if test "$withval" != "no"; then
+ if test "$withval" = "yes"; then
+ ODBC_INCDIR=$EMPRESSPATH/odbccl/include
+ ODBC_LIBDIR=$EMPRESSPATH/odbccl/lib
+ else
+ ODBC_INCDIR=$withval/include
+ ODBC_LIBDIR=$withval/lib
+ fi
+ ODBC_INCLUDE=-I$ODBC_INCDIR
+ ODBC_TYPE=empress
+ AC_DEFINE(HAVE_EMPRESS)
+ AC_MSG_RESULT(yes)
+ AC_FIND_EMPRESS_LIBS($ODBC_LIBDIR)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for Velocis support)
+AC_ARG_WITH(velocis,
+[ --with-velocis[=DIR] Include Velocis support. DIR is the Velocis
+ base install directory, defaults to /usr/local/velocis.],
+[
+ if test "$withval" != "no"; then
+ if test "$withval" = "yes"; then
+ ODBC_INCDIR=/usr/local/velocis/include
+ ODBC_LIBDIR=/usr/local/velocis
+ else
+ ODBC_INCDIR=$withval/include
+ ODBC_LIBDIR=$withval
+ fi
+ ODBC_INCLUDE=-I$ODBC_INCDIR
+ ODBC_LIBDIR="$ODBC_LIBDIR/bin"
+ case `uname` in
+ FreeBSD|BSD/OS)
+ ODBC_LIBS="$ODBC_LIBDIR/../lib/rdscli.a -lcompat";;
+ *)
+ ODBC_LIBS="-l_rdbc -l_sql";;
+ esac
+ ODBC_TYPE=velocis
+ AC_DEFINE(HAVE_VELOCIS)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for a custom ODBC support)
+AC_ARG_WITH(custom-odbc,
+[ --with-custom-odbc[=DIR] Include a user defined ODBC support.
+ The DIR is ODBC install base directory,
+ which defaults to /usr/local.
+ Make sure to define CUSTOM_ODBC_LIBS and
+ have some odbc.h in your include dirs.
+ E.g., you should define following for
+ Sybase SQL Anywhere 5.5.00 on QNX, prior to
+ run configure script:
+ CFLAGS=\"-DODBC_QNX -DSQLANY_BUG\"
+ LDFLAGS=-lunix
+ CUSTOM_ODBC_LIBS=\"-ldblib -lodbc\".],
+[
+ if test "$withval" = "yes"; then
+ withval=/usr/local
+ fi
+ if test "$withval" != "no"; then
+ ODBC_INCDIR=$withval/include
+ ODBC_LIBDIR=$withval/lib
+ ODBC_LFLAGS=-L$CODBC_LIBDIR
+ ODBC_INCLUDE=-I$CODBC_INCDIR
+ ODBC_LIBS=$CUSTOM_ODBC_LIBS
+ ODBC_TYPE=custom
+ AC_DEFINE(HAVE_CODBC)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for iODBC support)
+AC_ARG_WITH(iodbc,
+[ --with-iodbc[=DIR] Include iODBC support. DIR is the iODBC base
+ install directory, defaults to /usr/local.],
+[
+ if test "$withval" = "yes"; then
+ withval=/usr/local
+ fi
+ if test "$withval" != "no"; then
+ ODBC_INCDIR=$withval/include
+ ODBC_LIBDIR=$withval/lib
+ ODBC_LFLAGS=-L$IODBC_LIBDIR
+ ODBC_INCLUDE=-I$IODBC_INCDIR
+ ODBC_LIBS=-liodbc
+ ODBC_TYPE=iodbc
+ AC_DEFINE(HAVE_IODBC)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -z "$ODBC_TYPE"; then
+AC_MSG_CHECKING(for OpenLink ODBC support)
+AC_ARG_WITH(openlink,
+[ --with-openlink[=DIR] Include OpenLink ODBC support. DIR is the
+ OpenLink base install directory, defaults to
+ /usr/local/openlink.],
+[
+ if test "$withval" = "yes"; then
+ withval=/usr/local/openlink
+ fi
+ if test "$withval" != "no"; then
+ ODBC_INCDIR=$withval/odbcsdk/include
+ ODBC_LIBDIR=$withval/odbcsdk/lib
+ ODBC_LFLAGS=-L$OPENLINK_LIBDIR
+ ODBC_INCLUDE=-I$OPENLINK_INCDIR
+ ODBC_LIBS=-liodbc
+ ODBC_TYPE=openlink
+ AC_DEFINE(HAVE_OPENLINK)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+fi
+
+if test -n "$ODBC_TYPE"; then
+ INCLUDES="$INCLUDES $ODBC_INCLUDE"
+ EXTRA_LIBS="$EXTRA_LIBS $ODBC_LFLAGS $ODBC_LIBS"
+ AC_DEFINE(HAVE_UODBC, 1)
+ AC_SUBST(ODBC_INCDIR)
+ AC_SUBST(ODBC_INCLUDE)
+ AC_SUBST(ODBC_LIBDIR)
+ AC_SUBST(ODBC_LIBS)
+ AC_SUBST(ODBC_LFLAGS)
+ AC_SUBST(ODBC_TYPE)
+ PHP_EXTENSION(odbc)
+fi
diff --git a/ext/odbc/odbc.c b/ext/odbc/odbc.c
new file mode 100644
index 0000000000..df4287974e
--- /dev/null
+++ b/ext/odbc/odbc.c
@@ -0,0 +1,2312 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@guardian.no> |
+ | Andreas Karajannis <Andreas.Karajannis@gmd.de> |
+ | Frank M. Kromann <fmk@businessnet.dk> Support for DB/2 CLI |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* This file is based on the Adabas D extension.
+ * Adabas D will no longer be supported as separate module.
+ */
+#define IS_EXT_MODULE
+#if !PHP_31
+#undef THREAD_SAFE
+#endif
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#if !(WIN32|WINNT)
+#include "config.h"
+#include "build-defs.h"
+#endif
+#include <fcntl.h>
+
+#include "php.h"
+#include "dl/phpdl.h"
+#include "ext/standard/php3_standard.h"
+#include "php3_unified_odbc.h"
+#include "head.h"
+#include "snprintf.h"
+
+#if HAVE_UODBC
+
+#ifdef THREAD_SAFE
+
+void *UODBC_MUTEX;
+DWORD UODBC_TLS;
+static int numthreads=0;
+
+typedef struct UODBC_GLOBAL_STRUCT {
+ UODBC_MODULE PHP3_UODBC_MODULE;
+} UODBC_GLOBAL_STRUCT;
+
+#define UODBC_GLOBAL(a) UODBC_GLOBALS->a
+
+#define UODBC_TLS_VARS UODBC_GLOBAL_STRUCT *UODBC_GLOBALS = TlsGetValue(UODBC_TLS);
+
+#else
+UODBC_MODULE PHP3_UODBC_MODULE;
+#define UODBC_GLOBAL(a) a
+#define UODBC_TLS_VARS
+#endif
+
+function_entry UODBC_FUNCTIONS[] = {
+ UODBC_FE(setoption, NULL),
+ UODBC_FE(autocommit, NULL),
+ UODBC_FE(close, NULL),
+ UODBC_FE(close_all, NULL),
+ UODBC_FE(commit, NULL),
+ UODBC_FE(connect, NULL),
+ UODBC_FE(pconnect, NULL),
+ UODBC_FE(cursor, NULL),
+ UODBC_FE_ALIAS(do, exec, NULL),
+ UODBC_FE(exec, NULL),
+ UODBC_FE(prepare, NULL),
+ UODBC_FE(execute, NULL),
+ UODBC_FE(fetch_row, NULL),
+ UODBC_FE(fetch_into, NULL),
+ UODBC_FE(field_len, NULL),
+ UODBC_FE(field_name, NULL),
+ UODBC_FE(field_type, NULL),
+ UODBC_FE(field_num, NULL),
+ UODBC_FE(free_result, NULL),
+ UODBC_FE(num_fields, NULL),
+ UODBC_FE(num_rows, NULL),
+ UODBC_FE(result, NULL),
+ UODBC_FE(result_all, NULL),
+ UODBC_FE(rollback, NULL),
+ UODBC_FE(binmode, NULL),
+ UODBC_FE(longreadlen, NULL),
+#if defined(USE_ODBC_ALIAS) && defined(UODBC_UNIQUE_NAMES)
+ UODBC_ALIAS(setoption, NULL),
+ UODBC_ALIAS(autocommit, NULL),
+ UODBC_ALIAS(close, NULL),
+ UODBC_ALIAS(close_all, NULL),
+ UODBC_ALIAS(commit, NULL),
+ UODBC_ALIAS(connect, NULL),
+ UODBC_ALIAS(pconnect, NULL),
+ UODBC_ALIAS(cursor, NULL),
+ UODBC_ALIAS_FE(do, exec, NULL),
+ UODBC_ALIAS(exec, NULL),
+ UODBC_ALIAS(prepare, NULL),
+ UODBC_ALIAS(execute, NULL),
+ UODBC_ALIAS(fetch_row, NULL),
+ UODBC_ALIAS(fetch_into, NULL),
+ UODBC_ALIAS(field_len, NULL),
+ UODBC_ALIAS(field_name, NULL),
+ UODBC_ALIAS(field_type, NULL),
+ UODBC_ALIAS(field_num, NULL),
+ UODBC_ALIAS(free_result, NULL),
+ UODBC_ALIAS(num_fields, NULL),
+ UODBC_ALIAS(num_rows, NULL),
+ UODBC_ALIAS(result, NULL),
+ UODBC_ALIAS(result_all, NULL),
+ UODBC_ALIAS(rollback, NULL),
+ UODBC_ALIAS(binmode, NULL),
+ UODBC_ALIAS(longreadlen, NULL),
+#endif
+#if HAVE_SOLID
+ {"solid_fetch_prev",php3_solid_fetch_prev, NULL},
+#endif
+#if 0 && HAVE_IODBC /* this won't work with the new system */
+/* for backwards compatibility with the older odbc module*/
+ {"sqlconnect", php3_uodbc_connect, NULL},
+ {"sqldisconnect", php3_uodbc_close, NULL},
+ {"sqlfetch", php3_uodbc_fetch_row, NULL},
+ {"sqlexecdirect", php3_uodbc_do, NULL},
+ {"sqlgetdata", php3_uodbc_result, NULL},
+ {"sqlfree", php3_uodbc_free_result, NULL},
+ {"sqlrowcount", php3_uodbc_num_rows, NULL},
+#endif
+ { NULL, NULL, NULL }
+};
+
+php3_module_entry UODBC_MODULE_ENTRY = {
+ UODBC_MODULE_NAME,
+ UODBC_FUNCTIONS,
+ PHP3_MINIT_UODBC,
+ PHP3_MSHUTDOWN_UODBC,
+ PHP3_RINIT_UODBC,
+ NULL,
+ PHP3_INFO_UODBC,
+ STANDARD_MODULE_PROPERTIES
+};
+
+
+#if COMPILE_DL
+DLEXPORT php3_module_entry *get_module() { return &UODBC_MODULE_ENTRY; };
+#endif
+
+
+static void _free_result(UODBC_RESULT *res)
+{
+ int i;
+
+ if (res){
+ if (res->values) {
+ for(i = 0; i < res->numcols; i++){
+ if (res->values[i].value)
+ efree(res->values[i].value);
+ }
+ efree(res->values);
+ res->values = NULL;
+ }
+ if (res->stmt){
+#if HAVE_SOLID
+ SQLTransact(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, res->conn_ptr->hdbc,
+ (UWORD)SQL_COMMIT);
+#endif
+ SQLFreeStmt(res->stmt,SQL_DROP);
+#if !HAVE_DB2
+ res->stmt = NULL;
+#endif
+ }
+ efree(res);
+ }
+}
+
+static int _results_cleanup(list_entry *le)
+{
+ UODBC_TLS_VARS;
+
+ if (le->type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_result){
+ UODBC_CONNECTION *conn = ((UODBC_RESULT *) le->ptr)->conn_ptr;
+ if (!conn->open && ((UODBC_RESULT *) le->ptr)->stmt){
+ SQLFreeStmt(((UODBC_RESULT *) le->ptr)->stmt,SQL_DROP);
+#if !HAVE_DB2
+ ((UODBC_RESULT *) le->ptr)->stmt = NULL;
+#endif
+ }
+ }
+ return 0;
+}
+
+static void _close_connection(UODBC_CONNECTION *conn)
+{
+ /* FIXME
+ * Closing a connection will fail if there are
+ * pending transactions
+ */
+ UODBC_TLS_VARS;
+
+ conn->open = 0;
+ _php3_hash_apply(UODBC_GLOBAL(PHP3_UODBC_MODULE).resource_list,
+ (int (*)(void *))_results_cleanup);
+ SQLDisconnect(conn->hdbc);
+ SQLFreeConnect(conn->hdbc);
+ efree(conn);
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links--;
+}
+
+
+static void _close_pconnection(UODBC_CONNECTION *conn)
+{
+ UODBC_TLS_VARS;
+
+
+ conn->open = 0;
+ _php3_hash_apply(UODBC_GLOBAL(PHP3_UODBC_MODULE).resource_plist,
+ (int (*)(void *))_results_cleanup);
+
+ SQLDisconnect(conn->hdbc);
+ SQLFreeConnect(conn->hdbc);
+ free(conn);
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links--;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent--;
+}
+
+
+int PHP3_MINIT_UODBC(INIT_FUNC_ARGS)
+{
+#ifdef SQLANY_BUG
+ HDBC foobar;
+ RETCODE rc;
+#endif
+
+#if defined(THREAD_SAFE)
+ UODBC_GLOBAL_STRUCT *UODBC_GLOBALS;
+
+ PHP3_MUTEX_ALLOC(UODBC_MUTEX);
+ PHP3_MUTEX_LOCK(UODBC_MUTEX);
+ numthreads++;
+ if (numthreads==1){
+ if (!PHP3_TLS_PROC_STARTUP(UODBC_TLS)){
+ PHP3_MUTEX_UNLOCK(UODBC_MUTEX);
+ PHP3_MUTEX_FREE(UODBC_MUTEX);
+ return FAILURE;
+ }
+ }
+ PHP3_MUTEX_UNLOCK(UODBC_MUTEX);
+ if(!PHP3_TLS_THREAD_INIT(UODBC_TLS,UODBC_GLOBALS,UODBC_GLOBAL_STRUCT)){
+ PHP3_MUTEX_FREE(UODBC_MUTEX);
+ return FAILURE;
+ }
+#endif
+
+ SQLAllocEnv(&UODBC_GLOBAL(PHP3_UODBC_MODULE).henv);
+
+#if !PHP_31
+ cfg_get_string(ODBC_INI_VAR(default_db),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).defDB);
+ cfg_get_string(ODBC_INI_VAR(default_user),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).defUser);
+ cfg_get_string(ODBC_INI_VAR(default_pw),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).defPW);
+ if (cfg_get_long(ODBC_INI_VAR(allow_persistent),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).allow_persistent)
+ == FAILURE) {
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).allow_persistent = -1;
+ }
+ if (cfg_get_long(ODBC_INI_VAR(max_persistent),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent)
+ == FAILURE) {
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent = -1;
+ }
+ if (cfg_get_long(ODBC_INI_VAR(max_links),
+ &UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links)
+ == FAILURE) {
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links = -1;
+ }
+#else
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).allow_persistent = -1;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent = -1;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links = -1;
+#endif
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent = 0;
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).le_result =
+ register_list_destructors(_free_result, NULL);
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn =
+ register_list_destructors(_close_connection, NULL);
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn =
+ register_list_destructors(NULL, _close_pconnection);
+
+#ifdef SQLANY_BUG
+/* Make a dumb connection to avoid crash on SQLFreeEnv(),
+ * then release it immediately.
+ * This is required for SQL Anywhere 5.5.00 on QNX 4.24 at least.
+ * The SQLANY_BUG should be defined in CFLAGS.
+ */
+ if ( SQLAllocConnect(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, &foobar) != SQL_SUCCESS )
+ UODBC_SQL_ERROR(SQL_NULL_HDBC, SQL_NULL_HSTMT, "SQLAllocConnect");
+ else
+ {
+ rc = SQLConnect(foobar, UODBC_GLOBAL(PHP3_UODBC_MODULE).defDB, SQL_NTS, UODBC_GLOBAL(PHP3_UODBC_MODULE).defUser,
+ SQL_NTS, UODBC_GLOBAL(PHP3_UODBC_MODULE).defPW, SQL_NTS);
+ if(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
+ SQLDisconnect( foobar );
+ SQLFreeConnect( foobar );
+ }
+#endif
+
+ REGISTER_LONG_CONSTANT("ODBC_BINMODE_PASSTHRU", 0, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("ODBC_BINMODE_RETURN", 1, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("ODBC_BINMODE_CONVERT", 2, CONST_CS | CONST_PERSISTENT);
+ /* Define Constants for different cursor options
+ these Constants are are defined in <sqlext.h>
+ */
+ REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC, CONST_PERSISTENT | CONST_CS);
+ REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_DEFAULT", SQL_CUR_DEFAULT, CONST_PERSISTENT | CONST_CS);
+ return SUCCESS;
+}
+
+
+int PHP3_RINIT_UODBC(INIT_FUNC_ARGS)
+{
+ UODBC_TLS_VARS;
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defConn = -1;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links =
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent;
+#if PHP_31
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultlrl = 4096;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultbinmode = 1;
+#else
+ if (cfg_get_long(ODBC_INI_VAR(defaultlrl), &UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultlrl)
+ == FAILURE){
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultlrl = 4096;
+ }
+ if (cfg_get_long(ODBC_INI_VAR(defaultbinmode), &UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultbinmode) == FAILURE){
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultbinmode = 1;
+ }
+#endif
+ return SUCCESS;
+}
+
+int PHP3_MSHUTDOWN_UODBC(SHUTDOWN_FUNC_ARGS)
+{
+ UODBC_TLS_VARS;
+
+ SQLFreeEnv(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv);
+#ifdef THREAD_SAFE
+ PHP3_TLS_THREAD_FREE(UODBC_GLOBALS);
+ PHP3_MUTEX_LOCK(UODBC_MUTEX);
+ numthreads--;
+ if (!numthreads) {
+ PHP3_TLS_PROC_SHUTDOWN(UODBC_TLS);
+ PHP3_MUTEX_UNLOCK(UODBC_MUTEX);
+ PHP3_MUTEX_FREE(UODBC_MUTEX);
+ return SUCCESS;
+ }
+ PHP3_MUTEX_UNLOCK(UODBC_MUTEX);
+#endif
+ return SUCCESS;
+}
+
+
+void PHP3_INFO_UODBC(void)
+{
+ UODBC_TLS_VARS;
+
+#if HAVE_SOLID
+ php3_printf("Unified ODBC Support active (compiled with Solid)");
+#elif HAVE_ADABAS
+ php3_printf("Unified ODBC Support active (compiled with Adabas D)");
+#elif HAVE_IODBC && !(WIN32|WINNT)
+ php3_printf("Unified ODBC Support active (compiled with iODBC)");
+#elif HAVE_VELOCIS
+ php3_printf("Unified ODBC Support active (compiled with Velocis)");
+#elif HAVE_DB2
+ php3_printf("Unified ODBC Support active (compiled with IBM DB2)");
+#elif WIN32|WINNT
+ php3_printf("Unified ODBC Support active (compiled with win32 ODBC)");
+#elif HAVE_EMPRESS
+ PUTS("Unified ODBC Support active (compiled with Empress)");
+#else
+ php3_printf("Unified ODBC Support active (compiled with unknown library)");
+#endif
+ php3_printf("<BR>");
+#if DEBUG
+ php3_printf("default_db: %s<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).defDB);
+ php3_printf("default_user: %s<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).defUser);
+ php3_printf("default_pw: %s<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).defPW);
+#endif
+ php3_printf("allow_persistent: %d<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).allow_persistent);
+ php3_printf("max_persistent: %d<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent);
+ php3_printf("max_links: %d<br>\n",UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links);
+}
+
+
+
+/*
+ * List management functions
+ */
+
+int UODBC_ADD_RESULT(HashTable *list,UODBC_RESULT *result)
+{
+ UODBC_TLS_VARS;
+ return php3_list_insert(result, UODBC_GLOBAL(PHP3_UODBC_MODULE).le_result);
+}
+
+UODBC_RESULT *UODBC_GET_RESULT(HashTable *list, int ind)
+{
+ UODBC_RESULT *res;
+ int type;
+ UODBC_TLS_VARS;
+
+ res = (UODBC_RESULT*)php3_list_find(ind, &type);
+ if (!res || type != UODBC_GLOBAL(PHP3_UODBC_MODULE).le_result) {
+ php3_error(E_WARNING, "Bad result index %d", ind);
+ return NULL;
+ }
+ return res;
+}
+
+void UODBC_DEL_RESULT(HashTable *list, int ind)
+{
+ UODBC_RESULT *res;
+ int type;
+ UODBC_TLS_VARS;
+
+ res = (UODBC_RESULT *)php3_list_find(ind, &type);
+ if (!res || type != UODBC_GLOBAL(PHP3_UODBC_MODULE).le_result) {
+ php3_error(E_WARNING,"Can't find result %d", ind);
+ return;
+ }
+ php3_list_delete(ind);
+}
+
+#if 0
+int UODBC_ADD_CONN(HashTable *list, HDBC conn)
+{
+ UODBC_TLS_VARS;
+ return php3_list_insert(conn, UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn);
+}
+
+void uodbc_make_def_conn(HashTable *list)
+{
+ HDBC new_conn;
+ RETCODE rc;
+ UODBC_TLS_VARS;
+
+ SQLAllocConnect(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, &new_conn);
+ rc = SQLConnect(new_conn, UODBC_GLOBAL(PHP3_UODBC_MODULE).defDB,
+ SQL_NTS, UODBC_GLOBAL(PHP3_UODBC_MODULE).defUser,
+ SQL_NTS, UODBC_GLOBAL(PHP3_UODBC_MODULE).defPW, SQL_NTS);
+
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(new_conn, SQL_NULL_HSTMT, "SQLConnect");
+ } else {
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defConn = uodbc_add_conn(list, new_conn);
+ }
+}
+#endif
+
+UODBC_CONNECTION *UODBC_GET_CONN(HashTable *list, int ind)
+{
+ UODBC_CONNECTION *conn = NULL;
+ int type;
+ HashTable *plist;
+ UODBC_TLS_VARS;
+
+ plist = UODBC_GLOBAL(PHP3_UODBC_MODULE).resource_plist;
+
+ conn = (UODBC_CONNECTION *)php3_list_find(ind, &type);
+ if (conn && (type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn ||
+ type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn))
+ return conn;
+
+ conn = (UODBC_CONNECTION *)php3_plist_find(ind, &type);
+ if (conn && (type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn ||
+ type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn))
+ return conn;
+
+ php3_error(E_WARNING,"Bad ODBC connection number (%d)", ind);
+ return NULL;
+}
+
+#if HAVE_DB2
+void UODBC_SQL_ERROR(SQLHANDLE conn, SQLHANDLE stmt, char *func)
+#else
+void UODBC_SQL_ERROR(HDBC conn, HSTMT stmt, char *func)
+#endif
+{
+ char state[6]; /* Not used */
+ SDWORD error; /* Not used */
+ char errormsg[255];
+ SWORD errormsgsize; /* Not used */
+ UODBC_TLS_VARS;
+
+ SQLError(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, conn, stmt, state,
+ &error, errormsg, sizeof(errormsg)-1, &errormsgsize);
+ if (func) {
+ php3_error(E_WARNING, "SQL error: %s, SQL state %s in %s",
+ errormsg, state, func);
+ } else {
+ php3_error(E_WARNING, "SQL error: %s, SQL state %s",
+ errormsg, state);
+ }
+}
+
+/* Main User Functions */
+/* {{{ proto odbc_close_all(void)
+ Close all ODBC connections */
+UODBC_FUNCTION(close_all)
+{
+ void *ptr;
+ int type;
+ int i, nument = _php3_hash_next_free_element(list);
+ UODBC_TLS_VARS;
+
+ for (i = 1; i < nument; i++) {
+ ptr = php3_list_find(i, &type);
+ if (ptr && (type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn ||
+ type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn)){
+ php3_list_delete(i);
+ }
+ }
+}
+/* }}} */
+
+void php3_uodbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode)
+{
+ int res_ind;
+ UODBC_RESULT *result;
+ pval *arg1, *arg2;
+ UODBC_TLS_VARS;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ WRONG_PARAM_COUNT;
+
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+
+ res_ind = arg1->value.lval;
+
+ if (res_ind){
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL){
+ RETURN_FALSE;
+ }
+ if (mode)
+ result->longreadlen = arg2->value.lval;
+ else
+ result->binmode = arg2->value.lval;
+ } else {
+ if (mode)
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultlrl = arg2->value.lval;
+ else
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultbinmode = arg2->value.lval;
+ }
+
+ RETURN_TRUE
+}
+
+/* {{{ proto odbc_binmode(int result_id, int mode)
+ Handle binary column data */
+UODBC_FUNCTION(binmode)
+{
+ php3_uodbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+/* }}} */
+
+/* {{{ proto odbc_longreadlen(int result_id, int length)
+ Handle LONG columns */
+UODBC_FUNCTION(longreadlen)
+{
+ php3_uodbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+/* }}} */
+
+int UODBC_BINDCOLS(UODBC_RESULT *result)
+{
+ int i;
+ SWORD colnamelen; /* Not used */
+ SDWORD displaysize;
+ UODBC_TLS_VARS;
+
+ result->values = (UODBC_RESULT_VALUE *)
+ emalloc(sizeof(UODBC_RESULT_VALUE)*result->numcols);
+
+ if (result->values == NULL){
+ php3_error(E_WARNING, "Out of memory");
+ SQLFreeStmt(result->stmt, SQL_DROP);
+ return 0;
+ }
+
+ result->longreadlen = UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultlrl;
+ result->binmode = UODBC_GLOBAL(PHP3_UODBC_MODULE).defaultbinmode;
+
+ for(i = 0; i < result->numcols; i++){
+ SQLColAttributes(result->stmt, (UWORD)(i+1), SQL_COLUMN_NAME,
+ result->values[i].name,
+ sizeof(result->values[i].name),
+ &colnamelen,
+ 0);
+ SQLColAttributes(result->stmt, (UWORD)(i+1), SQL_COLUMN_TYPE,
+ NULL, 0, NULL, &result->values[i].coltype);
+
+ /* Don't bind LONG / BINARY columns, so that fetch behaviour can
+ be controlled by odbc_binmode() / odbc_longreadlen()
+ */
+
+ switch(result->values[i].coltype){
+ case SQL_BINARY:
+ case SQL_VARBINARY:
+ case SQL_LONGVARBINARY:
+ case SQL_LONGVARCHAR:
+ result->values[i].value = NULL;
+ break;
+
+#if HAVE_ADABAS
+ case SQL_TIMESTAMP:
+ result->values[i].value = (char *)emalloc(27);
+ SQLBindCol(result->stmt, (UWORD)(i+1), SQL_C_CHAR, result->values[i].value,
+ 27, &result->values[i].vallen);
+ break;
+#endif /* HAVE_ADABAS */
+ default:
+ SQLColAttributes(result->stmt, (UWORD)(i+1), SQL_COLUMN_DISPLAY_SIZE,
+ NULL, 0, NULL, &displaysize);
+ result->values[i].value = (char *)emalloc(displaysize + 1);
+ SQLBindCol(result->stmt, (UWORD)(i+1), SQL_C_CHAR, result->values[i].value,
+ displaysize + 1, &result->values[i].vallen);
+ break;
+ }
+ }
+ return 1;
+}
+
+/* {{{ proto odbc_prepare(int connection_id, string query)
+ Prepares a statement for execution */
+UODBC_FUNCTION(prepare)
+{
+ pval *arg1, *arg2;
+ int conn;
+ char *query;
+ UODBC_RESULT *result=NULL;
+ UODBC_CONNECTION *curr_conn=NULL;
+ RETCODE rc;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ conn = arg1->value.lval;
+ query = arg2->value.str.val;
+
+ if ((curr_conn = UODBC_GET_CONN(list, conn)) == NULL){
+ RETURN_FALSE;
+ }
+
+#if 0
+ _php3_stripslashes(query,NULL);
+#endif
+
+ result = (UODBC_RESULT *)emalloc(sizeof(UODBC_RESULT));
+ if (result == NULL){
+ php3_error(E_WARNING, "Out of memory");
+ RETURN_FALSE;
+ }
+
+ result->numparams = 0;
+
+ rc = SQLAllocStmt(curr_conn->hdbc, &(result->stmt));
+ if (rc == SQL_INVALID_HANDLE){
+ efree(result);
+ php3_error(E_WARNING, "SQLAllocStmt error 'Invalid Handle' in php3_uodbc_prepare");
+ RETURN_FALSE;
+ }
+
+ if (rc == SQL_ERROR){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SQLAllocStmt");
+ efree(result);
+ RETURN_FALSE;
+ }
+
+ if ((rc = SQLPrepare(result->stmt, query, SQL_NTS)) != SQL_SUCCESS){
+ UODBC_SQL_ERROR(curr_conn->hdbc, result->stmt, "SQLPrepare");
+ SQLFreeStmt(result->stmt, SQL_DROP);
+ RETURN_FALSE;
+ }
+
+ SQLNumParams(result->stmt, &(result->numparams));
+ SQLNumResultCols(result->stmt, &(result->numcols));
+
+ if (result->numcols > 0){
+ if (!UODBC_BINDCOLS(result)){
+ efree(result);
+ RETURN_FALSE;
+ }
+ } else {
+ result->values = NULL;
+ }
+ result->conn_ptr = curr_conn;
+ result->fetched = 0;
+ RETURN_LONG(UODBC_ADD_RESULT(list, result));
+}
+/* }}} */
+
+/*
+ * Execute prepared SQL statement. Supports only input parameters.
+ */
+/* {{{ proto odbc_execute(int result_id [, array parameters_array])
+ Execute a prepared statement */
+extern UODBC_FUNCTION(execute)
+{
+ pval *arg1, *arg2, arr, *tmp;
+ typedef struct params_t {
+ SDWORD vallen;
+ int fp;
+ } params_t;
+ params_t *params = NULL;
+ char *filename;
+ SWORD sqltype, scale, nullable;
+ UDWORD precision;
+ UODBC_RESULT *result=NULL;
+ int res_ind, numArgs, i, ne;
+ RETCODE rc;
+
+ numArgs = ARG_COUNT(ht);
+ if (numArgs == 1){
+ if (getParameters(ht, 1, &arg1) == FAILURE)
+ WRONG_PARAM_COUNT;
+ } else {
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ WRONG_PARAM_COUNT;
+
+ arr = *arg2;
+ if (arr.type != IS_ARRAY) {
+ php3_error(E_WARNING, "No array passed to odbc_execute()");
+ return;
+ }
+ }
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL){
+ RETURN_FALSE;
+ }
+
+ if (result->numparams > 0 && numArgs == 1) {
+ php3_error(E_WARNING, "No parameters to SQL statement given");
+ RETURN_FALSE;
+ }
+
+ if (result->numparams > 0){
+ if ((ne = _php3_hash_num_elements(arr.value.ht)) < result->numparams){
+ php3_error(E_WARNING,"Not enough parameters (%d should be %d) given",
+ ne, result->numparams);
+ RETURN_FALSE;
+ }
+
+ pval_copy_constructor(arg2);
+ _php3_hash_internal_pointer_reset(arr.value.ht);
+ params = (params_t *)emalloc(sizeof(params_t) * result->numparams);
+
+ for (i = 1; i <= result->numparams; i++) {
+ if (_php3_hash_get_current_data(arr.value.ht, (void **) &tmp) == FAILURE) {
+ php3_error(E_WARNING,"Error getting parameter");
+ SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
+ efree(params);
+ RETURN_FALSE;
+ }
+ convert_to_string(tmp);
+ if (tmp->type != IS_STRING) {
+ php3_error(E_WARNING,"Error converting parameter");
+ SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
+ _php3_hash_destroy(arr.value.ht);
+ efree(arr.value.ht);
+ efree(params);
+ RETURN_FALSE;
+ }
+
+ SQLDescribeParam(result->stmt, (UWORD)i, &sqltype, &precision,
+ &scale, &nullable);
+ params[i-1].vallen = tmp->value.str.len;
+ params[i-1].fp = -1;
+
+
+ if (tmp->value.str.val[0] == '\'') {
+ filename = &tmp->value.str.val[1];
+ filename[tmp->value.str.len - 2] = '\0';
+
+ if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
+ php3_error(E_WARNING,"Can't open file %s", filename);
+ SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
+ for (i = 0; i < result->numparams; i++) {
+ if (params[i].fp != -1) {
+ close(params[i].fp);
+ }
+ }
+ _php3_hash_destroy(arr.value.ht);
+ efree(arr.value.ht);
+ efree(params);
+ RETURN_FALSE;
+ }
+
+ params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
+
+ rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
+ SQL_C_BINARY, sqltype, precision, scale,
+ (void *)params[i-1].fp, 0,
+ &params[i-1].vallen);
+ } else {
+ /*if (IS_SQL_BINARY(sqltype)){
+ php3_error(E_WARNING,"No Filename for binary parameter");
+ SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
+ _php3_hash_destroy(arr.value.ht);
+ efree(arr.value.ht);
+ efree(params);
+ RETURN_FALSE;
+ }
+*/
+ rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
+ SQL_C_CHAR, sqltype, precision, scale,
+ tmp->value.str.val, 0,
+ &params[i-1].vallen);
+ }
+ _php3_hash_move_forward(arr.value.ht);
+ }
+ }
+ /* Close cursor, needed for doing multiple selects */
+ rc = SQLFreeStmt(result->stmt, SQL_CLOSE);
+
+ if (rc == SQL_ERROR){
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SQLFreeStmt");
+ }
+
+ rc = SQLExecute(result->stmt);
+
+ result->fetched = 0;
+ if (rc == SQL_NEED_DATA){
+ char buf[4096];
+ int fp, nbytes;
+ while(rc == SQL_NEED_DATA){
+ rc = SQLParamData(result->stmt, (PTR FAR *)&fp);
+ if (rc == SQL_NEED_DATA){
+ while((nbytes = read(fp, &buf, 4096)) > 0)
+ SQLPutData(result->stmt,(UCHAR FAR*) &buf, nbytes);
+ }
+ }
+ } else {
+ if (rc != SQL_SUCCESS){
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SQLExecute");
+ RETVAL_FALSE;
+ }
+ }
+
+ if (result->numparams > 0){
+ SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
+ for(i = 0; i < result->numparams; i++){
+ if (params[i].fp != -1)
+ close(params[i].fp);
+ }
+ _php3_hash_destroy(arr.value.ht);
+ efree(arr.value.ht);
+ efree(params);
+ }
+
+ if (rc == SQL_SUCCESS){
+ RETVAL_TRUE;
+ }
+}
+/* }}} */
+
+/* odbc_cursor simply returns a cursor name for the given stmt
+ * Adabas automagically generates cursor names, other drivers may not
+ */
+/* {{{ proto odbc_cursor(int result_id)
+ Get cursor name */
+UODBC_FUNCTION(cursor)
+{
+ pval *arg1;
+ int res_ind;
+ SWORD len, max_len;
+ char *cursorname;
+ UODBC_RESULT *result;
+ RETCODE rc;
+
+ if (getParameters(ht, 1, &arg1) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL) {
+ RETURN_FALSE;
+ }
+ rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN,
+ (void *)&max_len,0,&len);
+ if (rc != SQL_SUCCESS){
+ RETURN_FALSE;
+ }
+
+ if (max_len > 0){
+ cursorname = emalloc(max_len + 1);
+ if (cursorname == NULL){
+ php3_error(E_WARNING,"Out of memory");
+ RETURN_FALSE;
+ }
+ rc = SQLGetCursorName(result->stmt,cursorname,(SWORD)max_len,&len);
+ if (rc != SQL_SUCCESS){
+ char state[6]; /* Not used */
+ SDWORD error; /* Not used */
+ char errormsg[255];
+ SWORD errormsgsize; /* Not used */
+ UODBC_TLS_VARS;
+
+ SQLError(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, result->conn_ptr->hdbc,
+ result->stmt, state, &error, errormsg,
+ sizeof(errormsg)-1, &errormsgsize);
+ if (!strncmp(state,"S1015",5)){
+ sprintf(cursorname,"php3_curs_%d", (int)result->stmt);
+ if (SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS){
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc,result->stmt,
+ "SQLSetCursorName");
+ RETVAL_FALSE;
+ } else {
+ RETVAL_STRING(cursorname,1);
+ }
+ } else {
+ php3_error(E_WARNING, "SQL error: %s, SQL state %s", errormsg, state);
+ RETVAL_FALSE;
+ }
+ } else {
+ RETVAL_STRING(cursorname,1);
+ }
+ efree(cursorname);
+ } else {
+ RETVAL_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto odbc_exec(int connection_id, string query)
+ Prepare and execute an SQL statement */
+UODBC_FUNCTION(exec)
+{
+ pval *arg1, *arg2;
+ int conn;
+ char *query;
+ UODBC_RESULT *result=NULL;
+ UODBC_CONNECTION *curr_conn=NULL;
+ RETCODE rc;
+#if HAVE_SQL_EXTENDED_FETCH
+ UDWORD scrollopts;
+#endif
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ conn = arg1->value.lval;
+ query = arg2->value.str.val;
+
+ if ((curr_conn = UODBC_GET_CONN(list, conn)) == NULL){
+ RETURN_FALSE;
+ }
+
+#if 0
+ _php3_stripslashes(query,NULL);
+#endif
+
+ result = (UODBC_RESULT *)emalloc(sizeof(UODBC_RESULT));
+ if (result == NULL){
+ php3_error(E_WARNING, "Out of memory");
+ RETURN_FALSE;
+ }
+
+ rc = SQLAllocStmt(curr_conn->hdbc, &(result->stmt));
+ if (rc == SQL_INVALID_HANDLE){
+ php3_error(E_WARNING, "SQLAllocStmt error 'Invalid Handle' in PHP3_UODBC_DO");
+ efree(result);
+ RETURN_FALSE;
+ }
+
+ if (rc == SQL_ERROR){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SQLAllocStmt");
+ efree(result);
+ RETURN_FALSE;
+ }
+
+#if HAVE_SQL_EXTENDED_FETCH
+ /* Solid doesn't have ExtendedFetch, if DriverManager is used, get Info,
+ whether Driver supports ExtendedFetch */
+ rc = SQLGetInfo(curr_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){
+ UODBC_SQL_ERROR(curr_conn->hdbc, result->stmt, " SQLSetStmtOption");
+ SQLFreeStmt(result->stmt, SQL_DROP);
+ efree(result);
+ RETURN_FALSE;
+ }
+ }
+ } else {
+ result->fetch_abs = 0;
+ }
+#endif
+
+ rc = SQLExecDirect(result->stmt, query, SQL_NTS);
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ /* XXX FIXME we should really check out SQLSTATE with SQLError
+ * in case rc is SQL_SUCCESS_WITH_INFO here.
+ */
+ UODBC_SQL_ERROR(curr_conn->hdbc, result->stmt, "SQLExecDirect");
+ SQLFreeStmt(result->stmt, SQL_DROP);
+ efree(result);
+ RETURN_FALSE;
+ }
+
+ SQLNumResultCols(result->stmt, &(result->numcols));
+
+ /* For insert, update etc. cols == 0 */
+ if (result->numcols > 0){
+ if (!UODBC_BINDCOLS(result)){
+ efree(result);
+ RETURN_FALSE;
+ }
+ } else {
+ result->values = NULL;
+ }
+ result->conn_ptr = curr_conn;
+ result->fetched = 0;
+ RETURN_LONG(UODBC_ADD_RESULT(list, result));
+}
+/* }}} */
+
+/* {{{ proto odbc_fetch_into(int result_id [, int rownumber], array result_array)
+ Fetch one result row into an array */
+UODBC_FUNCTION(fetch_into)
+{
+ int res_ind, numArgs, i;
+ UODBC_RESULT *result;
+ RETCODE rc;
+ SWORD sql_c_type;
+ char *buf = NULL;
+#if HAVE_SQL_EXTENDED_FETCH
+ UDWORD crow;
+ UWORD RowStatus[1];
+ SDWORD rownum = -1;
+ pval *arg1, *arg2, *arr, tmp;
+
+ numArgs = ARG_COUNT(ht);
+
+ switch(numArgs){
+ case 2:
+ if (getParameters(ht, 2, &arg1, &arr) == FAILURE)
+ WRONG_PARAM_COUNT;
+ break;
+ case 3:
+ if (getParameters(ht, 3, &arg1, &arg2, &arr) == FAILURE)
+ WRONG_PARAM_COUNT;
+ convert_to_long(arg2);
+ rownum = arg2->value.lval;
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ }
+
+ if (!ParameterPassedByReference(ht, numArgs)){
+ php3_error(E_WARNING, "Array not passed by reference in call to odbc_fetch_into()");
+ RETURN_FALSE;
+ }
+#else
+ pval *arg1, *arr, tmp;
+
+ numArgs = ARG_COUNT(ht);
+
+ if (numArgs != 2 || getParameters(ht, 2, &arg1, &arr) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (!ParameterPassedByReference(ht, numArgs)){
+ php3_error(E_WARNING, "Array not passed by reference in call to odbc_fetch_into()");
+ RETURN_FALSE;
+ }
+#endif
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL){
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0) {
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+ if (arr->type != IS_ARRAY){
+ if (array_init(arr) == FAILURE){
+ php3_error(E_WARNING, "Can't convert to type Array");
+ RETURN_FALSE;
+ }
+ }
+
+#if 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;
+
+#if HAVE_SQL_EXTENDED_FETCH
+ if (rownum > 0 && result->fetch_abs)
+ result->fetched = rownum;
+ else
+#endif
+ result->fetched++;
+
+ for (i = 0; i < result->numcols; i++) {
+ 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) {
+ UODBC_SQL_ERROR(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;
+ }
+ _php3_hash_index_update(arr->value.ht, i, (void *) &tmp, sizeof(pval), NULL);
+ }
+ if (buf) efree(buf);
+ RETURN_LONG(result->numcols);
+}
+/* }}} */
+
+#if HAVE_SOLID
+void php3_solid_fetch_prev(INTERNAL_FUNCTION_PARAMETERS)
+{
+ int res_ind;
+ UODBC_RESULT *result;
+ RETCODE rc;
+ pval *arg1;
+
+ if (getParameters(ht, 1, &arg1) == FAILURE)
+ WRONG_PARAM_COUNT;
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0) {
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+ rc = SQLFetchPrev(result->stmt);
+
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ RETURN_FALSE;
+ }
+
+ if (result->fetched > 1) result->fetched--;
+
+ RETURN_TRUE;
+}
+#endif
+
+/* {{{ proto odbc_fetch_row(int result_id [, int row_number])
+ Fetch a row */
+UODBC_FUNCTION(fetch_row)
+{
+ int res_ind, numArgs;
+ SDWORD rownum = 1;
+ UODBC_RESULT *result;
+ RETCODE rc;
+ pval *arg1, *arg2;
+#if HAVE_SQL_EXTENDED_FETCH
+ UDWORD crow;
+ UWORD RowStatus[1];
+#endif
+
+ numArgs = ARG_COUNT(ht);
+ if (numArgs == 1){
+ if (getParameters(ht, 1, &arg1) == FAILURE)
+ WRONG_PARAM_COUNT;
+ } else {
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ WRONG_PARAM_COUNT;
+ convert_to_long(arg2);
+ rownum = arg2->value.lval;
+ }
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0) {
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+#if HAVE_SQL_EXTENDED_FETCH
+ if (result->fetch_abs){
+ if (numArgs > 1)
+ 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;
+ }
+
+ if (numArgs > 1) {
+ result->fetched = rownum;
+ } else {
+ result->fetched++;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto odbc_result(int result_id, mixed field)
+ Get result data */
+UODBC_FUNCTION(result)
+{
+ char *field;
+ int res_ind;
+ int field_ind;
+ SWORD sql_c_type = SQL_C_CHAR;
+ UODBC_RESULT *result;
+ int i = 0;
+ RETCODE rc;
+ SDWORD fieldsize;
+ pval *arg1, *arg2;
+#if HAVE_SQL_EXTENDED_FETCH
+ UDWORD crow;
+ UWORD RowStatus[1];
+#endif
+#if !defined(COMPILE_DL) && defined(THREAD_SAFE)
+ TLS_VARS;
+#endif
+
+ field_ind = -1;
+ field = NULL;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2 , &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ if (arg2->type == IS_STRING){
+ field = arg2->value.str.val;
+ } else {
+ convert_to_long(arg2);
+ field_ind = arg2->value.lval - 1;
+ }
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if ((result->numcols == 0)){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+ /* get field index if the field parameter was a string */
+ if (field != NULL){
+ for(i = 0; i < result->numcols; i++){
+ if (!strcasecmp(result->values[i].name, field)){
+ field_ind = i;
+ break;
+ }
+ }
+
+ if (field_ind < 0){
+ php3_error(E_WARNING, "Field %s not found", field);
+ RETURN_FALSE;
+ }
+ } else {
+ /* check for limits of field_ind if the field parameter was an int */
+ if (field_ind >= result->numcols || field_ind < 0){
+ php3_error(E_WARNING, "Field index is larger than the number of fields");
+ RETURN_FALSE;
+ }
+ }
+
+ if (result->fetched == 0){
+ /* User forgot to call odbc_fetchrow(), let's do it here */
+#if HAVE_SQL_EXTENDED_FETCH
+ if (result->fetch_abs)
+ 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;
+
+ result->fetched++;
+ }
+
+ switch(result->values[field_ind].coltype){
+ case SQL_BINARY:
+ case SQL_VARBINARY:
+ case SQL_LONGVARBINARY:
+ if (result->binmode <= 1) sql_c_type = SQL_C_BINARY;
+ if (result->binmode <= 0) break;
+ case SQL_LONGVARCHAR:
+ if (IS_SQL_LONG(result->values[field_ind].coltype)){
+ if (result->longreadlen <= 0)
+ break;
+ else
+ fieldsize = result->longreadlen;
+ } else {
+
+ SQLColAttributes(result->stmt, (UWORD)(field_ind + 1),
+ (UWORD)((sql_c_type == SQL_C_BINARY) ? SQL_COLUMN_LENGTH :
+ SQL_COLUMN_DISPLAY_SIZE),
+ NULL, 0, NULL, &fieldsize);
+ }
+ /* For char data, the length of the returned string will be longreadlen - 1 */
+ fieldsize = (result->longreadlen <= 0) ? 4096 : result->longreadlen;
+ field = emalloc(fieldsize);
+ if (!field){
+ php3_error(E_WARNING, "Out of memory");
+ RETURN_FALSE;
+ }
+ /* SQLGetData will truncate CHAR data to fieldsize - 1 bytes and append \0.
+ For binary data it is truncated to fieldsize bytes.
+ */
+ rc = SQLGetData(result->stmt, (UWORD)(field_ind + 1), sql_c_type,
+ field, fieldsize, &result->values[field_ind].vallen);
+
+ if (rc == SQL_ERROR) {
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SQLGetData");
+ efree(field);
+ RETURN_FALSE;
+ }
+
+ if (result->values[field_ind].vallen == SQL_NULL_DATA || rc == SQL_NO_DATA_FOUND){
+ efree(field);
+ RETURN_FALSE;
+ }
+ /* Reduce fieldlen by 1 if we have char data. One day we might
+ have binary strings... */
+ if (result->values[field_ind].coltype == SQL_LONGVARCHAR) fieldsize -= 1;
+ /* Don't duplicate result, saves one emalloc.
+ For SQL_SUCCESS, the length is in vallen.
+ */
+ RETURN_STRINGL(field, (rc == SQL_SUCCESS_WITH_INFO) ? fieldsize :
+ result->values[field_ind].vallen, 0);
+ break;
+
+ default:
+ if (result->values[field_ind].vallen == SQL_NULL_DATA){
+ RETURN_FALSE;
+ } else {
+ RETURN_STRINGL(result->values[field_ind].value, result->values[field_ind].vallen, 1);
+ }
+ break;
+ }
+
+/* If we come here, output unbound LONG and/or BINARY column data to the client */
+
+
+ /* We emalloc 1 byte more for SQL_C_CHAR (trailing \0) */
+ fieldsize = (sql_c_type == SQL_C_CHAR) ? 4096 : 4095;
+ if ((field = emalloc(fieldsize)) == NULL){
+ php3_error(E_WARNING,"Out of memory");
+ RETURN_FALSE;
+ }
+
+ /* Call SQLGetData() until SQL_SUCCESS is returned */
+ while (1) {
+ rc = SQLGetData(result->stmt, (UWORD)(field_ind + 1),sql_c_type,
+ field, fieldsize, &result->values[field_ind].vallen);
+
+ if (rc == SQL_ERROR) {
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SQLGetData");
+ efree(field);
+ RETURN_FALSE;
+ }
+
+ if (result->values[field_ind].vallen == SQL_NULL_DATA){
+ efree(field);
+ RETURN_FALSE;
+ }
+ /* chop the trailing \0 by outputing only 4095 bytes */
+ PHPWRITE(field,(rc == SQL_SUCCESS_WITH_INFO) ? 4095 :
+ result->values[field_ind].vallen);
+
+ if (rc == SQL_SUCCESS) { /* no more data avail */
+ efree(field);
+ RETURN_TRUE;
+ }
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto odbc_result_all(int result_id [, string format])
+ Print result as HTML table */
+UODBC_FUNCTION(result_all)
+{
+ char *buf = NULL;
+ int res_ind, numArgs;
+ UODBC_RESULT *result;
+ int i;
+ RETCODE rc;
+ pval *arg1, *arg2;
+ SWORD sql_c_type;
+#if HAVE_SQL_EXTENDED_FETCH
+ UDWORD crow;
+ UWORD RowStatus[1];
+#endif
+#if !defined(COMPILE_DL) && defined(THREAD_SAFE)
+ TLS_VARS
+#endif
+
+ numArgs = ARG_COUNT(ht);
+ if (numArgs == 1){
+ if (getParameters(ht, 1, &arg1) == FAILURE)
+ WRONG_PARAM_COUNT;
+ } else {
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ res_ind = arg1->value.lval;
+
+ /* check result */
+ if ((result = UODBC_GET_RESULT(list, res_ind)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+#if HAVE_SQL_EXTENDED_FETCH
+ if (result->fetch_abs)
+ 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){
+ php3_printf("<h2>No rows found</h2>\n");
+ RETURN_LONG(0);
+ }
+
+ /* Start table tag */
+ if (numArgs == 1){
+ php3_printf("<table><tr>");
+ } else {
+ convert_to_string(arg2);
+ php3_printf("<table %s ><tr>",arg2->value.str.val);
+ }
+
+ for(i = 0; i < result->numcols; i++)
+ php3_printf("<th>%s</th>", result->values[i].name);
+
+ php3_printf("</tr>\n");
+
+ while(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO){
+ result->fetched++;
+ php3_printf("<tr>");
+ for(i = 0; i < result->numcols; i++){
+ sql_c_type = SQL_C_CHAR;
+ switch(result->values[i].coltype){
+ case SQL_BINARY:
+ case SQL_VARBINARY:
+ case SQL_LONGVARBINARY:
+ if (result->binmode <= 0){
+ php3_printf("<td>Not printable</td>");
+ 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){
+ php3_printf("<td>Not printable</td>");
+ break;
+ }
+
+ if (buf == NULL) buf = emalloc(result->longreadlen);
+
+ rc = SQLGetData(result->stmt, (UWORD)(i + 1),sql_c_type,
+ buf, result->longreadlen, &result->values[i].vallen);
+
+ php3_printf("<td>");
+
+ if (rc == SQL_ERROR) {
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SQLGetData");
+ php3_printf("</td></tr></table>");
+ efree(buf);
+ RETURN_FALSE;
+ }
+ if (rc == SQL_SUCCESS_WITH_INFO)
+ php3_printf(buf,result->longreadlen);
+ else if (result->values[i].vallen == SQL_NULL_DATA){
+ php3_printf("&nbsp;</td>");
+ break;
+ }
+ else
+ {
+ php3_printf(buf, result->values[i].vallen);
+ }
+ php3_printf("</td>");
+ break;
+
+ default:
+ if (result->values[i].vallen == SQL_NULL_DATA){
+ php3_printf("<td>&nbsp;</td>");
+ } else {
+ php3_printf("<td>%s</td>", result->values[i].value);
+ }
+ break;
+ }
+ }
+ php3_printf("</tr>\n");
+
+#if HAVE_SQL_EXTENDED_FETCH
+ if (result->fetch_abs)
+ rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
+ else
+#endif
+ rc = SQLFetch(result->stmt);
+ }
+ php3_printf("</table>\n");
+ if (buf) efree(buf);
+ RETURN_LONG(result->fetched);
+}
+/* }}} */
+
+/* {{{ proto odbc_free_result(int result_id)
+ Free resources associated with a result */
+UODBC_FUNCTION(free_result)
+{
+ pval *arg1;
+
+ if ( getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ UODBC_DEL_RESULT(list, arg1->value.lval);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto odbc_connect(string DSN, string user, string password [, int cursor_option])
+ Connect to a datasource */
+UODBC_FUNCTION(connect)
+{
+ PHP3_UODBC_DO_CONNECT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto odbc_connect(string DSN, string user, string password [, int cursor_option])
+ Establish a persistant connection to a datasource */
+UODBC_FUNCTION(pconnect)
+{
+ PHP3_UODBC_DO_CONNECT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* Persistent connections: two list-types le_pconn, le_conn and a plist
+ * where hashed connection info is stored together with index pointer to
+ * the actual link of type le_pconn in the list. Only persistent
+ * connections get hashed up. Normal connections use existing pconnections.
+ * Maybe this has to change with regard to transactions on pconnections?
+ * Possibly set autocommit to on on request shutdown.
+ *
+ * We do have to hash non-persistent connections, and reuse connections.
+ * In the case where two connects were being made, without closing the first
+ * connect, access violations were occuring. This is because some of the
+ * "globals" in this module should actualy be per-connection variables. I
+ * simply fixed things to get them working for now. Shane
+ */
+void PHP3_UODBC_DO_CONNECT(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+{
+ char *db = NULL;
+ char *uid = NULL;
+ char *pwd = NULL;
+ pval *arg1, *arg2, *arg3, *arg4;
+ UODBC_CONNECTION *db_conn;
+ RETCODE rc;
+ list_entry *index_ptr;
+ char *hashed_details;
+ int hashed_len, len, id, cur_opt;
+ int type;
+ UODBC_TLS_VARS;
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).resource_list = list;
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).resource_plist = plist;
+
+ /* Now an optional 4th parameter specifying the cursor type
+ * defaulting to the cursors default
+ */
+ switch(ARG_COUNT(ht)) {
+ case 3:
+ if (getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ /* Use Default: Probably a better way to do this */
+ cur_opt = SQL_CUR_DEFAULT;
+ break;
+ case 4:
+ if (getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg4);
+ cur_opt = arg4->value.lval;
+
+ /* Confirm the cur_opt range */
+ if (! (cur_opt == SQL_CUR_USE_IF_NEEDED ||
+ cur_opt == SQL_CUR_USE_ODBC ||
+ cur_opt == SQL_CUR_USE_DRIVER ||
+ cur_opt == SQL_CUR_DEFAULT) ) {
+ php3_error(E_WARNING, "uODBC: Invalid Cursor type (%d)", cur_opt);
+ RETURN_FALSE;
+ }
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ convert_to_string(arg1);
+ convert_to_string(arg2);
+ convert_to_string(arg3);
+
+ db = arg1->value.str.val;
+ uid = arg2->value.str.val;
+ pwd = arg3->value.str.val;
+
+ if (UODBC_GLOBAL(PHP3_UODBC_MODULE).allow_persistent <= 0) {
+ persistent = 0;
+ }
+
+ if (UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links != -1 &&
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links >=
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_links) {
+ php3_error(E_WARNING, "uODBC: Too many open links (%d)",
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links);
+ RETURN_FALSE;
+ }
+
+ /* the user requested a persistent connection */
+ if (persistent &&
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent != -1 &&
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent >=
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).max_persistent) {
+ php3_error(E_WARNING,"uODBC: Too many open persistent links (%d)",
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent);
+ RETURN_FALSE;
+ }
+
+ len = strlen(db) + strlen(uid) + strlen(pwd) + strlen(UODBC_NAME) + 5;
+ hashed_details = emalloc(len);
+
+ if (hashed_details == NULL) {
+ php3_error(E_WARNING, "Out of memory");
+ RETURN_FALSE;
+ }
+
+ hashed_len = _php3_sprintf(hashed_details, "%s_%s_%s_%s_%d", UODBC_NAME, db, uid, pwd, cur_opt);
+
+ /* FIXME the idea of checking to see if our connection is already persistent
+ is good, but it adds a lot of overhead to non-persistent connections. We
+ should look and see if we can fix that somehow */
+ /* try to find if we already have this link in our persistent list,
+ * no matter if it is to be persistent or not
+ */
+
+ if ((persistent || (_php3_hash_find(list, hashed_details, hashed_len + 1,
+ (void **) &index_ptr) == FAILURE || !php3_list_find((int) index_ptr->ptr, &type))) &&
+ _php3_hash_find(plist, hashed_details, hashed_len + 1,
+ (void **) &index_ptr) == FAILURE) {
+ /* the link is not in the persistent list */
+ list_entry new_le, new_index_ptr;
+
+ if (persistent) {
+ db_conn = (UODBC_CONNECTION *)malloc(sizeof(UODBC_CONNECTION));
+ } else {
+ db_conn = (UODBC_CONNECTION *)emalloc(sizeof(UODBC_CONNECTION));
+ }
+
+ SQLAllocConnect(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, &db_conn->hdbc);
+#if HAVE_SOLID
+ SQLSetConnectOption(db_conn->hdbc, SQL_TRANSLATE_OPTION,
+ SQL_SOLID_XLATOPT_NOCNV);
+#endif
+#if HAVE_OPENLINK
+ {
+ char dsnbuf[300];
+ short dsnbuflen;
+
+ rc = SQLDriverConnect(db_conn->hdbc, NULL, db, SQL_NTS,
+ dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen,
+ SQL_DRIVER_COMPLETE);
+ }
+#else
+ if(cur_opt != SQL_CUR_DEFAULT){
+ rc = SQLSetConnectOption(db_conn->hdbc, SQL_ODBC_CURSORS, cur_opt);
+ if (rc != SQL_SUCCESS ) { /* && rc != SQL_SUCCESS_WITH_INFO ? */
+ UODBC_SQL_ERROR(db_conn->hdbc, SQL_NULL_HSTMT, "SQLSetConnectOption");
+ SQLFreeConnect(db_conn->hdbc);
+ if (persistent)
+ free(db_conn);
+ else
+ efree(db_conn);
+ RETURN_FALSE;
+ }
+ }
+
+#if HAVE_EMPRESS
+ {
+ int direct = 0;
+ char dsnbuf[300];
+ short dsnbuflen;
+ char *ldb = 0;
+
+ if (strstr ((char*)db, ";"))
+ {
+ direct = 1;
+ if (uid && !strstr ((char*)db, "uid") &&
+ !strstr ((char*)db, "UID"))
+ {
+ ldb = (char*) emalloc (strlen(db) +
+ strlen (uid) +
+ strlen (pwd) + 12);
+ sprintf (ldb, "%s;UID=%s;PWD=%s",
+ db, uid, pwd);
+ }
+ else
+ {
+ ldb = (char*) emalloc (strlen (db) + 1);
+ strcat (ldb, db);
+ }
+ }
+
+ if (direct)
+ rc = SQLDriverConnect (db_conn->hdbc, NULL,
+ ldb, strlen (ldb), dsnbuf, 300,
+ &dsnbuflen, SQL_DRIVER_NOPROMPT);
+
+ else
+ rc = SQLConnect(db_conn->hdbc, db, SQL_NTS,
+ uid, SQL_NTS, pwd, SQL_NTS);
+
+ if (ldb)
+ efree (ldb);
+ }
+#else
+ rc = SQLConnect(db_conn->hdbc, db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS);
+
+#endif
+
+#endif
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ UODBC_SQL_ERROR(db_conn->hdbc, SQL_NULL_HSTMT, "SQLConnect");
+ SQLFreeConnect(db_conn->hdbc);
+ if (persistent)
+ free(db_conn);
+ else
+ efree(db_conn);
+ RETURN_FALSE;
+ }
+ db_conn->open = 1;
+ if (persistent){
+ new_le.type = UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn;
+ new_le.ptr = db_conn;
+ return_value->value.lval =
+ php3_plist_insert(db_conn, UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn);
+ new_index_ptr.ptr = (void *) return_value->value.lval;
+#ifdef THREAD_SAFE
+ new_index_ptr.type = _php3_le_index_ptr();
+#else
+ new_index_ptr.type = le_index_ptr;
+#endif
+ if (_php3_hash_update(plist,hashed_details,hashed_len + 1,(void *) &new_index_ptr,
+ sizeof(list_entry),NULL)==FAILURE) {
+ SQLDisconnect(db_conn->hdbc);
+ SQLFreeConnect(db_conn->hdbc);
+ free(db_conn);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_persistent++;
+ } else {
+ new_le.type = UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn;
+ new_le.ptr = db_conn;
+ return_value->value.lval =
+ php3_list_insert(db_conn, UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn);
+ new_index_ptr.ptr = (void *) return_value->value.lval;
+#ifdef THREAD_SAFE
+ new_index_ptr.type = _php3_le_index_ptr();
+#else
+ new_index_ptr.type = le_index_ptr;
+#endif
+ if (_php3_hash_update(list,hashed_details,hashed_len + 1,(void *) &new_index_ptr,
+ sizeof(list_entry),NULL)==FAILURE) {
+ SQLDisconnect(db_conn->hdbc);
+ SQLFreeConnect(db_conn->hdbc);
+ efree(db_conn);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ }
+
+ UODBC_GLOBAL(PHP3_UODBC_MODULE).num_links++;
+
+ } else {
+ /* we are already connected */
+#ifdef THREAD_SAFE
+ if (index_ptr->type != _php3_le_index_ptr()) {
+#else
+ if (index_ptr->type != le_index_ptr) {
+#endif
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ id = (int) index_ptr->ptr;
+
+ /* first see if there is a persistent connection and use it,
+ else, if we are making a non-persistent connect, check our
+ non-persistent list */
+ db_conn = (UODBC_CONNECTION *)php3_plist_find(id, &type);
+ if(!db_conn && !persistent)
+ db_conn = (UODBC_CONNECTION *)php3_list_find(id, &type);
+
+
+ /* FIXME test if the connection is dead */
+ /* For Adabas D and local db connections, a reconnect is performed
+ * implicitly when needed. Cool.
+ */
+
+ if (db_conn && (type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn ||
+ type == UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn)){
+ return_value->value.lval = id;
+ } else {
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ }
+ efree(hashed_details);
+ return_value->type = IS_LONG;
+}
+
+/* {{{ proto odbc_close(int connection_id)
+ Close an ODBC connection */
+UODBC_FUNCTION(close)
+{
+ pval *arg1;
+ HDBC conn;
+ int type, ind;
+ UODBC_TLS_VARS;
+
+ if (getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ ind = (int)arg1->value.lval;
+ conn = (HDBC)php3_list_find(ind, &type);
+ if (!conn ||
+ (type != UODBC_GLOBAL(PHP3_UODBC_MODULE).le_conn &&
+ type != UODBC_GLOBAL(PHP3_UODBC_MODULE).le_pconn)) {
+ return;
+ }
+ php3_list_delete(ind);
+}
+/* }}} */
+
+/* {{{ proto odbc_num_rows(int result_id)
+ Get number of rows in a result */
+UODBC_FUNCTION(num_rows)
+{
+ UODBC_RESULT *result;
+ SDWORD rows;
+ pval *arg1;
+
+ if ( getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ SQLRowCount(result->stmt, &rows);
+ RETURN_LONG(rows);
+}
+/* }}} */
+
+/* {{{ proto odbc_num_fields(int result_id)
+ Get number of columns in a result */
+UODBC_FUNCTION(num_fields)
+{
+ UODBC_RESULT *result;
+ pval *arg1;
+
+ if ( getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(result->numcols);
+}
+/* }}} */
+
+/* {{{ proto odbc_field_name(int result_id, int field_number)
+ Get a column name */
+UODBC_FUNCTION(field_name)
+{
+ UODBC_RESULT *result;
+ pval *arg1, *arg2;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+ if (arg2->value.lval > result->numcols){
+ php3_error(E_WARNING, "Field index larger than number of fields");
+ RETURN_FALSE;
+ }
+
+ if (arg2->value.lval < 1){
+ php3_error(E_WARNING, "Field numbering starts at 1");
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(result->values[arg2->value.lval - 1].name,1)
+}
+/* }}} */
+
+/* {{{ proto odbc_field_type(int result_id, int field_number)
+ Get the datatype of a column */
+UODBC_FUNCTION(field_type)
+{
+ UODBC_RESULT *result;
+ char tmp[32];
+ SWORD tmplen;
+ pval *arg1, *arg2;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+ if (arg2->value.lval > result->numcols){
+ php3_error(E_WARNING, "Field index larger than number of fields");
+ RETURN_FALSE;
+ }
+
+ SQLColAttributes(result->stmt, (UWORD)arg2->value.lval,
+ SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL);
+ RETURN_STRING(tmp,1)
+}
+/* }}} */
+
+/* {{{ proto odbc_field_len(int result_id, int field_number)
+ Get the length of a column */
+UODBC_FUNCTION(field_len)
+{
+ UODBC_RESULT *result;
+ SDWORD len;
+ pval *arg1, *arg2;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (result->numcols == 0){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+
+ if (arg2->value.lval > result->numcols){
+ php3_error(E_WARNING, "Field index larger than number of fields");
+ RETURN_FALSE;
+ }
+ SQLColAttributes(result->stmt, (UWORD)arg2->value.lval,
+ SQL_COLUMN_PRECISION, NULL, 0, NULL, &len);
+
+ RETURN_LONG(len);
+}
+/* }}} */
+
+/* {{{ proto odbc_field_num(int result_id, string field_name)
+ Return column number */
+UODBC_FUNCTION(field_num)
+{
+ int field_ind;
+ char *fname;
+ UODBC_RESULT *result;
+ int i;
+ pval *arg1, *arg2;
+
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ fname = arg2->value.str.val;
+
+ if (arg1->value.lval == 1){
+ php3_error(E_WARNING, "No tuples available at this result index");
+ RETURN_FALSE;
+ }
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ field_ind = -1;
+ for(i = 0; i < result->numcols; i++){
+ if (strcasecmp(result->values[i].name, fname) == 0)
+ field_ind = i + 1;
+ }
+ if (field_ind == -1)
+ RETURN_FALSE;
+ RETURN_LONG(field_ind);
+}
+/* }}} */
+
+/* {{{ proto odbc_autocommit(int connection_id, int OnOff)
+ Toggle autocommit mode */
+UODBC_FUNCTION(autocommit)
+{
+ UODBC_CONNECTION *curr_conn;
+ RETCODE rc;
+ pval *arg1, *arg2 = NULL;
+ int argc;
+
+ argc = ARG_COUNT(ht);
+ if (argc == 2) {
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ } else if (argc == 1) {
+ if (getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ } else {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ if (arg2) {
+ convert_to_long(arg2);
+ }
+
+ if ((curr_conn = UODBC_GET_CONN(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (arg2) {
+ rc = SQLSetConnectOption(curr_conn->hdbc, SQL_AUTOCOMMIT,
+ (arg2->value.lval) ?
+ SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "Set autocommit");
+ RETURN_FALSE;
+ }
+ RETVAL_TRUE;
+ } else {
+ SDWORD status;
+
+ rc = SQLGetConnectOption(curr_conn->hdbc, SQL_AUTOCOMMIT, (PTR)&status);
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "Test autocommit");
+ RETURN_FALSE;
+ }
+ RETVAL_LONG((long)status);
+ }
+}
+/* }}} */
+
+void PHP3_UODBC_TRANSACT(INTERNAL_FUNCTION_PARAMETERS, int type)
+{
+ UODBC_CONNECTION *curr_conn;
+ RETCODE rc;
+ pval *arg1;
+ UODBC_TLS_VARS;
+
+ if ( getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+
+ if ((curr_conn = UODBC_GET_CONN(list, arg1->value.lval)) == NULL){
+ RETURN_FALSE;
+ }
+
+ rc = SQLTransact(UODBC_GLOBAL(PHP3_UODBC_MODULE).henv, curr_conn->hdbc, (UWORD)((type)?SQL_COMMIT:SQL_ROLLBACK));
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SQLTransact");
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+
+/* {{{ proto odbc_commit(int connection_id)
+ Commit an ODBC transaction */
+UODBC_FUNCTION(commit)
+{
+ PHP3_UODBC_TRANSACT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto odbc_rollback(int connection_id)
+ Rollback a transaction */
+UODBC_FUNCTION(rollback)
+{
+ PHP3_UODBC_TRANSACT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto odbc_setoption(??)
+ ?? */
+UODBC_FUNCTION(setoption)
+{
+ UODBC_CONNECTION *curr_conn;
+ UODBC_RESULT *result;
+ RETCODE rc;
+ pval *arg1, *arg2, *arg3, *arg4;
+
+ if ( getParameters(ht, 3, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_long(arg3);
+ convert_to_long(arg4);
+
+ switch (arg2->value.lval) {
+ case 1: /* SQLSetConnectOption */
+ if ((curr_conn = UODBC_GET_CONN(list, arg1->value.lval)) == NULL){
+ RETURN_FALSE;
+ }
+ rc = SQLSetConnectOption(curr_conn->hdbc, (unsigned short)(arg3->value.lval), (arg4->value.lval));
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SetConnectOption");
+ RETURN_FALSE;
+ }
+ break;
+ case 2: /* SQLSetStmtOption */
+ if ((result = UODBC_GET_RESULT(list, arg1->value.lval)) == NULL) {
+ RETURN_FALSE;
+ }
+ rc = SQLSetStmtOption(result->stmt, (unsigned short)(arg3->value.lval), (arg4->value.lval));
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ UODBC_SQL_ERROR(result->conn_ptr->hdbc, result->stmt, "SetStmtOption");
+ RETURN_FALSE;
+ }
+ break;
+ default:
+ php3_error(E_WARNING, "Unknown option type");
+ RETURN_FALSE;
+ break;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+#endif /* HAVE_UODBC */
+
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/odbc/php3_odbc.h b/ext/odbc/php3_odbc.h
new file mode 100644
index 0000000000..1357553e27
--- /dev/null
+++ b/ext/odbc/php3_odbc.h
@@ -0,0 +1,729 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@guardian.no> |
+ | Andreas Karajannis <Andreas.Karajannis@gmd.de> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _UNIFIED_ODBC_H
+#define _UNIFIED_ODBC_H
+
+#if HAVE_UODBC
+
+/*these defines are used to seperate the different
+database modules that use the uodbc interface so that
+two or more of them can be compiled into the same
+php binary*/
+
+/*
+*
+* Defines for ODBC
+*
+*/
+#if HAVE_UODBC
+/* win32 vars for thread local storage */
+#define UODBC_MUTEX uodbc_mutex
+#define UODBC_TLS UODBCTls
+#define UODBC_GLOBAL_STRUCT uodbc_global_struct
+#define UODBC_GLOBALS uodbc_globals
+/* defines for variables, structs, etc */
+#define UODBC_MODULE_NAME "ODBC (uODBC)"
+#define UODBC_FUNCTIONS uodbc_functions
+#define UODBC_MODULE_ENTRY uodbc_module_entry
+#define UODBC_CONNECTION uodbc_connection
+#define UODBC_RESULT_VALUE uodbc_result_value
+#define UODBC_RESULT uodbc_result
+#define UODBC_MODULE uodbc_module
+#define PHP3_UODBC_MODULE php3_uodbc_module
+
+/* function defines */
+#define PHP3_MINIT_UODBC php3_minit_uodbc
+#define PHP3_MSHUTDOWN_UODBC php3_mshutdown_uodbc
+#define PHP3_RINIT_UODBC php3_rinit_uodbc
+#define PHP3_INFO_UODBC php3_info_uodbc
+#define PHP3_UODBC_SETOPTION php3_uodbc_setoption
+#define PHP3_UODBC_AUTOCOMMIT php3_uodbc_autocommit
+#define PHP3_UODBC_CLOSE php3_uodbc_close
+#define PHP3_UDOBC_CLOSE_ALL php3_uodbc_close_all
+#define PHP3_UODBC_COMMIT php3_uodbc_commit
+#define PHP3_UODBC_CONNECT php3_uodbc_connect
+#define PHP3_UODBC_PCONNECT php3_uodbc_pconnect
+#define PHP3_UODBC_DO_CONNECT php3_uodbc_do_connect
+#define PHP3_UODBC_CURSOR php3_uodbc_cursor
+#define PHP3_UODBC_DO php3_uodbc_do
+#define PHP3_UODBC_EXECUTE php3_uodbc_execute
+#define PHP3_UODBC_FETCH_INTO php3_uodbc_fetch_into
+#define PHP3_UODBC_FETCH_ROW php3_uodbc_fetch_row
+#define PHP3_UODBC_FIELD_LEN php3_uodbc_field_len
+#define PHP3_UODBC_FIELD_NAME php3_uodbc_field_name
+#define PHP3_UODBC_FIELD_TYPE php3_uodbc_field_type
+#define PHP3_UODBC_FIELD_NUM php3_uodbc_field_num
+#define PHP3_UODBC_FREE_RESULT php3_uodbc_free_result
+#define PHP3_UODBC_NUM_FIELDS php3_uodbc_num_fields
+#define PHP3_UODBC_NUM_ROWS php3_uodbc_num_rows
+#define PHP3_UODBC_PREPARE php3_uodbc_prepare
+#define PHP3_UODBC_RESULT php3_uodbc_result
+#define PHP3_UODBC_RESULT_ALL php3_uodbc_result_all
+#define PHP3_UODBC_ROLLBACK php3_uodbc_rollback
+#define PHP3_UODBC_TRANSACT php3_uodbc_transact
+#define PHP3_UODBC_BINMODE php3_uodbc_binmode
+#define PHP3_UODBC_LONGREADLEN php3_uodbc_longreadlen
+
+/* internal function defines */
+#define UODBC_ADD_RESULT uodbc_add_result
+#define UODBC_GET_RESULT uodbc_get_result
+#define UODBC_DEL_RESULT uodbc_del_result
+#define UODBC_ADD_CONN uodbc_add_conn
+#define UODBC_GET_CONN uodbc_get_conn
+#define UODBC_DEL_CONN uodbc_del_conn
+#define UODBC_SQL_ERROR uodbc_sql_error
+#define UODBC_BINDCOLS uodbc_bindcols
+#define _FREE_UODBC_RESULT _free_uodbc_result
+#define _CLOSE_UODBC_CONNECTION _close_uodbc_connection
+#define _CLOSE_UODBC_PCONNECTION _close_uodbc_pconnection
+/* function name defines */
+#define ODBC_SETOPTION "odbc_setoption"
+#define ODBC_AUTOCOMMIT "odbc_autocommit"
+#define ODBC_CLOSE "odbc_close"
+#define ODBC_CLOSE_ALL "odbc_close_all"
+#define ODBC_COMMIT "odbc_commit"
+#define ODBC_CONNECT "odbc_connect"
+#define ODBC_PCONNECT "odbc_pconnect"
+#define ODBC_CURSOR "odbc_cursor"
+#define ODBC_DO "odbc_do"
+#define ODBC_EXEC "odbc_exec"
+#define ODBC_PREPARE "odbc_prepare"
+#define ODBC_EXECUTE "odbc_execute"
+#define ODBC_FETCH_ROW "odbc_fetch_row"
+#define ODBC_FETCH_INTO "odbc_fetch_into"
+#define ODBC_FIELD_LEN "odbc_field_len"
+#define ODBC_FIELD_NAME "odbc_field_name"
+#define ODBC_FIELD_TYPE "odbc_field_type"
+#define ODBC_FIELD_NUM "odbc_field_num"
+#define ODBC_FREE_RESULT "odbc_free_result"
+#define ODBC_NUM_FIELDS "odbc_num_fields"
+#define ODBC_NUM_ROWS "odbc_num_rows"
+#define ODBC_RESULT "odbc_result"
+#define ODBC_RESULT_ALL "odbc_result_all"
+#define ODBC_ROLLBACK "odbc_rollback"
+#define ODBC_TRANSACT "odbc_transact"
+#define ODBC_DO_CONNECT "odbc_do_connect"
+#define ODBC_LONGREADLEN "odbc_longreadlen"
+#define ODBC_BINMODE "odbc_binmode"
+
+/* ini variable defines */
+#define ODBC_INI_DEFAULTDB "uodbc.default_db"
+#define ODBC_INI_DEFAULTUSER "uodbc.default_user"
+#define ODBC_INI_DEFAULTPW "uodbc.default_pw"
+#define ODBC_INI_ALLOWPERSISTENT "uodbc.allow_persistent"
+#define ODBC_INI_MAXPERSISTENT "uodbc.max_persistent"
+#define ODBC_INI_MAXLINKS "uodbc.max_links"
+#define ODBC_INI_DEFAULTLRL "uodbc.defaultlrl"
+#define ODBC_INI_DEFAULTBINMODE "uodbc.defaultbinmode"
+#endif
+
+/*
+*
+* Defines for SOLID
+*
+*/
+
+
+#if 0 /* HAVE_SOLID turned off for now,
+ will use above uodbc defines for now */
+/* win32 vars for thread local storage */
+#define UODBC_MUTEX solid_mutex
+#define UODBC_TLS SOLIDTls
+#define UODBC_GLOBAL_STRUCT solid_global_struct
+#define UODBC_GLOBALS solid_globals
+/* defines for variables, structs, etc */
+#define UODBC_MODULE_NAME "SOLID (uODBC)"
+#define UODBC_FUNCTIONS solid_functions
+#define UODBC_MODULE_ENTRY solid_module_entry
+#define UODBC_CONNECTION solid_connection
+#define UODBC_RESULT_VALUE solid_result_value
+#define UODBC_RESULT solid_result
+#define UODBC_MODULE solid_module
+#define PHP3_UODBC_MODULE php3_solid_module
+
+/* function defines */
+#define PHP3_MINIT_UODBC php3_minit_solid
+#define PHP3_MSHUTDOWN_UODBC php3_mshutdown_solid
+#define PHP3_RINIT_UODBC php3_rinit_solid
+#define PHP3_INFO_UODBC php3_info_solid
+#define PHP3_UODBC_SETOPTION php3_solid_setoption
+#define PHP3_UODBC_AUTOCOMMIT php3_solid_autocommit
+#define PHP3_UODBC_CLOSE php3_solid_close
+#define PHP3_UDOBC_CLOSE_ALL php3_solid_close_all
+#define PHP3_UODBC_COMMIT php3_solid_commit
+#define PHP3_UODBC_CONNECT php3_solid_connect
+#define PHP3_UODBC_PCONNECT php3_solid_pconnect
+#define PHP3_UODBC_DO_CONNECT php3_solid_do_connect
+#define PHP3_UODBC_CURSOR php3_solid_cursor
+#define PHP3_UODBC_DO php3_solid_do
+#define PHP3_UODBC_EXECUTE php3_solid_execute
+#define PHP3_UODBC_FETCH_INTO php3_solid_fetch_into
+#define PHP3_UODBC_FETCH_ROW php3_solid_fetch_row
+#define PHP3_UODBC_FIELD_LEN php3_solid_field_len
+#define PHP3_UODBC_FIELD_NAME php3_solid_field_name
+#define PHP3_UODBC_FIELD_TYPE php3_solid_field_type
+#define PHP3_UODBC_FREE_RESULT php3_solid_free_result
+#define PHP3_UODBC_NUM_FIELDS php3_solid_num_fields
+#define PHP3_UODBC_NUM_ROWS php3_solid_num_rows
+#define PHP3_UODBC_PREPARE php3_solid_prepare
+#define PHP3_UODBC_RESULT php3_solid_result
+#define PHP3_UODBC_RESULT_ALL php3_solid_result_all
+#define PHP3_UODBC_ROLLBACK php3_solid_rollback
+#define PHP3_UODBC_TRANSACT php3_solid_transact
+
+/* internal function defines */
+#define UODBC_ADD_RESULT solid_add_result
+#define UODBC_GET_RESULT solid_get_result
+#define UODBC_DEL_RESULT solid_del_result
+#define UODBC_ADD_CONN solid_add_conn
+#define UODBC_GET_CONN solid_get_conn
+#define UODBC_DEL_CONN solid_del_conn
+#define UODBC_SQL_ERROR solid_sql_error
+#define UODBC_BINDCOLS solid_bindcols
+#define _FREE_UODBC_RESULT _free_solid_result
+#define _CLOSE_UODBC_CONNECTION _close_solid_connection
+#define _CLOSE_UODBC_PCONNECTION _close_solid_pconnection
+/* function name defines */
+#define ODBC_SETOPTION "solid_setoption"
+#define ODBC_AUTOCOMMIT "solid_autocommit"
+#define ODBC_CLOSE "solid_close"
+#define ODBC_CLOSE_ALL "solid_close_all"
+#define ODBC_COMMIT "solid_commit"
+#define ODBC_CONNECT "solid_connect"
+#define ODBC_PCONNECT "solid_pconnect"
+#define ODBC_CURSOR "solid_cursor"
+#define ODBC_DO "solid_do"
+#define ODBC_EXEC "solid_exec"
+#define ODBC_PREPARE "solid_prepare"
+#define ODBC_EXECUTE "solid_execute"
+#define ODBC_FETCH_ROW "solid_fetch_row"
+#define ODBC_FETCH_INTO "solid_fetch_into"
+#define ODBC_FIELD_LEN "solid_field_len"
+#define ODBC_FIELD_NAME "solid_field_name"
+#define ODBC_FIELD_TYPE "solid_field_type"
+#define ODBC_FREE_RESULT "solid_free_result"
+#define ODBC_NUM_FIELDS "solid_num_fields"
+#define ODBC_NUM_ROWS "solid_num_rows"
+#define ODBC_RESULT "solid_result"
+#define ODBC_RESULT_ALL "solid_result_all"
+#define ODBC_ROLLBACK "solid_rollback"
+#define ODBC_TRANSACT "solid_transact"
+#define ODBC_DO_CONNECT "solid_do_connect"
+
+/* ini variable defines */
+#define ODBC_INI_DEFAULTDB "solid.default_db"
+#define ODBC_INI_DEFAULTUSER "solid.default_user"
+#define ODBC_INI_DEFAULTPW "solid.default_pw"
+#define ODBC_INI_ALLOWPERSISTENT "solid.allow_persistent"
+#define ODBC_INI_MAXPERSISTENT "solid.max_persistent"
+#define ODBC_INI_MAXLINKS "solid.max_links"
+#endif
+
+
+/*
+*
+* Defines for ADABAS
+*
+*/
+
+
+#if 0 /* HAVE_ADABAS turned for for now, uses
+ defines from the ODBC section */
+/* win32 vars for thread local storage */
+#define UODBC_MUTEX adabas_mutex
+#define UODBC_TLS ADABASTls
+#define UODBC_GLOBAL_STRUCT adabas_global_struct
+#define UODBC_GLOBALS adabas_globals
+/* defines for variables, structs, etc */
+#define UODBC_MODULE_NAME "ADABAS D (uODBC)"
+#define UODBC_FUNCTIONS adabas_functions
+#define UODBC_MODULE_ENTRY adabas_module_entry
+#define UODBC_CONNECTION adabas_connection
+#define UODBC_RESULT_VALUE adabas_result_value
+#define UODBC_RESULT adabas_result
+#define UODBC_MODULE adabas_module
+#define PHP3_UODBC_MODULE php3_adabas_module
+
+/* function defines */
+#define PHP3_MINIT_UODBC php3_minit_adabas
+#define PHP3_MSHUTDOWN_UODBC php3_mshutdown_adabas
+#define PHP3_RINIT_UODBC php3_rinit_adabas
+#define PHP3_INFO_UODBC php3_info_adabas
+#define PHP3_UODBC_SETOPTION php3_adabas_setoption
+#define PHP3_UODBC_AUTOCOMMIT php3_adabas_autocommit
+#define PHP3_UODBC_CLOSE php3_adabas_close
+#define PHP3_UDOBC_CLOSE_ALL php3_adabas_close_all
+#define PHP3_UODBC_COMMIT php3_adabas_commit
+#define PHP3_UODBC_CONNECT php3_adabas_connect
+#define PHP3_UODBC_PCONNECT php3_adabas_pconnect
+#define PHP3_UODBC_DO_CONNECT php3_adabas_do_connect
+#define PHP3_UODBC_CURSOR php3_adabas_cursor
+#define PHP3_UODBC_DO php3_adabas_do
+#define PHP3_UODBC_EXECUTE php3_adabas_execute
+#define PHP3_UODBC_FETCH_INTO php3_adabas_fetch_into
+#define PHP3_UODBC_FETCH_ROW php3_adabas_fetch_row
+#define PHP3_UODBC_FIELD_LEN php3_adabas_field_len
+#define PHP3_UODBC_FIELD_NAME php3_adabas_field_name
+#define PHP3_UODBC_FIELD_TYPE php3_adabas_field_type
+#define PHP3_UODBC_FREE_RESULT php3_adabas_free_result
+#define PHP3_UODBC_NUM_FIELDS php3_adabas_num_fields
+#define PHP3_UODBC_NUM_ROWS php3_adabas_num_rows
+#define PHP3_UODBC_PREPARE php3_adabas_prepare
+#define PHP3_UODBC_RESULT php3_adabas_result
+#define PHP3_UODBC_RESULT_ALL php3_adabas_result_all
+#define PHP3_UODBC_ROLLBACK php3_adabas_rollback
+#define PHP3_UODBC_TRANSACT php3_adabas_transact
+
+/* internal function defines */
+#define UODBC_ADD_RESULT adabas_add_result
+#define UODBC_GET_RESULT adabas_get_result
+#define UODBC_DEL_RESULT adabas_del_result
+#define UODBC_ADD_CONN adabas_add_conn
+#define UODBC_GET_CONN adabas_get_conn
+#define UODBC_DEL_CONN adabas_del_conn
+#define UODBC_SQL_ERROR adabas_sql_error
+#define UODBC_BINDCOLS adabas_bindcols
+#define _FREE_UODBC_RESULT _free_adabas_result
+#define _CLOSE_UODBC_CONNECTION _close_adabas_connection
+#define _CLOSE_UODBC_PCONNECTION _close_adabas_pconnection
+/* function name defines */
+#define ODBC_SETOPTION "adabas_setoption"
+#define ODBC_AUTOCOMMIT "adabas_autocommit"
+#define ODBC_CLOSE "adabas_close"
+#define ODBC_CLOSE_ALL "adabas_close_all"
+#define ODBC_COMMIT "adabas_commit"
+#define ODBC_CONNECT "adabas_connect"
+#define ODBC_PCONNECT "adabas_pconnect"
+#define ODBC_CURSOR "adabas_cursor"
+#define ODBC_DO "adabas_do"
+#define ODBC_EXEC "adabas_exec"
+#define ODBC_PREPARE "adabas_prepare"
+#define ODBC_EXECUTE "adabas_execute"
+#define ODBC_FETCH_ROW "adabas_fetch_row"
+#define ODBC_FETCH_INTO "adabas_fetch_into"
+#define ODBC_FIELD_LEN "adabas_field_len"
+#define ODBC_FIELD_NAME "adabas_field_name"
+#define ODBC_FIELD_TYPE "adabas_field_type"
+#define ODBC_FREE_RESULT "adabas_free_result"
+#define ODBC_NUM_FIELDS "adabas_num_fields"
+#define ODBC_NUM_ROWS "adabas_num_rows"
+#define ODBC_RESULT "adabas_result"
+#define ODBC_RESULT_ALL "adabas_result_all"
+#define ODBC_ROLLBACK "adabas_rollback"
+#define ODBC_TRANSACT "adabas_transact"
+#define ODBC_DO_CONNECT "adabas_do_connect"
+
+/* ini variable defines */
+#define ODBC_INI_DEFAULTDB "adabas.default_db"
+#define ODBC_INI_DEFAULTUSER "adabas.default_user"
+#define ODBC_INI_DEFAULTPW "adabas.default_pw"
+#define ODBC_INI_ALLOWPERSISTENT "adabas.allow_persistent"
+#define ODBC_INI_MAXPERSISTENT "adabas.max_persistent"
+#define ODBC_INI_MAXLINKS "adabas.max_links"
+#endif
+
+/* checking in the same order as in configure.in */
+# if HAVE_SOLID
+# include <cli0core.h>
+# include <cli0ext1.h>
+# define HAVE_SQL_EXTENDED_FETCH 0
+extern void php3_solid_fetch_prev(INTERNAL_FUNCTION_PARAMETERS);
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE solid
+# define UODBC_NAME "solid"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(solid_##name, php3_solid_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(solid_##php_name, php3_solid_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_solid_##name)
+# define UODBC_FNAME(name) php3i_solid_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(solid.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(solid_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_solid_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define solid_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+#elif HAVE_EMPRESS
+# include <sql.h>
+# include <sqlext.h>
+# define HAVE_SQL_EXTENDED_FETCH 0
+
+#elif HAVE_ADABAS
+#include <WINDOWS.H>
+#include <sql.h>
+#include <sqlext.h>
+# define HAVE_SQL_EXTENDED_FETCH 1
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE adabas
+# define UODBC_NAME "adabas"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(ada_##name, php3_ada_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(ada_##php_name, php3_ada_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_ada_##name)
+# define UODBC_FNAME(name) php3i_ada_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(ada.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(ada_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_ada_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define ada_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+# elif HAVE_IODBC && !(WIN32|WINNT)
+# include <isql.h>
+# include <isqlext.h>
+# include <odbc_types.h>
+# include <odbc_funcs.h>
+# define HAVE_SQL_EXTENDED_FETCH 1
+# define SQL_FD_FETCH_ABSOLUTE 0x00000010L
+# define SQL_CURSOR_DYNAMIC 2UL
+# define SQL_NO_TOTAL (-4)
+# define SQL_SO_DYNAMIC 0x00000004L
+# define SQL_LEN_DATA_AT_EXEC_OFFSET (-100)
+# define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE iodbc
+# define UODBC_NAME "iodbc"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(iodbc_##name, php3_iodbc_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(iodbc_##php_name, php3_iodbc_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_iodbc_##name)
+# define UODBC_FNAME(name) php3i_iodbc_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(iodbc.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(iodbc_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_iodbc_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define iodbc_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+#elif HAVE_OPENLINK
+
+# include <iodbc.h>
+# include <isql.h>
+# include <isqlext.h>
+# include <udbcext.h>
+# define HAVE_SQL_EXTENDED_FETCH 1
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE opnlnk
+# define UODBC_NAME "opnlnk"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(opnlnk_##name, php3_opnlnk_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(opnlnk_##php_name, php3_opnlnk_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_opnlnk_##name)
+# define UODBC_FNAME(name) php3i_opnlnk_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(opnlnk.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(opnlnk_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_opnlnk_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define opnlnk_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+#elif HAVE_VELOCIS
+/* Nothing ??? */
+# define UNIX
+# define HAVE_SQL_EXTENDED_FETCH 1
+# include <sql.h>
+# include <sqlext.h>
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE velocis
+# define UODBC_NAME "velocis"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(velocis_##name, php3_velocis_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(velocis_##php_name, php3_velocis_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_velocis_##name)
+# define UODBC_FNAME(name) php3i_velocis_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(velocis.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(velocis_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_velocis_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define velocis_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+#elif HAVE_CODBC
+# define HAVE_SQL_EXTENDED_FETCH 1
+# include <odbc.h>
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE codbc
+# define UODBC_NAME "codbc"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(codbc_##name, php3_codbc_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(codbc_##php_name, php3_codbc_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_codbc_##name)
+# define UODBC_FNAME(name) php3i_codbc_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(codbc.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(codbc_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_codbc_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define codbc_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+#elif HAVE_DB2
+# define HAVE_SQL_EXTENDED_FETCH 1
+# include <sqlcli1.h>
+# ifdef DB268K
+/* Need to include ASLM for 68K applications */
+# include <LibraryManager.h>
+# endif
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE db2
+# define UODBC_NAME "db2"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(db2_##name, php3_db2_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(db2_##php_name, php3_db2_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_db2_##name)
+# define UODBC_FNAME(name) php3i_db2_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(db2.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(db2_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_db2_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define db2_module_ptr &UODBC_MODULE_ENTRY
+# endif
+
+# else /* MS ODBC */
+# define HAVE_SQL_EXTENDED_FETCH 1
+# include <WINDOWS.H>
+# include <sql.h>
+# include <sqlext.h>
+# if defined(UODBC_UNIQUE_NAMES)
+# define UODBC_TYPE wodbc
+# define UODBC_NAME "wodbc"
+# define UODBC_FE(name, arg_types) UODBC_NAMED_FE(wodbc_##name, php3_wodbc_##name, arg_types)
+# define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(wodbc_##php_name, php3_wodbc_##name, arg_types)
+# define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_wodbc_##name)
+# define UODBC_FNAME(name) php3i_wodbc_##name
+# define ODBC_INI_VAR_NAME(name) #name
+# define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(wuodbc.##a)
+# define UODBC_VAR_NAME(name) name
+# define UODBC_VAR(a) UODBC_VAR_NAME(wodbc_##a)
+# define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_wuodbc_##a)
+# define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+# define wodbc_module_ptr &UODBC_MODULE_ENTRY
+# endif
+# endif
+
+
+#if !defined(UODBC_UNIQUE_NAMES)
+#define UODBC_TYPE odbc
+#define UODBC_NAME "odbc"
+#define UODBC_FE(name, arg_types) UODBC_NAMED_FE(odbc_##name, php3_odbc_##name, arg_types)
+#define UODBC_FE_ALIAS(php_name, name, arg_types) UODBC_NAMED_FE(odbc_##php_name, php3_odbc_##name, arg_types)
+#define UODBC_FUNCTION(name) UODBC_NAMED_FUNCTION(php3_odbc_##name)
+#define UODBC_FNAME(name) php3i_odbc_##name
+#define ODBC_INI_VAR_NAME(name) #name
+#define ODBC_INI_VAR(a) ODBC_INI_VAR_NAME(uodbc.##a)
+#define UODBC_VAR_NAME(name) name
+#define UODBC_VAR(a) UODBC_VAR_NAME(uodbc_##a)
+#define PHP3_UODBC_VAR(a) UODBC_VAR_NAME(php3_uodbc_##a)
+#define UODBC_MODULE_ENTRY UODBC_VAR(module_entry)
+#define uodbc_module_ptr &UODBC_MODULE_ENTRY
+#else
+#define UODBC_ALIAS(name, arg_types) UODBC_NAMED_FE(odbc_##name, php3_odbc_##name, arg_types)
+#define UODBC_ALIAS_FE(php_name, name, arg_types) UODBC_NAMED_FE(odbc_##php_name, php3_odbc_##name, arg_types)
+#endif
+
+
+
+/*
+*
+* Defines for ODBC
+*
+*/
+
+/* win32 vars for thread local storage */
+#define UODBC_MUTEX UODBC_VAR(mutex)
+#define UODBC_TLS UODBC_VAR(Tls)
+#define UODBC_GLOBAL_STRUCT UODBC_VAR(global_struct)
+#define UODBC_GLOBALS UODBC_VAR(globals)
+/* defines for variables, structs, etc */
+#define UODBC_MODULE_NAME "ODBC"
+#define UODBC_FUNCTIONS UODBC_VAR(functions)
+#define UODBC_CONNECTION UODBC_VAR(connection)
+#define UODBC_RESULT_VALUE UODBC_VAR(result_value)
+#define UODBC_RESULT UODBC_VAR(result)
+#define UODBC_MODULE UODBC_VAR(module)
+#define UODBC_MODULE_PTR UODBC_VAR(module_ptr)
+#define PHP3_UODBC_MODULE PHP3_UODBC_VAR(module)
+
+/* function defines */
+#define PHP3_MINIT_UODBC UODBC_FNAME(minit)
+#define PHP3_MSHUTDOWN_UODBC UODBC_FNAME(mshutdown)
+#define PHP3_RINIT_UODBC UODBC_FNAME(rinit)
+#define PHP3_INFO_UODBC UODBC_FNAME(info)
+
+/* internal function defines */
+#define UODBC_ADD_RESULT UODBC_FNAME(add_result)
+#define UODBC_GET_RESULT UODBC_FNAME(get_result)
+#define UODBC_DEL_RESULT UODBC_FNAME(del_result)
+#define UODBC_ADD_CONN UODBC_FNAME(add_conn)
+#define UODBC_GET_CONN UODBC_FNAME(get_conn)
+#define UODBC_DEL_CONN UODBC_FNAME(del_conn)
+#define UODBC_SQL_ERROR UODBC_FNAME(sql_error)
+#define UODBC_BINDCOLS UODBC_FNAME(bindcols)
+#define PHP3_UODBC_DO_CONNECT UODBC_FNAME(_do_connect)
+#define PHP3_UODBC_TRANSACT UODBC_FNAME(_do_transact)
+
+# ifndef MSVC5
+# define FAR
+# endif
+
+extern php3_module_entry UODBC_MODULE_ENTRY;
+
+/* uODBC functions */
+extern int PHP3_MINIT_UODBC(INIT_FUNC_ARGS);
+extern int PHP3_MSHUTDOWN_UODBC(void);
+extern int PHP3_RINIT_UODBC(INIT_FUNC_ARGS);
+extern void PHP3_INFO_UODBC(void);
+extern UODBC_FUNCTION(setoption);
+extern UODBC_FUNCTION(autocommit);
+extern UODBC_FUNCTION(close);
+extern UODBC_FUNCTION(close_all);
+extern UODBC_FUNCTION(commit);
+extern UODBC_FUNCTION(connect);
+extern UODBC_FUNCTION(pconnect);
+extern void PHP3_UODBC_DO_CONNECT(INTERNAL_FUNCTION_PARAMETERS, int);
+extern UODBC_FUNCTION(cursor);
+extern UODBC_FUNCTION(exec);
+/*extern UODBC_FUNCTION(do);*/
+extern UODBC_FUNCTION(execute);
+extern UODBC_FUNCTION(fetch_into);
+extern UODBC_FUNCTION(fetch_row);
+extern UODBC_FUNCTION(field_len);
+extern UODBC_FUNCTION(field_name);
+extern UODBC_FUNCTION(field_type);
+extern UODBC_FUNCTION(field_num);
+extern UODBC_FUNCTION(free_result);
+extern UODBC_FUNCTION(num_fields);
+extern UODBC_FUNCTION(num_rows);
+extern UODBC_FUNCTION(prepare);
+extern UODBC_FUNCTION(result);
+extern UODBC_FUNCTION(result_all);
+extern UODBC_FUNCTION(rollback);
+extern void PHP3_UODBC_TRANSACT(INTERNAL_FUNCTION_PARAMETERS, int);
+extern UODBC_FUNCTION(binmode);
+extern UODBC_FUNCTION(longreadlen);
+
+typedef struct UODBC_CONNECTION {
+#if HAVE_DB2
+ SQLHANDLE hdbc;
+#else
+ HDBC hdbc;
+#endif
+ int open;
+} UODBC_CONNECTION;
+
+typedef struct UODBC_RESULT_VALUE {
+ char name[32];
+ char *value;
+ long int vallen;
+ SDWORD coltype;
+} UODBC_RESULT_VALUE;
+
+typedef struct UODBC_RESULT {
+#if HAVE_DB2
+ SQLHANDLE stmt;
+#else
+ HSTMT stmt;
+#endif
+ UODBC_RESULT_VALUE *values;
+ SWORD numcols;
+ SWORD numparams;
+# if HAVE_SQL_EXTENDED_FETCH
+ int fetch_abs;
+# endif
+ long longreadlen;
+ int binmode;
+ int fetched;
+ UODBC_CONNECTION *conn_ptr;
+} UODBC_RESULT;
+
+typedef struct {
+#if HAVE_DB2
+ SQLHANDLE henv;
+#else
+ HENV henv;
+#endif
+ char *defDB;
+ char *defUser;
+ char *defPW;
+ long allow_persistent;
+ long max_persistent;
+ long max_links;
+ long num_persistent;
+ long num_links;
+ int defConn;
+ int le_result, le_conn, le_pconn;
+ long defaultlrl;
+ long defaultbinmode;
+ HashTable *resource_list;
+ HashTable *resource_plist;
+} UODBC_MODULE;
+
+# ifndef THREAD_SAFE
+extern UODBC_MODULE PHP3_UODBC_MODULE;
+# endif
+
+int UODBC_ADD_RESULT(HashTable *list, UODBC_RESULT *result);
+UODBC_RESULT *UODBC_GET_RESULT(HashTable *list, int count);
+void UODBC_DEL_RESULT(HashTable *list, int count);
+int UODBC_ADD_CONN(HashTable *list, HDBC conn);
+UODBC_CONNECTION *UODBC_GET_CONN(HashTable *list, int count);
+void UODBC_DEL_CONN(HashTable *list, int ind);
+#if HAVE_DB2
+void UODBC_SQL_ERROR(SQLHANDLE conn, SQLHANDLE stmt, char *func);
+#else
+void UODBC_SQL_ERROR(HDBC conn, HSTMT stmt, char *func);
+#endif
+int UODBC_BINDCOLS(UODBC_RESULT *result);
+
+#define IS_SQL_LONG(x) (x == SQL_LONGVARBINARY || x == SQL_LONGVARCHAR)
+#define IS_SQL_BINARY(x) (x == SQL_BINARY || x == SQL_VARBINARY || x == SQL_LONGVARBINARY)
+
+#else
+# define uodbc_module_ptr NULL
+
+#endif /* HAVE_UODBC || HAVE_DB2 */
+
+#endif /* _UNIFIED_ODBC_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/odbc/php3_velocis.h b/ext/odbc/php3_velocis.h
new file mode 100644
index 0000000000..19d9f4070a
--- /dev/null
+++ b/ext/odbc/php3_velocis.h
@@ -0,0 +1,108 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Nikolay P. Romanyuk <mag@redcom.ru> |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _PHP3_VELOCIS_H
+#define _PHP3_VELOCIS_H
+
+#if COMPILE_DL
+#undef HAVE_VELOCIS
+#define HAVE_VELOCIS 1
+#endif
+
+#if HAVE_VELOCIS && !HAVE_UODBC
+#define UNIX
+#include <sql.h>
+#include <sqlext.h>
+
+typedef struct VConn {
+ HDBC hdbc;
+ long index;
+} VConn;
+
+typedef struct {
+ char name[32];
+ char *value;
+ long vallen;
+ SDWORD valtype;
+} VResVal;
+
+typedef struct Vresult {
+ HSTMT hstmt;
+ VConn *conn;
+ long index;
+ VResVal *values;
+ long numcols;
+ int fetched;
+} Vresult;
+
+typedef struct {
+ long num_links;
+ long max_links;
+ int le_link,le_result;
+} velocis_module;
+
+extern php3_module_entry velocis_module_entry;
+#define velocis_module_ptr &velocis_module_entry
+
+/* velocis.c functions */
+extern int php3_minit_velocis(INIT_FUNC_ARGS);
+extern int php3_rinit_velocis(INIT_FUNC_ARGS);
+extern void php3_info_velocis(void);
+extern int php3_shutdown_velocis(void);
+extern void php3_velocis_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_exec(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_fetch(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_freeresult(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_autocommit(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_off_autocommit(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_commit(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_rollback(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_fieldnum(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_velocis_fieldname(INTERNAL_FUNCTION_PARAMETERS);
+
+extern velocis_module php3_velocis_module;
+
+#else
+
+#define velocis_module_ptr NULL
+
+#endif /* HAVE_VELOCIS */
+#endif /* _PHP3_VELOCIS_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/odbc/setup.stub b/ext/odbc/setup.stub
new file mode 100644
index 0000000000..8f2b2a942c
--- /dev/null
+++ b/ext/odbc/setup.stub
@@ -0,0 +1,76 @@
+# $Id$ -*- sh -*-
+
+# Solid
+define_option with-solid 'Solid support?' yesnodir \
+ 'no /usr/local/solid Solid install' \
+' Whether to build PHP with Solid support.\n
+ More information about Solid can be found at http://www.solidtech.com/.'
+
+# Empress
+if test "$option_value_with_solid" = "no"; then
+define_option with-empress 'Empress support?' yesnodir \
+ "no $EMPRESSPATH Empress home" \
+' Whether to build PHP with Empress support. Has been confirmed to
+ work with Empress Version 8.10. If you have not set up your
+ Empress environment, enter what $EMPRESSPATH is usually set to here.
+ More info about Empress can be found at http://www.empress.com/.'
+fi
+
+# iODBC
+if test "$option_value_with_solid" = "no" -a \
+ "$option_value_with_empress" = "no"; then
+define_option with-iodbc 'iODBC support?' yesnodir \
+ 'no /usr/local iODBC install' \
+' Whether to build PHP with iODBC support. This feature was first\n
+ developed for iODBC Driver Manager, a freely redistributable ODBC\n
+ driver manager which runs under many flavors of UNIX.\n
+ More info about iODBC can be found on the FreeODBC Pages at \n
+ http://users.ids.net/~bjepson/freeODBC/.'
+fi
+
+# OpenLink
+if test "$option_value_with_solid" = "no" -a \
+ "$option_value_with_empress" = "no" -a \
+ "$option_value_with_iodbc" = "no"; then
+define_option with-openlink 'OpenLink ODBC support?' yesnodir \
+ 'no /usr/local/openlink OpenLink install' \
+' Whether to build PHP with OpenLink ODBC support. See
+ http://www.openlinksw.com/ for more information.'
+fi
+
+# Adabas D
+if test "$option_value_with_solid" = "no" -a \
+ "$option_value_with_empress" = "no" -a \
+ "$option_value_with_iodbc" = "no" -a \
+ "$option_value_with_openlink" = "no"; then
+define_option with-adabas 'Adabas D support?' yesnodir \
+ 'no /usr/local Adabas D install root' \
+' Whether to build with Adabas D support.\n
+ More info about Adabas D can be found at http://www.adabas.com/.'
+fi
+
+# Velocis
+if test "$option_value_with_solid" = "no" -a \
+ "$option_value_with_empress" = "no" -a \
+ "$option_value_with_iodbc" = "no" -a \
+ "$option_value_with_openlink" = "no" -a \
+ "$option_value_with_adabas" = "no"; then
+define_option with-velocis 'Velocis support?' yesnodir \
+ 'no /usr/local/velocis Velocis install' \
+' Whether to build PHP with Velocis support.\n
+ More information about Velocis can be found at http://www.raima.com/.'
+fi
+
+# Custom ODBC
+if test "$option_value_with_solid" = "no" -a \
+ "$option_value_with_empress" = "no" -a \
+ "$option_value_with_iodbc" = "no" -a \
+ "$option_value_with_openlink" = "no" -a \
+ "$option_value_with_adabas" = "no" -a \
+ "$option_value_with_velocis" = "no"; then
+define_option with-custom-odbc 'custom ODBC support?' yesnodir \
+ 'no /usr/local CODBC install' \
+' Whether to build PHP with CODBC support. This feature was first
+ developed for Sybase SQL Anywhere 5.5 on QNX, but may be used for
+ any unknown ODBC driver on all flavors of UNIX.'
+fi
diff --git a/ext/odbc/velocis.c b/ext/odbc/velocis.c
new file mode 100644
index 0000000000..0c5b03eab0
--- /dev/null
+++ b/ext/odbc/velocis.c
@@ -0,0 +1,646 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Nikolay P. Romanyuk <mag@redcom.ru> |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/*
+ * TODO:
+ * velocis_fetch_into(),
+ * Check all on real life apps.
+ */
+
+#include "php.h"
+#include "php3_velocis.h"
+
+#if HAVE_VELOCIS && !HAVE_UODBC
+
+function_entry velocis_functions[] = {
+ {"velocis_connect", php3_velocis_connect, NULL},
+ {"velocis_close", php3_velocis_close, NULL},
+ {"velocis_exec", php3_velocis_exec, NULL},
+ {"velocis_fetch", php3_velocis_fetch, NULL},
+ {"velocis_result", php3_velocis_result, NULL},
+ {"velocis_freeresult", php3_velocis_freeresult, NULL},
+ {"velocis_autocommit", php3_velocis_autocommit, NULL},
+ {"velocis_off_autocommit", php3_velocis_off_autocommit, NULL},
+ {"velocis_commit", php3_velocis_commit, NULL},
+ {"velocis_rollback", php3_velocis_rollback, NULL},
+ {"velocis_fieldnum", php3_velocis_fieldnum, NULL},
+ {"velocis_fieldname", php3_velocis_fieldname, NULL},
+ {NULL, NULL, NULL}
+};
+
+php3_module_entry velocis_module_entry = {
+ "Velocis", velocis_functions, php3_minit_velocis, php3_shutdown_velocis,
+ php3_rinit_velocis, NULL, php3_info_velocis, STANDARD_MODULE_PROPERTIES
+};
+
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &velocis_module_entry; }
+#endif
+
+THREAD_LS velocis_module php3_velocis_module;
+THREAD_LS static HENV henv;
+
+static void _close_velocis_link(VConn *conn)
+{
+ if ( conn ) {
+ efree(conn);
+ }
+}
+
+static void _free_velocis_result(Vresult *res)
+{
+ if ( res && res->values ) {
+ register int i;
+ for ( i=0; i < res->numcols; i++ ) {
+ if ( res->values[i].value )
+ efree(res->values[i].value);
+ }
+ efree(res->values);
+ }
+ if ( res ) {
+ efree(res);
+ }
+}
+
+int php3_minit_velocis(INIT_FUNC_ARGS)
+{
+ SQLAllocEnv(&henv);
+ if ( cfg_get_long("velocis.max_links",&php3_velocis_module.max_links) == FAILURE ) {
+ php3_velocis_module.max_links = -1;
+ }
+ php3_velocis_module.num_links = 0;
+ php3_velocis_module.le_link = register_list_destructors(_close_velocis_link,NULL);
+ php3_velocis_module.le_result = register_list_destructors(_free_velocis_result,NULL);
+
+ return SUCCESS;
+}
+
+int php3_rinit_velocis(INIT_FUNC_ARGS)
+{
+ return SUCCESS;
+}
+
+
+void php3_info_velocis(void)
+{
+ php3_printf("RAIMA Velocis Support Active");
+}
+
+int php3_shutdown_velocis(void)
+{
+ SQLFreeEnv(henv);
+ return SUCCESS;
+}
+
+/* Some internal functions. Connections and result manupulate */
+
+static int
+velocis_add_conn(HashTable *list,VConn *conn,HDBC hdbc)
+{
+ int ind;
+
+ ind = php3_list_insert(conn,php3_velocis_module.le_link);
+ conn->hdbc = hdbc;
+ conn->index = ind;
+
+ return(ind);
+}
+
+static VConn *
+velocis_find_conn(HashTable *list,int ind)
+{
+ VConn *conn;
+ int type;
+
+ conn = php3_list_find(ind,&type);
+ if ( !conn || type != php3_velocis_module.le_link ) {
+ return(NULL);
+ }
+ return(conn);
+}
+
+static void
+velocis_del_conn(HashTable *list,int ind)
+{
+ php3_list_delete(ind);
+}
+
+static int
+velocis_add_result(HashTable *list,Vresult *res,VConn *conn)
+{
+ int ind;
+
+ ind = php3_list_insert(res,php3_velocis_module.le_result);
+ res->conn = conn;
+ res->index = ind;
+
+ return(ind);
+}
+
+static Vresult *
+velocis_find_result(HashTable *list,int ind)
+{
+ Vresult *res;
+ int type;
+
+ res = php3_list_find(ind,&type);
+ if ( !res || type != php3_velocis_module.le_result ) {
+ return(NULL);
+ }
+ return(res);
+}
+
+static void
+velocis_del_result(HashTable *list,int ind)
+{
+ php3_list_delete(ind);
+}
+
+/* Users functions */
+
+void php3_velocis_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *serv,*user,*pass;
+ char *Serv = NULL;
+ char *User = NULL;
+ char *Pass = NULL;
+ RETCODE stat;
+ HDBC hdbc;
+ VConn *new;
+ long ind;
+
+ if ( php3_velocis_module.max_links != -1 && php3_velocis_module.num_links == php3_velocis_module.max_links ) {
+ php3_error(E_WARNING,"Velocis: Too many open connections (%d)",php3_velocis_module.num_links);
+ RETURN_FALSE;
+ }
+ if ( ARG_COUNT(ht) != 3 ||
+ getParameters(ht,3,&serv,&user,&pass) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(serv);
+ convert_to_string(user);
+ convert_to_string(pass);
+ Serv = serv->value.str.val;
+ User = user->value.str.val;
+ Pass = pass->value.str.val;
+ stat = SQLAllocConnect(henv,&hdbc);
+ if ( stat != SQL_SUCCESS ) {
+ php3_error(E_WARNING,"Velocis: Could not allocate connection handle");
+ RETURN_FALSE;
+ }
+ stat = SQLConnect(hdbc,Serv,SQL_NTS,User,SQL_NTS,Pass,SQL_NTS);
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: Could not connect to server \"%s\" for %s",Serv,User);
+ SQLFreeConnect(hdbc);
+ RETURN_FALSE;
+ }
+ new = (VConn *)emalloc(sizeof(VConn));
+ if ( new == NULL ) {
+ php3_error(E_WARNING,"Velocis: Out of memory for store connection");
+ SQLFreeConnect(hdbc);
+ RETURN_FALSE;
+ }
+ ind = velocis_add_conn(list,new,hdbc);
+ php3_velocis_module.num_links++;
+ RETURN_LONG(ind);
+}
+
+void php3_velocis_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *id;
+ VConn *conn;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&id) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(id);
+ conn = velocis_find_conn(list,id->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",id->value.lval);
+ RETURN_FALSE;
+ }
+ SQLDisconnect(conn->hdbc);
+ SQLFreeConnect(conn->hdbc);
+ velocis_del_conn(list,id->value.lval);
+ php3_velocis_module.num_links--;
+ RETURN_TRUE;
+}
+
+void php3_velocis_exec(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind,*exec_str;
+ char *query = NULL;
+ int indx;
+ VConn *conn;
+ Vresult *res;
+ RETCODE stat;
+ SWORD cols,i,colnamelen;
+ SDWORD rows,coldesc;
+
+ if ( ARG_COUNT(ht) != 2 || getParameters(ht,2,&ind,&exec_str) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ conn = velocis_find_conn(list,ind->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",ind->value.lval);
+ RETURN_FALSE;
+ }
+ convert_to_string(exec_str);
+ query = exec_str->value.str.val;
+
+ res = (Vresult *)emalloc(sizeof(Vresult));
+ if ( res == NULL ) {
+ php3_error(E_WARNING,"Velocis: Out of memory for result");
+ RETURN_FALSE;
+ }
+ stat = SQLAllocStmt(conn->hdbc,&res->hstmt);
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: SQLAllocStmt return %d",stat);
+ efree(res);
+ RETURN_FALSE;
+ }
+ stat = SQLExecDirect(res->hstmt,query,SQL_NTS);
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: Can not execute \"%s\" query",query);
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ efree(res);
+ RETURN_FALSE;
+ }
+ /* Success query */
+ stat = SQLNumResultCols(res->hstmt,&cols);
+ if ( stat != SQL_SUCCESS ) {
+ php3_error(E_WARNING,"Velocis: SQLNumResultCols return %d",stat);
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ efree(res);
+ RETURN_FALSE;
+ }
+ if ( !cols ) { /* Was INSERT, UPDATE, DELETE, etc. query */
+ stat = SQLRowCount(res->hstmt,&rows);
+ if ( stat != SQL_SUCCESS ) {
+ php3_error(E_WARNING,"Velocis: SQLNumResultCols return %d",stat);
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ efree(res);
+ RETURN_FALSE;
+ }
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ efree(res);
+ RETURN_LONG(rows);
+ } else { /* Was SELECT query */
+ res->values = (VResVal *)emalloc(sizeof(VResVal)*cols);
+ if ( res->values == NULL ) {
+ php3_error(E_WARNING,"Velocis: Out of memory for result columns");
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ efree(res);
+ RETURN_FALSE;
+ }
+ res->numcols = cols;
+ for ( i = 0; i < cols; i++ ) {
+ SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_NAME,
+ res->values[i].name,sizeof(res->values[i].name),
+ &colnamelen,NULL);
+ SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_TYPE,
+ NULL,0,NULL,&res->values[i].valtype);
+ switch ( res->values[i].valtype ) {
+ case SQL_LONGVARBINARY:
+ case SQL_LONGVARCHAR:
+ res->values[i].value = NULL;
+ continue;
+ default:
+ break;
+ }
+ SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_DISPLAY_SIZE,
+ NULL,0,NULL,&coldesc);
+ res->values[i].value = (char *)emalloc(coldesc+1);
+ if ( res->values[i].value != NULL ) {
+ SQLBindCol(res->hstmt,i+1,SQL_C_CHAR,
+ res->values[i].value,coldesc+1,
+ &res->values[i].vallen);
+ }
+ }
+ }
+ res->fetched = 0;
+ indx = velocis_add_result(list,res,conn);
+ RETURN_LONG(indx);
+}
+
+void php3_velocis_fetch(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind;
+ Vresult *res;
+ RETCODE stat;
+ UDWORD row;
+ UWORD RowStat[1];
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&ind) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ res = velocis_find_result(list,ind->value.lval);
+ if ( !res ) {
+ php3_error(E_WARNING,"Velocis: Not result index (%d)",ind->value.lval);
+ RETURN_FALSE;
+ }
+ stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
+ if ( stat == SQL_NO_DATA_FOUND ) {
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: SQLFetch return error");
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ res->fetched = 1;
+ RETURN_TRUE;
+}
+
+void php3_velocis_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind,*col;
+ Vresult *res;
+ RETCODE stat;
+ int i,sql_c_type;
+ UDWORD row;
+ UWORD RowStat[1];
+ SWORD indx = -1;
+ char *field = NULL;
+
+ if ( ARG_COUNT(ht) != 2 || getParameters(ht,2,&ind,&col) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ res = velocis_find_result(list,ind->value.lval);
+ if ( !res ) {
+ php3_error(E_WARNING,"Velocis: Not result index (%d),ind->value.lval");
+ RETURN_FALSE;
+ }
+ if ( col->type == IS_STRING ) {
+ field = col->value.str.val;
+ } else {
+ convert_to_long(col);
+ indx = col->value.lval;
+ }
+ if ( field ) {
+ for ( i = 0; i < res->numcols; i++ ) {
+ if ( !strcasecmp(res->values[i].name,field)) {
+ indx = i;
+ break;
+ }
+ }
+ if ( indx < 0 ) {
+ php3_error(E_WARNING, "Field %s not found",field);
+ RETURN_FALSE;
+ }
+ } else {
+ if ( indx < 0 || indx >= res->numcols ) {
+ php3_error(E_WARNING,"Velocis: Field index not in range");
+ RETURN_FALSE;
+ }
+ }
+ if ( !res->fetched ) {
+ stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
+ if ( stat == SQL_NO_DATA_FOUND ) {
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: SQLFetch return error");
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ res->fetched = 1;
+ }
+ switch ( res->values[indx].valtype ) {
+ case SQL_LONGVARBINARY:
+ sql_c_type = SQL_C_BINARY;
+ goto l1;
+ case SQL_LONGVARCHAR:
+ sql_c_type = SQL_C_CHAR;
+l1:
+ if ( !res->values[indx].value ) {
+ res->values[indx].value = emalloc(4096);
+ if ( !res->values[indx].value ) {
+ php3_error(E_WARNING,"Out of memory");
+ RETURN_FALSE;
+ }
+ }
+ stat = SQLGetData(res->hstmt,indx+1,sql_c_type,
+ res->values[indx].value,4095,&res->values[indx].vallen);
+ if ( stat == SQL_NO_DATA_FOUND ) {
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: SQLGetData return error");
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_FALSE;
+ }
+ if ( res->values[indx].valtype == SQL_LONGVARCHAR ) {
+ RETURN_STRING(res->values[indx].value,TRUE);
+ } else {
+ RETURN_LONG((long)res->values[indx].value);
+ }
+ default:
+ if ( res->values[indx].value != NULL ) {
+ RETURN_STRING(res->values[indx].value,TRUE);
+ }
+ }
+}
+
+void php3_velocis_freeresult(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind;
+ Vresult *res;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&ind) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ res = velocis_find_result(list,ind->value.lval);
+ if ( !res ) {
+ php3_error(E_WARNING,"Velocis: Not result index (%d)",ind->value.lval);
+ RETURN_FALSE;
+ }
+ SQLFreeStmt(res->hstmt,SQL_DROP);
+ velocis_del_result(list,ind->value.lval);
+ RETURN_TRUE;
+}
+
+void php3_velocis_autocommit(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *id;
+ RETCODE stat;
+ VConn *conn;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&id) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(id);
+ conn = velocis_find_conn(list,id->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",id->value.lval);
+ RETURN_FALSE;
+ }
+ stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_ON);
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: Set autocommit_on option failure");
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+void php3_velocis_off_autocommit(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *id;
+ RETCODE stat;
+ VConn *conn;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&id) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(id);
+ conn = velocis_find_conn(list,id->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",id->value.lval);
+ RETURN_FALSE;
+ }
+ stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF);
+ if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
+ php3_error(E_WARNING,"Velocis: Set autocommit_off option failure");
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+void php3_velocis_commit(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *id;
+ RETCODE stat;
+ VConn *conn;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&id) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(id);
+ conn = velocis_find_conn(list,id->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",id->value.lval);
+ RETURN_FALSE;
+ }
+ stat = SQLTransact(NULL,conn->hdbc,SQL_COMMIT);
+ if ( stat != SQL_SUCCESS ) {
+ php3_error(E_WARNING,"Velocis: Commit failure");
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+void php3_velocis_rollback(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *id;
+ RETCODE stat;
+ VConn *conn;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&id) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(id);
+ conn = velocis_find_conn(list,id->value.lval);
+ if ( !conn ) {
+ php3_error(E_WARNING,"Velocis: Not connection index (%d)",id->value.lval);
+ RETURN_FALSE;
+ }
+ stat = SQLTransact(NULL,conn->hdbc,SQL_ROLLBACK);
+ if ( stat != SQL_SUCCESS ) {
+ php3_error(E_WARNING,"Velocis: Rollback failure");
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+void php3_velocis_fieldname(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind,*col;
+ Vresult *res;
+ SWORD indx;
+
+ if ( ARG_COUNT(ht) != 2 || getParameters(ht,2,&ind,&col) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ res = velocis_find_result(list,ind->value.lval);
+ if ( !res ) {
+ php3_error(E_WARNING,"Velocis: Not result index (%d),ind->value.lval");
+ RETURN_FALSE;
+ }
+ convert_to_long(col);
+ indx = col->value.lval;
+ if ( indx < 0 || indx >= res->numcols ) {
+ php3_error(E_WARNING,"Velocis: Field index not in range");
+ RETURN_FALSE;
+ }
+ RETURN_STRING(res->values[indx].name,TRUE);
+}
+
+void php3_velocis_fieldnum(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *ind;
+ Vresult *res;
+
+ if ( ARG_COUNT(ht) != 1 || getParameters(ht,1,&ind) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(ind);
+ res = velocis_find_result(list,ind->value.lval);
+ if ( !res ) {
+ php3_error(E_WARNING,"Velocis: Not result index (%d),ind->value.lval");
+ RETURN_FALSE;
+ }
+ RETURN_LONG(res->numcols);
+}
+
+#endif /* HAVE_VELOCIS */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/internal_functions.c b/internal_functions.c
index bfdaad1d98..b464d8cecd 100644
--- a/internal_functions.c
+++ b/internal_functions.c
@@ -43,6 +43,7 @@
#include "ext/standard/php3_standard.h"
#include "ext/gd/php3_gd.h"
#include "ext/dbase/dbase.h"
+#include "ext/odbc/php3_odbc.h"
#include "functions/php3_ifx.h"
#include "functions/php3_ldap.h"
@@ -52,19 +53,15 @@
#include "functions/php3_oci8.h"
#include "functions/oracle.h"
#include "functions/php3_pgsql.h"
-#include "functions/php3_velocis.h"
#include "functions/php3_sybase.h"
#include "functions/php3_sybase-ct.h"
#include "functions/imap.h"
#include "functions/dl.h"
#include "functions/head.h"
#include "functions/post.h"
-#include "functions/php3_solid.h"
-#include "functions/adabasd.h"
#include "functions/hw.h"
#include "functions/filepro.h"
#include "functions/db.h"
-#include "functions/php3_unified_odbc.h"
#include "dl/snmp/php3_snmp.h"
#include "functions/php3_zlib.h"
#include "functions/php3_COM.h"
@@ -96,7 +93,6 @@ zend_module_entry *php3_builtin_modules[] =
pgsql_module_ptr,
ifx_module_ptr,
ldap_module_ptr,
- velocis_module_ptr,
filepro_module_ptr,
sybase_module_ptr,
sybct_module_ptr,
@@ -104,8 +100,6 @@ zend_module_entry *php3_builtin_modules[] =
dbase_module_ptr,
hw_module_ptr,
regexp_module_ptr,
- solid_module_ptr,
- adabas_module_ptr,
gd_module_ptr,
oci8_module_ptr,
oracle_module_ptr,
diff --git a/setup b/setup
index 0d6bab48e3..ae87062165 100644
--- a/setup
+++ b/setup
@@ -246,24 +246,6 @@ define_option with-oracle 'Oracle support?' yesnodir \
Oracle environment, enter what $ORACLE_HOME is usually set to here.\n
More info about Oracle can be found at http://www.oracle.com/.'
-define_option with-iodbc 'iODBC support?' yesnodir \
- 'no /usr/local iODBC install' \
-' Whether to build PHP with iODBC support. This feature was first\n
- developed for iODBC Driver Manager, a freely redistributable ODBC\n
- driver manager which runs under many flavors of UNIX.\n
- More info about iODBC can be found on the FreeODBC Pages at \n
- http://users.ids.net/~bjepson/freeODBC/.'
-
-define_option with-openlink 'OpenLink ODBC support?' yesnodir \
- 'no /usr/local/openlink OpenLink install' \
-' Whether to build PHP with OpenLink ODBC support. See
- http://www.openlinksw.com/ for more information.'
-
-define_option with-adabas 'Adabas D support?' yesnodir \
- 'no /usr/local Adabas D install root' \
-' Whether to build with Adabas D support.\n
- More info about Adabas D can be found at http://www.adabas.com/.'
-
define_option with-sybase 'Sybase support?' yesnodir \
'no /home/sybase Sybase install' \
' Whether to build PHP with Sybase support (DBLib only).\n
@@ -291,18 +273,6 @@ define_option with-pgsql 'PostgreSQL support?' yesnodir \
More info about PostgreSQL can be found at\n
http://www.postgreSQL.org/.'
-define_option with-solid 'Solid support?' yesnodir \
- 'no /usr/local/solid Solid install' \
-' Whether to build PHP with Solid support.\n
- More information about Solid can be found at http://www.solidtech.com/.'
-
-define_option with-empress 'Empress support?' yesnodir \
- "no $EMPRESSPATH Empress home" \
-' Whether to build PHP with Empress support. Has been confirmed to
- work with Empress Version 8.10. If you have not set up your
- Empress environment, enter what $EMPRESSPATH is usually set to here.
- More info about Empress can be found at http://www.empress.com/.'
-
define_option with-informix 'Informix support?' yesnodir \
"no $INFORMIXDIR Informix home" \
' Whether to build PHP with Informix support. If you have not set up your\n
@@ -331,32 +301,6 @@ define_option with-imap 'IMAP support?' yesnodir \
support.\n
More information about LDAP can be found in RFC1777 and RFC1778.'
-define_option with-velocis 'Velocis support?' yesnodir \
- 'no /usr/local/velocis Velocis install' \
-' Whether to build PHP with Velocis support.\n
- More information about Velocis can be found at http://www.raima.com/.'
-
-define_option with-custom-odbc 'custom ODBC support?' yesnodir \
- 'no /usr/local CODBC install' \
-' Whether to build PHP with CODBC support. This feature was first
- developed for Sybase SQL Anywhere 5.5 on QNX, but may be used for
- any unknown ODBC driver on all flavors of UNIX.'
-
-if test "$option_value_with_iodbc" != "no" -o \
- "$option_value_with_solid" != "no" -o \
- "$option_value_with_adabas" != "no" -o \
- "$option_value_with_velocis" != "no" -o \
- "$option_value_with_custom_odbc" != "no"
-then
-define_option enable-unified-odbc 'Enable unified ODBC support?' yesno yes \
-' Whether to enabled the unified ODBC support. This is a database\n
- module that compiles with the C API of several DBMSes that happen to\n
- use ODBC as their C-API. Has been tested with iODBC, Solid, Adabas D,\n
- Empress, and Sybase SQL Anywhere. Requires that some one (and only one)\n
- specific ODBC module is enabled, or some custom ODBC library specified\n
- instead.'
-fi
-
define_option with-filepro 'filePro support? ' yesno no \
' Whether to use the bundled filePro library. Read-access only.'