summaryrefslogtreecommitdiff
path: root/ext/oci8
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2005-12-01 13:39:48 +0000
committerAntony Dovgal <tony2001@php.net>2005-12-01 13:39:48 +0000
commit3756201e048585a891540645ea22adf3b1b96d20 (patch)
tree83bbb31ef0ae4d58f0de5f4a7ec62ffce0afb568 /ext/oci8
parent916ad6c8f71b340a13800f2be08cd83c96242874 (diff)
downloadphp-git-3756201e048585a891540645ea22adf3b1b96d20.tar.gz
upgrade bundled OCI8 to v.1.1
Diffstat (limited to 'ext/oci8')
-rw-r--r--ext/oci8/CREDITS2
-rw-r--r--ext/oci8/README61
-rw-r--r--ext/oci8/config.m4142
-rw-r--r--ext/oci8/config.w326
-rw-r--r--ext/oci8/oci8.c7336
-rw-r--r--ext/oci8/oci8.dsp28
-rw-r--r--ext/oci8/oci8_collection.c611
-rw-r--r--ext/oci8/oci8_interface.c2125
-rw-r--r--ext/oci8/oci8_lob.c702
-rw-r--r--ext/oci8/oci8_statement.c1347
-rw-r--r--ext/oci8/package.xml234
-rw-r--r--ext/oci8/php_oci8.h193
-rw-r--r--ext/oci8/php_oci8_int.h422
-rw-r--r--ext/oci8/tests/bind_empty.phpt44
-rw-r--r--ext/oci8/tests/bug26133.phpt31
-rw-r--r--ext/oci8/tests/bug27303.phpt257
-rw-r--r--ext/oci8/tests/bug27303_2.phpt257
-rw-r--r--ext/oci8/tests/bug27303_3.phpt257
-rw-r--r--ext/oci8/tests/bug27303_4.phpt257
-rw-r--r--ext/oci8/tests/bug32325.phpt44
-rw-r--r--ext/oci8/tests/close.phpt22
-rw-r--r--ext/oci8/tests/coll_001.phpt33
-rw-r--r--ext/oci8/tests/coll_002.phpt36
-rw-r--r--ext/oci8/tests/coll_002_func.phpt36
-rw-r--r--ext/oci8/tests/coll_003.phpt40
-rw-r--r--ext/oci8/tests/coll_003_func.phpt40
-rw-r--r--ext/oci8/tests/coll_004.phpt35
-rw-r--r--ext/oci8/tests/coll_004_func.phpt35
-rw-r--r--ext/oci8/tests/coll_005.phpt33
-rw-r--r--ext/oci8/tests/coll_006.phpt36
-rw-r--r--ext/oci8/tests/coll_006_func.phpt36
-rw-r--r--ext/oci8/tests/coll_007.phpt40
-rw-r--r--ext/oci8/tests/coll_008.phpt35
-rw-r--r--ext/oci8/tests/coll_009.phpt48
-rw-r--r--ext/oci8/tests/coll_009_func.phpt48
-rw-r--r--ext/oci8/tests/coll_010.phpt47
-rw-r--r--ext/oci8/tests/coll_010_func.phpt47
-rw-r--r--ext/oci8/tests/coll_011.phpt49
-rw-r--r--ext/oci8/tests/coll_011_func.phpt49
-rw-r--r--ext/oci8/tests/coll_012.phpt47
-rw-r--r--ext/oci8/tests/coll_012_func.phpt47
-rw-r--r--ext/oci8/tests/coll_013.phpt44
-rw-r--r--ext/oci8/tests/coll_013_func.phpt44
-rw-r--r--ext/oci8/tests/coll_014.phpt44
-rw-r--r--ext/oci8/tests/coll_014_func.phpt44
-rw-r--r--ext/oci8/tests/coll_015.phpt44
-rw-r--r--ext/oci8/tests/coll_015_func.phpt44
-rw-r--r--ext/oci8/tests/coll_016.phpt54
-rw-r--r--ext/oci8/tests/coll_016_func.phpt54
-rw-r--r--ext/oci8/tests/coll_017.phpt44
-rw-r--r--ext/oci8/tests/coll_017_func.phpt44
-rw-r--r--ext/oci8/tests/commit.phpt153
-rw-r--r--ext/oci8/tests/commit_old.phpt151
-rw-r--r--ext/oci8/tests/connect.inc24
-rw-r--r--ext/oci8/tests/connect.phpt27
-rw-r--r--ext/oci8/tests/connect_1.phpt40
-rw-r--r--ext/oci8/tests/connect_1_old.phpt40
-rw-r--r--ext/oci8/tests/connect_old.phpt27
-rw-r--r--ext/oci8/tests/connect_without_oracle_home.phpt25
-rw-r--r--ext/oci8/tests/connect_without_oracle_home_old.phpt25
-rw-r--r--ext/oci8/tests/create_table.inc13
-rw-r--r--ext/oci8/tests/create_type.inc17
-rw-r--r--ext/oci8/tests/cursor_bind_err.phpt53
-rw-r--r--ext/oci8/tests/cursors.phpt64
-rw-r--r--ext/oci8/tests/cursors_old.phpt69
-rw-r--r--ext/oci8/tests/debug.phpt36
-rw-r--r--ext/oci8/tests/default_prefetch.phpt55
-rw-r--r--ext/oci8/tests/default_prefetch1.phpt55
-rw-r--r--ext/oci8/tests/default_prefetch2.phpt58
-rw-r--r--ext/oci8/tests/define.phpt46
-rw-r--r--ext/oci8/tests/define_old.phpt46
-rw-r--r--ext/oci8/tests/drop_table.inc6
-rw-r--r--ext/oci8/tests/drop_type.inc12
-rw-r--r--ext/oci8/tests/error.phpt45
-rw-r--r--ext/oci8/tests/error1.phpt23
-rw-r--r--ext/oci8/tests/error_old.phpt45
-rw-r--r--ext/oci8/tests/exec_fetch.phpt24
-rw-r--r--ext/oci8/tests/fetch.phpt61
-rw-r--r--ext/oci8/tests/fetch_all.phpt154
-rw-r--r--ext/oci8/tests/fetch_array.phpt235
-rw-r--r--ext/oci8/tests/fetch_assoc.phpt69
-rw-r--r--ext/oci8/tests/fetch_into.phpt87
-rw-r--r--ext/oci8/tests/fetch_into1.phpt197
-rw-r--r--ext/oci8/tests/fetch_into2.phpt75
-rw-r--r--ext/oci8/tests/fetch_object.phpt69
-rw-r--r--ext/oci8/tests/fetch_row.phpt69
-rw-r--r--ext/oci8/tests/field_funcs.phpt110
-rw-r--r--ext/oci8/tests/field_funcs_old.phpt110
-rw-r--r--ext/oci8/tests/lob_001.phptbin0 -> 1415 bytes
-rw-r--r--ext/oci8/tests/lob_002.phpt71
-rw-r--r--ext/oci8/tests/lob_003.phptbin0 -> 1787 bytes
-rw-r--r--ext/oci8/tests/lob_004.phpt85
-rw-r--r--ext/oci8/tests/lob_005.phpt57
-rw-r--r--ext/oci8/tests/lob_006.phptbin0 -> 1853 bytes
-rw-r--r--ext/oci8/tests/lob_007.phpt71
-rw-r--r--ext/oci8/tests/lob_008.phpt70
-rw-r--r--ext/oci8/tests/lob_009.phpt74
-rw-r--r--ext/oci8/tests/lob_009.txt6
-rw-r--r--ext/oci8/tests/lob_010.phpt51
-rw-r--r--ext/oci8/tests/lob_011.phpt81
-rw-r--r--ext/oci8/tests/lob_012.phpt55
-rw-r--r--ext/oci8/tests/lob_013.phpt59
-rw-r--r--ext/oci8/tests/lob_014.phpt63
-rw-r--r--ext/oci8/tests/lob_015.phpt56
-rw-r--r--ext/oci8/tests/lob_016.phpt72
-rw-r--r--ext/oci8/tests/lob_017.phpt74
-rw-r--r--ext/oci8/tests/lob_018.phpt72
-rw-r--r--ext/oci8/tests/lob_temp.phpt41
-rw-r--r--ext/oci8/tests/lob_temp1.phpt37
-rw-r--r--ext/oci8/tests/num.phpt71
-rw-r--r--ext/oci8/tests/oci_execute_segfault.phpt35
-rw-r--r--ext/oci8/tests/old_oci_close.phpt28
-rw-r--r--ext/oci8/tests/old_oci_close1.phpt30
-rw-r--r--ext/oci8/tests/password.phpt35
-rw-r--r--ext/oci8/tests/password_new.phpt35
-rw-r--r--ext/oci8/tests/password_old.phpt35
-rw-r--r--ext/oci8/tests/persistent.phpt32
-rw-r--r--ext/oci8/tests/prefetch.phpt56
-rw-r--r--ext/oci8/tests/prefetch_old.phpt56
-rw-r--r--ext/oci8/tests/privileged_connect.phpt31
-rw-r--r--ext/oci8/tests/privileged_connect1.phpt33
-rw-r--r--ext/oci8/tests/serverversion.phpt35
-rw-r--r--ext/oci8/tests/statement_cache.phpt40
-rw-r--r--ext/oci8/tests/statement_type.phpt51
-rw-r--r--ext/oci8/tests/statement_type_old.phpt51
-rw-r--r--ext/oci8/tests/uncommitted.phpt22
126 files changed, 13135 insertions, 6706 deletions
diff --git a/ext/oci8/CREDITS b/ext/oci8/CREDITS
index 884efcaa92..18cad81c3e 100644
--- a/ext/oci8/CREDITS
+++ b/ext/oci8/CREDITS
@@ -1,2 +1,2 @@
OCI8
-Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal
+Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal, Andi Gutmans, Wez Furlong
diff --git a/ext/oci8/README b/ext/oci8/README
new file mode 100644
index 0000000000..b9df41db3a
--- /dev/null
+++ b/ext/oci8/README
@@ -0,0 +1,61 @@
+Installing OCI8
+---------------
+
+1. Common requirements.
+2. Installing as shared extension.
+3. Installing as statically compiled extension.
+4. Installing from PECL.
+
+
+1. Common requirements
+----------------------
+In case if you use Oracle Instant Client, you don't have to set ORACLE_HOME and
+most of the other environment variables to build PHP with OCI8 support.
+The only variables you may have to set are:
+LD_LIBRARY_PATH - it must include Instant Client libraries dir
+NLS_LANG - in case if you want to change the default encoding used during
+interaction with Oracle servers
+
+If you use common Oracle Client installation that comes along with the Oracle
+server installation, you MUST set at least ORACLE_HOME environment variable
+and make it visible for your web-server BEFORE it starts. Most appropriate
+places to add ORACLE_HOME definition are:
+- /etc/profile
+- /etc/profile.local
+- /etc/profile.d
+and others.
+
+2. Installing as shared extension
+---------------------------------
+To install OCI8 as shared extension (i.e. the one you should put into
+your php.ini) use the following configure lines to configure PHP:
+a) if you use common Oracle Client installation:
+./configure --with-oci8=shared,$ORACLE_HOME
+
+b) with Oracle Instant Client:
+./configure --with-oci8=shared,instantclient,/path/to/instant/client/lib
+If you use rpm-based installation of Oracle Instant Client, your configure
+line will look like this:
+./configure --with-oci8=shared,instantclient,/usr/lib/oracle/<OIC version>/client/lib
+
+Follow the usual building procedure after that and you'll get OCI8 shared
+extension (i.e. oci8.so). Add it into the php.ini file like this:
+extension=oci8.so
+and don't forget to specify the right extension_dir for PHP to be able
+to find shared extensions correctly.
+
+3. Installing as statically compiled extension
+----------------------------------------------
+To install OCI8 as statically compiled module use the following configure lines:
+a) with common Oracle Client installation
+./configure --with-oci8=$ORACLE_HOME
+
+b) with Oracle Instant Client
+./configure --with-oci8=instantclient,/path/to/instant/client/lib
+
+After successful compile, you don't have to add oci8.so to the php.ini, the module will
+be usable without any additional actions.
+
+4. Installing from PECL
+-----------------------
+TBD
diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4
index 54342dc32f..798c761b6f 100644
--- a/ext/oci8/config.m4
+++ b/ext/oci8/config.m4
@@ -2,6 +2,12 @@ dnl
dnl $Id$
dnl
+if test -z "$SED"; then
+ PHP_OCI8_SED="sed";
+else
+ PHP_OCI8_SED="$SED";
+fi
+
AC_DEFUN([PHP_OCI_IF_DEFINED],[
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$3
@@ -19,7 +25,16 @@ AC_DEFUN([PHP_OCI_IF_DEFINED],[
])
AC_DEFUN([AC_OCI8_CHECK_LIB_DIR],[
- PHP_CHECK_64BIT([ TMP_OCI8_LIB_DIR=lib32 ], [ TMP_OCI8_LIB_DIR=lib ])
+ AC_CHECK_SIZEOF(long int, 4)
+ AC_MSG_CHECKING([checking if we're at 64-bit platform])
+ if test "$ac_cv_sizeof_long_int" = "4" ; then
+ AC_MSG_RESULT([no])
+ TMP_OCI8_LIB_DIR=lib32
+ else
+ AC_MSG_RESULT([yes])
+ TMP_OCI8_LIB_DIR=lib
+ fi
+
AC_MSG_CHECKING([OCI8 libraries dir])
if test -d "$OCI8_DIR/lib" -a ! -d "$OCI8_DIR/lib32"; then
OCI8_LIB_DIR=lib
@@ -54,7 +69,7 @@ AC_DEFUN([AC_OCI8IC_VERSION],[
AC_DEFUN([AC_OCI8_VERSION],[
AC_MSG_CHECKING([Oracle version])
if test -s "$OCI8_DIR/orainst/unix.rgs"; then
- OCI8_VERSION=`grep '"ocommon"' $OCI8_DIR/orainst/unix.rgs | sed 's/[ ][ ]*/:/g' | cut -d: -f 6 | cut -c 2-4`
+ OCI8_VERSION=`grep '"ocommon"' $OCI8_DIR/orainst/unix.rgs | $PHP_OCI_SED 's/[ ][ ]*/:/g' | cut -d: -f 6 | cut -c 2-4`
test -z "$OCI8_VERSION" && OCI8_VERSION=7.3
elif test -f $OCI8_DIR/$OCI8_LIB_DIR/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
OCI8_VERSION=10.1
@@ -76,26 +91,33 @@ AC_DEFUN([AC_OCI8_VERSION],[
AC_MSG_RESULT($OCI8_VERSION)
])
-PHP_ARG_WITH(oci8, for Oracle (OCI8) support using ORACLE_HOME installation,
-[ --with-oci8[=DIR] Include Oracle (OCI8) support using an ORACLE_HOME
- install. The default DIR is ORACLE_HOME])
-
-if test "$PHP_OCI8" = "no"; then
- PHP_ARG_WITH(oci8-instant-client, for Oracle (OCI8) support using Oracle Instant Client,
- [ --with-oci8-instant-client[=DIR]
- Include Oracle (OCI8) support using
- Oracle Instant Client. DIR is the directory with the
- Instant Client libraries. On Linux it will default to
- /usr/lib/oracle/<most_recent_version>/client/lib
- Other platforms will need to have it explicitly specified])
-else
- PHP_OCI8_INSTANT_CLIENT="no";
+
+dnl --with-oci8=shared,instantclient,/path/to/client/dir/lib
+dnl or
+dnl --with-oci8=shared,/path/to/oracle/home
+PHP_ARG_WITH(oci8, for Oracle (OCI8) support,
+[ --with-oci8[=DIR] Include Oracle (OCI8) support.
+ The default DIR is ORACLE_HOME.
+ Use --with-oci8=instantclient,/path/to/oic/lib
+ to use Oracle Instant Client installation])
+
+PHP_OCI8_INSTANT_CLIENT="no"
+
+if test "`echo $PHP_OCI8 | cut -d, -f2`" = "instantclient"; then
+ PHP_OCI8_INSTANT_CLIENT="`echo $PHP_OCI8 | cut -d, -f3`"
+ PHP_OCI8="`echo $PHP_OCI8 | cut -d, -f1,4`"
+ if test "$PHP_OCI8_INSTANT_CLIENT" = ""; then
+ PHP_OCI8_INSTANT_CLIENT="yes"
+ fi
+elif test "`echo $PHP_OCI8 | cut -d, -f1`" = "instantclient"; then
+ PHP_OCI8_INSTANT_CLIENT="`echo $PHP_OCI8 | cut -d, -f2`"
+ PHP_OCI8="`echo $PHP_OCI8 | cut -d, -f3,4`"
+ if test "$PHP_OCI8_INSTANT_CLIENT" = ""; then
+ PHP_OCI8_INSTANT_CLIENT="yes"
+ fi
fi
-if test "$PHP_OCI8" != "no"; then
- if test "$PHP_OCI8_INSTANT_CLIENT" != "no"; then
- AC_MSG_ERROR([--with-oci8 and --with-oci8-instant-client are mutually exclusive])
- fi
+if test "$PHP_OCI8" != "no" && test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then
AC_MSG_CHECKING([Oracle Install Directory])
if test "$PHP_OCI8" = "yes"; then
@@ -138,12 +160,40 @@ if test "$PHP_OCI8" != "no"; then
PHP_ADD_LIBRARY_WITH_PATH(core4, "", OCI8_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(psa, "", OCI8_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(clntsh, $OCI8_DIR/$OCI8_LIB_DIR, OCI8_SHARED_LIBADD)
+
+ PHP_CHECK_LIBRARY(clntsh, OCIEnvCreate,
+ [
+ AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
+
+ PHP_CHECK_LIBRARY(clntsh, OCIStmtPrepare2,
+ [
+ AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
;;
8.1)
PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD)
PHP_ADD_LIBPATH($OCI8_DIR/$OCI8_LIB_DIR, OCI8_SHARED_LIBADD)
+ PHP_CHECK_LIBRARY(clntsh, OCIEnvCreate,
+ [
+ AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
+
+ PHP_CHECK_LIBRARY(clntsh, OCIStmtPrepare2,
+ [
+ AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
+
dnl
dnl OCI_ATTR_STATEMENT is not available in all 8.1.x versions
dnl
@@ -160,7 +210,7 @@ if test "$PHP_OCI8" != "no"; then
[
PHP_CHECK_LIBRARY(clntsh, OCINlsCharSetNameToId,
[
- AC_DEFINE(HAVE_OCI_9_2,1,[ ])
+ AC_DEFINE(HAVE_OCI_ENV_NLS_CREATE,1,[ ])
OCI8_VERSION=9.2
], [], [
-L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
@@ -168,13 +218,30 @@ if test "$PHP_OCI8" != "no"; then
], [], [
-L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
])
+
+ PHP_CHECK_LIBRARY(clntsh, OCIEnvCreate,
+ [
+ AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
+
+ PHP_CHECK_LIBRARY(clntsh, OCIStmtPrepare2,
+ [
+ AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
+ ], [], [
+ -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
+ ])
+
;;
10.1)
PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD)
PHP_ADD_LIBPATH($OCI8_DIR/$OCI8_LIB_DIR, OCI8_SHARED_LIBADD)
AC_DEFINE(HAVE_OCI8_ATTR_STATEMENT,1,[ ])
- AC_DEFINE(HAVE_OCI_9_2,1,[ ])
+ AC_DEFINE(HAVE_OCI_ENV_NLS_CREATE,1,[ ])
+ AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
+ AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ])
AC_DEFINE(PHP_OCI8_HAVE_COLLECTIONS,1,[ ])
;;
@@ -207,18 +274,22 @@ if test "$PHP_OCI8" != "no"; then
PHP_CHECK_LIBRARY(clntsh, OCICollAssign,
[
AC_DEFINE(PHP_OCI8_HAVE_COLLECTIONS,1,[ ])
- ], [], [
+ PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
+ ],
+ [
+ PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_interface.c, $ext_shared)
+ ],
+ [
-L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD
])
- PHP_NEW_EXTENSION(oci8, oci8.c, $ext_shared)
AC_DEFINE(HAVE_OCI8,1,[ ])
PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
PHP_SUBST_OLD(OCI8_DIR)
PHP_SUBST_OLD(OCI8_VERSION)
-elif test "$PHP_OCI8_INSTANT_CLIENT" != "no"; then
+elif test "$PHP_OCI8" != "no" && test "$PHP_OCI8_INSTANT_CLIENT" != "no"; then
AC_MSG_CHECKING([Oracle Instant Client directory])
if test "$PHP_OCI8_INSTANT_CLIENT" = "yes"; then
@@ -227,7 +298,7 @@ dnl directory to the libraries. But on Linux we default to the most recent
dnl version in /usr/lib
PHP_OCI8_INSTANT_CLIENT=`ls -d /usr/lib/oracle/*/client/lib 2> /dev/null | tail -1`
if test -z "$PHP_OCI8_INSTANT_CLIENT"; then
- AC_MSG_ERROR([Oracle Instant Client directory not found. Try --with-oci8-instant-client=DIR])
+ AC_MSG_ERROR([Oracle Instant Client directory not found. Try --with-oci8=instantclient,DIR])
fi
fi
AC_MSG_RESULT($PHP_OCI8_INSTANT_CLIENT)
@@ -237,11 +308,14 @@ dnl version in /usr/lib
AC_MSG_CHECKING([Oracle Instant Client SDK header directory])
dnl Header directory for Instant Client SDK RPM install
- OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | sed -e 's!^/usr/lib/oracle/\(.*\)/client/lib[[/]]*$!/usr/include/oracle/\1/client!'`
+ OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/lib/oracle/\(.*\)/client/lib[[/]]*$!/usr/include/oracle/\1/client!'`
dnl Header directory for Instant Client SDK zip file install
OCISDKZIPINC=$PHP_OCI8_INSTANT_CLIENT/sdk/include
+dnl Header directory for manual installation
+ OCISDKMANINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!\(.*\)/lib[[/]]*$!\1/include!'`
+
if test -f "$OCISDKRPMINC/oci.h"; then
AC_MSG_RESULT($OCISDKRPMINC)
PHP_ADD_INCLUDE($OCISDKRPMINC)
@@ -250,11 +324,15 @@ dnl Header directory for Instant Client SDK zip file install
AC_MSG_RESULT($OCISDKZIPINC)
PHP_ADD_INCLUDE($OCISDKZIPINC)
OCI8INCDIR=$OCISDKZIPINC
+ elif test -f "$OCISDKMANINC/oci.h"; then
+ AC_MSG_RESULT($OCISDKMANINC)
+ PHP_ADD_INCLUDE($OCISDKMANINC)
+ OCI8INCDIR=$OCISDKMANINC
else
AC_MSG_ERROR([Oracle Instant Client SDK header files not found])
fi
- OCISYSLIBLIST=`echo "$OCI8INCDIR" | sed -e 's!\(.*\)/include$!\1/demo/sysliblist!'`
+ OCISYSLIBLIST=`echo "$OCI8INCDIR" | $PHP_OCI_SED -e 's!\(.*\)/include$!\1/demo/sysliblist!'`
if test -f "$OCISYSLIBLIST"; then
PHP_EVAL_LIBLINE(`cat $OCISYSLIBLIST`, OCI8_SYSLIB)
fi
@@ -271,13 +349,15 @@ dnl Header directory for Instant Client SDK zip file install
;;
esac
+ AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[ ])
AC_DEFINE(HAVE_OCI8_ATTR_STATEMENT,1,[ ])
- AC_DEFINE(HAVE_OCI_9_2,1,[ ])
+ AC_DEFINE(HAVE_OCI_ENV_NLS_CREATE,1,[ ])
+ AC_DEFINE(HAVE_OCI_ENV_CREATE,1,[ ])
+ AC_DEFINE(HAVE_OCI_STMT_PREPARE2,1,[ ])
AC_DEFINE(HAVE_OCI8_TEMP_LOB,1,[ ])
AC_DEFINE(PHP_OCI8_HAVE_COLLECTIONS,1,[ ])
- AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[ ])
- PHP_NEW_EXTENSION(oci8, oci8.c, $ext_shared)
+ PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
AC_DEFINE(HAVE_OCI8,1,[ ])
PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
diff --git a/ext/oci8/config.w32 b/ext/oci8/config.w32
index d95d4e6e65..7b31e44859 100644
--- a/ext/oci8/config.w32
+++ b/ext/oci8/config.w32
@@ -5,11 +5,11 @@ ARG_WITH("oci8", "OCI8 support", "no");
if (PHP_OCI8 != "no") {
- if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8", PHP_PHP_BUILD + "\\oci805\\include;" + PHP_OCI8) &&
- CHECK_LIB("oci.lib", "oci8", PHP_OCI8)
+ if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8", PHP_PHP_BUILD + "\\include\\instantclient;" + PHP_OCI8) &&
+ CHECK_LIB("oci.lib", "oci8", PHP_PHP_BUILD + "\\lib\\instantclient;" + PHP_OCI8)
) {
- EXTENSION('oci8', 'oci8.c');
+ EXTENSION('oci8', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c');
AC_DEFINE('HAVE_OCI8_TEMP_LOB', 1);
AC_DEFINE('HAVE_OCI8', 1);
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c
index 0796ac3434..2eca5e38f6 100644
--- a/ext/oci8/oci8.c
+++ b/ext/oci8/oci8.c
@@ -19,44 +19,21 @@
| Collection support by Andy Sautins <asautins@veripost.net> |
| Temporary LOB support by David Benson <dbenson@mancala.com> |
| ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+----------------------------------------------------------------------+
- */
+*/
/* $Id$ */
-
-/* TODO list:
+/* TODO
+ *
+ * file://localhost/www/docs/oci10/ociaahan.htm#423823 - implement lob_empty() with OCI_ATTR_LOBEMPTY
*
- * - php.ini flags
- * especialliy important for things like oci_ping
- * allowpconns
- * timeout
- * maxlifetime
- * maxpconns
- * - Change return-value for OCIFetch*() (1-row read, 0-Normal end, false-error)
- * - Error mode (print or shut up?)
- * - binding of arrays
- * - Character sets for NCLOBS
- * - split the module into an upper (php-callable) and lower (c-callable) layer!
- * - remove all XXXs
- * - clean up and documentation
- * - make OCIInternalDebug accept a mask of flags....
- * - have one ocifree() call.
- * - make it possible to have persistent statements?
- * - failover
- * - change all the lob stuff to work without classes (optional)!
- * - make sure that the callbacks terminate the strings with \0
- * - cleanup the ociexecute semantics for refcursors
- * - make $lob->savefile use O_BINARY
- * - line 2728: ub4 length = -1; needs fixing
- * - delay OCIInitialize() as far as we can.
- * - add PHP Array <-> OCICollection conversion
- * - add Collection iterator object for INDEX BY tables
- * - make auto-rollback only happen if we have an outstanding transaction
- * - implement ocidisconnect
- * - add OCI9-specific functions and separate them from OCI8 with ifdefs
- */
-
-/* {{{ includes & stuff */
+ * get OCI_ATTR_CHARSET_ID attr of column to detect UTF string and multiply buffer in 4 times
+ *
+ * */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -65,30 +42,27 @@
#include "php.h"
#include "ext/standard/info.h"
#include "php_ini.h"
+#include "ext/standard/php_smart_str.h"
#if HAVE_OCI8
#include "php_oci8.h"
+#include "php_oci8_int.h"
-/* True globals, only used by thread safe functions */
-static TsHashTable *persistent_servers;
-static TsHashTable *persistent_sessions;
-
-static long num_persistent = 0;
-static long num_links = 0;
+ZEND_DECLARE_MODULE_GLOBALS(oci)
/* True globals, no need for thread safety */
-static int le_conn;
-static int le_stmt;
-static int le_desc;
+int le_connection;
+int le_pconnection;
+int le_statement;
+int le_descriptor;
#ifdef PHP_OCI8_HAVE_COLLECTIONS
-static int le_coll;
+int le_collection;
#endif
-static int le_server;
-static int le_session;
-static zend_class_entry *oci_lob_class_entry_ptr;
+
+zend_class_entry *oci_lob_class_entry_ptr;
#ifdef PHP_OCI8_HAVE_COLLECTIONS
-static zend_class_entry *oci_coll_class_entry_ptr;
+zend_class_entry *oci_coll_class_entry_ptr;
#endif
#ifndef SQLT_BFILEE
@@ -98,195 +72,52 @@ static zend_class_entry *oci_coll_class_entry_ptr;
#define SQLT_CFILEE 115
#endif
-#define SAFE_STRING(s) ((s)?(s):"")
+#define PHP_OCI_ERRBUF_LEN 512
-#ifdef ZTS
-MUTEX_T mx_lock;
-
-#define mutex_alloc(mutex) mutex = tsrm_mutex_alloc()
-#define mutex_free(mutex) tsrm_mutex_free(mutex)
-#define mutex_lock(mutex) tsrm_mutex_lock(mutex)
-#define mutex_unlock(mutex) tsrm_mutex_unlock(mutex)
-#define thread_id() tsrm_thread_id()
+#if ZEND_MODULE_API_NO > 20020429
+#define ONUPDATELONGFUNC OnUpdateLong
#else
-#define mutex_alloc(mutex)
-#define mutex_free(mutex)
-#define mutex_lock(mutex)
-#define mutex_unlock(mutex)
-#define thread_id() 1
+#define ONUPDATELONGFUNC OnUpdateInt
#endif
-/* dirty marcos to make sure we _never_ call oracle-functions recursivly
- *
- * i'm well aware that we should _never_ call exit directly - this core is for
- * pure testing and commented out - as you can see;-)
- * thies@thieso.net 20010723
- */
-
-#define CALL_OCI(call) \
-{ \
- if (OCI(in_call)) { \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI8 Recursive call!"); \
- exit(-1); \
- } else { \
- OCI(in_call)=1; \
- call; \
- OCI(in_call)=0; \
- } \
-}
-
-#define CALL_OCI_RETURN(retcode,call) \
-{ \
- if (OCI(in_call)) { \
- retcode=-1; \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI8 Recursive call!"); \
- exit(-1); \
- } else { \
- OCI(in_call)=1; \
- retcode=call; \
- OCI(in_call)=0; \
- } \
-}
-
-#include <fcntl.h>
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
+/* static protos {{{ */
+static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
+static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
+static void php_oci_statement_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
+static void php_oci_descriptor_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
+static void php_oci_collection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
+static int php_oci_persistent_helper(list_entry *le TSRMLS_DC);
+static int php_oci_connection_ping(php_oci_connection * TSRMLS_DC);
+static int php_oci_connection_status(php_oci_connection * TSRMLS_DC);
+static int php_oci_connection_close(php_oci_connection * TSRMLS_DC);
/* }}} */
-/* {{{ thread safety stuff */
-
-#ifdef ZTS
-int oci_globals_id;
-#else
-PHP_OCI_API php_oci_globals oci_globals;
-#endif
-/* }}} */
/* {{{ dynamically loadable module stuff */
-
#ifdef COMPILE_DL_OCI8
ZEND_GET_MODULE(oci8)
-# ifdef PHP_WIN32
-# include "zend_arg_defs.c"
-# endif
#endif /* COMPILE_DL */
-
-/* }}} */
-/* {{{ startup/shutdown/info/internal function prototypes */
-
-PHP_MINIT_FUNCTION(oci);
-PHP_RINIT_FUNCTION(oci);
-PHP_MSHUTDOWN_FUNCTION(oci);
-PHP_RSHUTDOWN_FUNCTION(oci);
-PHP_MINFO_FUNCTION(oci);
-
-static ub4 oci_handle_error(oci_connection *connection, ub4 errcode);
-static ub4 oci_error(OCIError *err_p, char *what, sword status);
-static int oci_ping(oci_server *server);
-static void oci_debug(const char *format, ...);
-
-static void _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC);
-static void _oci_stmt_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-static void _oci_descriptor_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-static void _oci_coll_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-#endif
-static void _oci_server_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-static void _oci_session_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-static void php_oci_free_conn_list(zend_rsrc_list_entry *rsrc TSRMLS_DC);
-
-static void _oci_column_hash_dtor(void *data);
-static void _oci_define_hash_dtor(void *data);
-static void _oci_bind_hash_dtor(void *data);
-static void _oci_desc_flush_hash_dtor(void *data);
-
-static oci_connection *oci_get_conn(zval ** TSRMLS_DC);
-static oci_statement *oci_get_stmt(zval ** TSRMLS_DC);
-static oci_descriptor *oci_get_desc(int TSRMLS_DC);
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-/* Questionable name. Very close to oci_get_col */
-static oci_collection *oci_get_coll(int TSRMLS_DC);
-#endif
-static oci_out_column *oci_get_col(oci_statement *, int, zval **);
-
-static int _oci_make_zval(zval *, oci_statement *, oci_out_column *, char *, int mode TSRMLS_DC);
-static oci_statement *oci_parse(oci_connection *, char *, int);
-static int oci_execute(oci_statement *, char *, ub4 mode);
-static int oci_fetch(oci_statement *, ub4, char * TSRMLS_DC);
-static int oci_lobgetlen(oci_connection *, oci_descriptor *, ub4 *length);
-static int oci_loadlob(oci_connection *, oci_descriptor *, char **, ub4 *length);
-static int oci_readlob(oci_connection *, oci_descriptor *, char **, ub4 *len);
-static int oci_setprefetch(oci_statement *statement, int size);
-
-static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclusive);
-
-static oci_server *_oci_open_server(char *dbname,int persistent);
-static void _oci_close_server(oci_server *server);
-
-static oci_session *_oci_open_session(oci_server* server,char *username,char *password,int persistent,int exclusive, char *charset);
-static void _oci_close_session(oci_session *session);
-
-static sb4 oci_bind_in_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 *, ub1 *, dvoid **);
-static sb4 oci_bind_out_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 **, ub1 *, dvoid **, ub2 **);
-
-#if 0
-static sb4 oci_failover_callback(dvoid *svchp,dvoid* envhp,dvoid *fo_ctx,ub4 fo_type, ub4 fo_event);
-#endif
-
-static int oci_lob_flush(oci_descriptor *, int flush_flag TSRMLS_DC);
-
/* }}} */
-/* {{{ extension macros
-*/
-#define OCI_GET_STMT(statement,value) \
- statement = oci_get_stmt(value TSRMLS_CC); \
- if (statement == NULL) { \
- RETURN_FALSE; \
- }
-
-#define OCI_GET_CONN(connection,value) \
- connection = oci_get_conn(value TSRMLS_CC); \
- if (connection == NULL) { \
- RETURN_FALSE; \
- }
-
-#define OCI_GET_DESC(descriptor,index) \
- descriptor = oci_get_desc(index TSRMLS_CC); \
- if (descriptor == NULL) { \
- RETURN_FALSE; \
- }
-
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-#define OCI_GET_COLL(collection,index) \
- collection = oci_get_coll(index TSRMLS_CC); \
- if (collection == NULL) { \
- RETURN_FALSE; \
- }
+#ifdef ZEND_ENGINE_2
+ZEND_BEGIN_ARG_INFO(oci_second_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(oci_third_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ZEND_END_ARG_INFO()
+#else
+static unsigned char oci_second_arg_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };
+static unsigned char oci_third_arg_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
#endif
-#define IS_LOB_INTERNAL(lob) \
- if (lob->type != OCI_DTYPE_LOB) { \
- switch (lob->type) { \
- case OCI_DTYPE_FILE: \
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "internal LOB was expected, FILE locator is given"); \
- break; \
- case OCI_DTYPE_ROWID: \
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "internal LOB was expected, ROWID locator is given"); \
- break; \
- default: \
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "internal LOB was expected, locator of unknown type is given"); \
- break; \
- } \
- RETURN_FALSE; \
- }
-/* }}} */
-
/* {{{ extension function prototypes
*/
PHP_FUNCTION(oci_bind_by_name);
+PHP_FUNCTION(oci_bind_array_by_name);
PHP_FUNCTION(oci_define_by_name);
PHP_FUNCTION(oci_field_is_null);
PHP_FUNCTION(oci_field_name);
@@ -363,20 +194,10 @@ PHP_FUNCTION(oci_collection_trim);
/* {{{ extension definition structures
*/
-#define OCI_ASSOC 1<<0
-#define OCI_NUM 1<<1
-#define OCI_BOTH (OCI_ASSOC|OCI_NUM)
-
-#define OCI_RETURN_NULLS 1<<2
-#define OCI_RETURN_LOBS 1<<3
-
-#define OCI_FETCHSTATEMENT_BY_COLUMN 1<<4
-#define OCI_FETCHSTATEMENT_BY_ROW 1<<5
-#define OCI_FETCHSTATEMENT_BY (OCI_FETCHSTATEMENT_BY_COLUMN | OCI_FETCHSTATEMENT_BY_ROW)
-
static zend_function_entry php_oci_functions[] = {
- PHP_FE(oci_define_by_name, third_arg_force_ref)
- PHP_FE(oci_bind_by_name, third_arg_force_ref)
+ PHP_FE(oci_define_by_name, oci_third_arg_force_ref)
+ PHP_FE(oci_bind_by_name, oci_third_arg_force_ref)
+ PHP_FE(oci_bind_array_by_name, oci_third_arg_force_ref)
PHP_FE(oci_field_is_null, NULL)
PHP_FE(oci_field_name, NULL)
PHP_FE(oci_field_size, NULL)
@@ -391,8 +212,8 @@ static zend_function_entry php_oci_functions[] = {
PHP_FE(oci_fetch_row, NULL)
PHP_FE(oci_fetch_assoc, NULL)
PHP_FE(oci_fetch_array, NULL)
- PHP_FE(ocifetchinto, second_arg_force_ref)
- PHP_FE(oci_fetch_all, second_arg_force_ref)
+ PHP_FE(ocifetchinto, oci_second_arg_force_ref)
+ PHP_FE(oci_fetch_all, oci_second_arg_force_ref)
PHP_FE(oci_free_statement, NULL)
PHP_FE(oci_internal_debug, NULL)
PHP_FE(oci_num_fields, NULL)
@@ -445,8 +266,8 @@ static zend_function_entry php_oci_functions[] = {
PHP_FALIAS(oci_free_cursor, oci_free_statement, NULL)
PHP_FALIAS(ocifreecursor, oci_free_statement, NULL)
- PHP_FALIAS(ocibindbyname, oci_bind_by_name, third_arg_force_ref)
- PHP_FALIAS(ocidefinebyname, oci_define_by_name, third_arg_force_ref)
+ PHP_FALIAS(ocibindbyname, oci_bind_by_name, oci_third_arg_force_ref)
+ PHP_FALIAS(ocidefinebyname, oci_define_by_name, oci_third_arg_force_ref)
PHP_FALIAS(ocicolumnisnull, oci_field_is_null, NULL)
PHP_FALIAS(ocicolumnname, oci_field_name, NULL)
PHP_FALIAS(ocicolumnsize, oci_field_size, NULL)
@@ -457,7 +278,7 @@ static zend_function_entry php_oci_functions[] = {
PHP_FALIAS(ociexecute, oci_execute, NULL)
PHP_FALIAS(ocicancel, oci_cancel, NULL)
PHP_FALIAS(ocifetch, oci_fetch, NULL)
- PHP_FALIAS(ocifetchstatement, oci_fetch_all, second_arg_force_ref)
+ PHP_FALIAS(ocifetchstatement, oci_fetch_all, oci_second_arg_force_ref)
PHP_FALIAS(ocifreestatement, oci_free_statement, NULL)
PHP_FALIAS(ociinternaldebug, oci_internal_debug, NULL)
PHP_FALIAS(ocinumcols, oci_num_fields, NULL)
@@ -511,6 +332,8 @@ static zend_function_entry php_oci_lob_class_functions[] = {
PHP_FALIAS(append, oci_lob_append, NULL)
PHP_FALIAS(size, oci_lob_size, NULL)
PHP_FALIAS(writetofile, oci_lob_export, NULL)
+ PHP_FALIAS(export, oci_lob_export, NULL)
+ PHP_FALIAS(import, oci_lob_import, NULL)
#ifdef HAVE_OCI8_TEMP_LOB
PHP_FALIAS(writetemporary, oci_lob_write_temporary, NULL)
PHP_FALIAS(close, oci_lob_close, NULL)
@@ -544,58 +367,98 @@ zend_module_entry oci8_module_entry = {
PHP_RINIT(oci), /* per-request startup function */
PHP_RSHUTDOWN(oci), /* per-request shutdown function */
PHP_MINFO(oci), /* information function */
- NO_VERSION_YET,
+ "1.1",
STANDARD_MODULE_PROPERTIES
};
/* }}} */
+/* {{{ PHP_INI */
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("oci8.max_persistent", "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC, max_persistent, zend_oci_globals, oci_globals)
+ STD_PHP_INI_ENTRY("oci8.persistent_timeout", "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC, persistent_timeout, zend_oci_globals, oci_globals)
+ STD_PHP_INI_ENTRY("oci8.ping_interval", "60", PHP_INI_SYSTEM, ONUPDATELONGFUNC, ping_interval, zend_oci_globals, oci_globals)
+ STD_PHP_INI_BOOLEAN("oci8.privileged_connect", "0", PHP_INI_SYSTEM, OnUpdateBool, privileged_connect, zend_oci_globals, oci_globals)
+ STD_PHP_INI_ENTRY("oci8.statement_cache_size", "20", PHP_INI_SYSTEM, ONUPDATELONGFUNC, statement_cache_size, zend_oci_globals, oci_globals)
+ STD_PHP_INI_ENTRY("oci8.default_prefetch", "10", PHP_INI_SYSTEM, ONUPDATELONGFUNC, default_prefetch, zend_oci_globals, oci_globals)
+ STD_PHP_INI_ENTRY("oci8.old_oci_close_semantics", "0", PHP_INI_SYSTEM, OnUpdateBool, old_oci_close_semantics, zend_oci_globals, oci_globals)
+PHP_INI_END()
+/* }}} */
+
/* {{{ startup, shutdown and info functions
*/
-static void php_oci_init_globals(php_oci_globals *oci_globals_p TSRMLS_DC)
-{
- OCI(shutdown) = 0;
- OCI(in_call) = 0;
-
- CALL_OCI(
- OCIEnvInit(
- &OCI(pEnv),
- OCI_DEFAULT,
- 0,
- NULL
- )
- );
-
- CALL_OCI(
- OCIHandleAlloc(
- OCI(pEnv),
- (dvoid **)&OCI(pError),
- OCI_HTYPE_ERROR,
- 0,
- NULL
- )
- );
-}
-static int _sessions_pcleanup(zend_llist *session_list)
+/* {{{ php_oci_init_global_handles()
+ Initialize global handles only when they are needed
+*/
+static void php_oci_init_global_handles(TSRMLS_D)
{
- zend_llist_destroy(session_list);
+ sword errcode;
+ sb4 error_code = 0;
+ text tmp_buf[PHP_OCI_ERRBUF_LEN];
- return 1;
-}
+ errcode = OCIEnvInit (&OCI_G(env), OCI_DEFAULT, 0, NULL);
+
+ if (errcode == OCI_ERROR) {
+ goto oci_error;
+ }
+
+ errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
+
+ if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) {
+ goto oci_error;
+ }
-static int _session_pcleanup(oci_session *session)
-{
- _oci_close_session(session);
+ return;
+
+oci_error:
+
+ OCIErrorGet(OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
- return 1;
-}
+ if (error_code) {
+ int tmp_buf_len = strlen(tmp_buf);
+
+ if (tmp_buf[tmp_buf_len - 1] == '\n') {
+ tmp_buf[tmp_buf_len - 1] = '\0';
+ }
+
+ if (errcode != OCI_SUCCESS_WITH_INFO) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf);
+
+ OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
+
+ OCI_G(env) = NULL;
+ OCI_G(err) = NULL;
+ }
+ else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
+ }
+ }
+} /* }}} */
-static int _server_pcleanup(oci_server *server)
+/* {{{ php_oci_cleanup_global_handles()
+ Free global handles (if they were initialized before)
+*/
+static void php_oci_cleanup_global_handles(TSRMLS_D)
{
- _oci_close_server(server);
+ if (OCI_G(err)) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR));
+ OCI_G(err) = NULL;
+ }
+
+ if (OCI_G(env)) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV));
+ OCI_G(env) = NULL;
+ }
+} /* }}} */
- return 1;
+/* {{{ php_oci_init_globals()
+ Zerofill globals during module init
+*/
+static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC)
+{
+ memset(oci_globals, 0, sizeof(zend_oci_globals));
}
+/* }}} */
PHP_MINIT_FUNCTION(oci)
{
@@ -604,53 +467,32 @@ PHP_MINIT_FUNCTION(oci)
zend_class_entry oci_coll_class_entry;
#endif
-#ifdef HAVE_OCI8_SHARED_MODE
-
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-#define PHP_OCI_INIT_MODE_TMP OCI_SHARED | OCI_OBJECT
-#else
-#define PHP_OCI_INIT_MODE_TMP OCI_SHARED
-#endif
-
-#else
-
#ifdef PHP_OCI8_HAVE_COLLECTIONS
#define PHP_OCI_INIT_MODE_TMP OCI_DEFAULT | OCI_OBJECT
#else
#define PHP_OCI_INIT_MODE_TMP OCI_DEFAULT
#endif
-#endif
-
#ifdef ZTS
#define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP | OCI_THREADED
#else
#define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP
#endif
- mutex_alloc(mx_lock);
-
- persistent_servers = malloc(sizeof(TsHashTable));
- persistent_sessions = malloc(sizeof(TsHashTable));
- zend_ts_hash_init(persistent_servers, 13, NULL, (dtor_func_t) _server_pcleanup, 1);
- zend_ts_hash_init(persistent_sessions, 13, NULL, (dtor_func_t) _sessions_pcleanup, 1);
-
+#if !HAVE_OCI_ENV_CREATE
OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL);
-
-#ifdef ZTS
- ts_allocate_id(&oci_globals_id, sizeof(php_oci_globals), (ts_allocate_ctor) php_oci_init_globals, NULL);
-#else
- php_oci_init_globals(&oci_globals TSRMLS_CC);
#endif
- le_stmt = zend_register_list_destructors_ex(_oci_stmt_list_dtor, NULL, "oci8 statement", module_number);
- le_conn = zend_register_list_destructors_ex(php_oci_free_conn_list, NULL, "oci8 connection", module_number);
- le_desc = zend_register_list_destructors_ex(_oci_descriptor_list_dtor, NULL, "oci8 descriptor", module_number);
+ ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, NULL);
+ REGISTER_INI_ENTRIES();
+
+ le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
+ le_connection = zend_register_list_destructors_ex(php_oci_connection_list_dtor, NULL, "oci8 connection", module_number);
+ le_pconnection = zend_register_list_destructors_ex(NULL, php_oci_pconnection_list_dtor, "oci8 persistent connection", module_number);
+ le_descriptor = zend_register_list_destructors_ex(php_oci_descriptor_list_dtor, NULL, "oci8 descriptor", module_number);
#ifdef PHP_OCI8_HAVE_COLLECTIONS
- le_coll = zend_register_list_destructors_ex(_oci_coll_list_dtor, NULL, "oci8 collection", module_number);
+ le_collection = zend_register_list_destructors_ex(php_oci_collection_list_dtor, NULL, "oci8 collection", module_number);
#endif
- le_server = zend_register_list_destructors_ex(_oci_server_list_dtor, NULL, "oci8 server", module_number);
- le_session = zend_register_list_destructors_ex(_oci_session_list_dtor, NULL, "oci8 session", module_number);
INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions);
#ifdef PHP_OCI8_HAVE_COLLECTIONS
@@ -664,14 +506,16 @@ PHP_MINIT_FUNCTION(oci)
/* thies@thieso.net 990203 i do not think that we will need all of them - just in here for completeness for now! */
REGISTER_LONG_CONSTANT("OCI_DEFAULT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_SYSOPER",OCI_SYSOPER, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_SYSDBA",OCI_SYSDBA, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_DESCRIBE_ONLY",OCI_DESCRIBE_ONLY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_COMMIT_ON_SUCCESS",OCI_COMMIT_ON_SUCCESS, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_EXACT_FETCH",OCI_EXACT_FETCH, CONST_CS | CONST_PERSISTENT);
/* for $LOB->seek() */
- REGISTER_LONG_CONSTANT("OCI_SEEK_SET",OCI_SEEK_SET, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_SEEK_CUR",OCI_SEEK_CUR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_SEEK_END",OCI_SEEK_END, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_SEEK_SET",PHP_OCI_SEEK_SET, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_SEEK_CUR",PHP_OCI_SEEK_CUR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_SEEK_END",PHP_OCI_SEEK_END, CONST_CS | CONST_PERSISTENT);
/* for $LOB->flush() */
REGISTER_LONG_CONSTANT("OCI_LOB_BUFFER_FREE",OCI_LOB_BUFFER_FREE, CONST_CS | CONST_PERSISTENT);
@@ -682,11 +526,28 @@ PHP_MINIT_FUNCTION(oci)
REGISTER_LONG_CONSTANT("SQLT_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLT_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLT_RDD",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_RSET",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_AFC",SQLT_AFC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_CHR",SQLT_CHR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_VCS",SQLT_VCS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_AVC",SQLT_AVC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_STR",SQLT_STR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_LVC",SQLT_LVC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_FLT",SQLT_FLT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_UIN",SQLT_UIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_LNG",SQLT_LNG, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_ODT",SQLT_ODT, CONST_CS | CONST_PERSISTENT);
+#if defined(HAVE_OCI_INSTANT_CLIENT) || (defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION > 10)
+ REGISTER_LONG_CONSTANT("SQLT_BDOUBLE",SQLT_BDOUBLE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SQLT_BFLOAT",SQLT_BFLOAT, CONST_CS | CONST_PERSISTENT);
+#endif
#ifdef PHP_OCI8_HAVE_COLLECTIONS
REGISTER_LONG_CONSTANT("OCI_B_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
- REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE",CONST_PERSISTENT);
+ REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE", CONST_CS | CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("OCI_B_BFILE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
@@ -696,17 +557,19 @@ PHP_MINIT_FUNCTION(oci)
REGISTER_LONG_CONSTANT("OCI_B_ROWID",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_B_CURSOR",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OCI_B_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_B_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_B_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
/* for OCIFetchStatement */
- REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", PHP_OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT);
/* for OCIFetchInto & OCIResult */
- REGISTER_LONG_CONSTANT("OCI_ASSOC",OCI_ASSOC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_NUM",OCI_NUM, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_BOTH",OCI_BOTH, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_RETURN_NULLS",OCI_RETURN_NULLS, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("OCI_RETURN_LOBS",OCI_RETURN_LOBS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_ASSOC",PHP_OCI_ASSOC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_NUM",PHP_OCI_NUM, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_BOTH",PHP_OCI_BOTH, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_RETURN_NULLS",PHP_OCI_RETURN_NULLS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OCI_RETURN_LOBS",PHP_OCI_RETURN_LOBS, CONST_CS | CONST_PERSISTENT);
/* for OCINewDescriptor (real "oci" names + short "php" names*/
REGISTER_LONG_CONSTANT("OCI_DTYPE_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
@@ -730,53 +593,39 @@ PHP_MINIT_FUNCTION(oci)
PHP_RINIT_FUNCTION(oci)
{
- OCI(debug_mode) = 0; /* start "fresh" */
-/* OCI(in_call) = 0; i don't think we want this! */
-
- oci_debug("php_rinit_oci");
+ OCI_G(debug_mode) = 0; /* start "fresh" */
+ OCI_G(num_links) = OCI_G(num_persistent);
+ OCI_G(errcode) = 0;
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(oci)
{
- OCI(shutdown) = 1;
-
- oci_debug("START php_mshutdown_oci");
-
- zend_ts_hash_destroy(persistent_sessions);
- zend_ts_hash_destroy(persistent_servers);
-
- free(persistent_sessions);
- free(persistent_servers);
-
- mutex_free(mx_lock);
+ OCI_G(shutdown) = 1;
+
+ UNREGISTER_INI_ENTRIES();
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) OCI(pEnv),
- OCI_HTYPE_ENV
- )
- );
+#ifndef ZTS
+ php_oci_cleanup_global_handles(TSRMLS_C);
+#endif
- oci_debug("END php_mshutdown_oci");
+#if !HAVE_OCI_ENV_CREATE
+ OCITerminate(OCI_DEFAULT);
+#endif
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(oci)
{
- oci_debug("START php_rshutdown_oci");
+ /* check persistent connections and do the necessary actions if needed */
+ zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
-#if 0
- /* XXX free all statements, rollback all outstanding transactions */
-
- zend_ts_hash_apply(persistent_sessions, (apply_func_t) _session_cleanup TSRMLS_CC);
- zend_ts_hash_apply(persistent_servers, (apply_func_t) _server_cleanup TSRMLS_CC);
+#ifdef ZTS
+ php_oci_cleanup_global_handles(TSRMLS_C);
#endif
- oci_debug("END php_rshutdown_oci");
-
return SUCCESS;
}
@@ -788,15 +637,20 @@ PHP_MINFO_FUNCTION(oci)
php_info_print_table_row(2, "OCI8 Support", "enabled");
php_info_print_table_row(2, "Revision", "$Revision$");
- sprintf(buf, "%ld", num_persistent);
- php_info_print_table_row(2, "Active Persistent Links", buf);
- sprintf(buf, "%ld", num_links);
- php_info_print_table_row(2, "Active Links", buf);
+ sprintf(buf, "%ld", OCI_G(num_persistent));
+ php_info_print_table_row(2, "Active Persistent Connections", buf);
+ sprintf(buf, "%ld", OCI_G(num_links));
+ php_info_print_table_row(2, "Active Connections", buf);
-#ifndef PHP_WIN32
+#if !defined(PHP_WIN32) && !defined(HAVE_OCI_INSTANT_CLIENT)
php_info_print_table_row(2, "Oracle Version", PHP_OCI8_VERSION );
php_info_print_table_row(2, "Compile-time ORACLE_HOME", PHP_OCI8_DIR );
php_info_print_table_row(2, "Libraries Used", PHP_OCI8_SHARED_LIBADD );
+#else
+# if defined(HAVE_OCI_INSTANT_CLIENT) && defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
+ sprintf(buf, "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION);
+ php_info_print_table_row(2, "Oracle Instant Client Version", buf);
+# endif
#endif
#ifdef HAVE_OCI8_TEMP_LOB
@@ -812,111 +666,116 @@ PHP_MINFO_FUNCTION(oci)
#endif
php_info_print_table_end();
+
+ DISPLAY_INI_ENTRIES();
}
/* }}} */
-/* {{{ _oci_define_hash_dtor()
-*/
-static void _oci_define_hash_dtor(void *data)
-{
- oci_define *define = (oci_define *) data;
+/* list destructors {{{ */
- oci_debug("_oci_define_hash_dtor: %s",define->name);
-
- zval_ptr_dtor(&define->zval);
+/* {{{ php_oci_connection_list_dtor()
+ Non-persistent connection destructor */
+static void php_oci_connection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
+{
+ php_oci_connection *connection = (php_oci_connection *)entry->ptr;
+ php_oci_connection_close(connection TSRMLS_CC);
+ OCI_G(num_links)--;
+} /* }}} */
- if (define->name) {
- efree(define->name);
- define->name = 0;
- }
-}
-/* }}} */
+/* {{{ php_oci_pconnection_list_dtor()
+ Persistent connection destructor */
+static void php_oci_pconnection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
+{
+ php_oci_connection *connection = (php_oci_connection *)entry->ptr;
+ php_oci_connection_close(connection TSRMLS_CC);
+ OCI_G(num_persistent)--;
+} /* }}} */
-/* {{{ _oci_desc_flush_hash_dtor()
- */
-static void _oci_desc_flush_hash_dtor(void *data)
+/* {{{ php_oci_statement_list_dtor()
+ Statement destructor */
+static void php_oci_statement_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
{
- oci_descriptor *descr = *(oci_descriptor **)data;
- TSRMLS_FETCH();
-
- if (descr->buffering == 2 && (descr->type == OCI_DTYPE_LOB || descr->type == OCI_DTYPE_FILE)) {
- oci_lob_flush(descr,OCI_LOB_BUFFER_FREE TSRMLS_CC);
- descr->buffering = 1;
- }
-}
-/* }}} */
+ php_oci_statement *statement = (php_oci_statement *)entry->ptr;
+ php_oci_statement_free(statement TSRMLS_CC);
+} /* }}} */
-/* {{{ _oci_bind_hash_dtor()
-*/
-static void _oci_bind_hash_dtor(void *data)
+/* {{{ php_oci_descriptor_list_dtor()
+ Descriptor destructor */
+static void php_oci_descriptor_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
{
- oci_bind *bind = (oci_bind *) data;
+ php_oci_descriptor *descriptor = (php_oci_descriptor *)entry->ptr;
+ php_oci_lob_free(descriptor TSRMLS_CC);
+} /* }}} */
- oci_debug("_oci_bind_hash_dtor:");
+/* {{{ php_oci_collection_list_dtor()
+ Collection destructor */
+static void php_oci_collection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
+{
+ php_oci_collection *collection = (php_oci_collection *)entry->ptr;
+ php_oci_collection_close(collection TSRMLS_CC);
+} /* }}} */
- zval_ptr_dtor(&(bind->zval));
-}
/* }}} */
-/* {{{ _oci_bind_pre_exec()
-*/
-static int _oci_bind_pre_exec(void *data TSRMLS_DC)
-{
- oci_bind *bind = (oci_bind *) data;
+/* hash destructors {{{ */
- /* reset all bind stuff to a normal state..-. */
+/* {{{ php_oci_define_hash_dtor()
+ Define hash destructor */
+void php_oci_define_hash_dtor(void *data)
+{
+ php_oci_define *define = (php_oci_define *) data;
- bind->indicator = 0;
+ zval_ptr_dtor(&define->zval);
- return 0;
+ if (define->name) {
+ efree(define->name);
+ define->name = NULL;
+ }
}
/* }}} */
-/* {{{ _oci_bind_post_exec()
-*/
-static int _oci_bind_post_exec(void *data TSRMLS_DC)
+/* {{{ php_oci_bind_hash_dtor()
+ Bind hash destructor */
+void php_oci_bind_hash_dtor(void *data)
{
- oci_bind *bind = (oci_bind *) data;
+ php_oci_bind *bind = (php_oci_bind *) data;
- if (bind->indicator == -1) { /* NULL */
- zval *val = bind->zval;
- if (Z_TYPE_P(val) == IS_STRING) {
- *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */
- }
- zval_dtor(val);
- ZVAL_NULL(val);
- } else if (Z_TYPE_P(bind->zval) == IS_STRING) {
- Z_STRVAL_P(bind->zval) = erealloc(Z_STRVAL_P(bind->zval), Z_STRLEN_P(bind->zval)+1);
- Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0';
+ if (bind->array.elements) {
+ efree(bind->array.elements);
}
+/* if (bind->array.element_lengths) {
+ efree(bind->array.element_lengths);
+ }
+ if (bind->array.indicators) {
+ efree(bind->array.indicators);
+ }
+ if (bind->array.retcodes) {
+ efree(bind->array.retcodes);
+ }
+*/
-
- return 0;
+ zval_ptr_dtor(&bind->zval);
}
/* }}} */
-/* {{{ _oci_column_hash_dtor()
-*/
-static void _oci_column_hash_dtor(void *data)
+/* {{{ php_oci_column_hash_dtor()
+ Column hash destructor */
+void php_oci_column_hash_dtor(void *data)
{
- oci_out_column *column = (oci_out_column *) data;
+ php_oci_out_column *column = (php_oci_out_column *) data;
TSRMLS_FETCH();
- oci_debug("START _oci_column_hash_dtor: %s",column->name);
-
if (column->stmtid) {
zend_list_delete(column->stmtid);
}
if (column->is_descr) {
zend_list_delete(column->descid);
- } else {
- if (column->data) {
- efree(column->data);
- }
}
- oci_debug("END _oci_column_hash_dtor: %s",column->name);
+ if (column->data) {
+ efree(column->data);
+ }
if (column->name) {
efree(column->name);
@@ -924,6259 +783,936 @@ static void _oci_column_hash_dtor(void *data)
}
/* }}} */
-/* {{{ _oci_stmt_list_dtor()
-*/
-static void _oci_stmt_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+/* {{{ php_oci_descriptor_flush_hash_dtor()
+ Flush descriptors on commit */
+void php_oci_descriptor_flush_hash_dtor(void *data)
{
- oci_statement *statement = (oci_statement *)rsrc->ptr;
- oci_debug("START _oci_stmt_list_dtor: id=%d last_query=\"%s\"",statement->id,SAFE_STRING(statement->last_query));
-
- if (statement->pStmt) {
- CALL_OCI(
- OCIHandleFree(
- statement->pStmt,
- OCI_HTYPE_STMT
- )
- );
-
- statement->pStmt = 0;
- }
-
- if (statement->pError) {
- CALL_OCI(
- OCIHandleFree(
- statement->pError,
- OCI_HTYPE_ERROR
- )
- );
-
- statement->pError = 0;
- }
-
- if (statement->last_query) {
- efree(statement->last_query);
- }
-
- if (statement->columns) {
- zend_hash_destroy(statement->columns);
- efree(statement->columns);
- }
-
- if (statement->binds) {
- zend_hash_destroy(statement->binds);
- efree(statement->binds);
- }
-
- if (statement->defines) {
- zend_hash_destroy(statement->defines);
- efree(statement->defines);
- }
-
- oci_debug("END _oci_stmt_list_dtor: id=%d",statement->id);
-
- efree(statement);
-}
-/* }}} */
-
-/* {{{ _oci_conn_list_dtor()
-*/
-static void _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC)
-{
- /*
- as the connection is "only" a in memory service context we do not disconnect from oracle.
- */
-
- oci_debug("START _oci_conn_list_dtor: id=%d",connection->id);
-
- if (connection->pServiceContext) {
-
- if (connection->needs_commit) {
- oci_debug("OCITransRollback");
- CALL_OCI_RETURN(connection->error,
- OCITransRollback(
- connection->pServiceContext,
- connection->pError,
- (ub4)0
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "failed to rollback outstanding transactions!", connection->error);
- }
- connection->needs_commit = 0;
- } else {
- oci_debug("nothing to do..");
- }
-
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) connection->pServiceContext,
- (ub4) OCI_HTYPE_SVCCTX
- )
- );
- }
+ php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
+ TSRMLS_FETCH();
- if (connection->pError) {
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) connection->pError,
- (ub4) OCI_HTYPE_ERROR
- )
- );
- }
-
- if (connection->session && connection->session->exclusive) {
- /* close associated session when destructed */
- zend_list_delete(connection->session->num);
- }
-
- if (connection->descriptors) {
- zend_hash_destroy(connection->descriptors);
- efree(connection->descriptors);
+ if (descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
+ php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
+ descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
}
-
- oci_debug("END _oci_conn_list_dtor: id=%d",connection->id);
-
- efree(connection);
-}
-/* }}} */
-
-/* {{{ php_oci_free_conn_list
- */
-static void php_oci_free_conn_list(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
- oci_connection *conn = (oci_connection *)rsrc->ptr;
- _oci_conn_list_dtor(conn TSRMLS_CC);
-}
-/* }}} */
-
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-
-/* {{{ _oci_coll_list_dtor()
- */
-static void _oci_coll_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
- oci_collection *coll = (oci_collection *)rsrc->ptr;
- oci_debug("START _oci_coll_list_dtor: %d",coll->id);
-
- /* Note sure if we need to free the object. Have an
- oracle TAR out on this one.
- OCIDescriptorFree(descr->ocidescr, descr->type); */
-
- oci_debug("END _oci_coll_list_dtor: %d",coll->id);
-
- efree(coll);
-}
-/* }}} */
-#endif
-
-/* {{{ _oci_descriptor_list_dtor()
- */
-static void _oci_descriptor_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
- oci_descriptor *descr = (oci_descriptor *)rsrc->ptr;
- oci_debug("START _oci_descriptor_list_dtor: %d",descr->id);
-
- /* flushing Lobs & Files with buffering enabled */
- if ((descr->type == OCI_DTYPE_FILE || descr->type == OCI_DTYPE_LOB) && descr->buffering == 2) {
- oci_debug("descriptor #%d needs to be flushed. flushing..",descr->id);
- oci_lob_flush(descr,OCI_LOB_BUFFER_FREE TSRMLS_CC);
- }
-
- CALL_OCI(
- OCIDescriptorFree(
- descr->ocidescr,
- descr->type
- )
- );
-
- oci_debug("END _oci_descriptor_list_dtor: %d",descr->id);
-
- efree(descr);
}
/* }}} */
-/* {{{ _oci_server_list_dtor()
- */
-static void _oci_server_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
-#if 0
- oci_server *server = (oci_server *)rsrc->ptr;
- if (server->persistent)
- return;
-
- _oci_close_server(server);
-#endif
-}
/* }}} */
-/* {{{ _oci_session_list_dtor()
- */
-static void _oci_session_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+/* {{{ php_oci_error()
+ Fetch & print out error message if we get an error */
+sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
{
- oci_session *session = (oci_session *)rsrc->ptr;
- if (session->persistent) {
- /* clear thread assignment */
- session->thread = 0;
- return;
- }
-
- _oci_close_session(session);
-}
-/* }}} */
-
-/* {{{ oci_handle_error
- */
-static ub4 oci_handle_error(oci_connection *connection, ub4 errcode)
-{
- switch (errcode) {
- case 1013: /* user requested cancel of current operation */
- zend_bailout();
- break;
-
- case 22: /* ORA-00022 Invalid session id */
- case 1012: /* ORA-01012: */
- case 3113: /* ORA-03113: end-of-file on communication channel */
- case 604:
- case 1041:
- connection->is_open = 0;
- connection->session->is_open = 0;
- connection->session->server->is_open = 0;
- return 1; /* fatal error */
- }
-
- return 0; /* no fatal error */
-}
-/* }}} */
-
-/* {{{ oci_error()
-*/
-static ub4 oci_error(OCIError *err_p, char *what, sword status)
-{
- text errbuf[512];
+ text *errbuf = (text *)NULL;
sb4 errcode = 0;
- TSRMLS_FETCH();
switch (status) {
case OCI_SUCCESS:
break;
case OCI_SUCCESS_WITH_INFO:
- CALL_OCI(
- OCIErrorGet(
- err_p,
- (ub4)1,
- NULL,
- &errcode,
- errbuf,
- (ub4)sizeof(errbuf),
- (ub4)OCI_HTYPE_ERROR
- )
- );
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_SUCCESS_WITH_INFO: %s", what, errbuf);
+ errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf);
+ efree(errbuf);
break;
case OCI_NEED_DATA:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_NEED_DATA", what);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NEED_DATA");
break;
case OCI_NO_DATA:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_NO_DATA", what);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA");
break;
- case OCI_ERROR: {
- CALL_OCI(
- OCIErrorGet(
- err_p,
- (ub4)1,
- NULL,
- &errcode,
- errbuf,
- (ub4)sizeof(errbuf),
- (ub4)OCI_HTYPE_ERROR
- )
- );
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", what, errbuf);
+ case OCI_ERROR:
+ errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf);
+ efree(errbuf);
break;
- }
case OCI_INVALID_HANDLE:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_INVALID_HANDLE", what);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_INVALID_HANDLE");
break;
case OCI_STILL_EXECUTING:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_STILL_EXECUTING", what);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_STILL_EXECUTING");
break;
case OCI_CONTINUE:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: OCI_CONTINUE", what);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE");
break;
default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", status);
break;
}
return errcode;
}
/* }}} */
-/* {{{ oci_ping()
-*/
-static int oci_ping(oci_server *server)
+/* {{{ php_oci_fetch_errmsg()
+ Fetch error message into the buffer from the error handle provided */
+sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC)
{
- char version[256];
- TSRMLS_FETCH();
-
- CALL_OCI_RETURN(OCI(error),
- OCIServerVersion(
- server->pServer,
- OCI(pError),
- (text*)version,
- sizeof(version),
- OCI_HTYPE_SERVER
- )
- );
-
- if (OCI(error) == OCI_SUCCESS) {
- return 1;
- }
+ sb4 error_code = 0;
+ text tmp_buf[PHP_OCI_ERRBUF_LEN];
- oci_error(OCI(pError), "oci_ping", OCI(error));
-
- return 0;
-}
-/* }}} */
-
-/************************* INTERNAL FUNCTIONS *************************/
-
-/* {{{ oci_debug()
-*/
-static void oci_debug(const char *format, ...)
-{
- TSRMLS_FETCH();
-
- if (OCI(debug_mode)) {
- char buffer[1024];
- va_list args;
-
- va_start(args, format);
- vsnprintf(buffer, sizeof(buffer)-1, format, args);
- va_end(args);
- buffer[sizeof(buffer)-1] = '\0';
- php_printf("OCIDebug: %s<br />\n", buffer);
- }
-}
-/* }}} */
-
-/* {{{ oci_get_conn()
-*/
-static oci_connection *oci_get_conn(zval **conn TSRMLS_DC)
-{
- oci_connection *connection;
-
- connection = (oci_connection *) zend_fetch_resource(conn TSRMLS_CC, -1, "OCI8-Connection", NULL, 1, le_conn);
-
- if (connection && connection->is_open) {
- return connection;
- } else {
- return (oci_connection *) NULL;
- }
-}
-/* }}} */
-
-/* {{{ oci_get_stmt()
-*/
-static oci_statement *oci_get_stmt(zval **stmt TSRMLS_DC)
-{
- oci_statement *statement;
-
- statement = (oci_statement *) zend_fetch_resource(stmt TSRMLS_CC, -1, "OCI8-Statement", NULL, 1, le_stmt);
-
- if (statement && statement->conn->is_open) {
- return statement;
- } else {
- return (oci_statement *) NULL;
- }
-}
-/* }}} */
-
-/* {{{ oci_get_desc()
-*/
-static oci_descriptor *oci_get_desc(int ind TSRMLS_DC)
-{
- oci_descriptor *descriptor;
- int actual_resource_type;
-
- descriptor = (oci_descriptor *) zend_list_find(ind, &actual_resource_type);
-
- if (descriptor && (actual_resource_type == le_desc)) {
- return descriptor;
- } else {
- return (oci_descriptor *) NULL;
- }
-}
-/* }}} */
-
-/* {{{ oci_get_col()
-*/
-static oci_out_column *oci_get_col(oci_statement *statement, int col, zval **value)
-{
- oci_out_column *outcol = NULL;
- int i;
- TSRMLS_FETCH();
-
- if (statement->columns == 0) { /* we release the columns at the end of a fetch */
- return NULL;
- }
-
- if (value) {
- if (Z_TYPE_PP(value) == IS_STRING) {
- for (i = 0; i < statement->ncolumns; i++) {
- outcol = oci_get_col(statement, i + 1, 0);
- if (outcol == NULL) {
- continue;
- } else if (((int) outcol->name_len == Z_STRLEN_PP(value)) &&
- (!strncmp(outcol->name, Z_STRVAL_PP(value), Z_STRLEN_PP(value)))
- ) {
- return outcol;
- }
- }
- } else {
- convert_to_long_ex(value);
- return oci_get_col(statement,Z_LVAL_PP(value),0);
+ tmp_buf[0] = '\0';
+
+ PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR));
+
+ if (error_code) {
+ int tmp_buf_len = strlen(tmp_buf);
+
+ if (tmp_buf[tmp_buf_len - 1] == '\n') {
+ tmp_buf[tmp_buf_len - 1] = '\0';
}
- } else if (col != -1) {
- if (zend_hash_index_find(statement->columns, col, (void **)&outcol) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column %d", col);
- return NULL;
+ if (error_buf) {
+ *error_buf = NULL;
+ *error_buf = estrndup(tmp_buf, tmp_buf_len + 1);
}
- return outcol;
}
+ return error_code;
+} /* }}} */
- return NULL;
-}
-/* }}} */
-
-/* {{{ oci_new_desc()
-*/
-static oci_descriptor *oci_new_desc(int type, oci_connection *connection)
+#ifdef HAVE_OCI8_ATTR_STATEMENT
+/* {{{ php_oci_fetch_sqltext_offset()
+ Compute offset in the SQL statement */
+int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset TSRMLS_DC)
{
- oci_descriptor *descr;
- TSRMLS_FETCH();
+ *sqltext = NULL;
+ *error_offset = 0;
- descr = emalloc(sizeof(oci_descriptor));
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (text *) sqltext, (ub4 *)0, OCI_ATTR_STATEMENT, statement->err));
- descr->type = type;
-
- switch (descr->type) {
- case OCI_DTYPE_FILE:
- case OCI_DTYPE_LOB:
- case OCI_DTYPE_ROWID:
- break;
-
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown descriptor type %d.", descr->type);
- efree(descr);
- return 0;
- }
-
- CALL_OCI_RETURN(OCI(error),
- OCIDescriptorAlloc(
- connection->session->pEnv,
- (dvoid*)&(descr->ocidescr),
- descr->type,
- (size_t) 0,
- (dvoid **) 0
- )
- );
-
- if (OCI(error)) {
- ub4 error;
- error = oci_error(OCI(pError),"OCIDescriptorAlloc %d",OCI(error));
- oci_handle_error(connection, error);
- efree(descr);
- return 0;
- }
-
- descr->id = zend_list_insert(descr,le_desc);
- descr->conn = connection;
- descr->lob_current_position = 0;
- descr->lob_size = -1; /* we should set it to -1 to know, that it's just not initialized */
- descr->buffering = 0; /* buffering is off by default */
- zend_list_addref(connection->id);
-
- if (descr->type == OCI_DTYPE_LOB || descr->type == OCI_DTYPE_FILE) {
- /* add Lobs & Files to hash. we'll flush them ate the end */
- if (!connection->descriptors) {
- ALLOC_HASHTABLE(connection->descriptors);
- zend_hash_init(connection->descriptors, 13, NULL, _oci_desc_flush_hash_dtor, 0);
- }
-
- zend_hash_next_index_insert(connection->descriptors,&descr,sizeof(oci_descriptor *),NULL);
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ return 1;
}
- oci_debug("oci_new_desc %d",descr->id);
-
- return descr;
-}
-/* }}} */
-
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-/* {{{ _oci_get_ocicoll()
-*/
-static int _oci_get_ocicoll(zval *id,oci_collection **collection TSRMLS_DC)
-{
- zval **coll;
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)error_offset, (ub4 *)0, OCI_ATTR_PARSE_ERROR_OFFSET, statement->err));
- if (zend_hash_find(Z_OBJPROP_P(id), "collection", sizeof("collection"), (void **)&coll) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot find collection");
- return 0;
- }
- if ((*collection = oci_get_coll(Z_LVAL_PP(coll) TSRMLS_CC)) == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "collection not found");
- return 0;
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ return 1;
}
-
- return Z_LVAL_PP(coll);
-}
-/* }}} */
-
+ return 0;
+} /* }}} */
#endif
-/* {{{ _oci_get_ocidesc()
-*/
-static int _oci_get_ocidesc(zval *id,oci_descriptor **descriptor TSRMLS_DC)
+/* {{{ php_oci_do_connect()
+ Connect wrapper */
+void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive)
{
- zval **desc;
+ php_oci_connection *connection;
+ char *username, *password;
+ char *dbname = NULL, *charset = NULL;
+ int username_len = 0, password_len = 0;
+ int dbname_len = 0, charset_len = 0;
+ long session_mode = OCI_DEFAULT;
+
+ /* if a fourth parameter is handed over, it is the charset identifier (but is only used in Oracle 9i+) */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ssl", &username, &username_len, &password, &password_len, &dbname, &dbname_len, &charset, &charset_len, &session_mode) == FAILURE) {
+ return;
+ }
- if (zend_hash_find(Z_OBJPROP_P(id), "descriptor", sizeof("descriptor"), (void **)&desc) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot find descriptor");
- return 0;
+ if (!charset_len) {
+ charset = NULL;
}
+
+ connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC);
- if ((*descriptor = oci_get_desc(Z_LVAL_PP(desc) TSRMLS_CC)) == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor not found");
- return 0;
+ if (!connection) {
+ RETURN_FALSE;
}
+ RETURN_RESOURCE(connection->rsrc_id);
- return Z_LVAL_PP(desc);
-}
-/* }}} */
+} /* }}} */
-/* {{{ _oci_make_zval()
-*/
-static int _oci_make_zval(zval *value,oci_statement *statement,oci_out_column *column, char *func, int mode TSRMLS_DC)
+/* {{{ php_oci_do_connect_ex()
+ * The real connect function. Allocates all the resources needed, establishes the connection and returns the result handle (or NULL) */
+php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, long session_mode, int persistent, int exclusive TSRMLS_DC)
{
- oci_descriptor *descr;
- ub4 loblen;
- int size;
- char *buffer;
-
- if (column->indicator || column->retcode)
- if ((column->indicator != -1) && (column->retcode != 1405))
- oci_debug("_oci_make_zval: %16s,retlen = %4d,retlen4 = %d,storage_size4 = %4d,indicator %4d, retcode = %4d",
- column->name,column->retlen,column->retlen4,column->storage_size4,column->indicator,column->retcode);
-
- if ((!statement->has_data) || (column->indicator == -1)) { /* column is NULL or statment has no current data */
- ZVAL_NULL(value);
- return 0;
- }
+ list_entry *le;
+ list_entry new_le;
+ php_oci_connection *connection = NULL;
+ smart_str hashed_details = {0};
+ time_t timestamp;
+#if HAVE_OCI_ENV_NLS_CREATE
+ ub2 charsetid = 0;
+#endif
- if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
- ZVAL_RESOURCE(value,column->stmtid);
- zend_list_addref(column->stmtid);
- } else if (column->is_descr) {
- if ((column->data_type != SQLT_RDD) && (mode & OCI_RETURN_LOBS)) {
- /* OCI_RETURN_LOBS means that we want the content of the LOB back instead of the locator */
-
- descr = oci_get_desc(column->descid TSRMLS_CC);
- if (!descr) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to find my descriptor %p",column->data);
- return -1;
- }
-
- if (oci_loadlob(statement->conn,descr,&buffer,&loblen)) {
- ZVAL_FALSE(value);
- } else {
- if (loblen > 0) {
- ZVAL_STRINGL(value,buffer,loblen,0);
- }
- else {
- ZVAL_EMPTY_STRING(value);
- }
- }
- } else {
- /* return the locator */
- object_init_ex(value, oci_lob_class_entry_ptr);
- add_property_resource(value, "descriptor", column->descid);
- zend_list_addref(column->descid);
- }
- } else {
- switch (column->retcode) {
- case 0:
- /* intact value */
- if (column->piecewise) {
- size = column->retlen4;
- } else {
- size = column->retlen;
+ switch (session_mode) {
+ case OCI_DEFAULT:
+ break;
+ case OCI_SYSOPER:
+ case OCI_SYSDBA:
+ if (!OCI_G(privileged_connect)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Privileged connect is disabled. Enable oci8.privileged_connect to be able to connect as SYSOPER or SYSDBA");
+ return NULL;
}
break;
-
- default:
- /* XXX we SHOULD maybe have a different behaviour for unknown results! */
- ZVAL_FALSE(value);
- return 0;
- }
-
- ZVAL_STRINGL(value,column->data,size,1);
- }
-
- return 0;
-}
-/* }}} */
-
-/* {{{ oci_setprefetch()
-*/
-static int oci_setprefetch(oci_statement *statement,int size)
-{
- ub4 prefetch;
- sword error;
- TSRMLS_FETCH();
-
- prefetch = size * 1024;
-
- CALL_OCI_RETURN(error,
- OCIAttrSet(
- statement->pStmt,
- OCI_HTYPE_STMT,
- &prefetch,
- 0,
- OCI_ATTR_PREFETCH_MEMORY,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY", error);
-
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid session mode specified (%ld)", session_mode);
+ return NULL;
+ break;
}
- prefetch = size;
- CALL_OCI_RETURN(error,
- OCIAttrSet(
- statement->pStmt,
- OCI_HTYPE_STMT,
- &prefetch,
- 0,
- OCI_ATTR_PREFETCH_ROWS,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
+ smart_str_appendl_ex(&hashed_details, "oci8___", sizeof("oci8___") - 1, 0);
+ smart_str_appendl_ex(&hashed_details, username, username_len, 0);
+ smart_str_appendl_ex(&hashed_details, "__", sizeof("__") - 1, 0);
+ if (dbname) {
+ smart_str_appendl_ex(&hashed_details, dbname, dbname_len, 0);
}
+ smart_str_appendl_ex(&hashed_details, "__", sizeof("__") - 1, 0);
- return 1;
-}
-/* }}} */
-
-/* {{{ oci_parse()
-*/
-static oci_statement *oci_parse(oci_connection *connection, char *query, int len)
-{
- oci_statement *statement;
- sword error;
- TSRMLS_FETCH();
-
- statement = ecalloc(1,sizeof(oci_statement));
-
- CALL_OCI(
- OCIHandleAlloc(
- connection->session->pEnv,
- (dvoid **)&statement->pStmt,
- OCI_HTYPE_STMT,
- 0,
- NULL
- )
- );
-
- CALL_OCI(
- OCIHandleAlloc(
- connection->session->pEnv,
- (dvoid **)&statement->pError,
- OCI_HTYPE_ERROR,
- 0,
- NULL
- )
- );
-
- if (len > 0) {
- CALL_OCI_RETURN(error,
- OCIStmtPrepare(
- statement->pStmt,
- connection->pError,
- (text*)query,
- len,
- OCI_NTV_SYNTAX,
- OCI_DEFAULT
- )
- );
-
- connection->error = oci_error(connection->pError, "OCIParse", error);
- if (connection->error) {
- CALL_OCI(
- OCIHandleFree(
- statement->pStmt,
- OCI_HTYPE_STMT
- )
- );
-
- CALL_OCI(
- OCIHandleFree(
- statement->pError,
- OCI_HTYPE_ERROR
- )
- );
-
- efree(statement);
- oci_handle_error(connection, connection->error);
- return 0;
- }
+#if HAVE_OCI_ENV_NLS_CREATE
+ if (charset && *charset) {
+ smart_str_appends_ex(&hashed_details, charset, 1);
}
+ else {
+ size_t rsize;
- if (query) {
- statement->last_query = estrdup(query);
+ PHP_OCI_CALL(OCINlsEnvironmentVariableGet, (&charsetid, 2, OCI_NLS_CHARSET_ID, 0, &rsize));
+ smart_str_append_unsigned_ex(&hashed_details, charsetid, 0);
}
-
- statement->conn = connection;
- statement->has_data = 0;
-
- statement->id = zend_list_insert(statement,le_stmt);
-
- oci_debug("oci_parse \"%s\" id=%d conn=%d",
- SAFE_STRING(query),
- statement->id,
- statement->conn->id);
-
- zend_list_addref(statement->conn->id);
-
- return statement;
-}
-/* }}} */
-
-/* {{{ oci_execute()
-*/
-static int oci_execute(oci_statement *statement, char *func,ub4 mode)
-{
- oci_out_column *outcol;
- oci_out_column column;
- OCIParam *param = 0;
- text *colname;
- ub4 counter;
- ub2 define_type;
- ub4 iters;
- ub4 colcount;
- ub2 dynamic;
- int dtype;
- dvoid *buf;
- oci_descriptor *descr;
- sword error;
- TSRMLS_FETCH();
-
- if (!statement->stmttype) {
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (ub2 *)&statement->stmttype,
- (ub4 *)0,
- OCI_ATTR_STMT_TYPE,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_STMT_TYPE", error);
-
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0;
- }
+#else
+ if (charset && *charset) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Your version of Oracle Client doesn't support setting the charset; bad or no charset conversions may result");
}
+#endif
- if (statement->stmttype == OCI_STMT_SELECT) {
- iters = 0;
- } else {
- iters = 1;
- }
+ timestamp = time(NULL);
- if (statement->last_query) {
- /* if we execute refcursors we don't have a query and
- we don't want to execute!!! */
-
- if (statement->binds) {
- zend_hash_apply(statement->binds, (apply_func_t) _oci_bind_pre_exec TSRMLS_CC);
- }
-
- CALL_OCI_RETURN(error,
- OCIStmtExecute(
- statement->conn->pServiceContext,
- statement->pStmt,
- statement->pError,
- iters,
- 0,
- NULL,
- NULL,
- mode
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIStmtExecute", error);
-
- if (statement->binds) {
- zend_hash_apply(statement->binds, (apply_func_t) _oci_bind_post_exec TSRMLS_CC);
- }
-
- oci_handle_error(statement->conn, statement->error);
-
- if (statement->error) {
- return 0;
- }
-
- if (mode & OCI_COMMIT_ON_SUCCESS) {
- statement->conn->needs_commit = 0;
- } else {
- statement->conn->needs_commit = 1;
- }
- }
-
- if ((statement->stmttype == OCI_STMT_SELECT) && (statement->executed == 0)) {
- /* we only need to do the define step is this very statement is executed the first time! */
- statement->executed = 1;
-
- ALLOC_HASHTABLE(statement->columns);
- zend_hash_init(statement->columns, 13, NULL, _oci_column_hash_dtor, 0);
-
- counter = 1;
-
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (dvoid *)&colcount,
- (ub4 *)0,
- OCI_ATTR_PARAM_COUNT,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_PARAM_COUNT", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
-
- statement->ncolumns = colcount;
-
- for (counter = 1; counter <= colcount; counter++) {
- memset(&column,0,sizeof(oci_out_column));
-
- if (zend_hash_index_update(statement->columns, counter, &column,
- sizeof(oci_out_column), (void**) &outcol) == FAILURE) {
- efree(statement->columns);
- /* out of memory */
- return 0;
- }
-
- outcol->statement = statement;
-
- CALL_OCI_RETURN(error,
- OCIParamGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- statement->pError,
- (dvoid**)&param,
- counter
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIParamGet OCI_HTYPE_STMT", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
-
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)param,
- OCI_DTYPE_PARAM,
- (dvoid *)&outcol->data_type,
- (ub4 *)0,
- OCI_ATTR_DATA_TYPE,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_TYPE", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
-
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)param,
- OCI_DTYPE_PARAM,
- (dvoid *)&outcol->data_size,
- (dvoid *)0,
- OCI_ATTR_DATA_SIZE,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_SIZE", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
+ smart_str_append_unsigned_ex(&hashed_details, session_mode, 0);
+ smart_str_0(&hashed_details);
- outcol->storage_size4 = outcol->data_size;
- outcol->retlen = outcol->data_size;
+ /* make it lowercase */
+ php_strtolower(hashed_details.c, hashed_details.len);
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)param,
- OCI_DTYPE_PARAM,
- (dvoid *)&outcol->scale,
- (dvoid *)0,
- OCI_ATTR_SCALE,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_SCALE", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we lose memory!!! */
- }
-
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)param,
- OCI_DTYPE_PARAM,
- (dvoid *)&outcol->precision,
- (dvoid *)0,
- OCI_ATTR_PRECISION,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_PRECISION", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we lose memory!!! */
- }
-
- CALL_OCI_RETURN(error,
- OCIAttrGet(
- (dvoid *)param,
- OCI_DTYPE_PARAM,
- (dvoid **)&colname, /* XXX this string is NOT zero terminated!!!! */
- (ub4 *)&outcol->name_len,
- (ub4)OCI_ATTR_NAME,
- statement->pError
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_NAME", error);
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
-
- outcol->name = estrndup((char*) colname,outcol->name_len);
-
- /* find a user-setted define */
- if (statement->defines) {
- zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define);
- }
-
- buf = 0;
- switch (outcol->data_type) {
- case SQLT_RSET:
- outcol->pstmt = oci_parse(statement->conn,0,0);
- outcol->stmtid = outcol->pstmt->id;
-
- define_type = SQLT_RSET;
- outcol->is_cursor = 1;
- outcol->storage_size4 = -1;
- outcol->retlen = -1;
- dynamic = OCI_DEFAULT;
- buf = &(outcol->pstmt->pStmt);
- break;
-
- case SQLT_RDD: /* ROWID */
- case SQLT_BLOB: /* binary LOB */
- case SQLT_CLOB: /* character LOB */
- case SQLT_BFILE: /* binary file LOB */
- define_type = outcol->data_type;
- outcol->is_descr = 1;
- outcol->storage_size4 = -1;
- dynamic = OCI_DEFAULT;
-
- if (outcol->data_type == SQLT_BFILE) {
- dtype = OCI_DTYPE_FILE;
- } else if (outcol->data_type == SQLT_RDD ) {
- dtype = OCI_DTYPE_ROWID;
- } else {
- dtype = OCI_DTYPE_LOB;
- }
-
- descr = oci_new_desc(dtype,statement->conn);
- if (!descr) {
- /* need better error checking XXX */
- }
- outcol->descid = descr->id;
- buf = &(descr->ocidescr);
- break;
-
- case SQLT_LNG:
- case SQLT_LBI:
- if (outcol->data_type == SQLT_LBI) {
- define_type = SQLT_BIN;
- } else {
- define_type = SQLT_CHR;
- }
- outcol->storage_size4 = OCI_MAX_DATA_SIZE;
- outcol->piecewise = 1;
- dynamic = OCI_DYNAMIC_FETCH;
- break;
-
- case SQLT_BIN:
- default:
- define_type = SQLT_CHR;
- if ((outcol->data_type == SQLT_DAT) || (outcol->data_type == SQLT_NUM)
-#ifdef SQLT_TIMESTAMP
- || (outcol->data_type == SQLT_TIMESTAMP)
-#endif
-#ifdef SQLT_TIMESTAMP_TZ
- || (outcol->data_type == SQLT_TIMESTAMP_TZ)
-#endif
- ) {
- outcol->storage_size4 = 512; /* XXX this should fit "most" NLS date-formats and Numbers */
- } else {
- outcol->storage_size4++; /* add one for string terminator */
- }
- if (outcol->data_type == SQLT_BIN) {
- outcol->storage_size4 *= 3;
- }
- dynamic = OCI_DEFAULT;
- buf = outcol->data = (text *) emalloc(outcol->storage_size4);
- break;
- }
-
- if (dynamic == OCI_DYNAMIC_FETCH) {
- CALL_OCI_RETURN(error,
- OCIDefineByPos(
- statement->pStmt, /* IN/OUT handle to the requested SQL query */
- (OCIDefine **)&outcol->pDefine, /* IN/OUT pointer to a pointer to a define handle */
- statement->pError, /* IN/OUT An error handle */
- counter, /* IN position in the select list */
- (dvoid *)NULL, /* IN/OUT pointer to a buffer */
- outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
- define_type, /* IN The data type */
- (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
- (ub2 *)NULL, /* IN/OUT Pointer to array of length of data fetched */
- (ub2 *)NULL, /* OUT Pointer to array of column-level return codes */
- OCI_DYNAMIC_FETCH /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIDefineByPos", error);
- } else {
- CALL_OCI_RETURN(error,
- OCIDefineByPos(
- statement->pStmt, /* IN/OUT handle to the requested SQL query */
- (OCIDefine **)&outcol->pDefine, /* IN/OUT pointer to a pointer to a define handle */
- statement->pError, /* IN/OUT An error handle */
- counter, /* IN position in the select list */
- (dvoid *)buf, /* IN/OUT pointer to a buffer */
- outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
- define_type, /* IN The data type */
- (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
- (ub2 *)&outcol->retlen, /* IN/OUT Pointer to array of length of data fetched */
- (ub2 *)&outcol->retcode, /* OUT Pointer to array of column-level return codes */
- OCI_DEFAULT /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
- )
- );
-
- statement->error = oci_error(statement->pError, "OCIDefineByPos", error);
- }
- if (statement->error) {
- oci_handle_error(statement->conn, statement->error);
- return 0; /* XXX we loose memory!!! */
- }
- }
- }
-
- return 1;
-}
-/* }}} */
-
-/* {{{ oci_fetch()
-*/
-static int _oci_column_pre_fetch(void *data TSRMLS_DC)
-{
- oci_out_column *col = (oci_out_column *) data;
+ /* Initialize global handles if the weren't initialized before */
- if (col->piecewise) {
- col->retlen4 = 0;
+ if (OCI_G(env) == NULL) {
+ php_oci_init_global_handles(TSRMLS_C);
}
- return 0;
-}
-
-static int oci_fetch(oci_statement *statement, ub4 nrows, char *func TSRMLS_DC)
-{
- int i;
- oci_out_column *column;
-
- if (statement->columns) {
- zend_hash_apply(statement->columns, (apply_func_t) _oci_column_pre_fetch TSRMLS_CC);
- }
-
-
- CALL_OCI_RETURN(statement->error,
- OCIStmtFetch(
- statement->pStmt,
- statement->pError,
- nrows,
- OCI_FETCH_NEXT,
- OCI_DEFAULT
- )
- );
-
- if ((statement->error == OCI_NO_DATA) || (nrows == 0)) {
- if (statement->last_query == 0) {
- /* reset define-list for refcursors */
- if (statement->columns) {
- zend_hash_destroy(statement->columns);
- efree(statement->columns);
- statement->columns = 0;
- statement->ncolumns = 0;
+ if (!exclusive && !new_password) {
+
+ if (persistent && zend_hash_find(&EG(persistent_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
+ /* found */
+ if (le->type == le_pconnection) {
+ connection = (php_oci_connection *)le->ptr;
+ }
+ }
+ else if (!persistent && zend_hash_find(&EG(regular_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
+ if (le->type == le_index_ptr) {
+ int type;
+ long link;
+ void *ptr;
+
+ link = (long) le->ptr;
+ ptr = zend_list_find(link,&type);
+ if (ptr && (type == le_connection)) {
+ connection = (php_oci_connection *)ptr;
+ }
}
- statement->executed = 0;
}
- statement->error = 0; /* OCI_NO_DATA is NO error for us!!! */
- statement->has_data = 0;
-
- return 0;
- }
-
- while (statement->error == OCI_NEED_DATA) {
- for (i = 0; i < statement->ncolumns; i++) {
- column = oci_get_col(statement, i + 1, 0);
- if (column->piecewise) {
- if (!column->data) {
- column->data = (text *) emalloc(OCI_PIECE_SIZE);
- } else {
- column->data = erealloc(column->data,column->retlen4 + OCI_PIECE_SIZE);
+ if (connection) {
+ if (connection->is_open) {
+ /* found an open connection. now ping it */
+ if (connection->is_persistent) {
+ /* check connection liveness in the following order:
+ * 1) always check OCI_ATTR_SERVER_STATUS
+ * 2) see if it's time to ping it
+ * 3) ping it if needed
+ * */
+ if (php_oci_connection_status(connection TSRMLS_CC)) {
+ /* only ping if:
+ * 1) next_ping > 0, which means that ping_interval is not -1 (aka "Off")
+ * 2) current_timestamp > next_ping, which means "it's time to check if it's still alive"
+ * */
+ if ( (connection->next_ping > 0) && (timestamp > connection->next_ping) && !php_oci_connection_ping(connection TSRMLS_CC)) {
+ /* server died */
+ }
+ else {
+ /* okay, the connection is open and the server is still alive */
+ connection->used_this_request = 1;
+ smart_str_free_ex(&hashed_details, 0);
+ connection->rsrc_id = zend_list_insert(connection, le_pconnection);
+ return connection;
+ }
+ }
+ /* server died */
+ zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
+ php_oci_connection_close(connection TSRMLS_CC);
+ connection = NULL;
+ goto open;
}
-
- column->cb_retlen = OCI_PIECE_SIZE;
-
- CALL_OCI(
- OCIStmtSetPieceInfo(
- (void *) column->pDefine,
- OCI_HTYPE_DEFINE,
- statement->pError,
- ((char*)column->data) + column->retlen4,
- &(column->cb_retlen),
- OCI_NEXT_PIECE,
- &column->indicator,
- &column->retcode
- )
- );
+ else {
+ /* we do not ping non-persistent connections */
+ smart_str_free_ex(&hashed_details, 0);
+ zend_list_addref(connection->rsrc_id);
+ return connection;
+ }
+ } else {
+ zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
+ connection = NULL;
+ goto open;
}
}
-
- CALL_OCI_RETURN(statement->error,
- OCIStmtFetch(
- statement->pStmt,
- statement->pError,
- nrows,
- OCI_FETCH_NEXT,
- OCI_DEFAULT
- )
- );
-
- for (i = 0; i < statement->ncolumns; i++) {
- column = oci_get_col(statement, i + 1, 0);
- if (column->piecewise) {
- column->retlen4 += column->cb_retlen;
+ else {
+ /* found something, but it's not a connection, delete it */
+ if (persistent) {
+ zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
+ }
+ else {
+ zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
}
}
}
-
- if (statement->error == OCI_SUCCESS_WITH_INFO || statement->error == OCI_SUCCESS) {
- statement->has_data = 1;
-
- /* do the stuff needed for OCIDefineByName */
- for (i = 0; i < statement->ncolumns; i++) {
- column = oci_get_col(statement, i + 1, 0);
- if (column == NULL) {
- continue;
- }
+open:
+ if (persistent) {
+ zend_bool alloc_non_persistent = 0;
- if (!column->define) {
- continue;
- }
+ if (OCI_G(max_persistent)!=-1 && OCI_G(num_persistent)>=OCI_G(max_persistent)) {
+ /* try to find an idle connection and kill it */
+ zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
- zval_dtor(column->define->zval);
- _oci_make_zval(column->define->zval,statement,column,"OCIFetch",0 TSRMLS_CC);
- }
-
- return 1;
- }
-
- oci_error(statement->pError, func, statement->error);
- oci_handle_error(statement->conn, statement->error);
-
- statement->has_data = 0;
-
- return 0;
-}
-/* }}} */
-
-/* {{{ oci_lobgetlen()
-*/
-static int oci_lobgetlen(oci_connection *connection, oci_descriptor *mydescr, ub4 *loblen)
-{
- TSRMLS_FETCH();
-
- *loblen = 0;
-
- /* do we need to ask oracle about LOB's length, if we do already know it? I think no. */
- if (mydescr->lob_size >= 0) {
- *loblen = mydescr->lob_size;
- } else {
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileOpen(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- OCI_FILE_READONLY
- )
- );
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileOpen",connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
+ if (OCI_G(max_persistent)!=-1 && OCI_G(num_persistent)>=OCI_G(max_persistent)) {
+ /* all persistent connactions are in use, fallback to non-persistent connection creation */
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Too many open persistent connections (%ld)", OCI_G(num_persistent));
+ alloc_non_persistent = 1;
}
}
- CALL_OCI_RETURN(connection->error,
- OCILobGetLength(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- loblen
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobGetLength",connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
+ if (alloc_non_persistent) {
+ connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
+ connection->hash_key = estrndup(hashed_details.c, hashed_details.len+1);
+ connection->is_persistent = 0;
}
- mydescr->lob_size = *loblen;
-
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileClose(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileClose", connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
- }
+ else {
+ connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection));
+ connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len);
+ connection->is_persistent = 1;
}
}
-
- oci_debug("oci_lobgetlen: len=%d",*loblen);
-
- return 0;
-}
-/* }}} */
-
-/* {{{ oci_loadlob()
-*/
-#define LOBREADSIZE 1048576l /* 1MB */
-static int oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer, ub4 *loblen)
-{
- ub4 siz = 0;
- ub4 readlen = 0;
- char *buf;
- TSRMLS_FETCH();
-
- *loblen = 0;
-
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileOpen(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- OCI_FILE_READONLY
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileOpen",connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
- }
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobGetLength(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- &readlen
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobGetLength",connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
+ else {
+ connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
+ connection->hash_key = estrndup(hashed_details.c, hashed_details.len+1);
+ connection->is_persistent = 0;
}
- if (readlen == 0) {
- return 0;
+ connection->idle_expiry = (OCI_G(persistent_timeout) > 0) ? (timestamp + OCI_G(persistent_timeout)) : 0;
+ if (OCI_G(ping_interval) >= 0) {
+ connection->next_ping = timestamp + OCI_G(ping_interval);
}
-
- buf = emalloc(readlen + 1);
-
- while (readlen > 0) { /* thies loop should not be entered on readlen == 0 */
- CALL_OCI_RETURN(connection->error,
- OCILobRead(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- &readlen, /* IN/OUT bytes toread/read */
- siz + 1, /* offset (starts with 1) */
- (dvoid *) ((char *) buf + siz),
- readlen, /* size of buffer */
- (dvoid *)0,
- (OCICallbackLobRead) 0, /* callback... */
- (ub2) connection->session->charsetId, /* The character set ID of the buffer data. */
- (ub1) SQLCS_IMPLICIT /* The character set form of the buffer data. */
- )
- );
-
- siz += readlen;
- readlen = LOBREADSIZE;
-
- if (connection->error == OCI_NEED_DATA) {
- buf = erealloc(buf,siz + LOBREADSIZE + 1);
- continue;
- } else {
- break;
- }
+ else {
+ /* -1 means "Off" */
+ connection->next_ping = 0;
}
+
+ smart_str_free_ex(&hashed_details, 0);
- if (connection->error) {
- oci_error(connection->pError, "OCILobRead", connection->error);
- oci_handle_error(connection, connection->error);
- efree(buf);
- return -1;
+ /* allocate environment handle */
+#if HAVE_OCI_ENV_NLS_CREATE
+#define PHP_OCI_INIT_FUNC_NAME "OCIEnvNlsCreate"
+
+ if (charset && *charset) {
+ charsetid = PHP_OCI_CALL(OCINlsCharSetNameToId, (OCI_G(env), charset));
+ connection->charset = charsetid;
}
-
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileClose(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileClose", connection->error);
- oci_handle_error(connection, connection->error);
- efree(buf);
- return -1;
- }
+ else if (charsetid) {
+ connection->charset = charsetid;
}
- buf = erealloc(buf,siz+1);
- buf[ siz ] = 0;
-
- *buffer = buf;
- *loblen = siz;
-
- oci_debug("oci_loadlob: size=%d",siz);
-
- return 0;
-}
-/* }}} */
-
-/* {{{ oci_readlob()
-*/
-static int oci_readlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer, ub4 *len)
-{
- ub4 siz = 0;
- ub4 readlen = 0;
- ub4 loblen = 0;
- ub4 bytes = 0;
- char *buf;
- TSRMLS_FETCH();
-
- /* we're not going to read LOB, if length is not known */
- if (!len || (int)*len <= 0) {
- return -1;
- }
+ /* create an environment using the character set id, Oracle 9i+ ONLY */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIEnvNlsCreate, (&(connection->env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, charsetid, charsetid));
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileOpen(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- OCI_FILE_READONLY
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileOpen",connection->error);
- oci_handle_error(connection, connection->error);
- return -1;
- }
- }
+#elif HAVE_OCI_ENV_CREATE
+#define PHP_OCI_INIT_FUNC_NAME "OCIEnvCreate"
- if (oci_lobgetlen(connection, mydescr, &loblen) != 0) {
- *len = 0;
- return -1;
- }
-
- if (loblen == 0) {
- return 0;
- }
+ /* allocate env handle without NLS support */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIEnvCreate, (&(connection->env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL));
+#else
+#define PHP_OCI_INIT_FUNC_NAME "OCIEnvInit"
- /* check if we're in LOB's borders */
- if ((mydescr->lob_current_position + *len) > loblen) {
- *len = loblen - mydescr->lob_current_position;
- }
-
- if ((int)*len > 0) {
- buf = emalloc(*len + 1);
-
- /* set offset to current LOB's position */
- siz = mydescr->lob_current_position;
+ /* the simpliest way */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIEnvInit, (&(connection->env), OCI_DEFAULT, 0, NULL));
+#endif
- /* check if len is smaller, if not - using LOBREADSIZE' sized buffer */
- if (*len > LOBREADSIZE) {
- readlen = LOBREADSIZE;
- } else {
- readlen = *len;
- }
- } else {
- *len = 0;
- return -1;
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+#ifdef HAVE_OCI_INSTANT_CLIENT
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_OCI_INIT_FUNC_NAME "() failed. There is something wrong with your system - please check that LD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries");
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_OCI_INIT_FUNC_NAME "() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory");
+#endif
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
}
+
+ /* allocate our server handle {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(connection->server), OCI_HTYPE_SERVER, 0, NULL));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- while (readlen > 0 && bytes < *len && siz < loblen) { /* paranoia */
- CALL_OCI_RETURN(connection->error,
- OCILobRead(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr,
- &readlen, /* IN/OUT bytes toread/read */
- siz + 1, /* offset (starts with 1) */
- (dvoid *) ((char *) buf + bytes),
- readlen, /* size of buffer */
- (dvoid *)0,
- (OCICallbackLobRead) 0, /* callback... */
- (ub2) connection->session->charsetId, /* The character set ID of the buffer data. */
- (ub1) SQLCS_IMPLICIT /* The character set form of the buffer data. */
- )
- );
-
- siz += readlen;
- bytes += readlen;
-
- if ((*len - bytes) > LOBREADSIZE) {
- readlen = LOBREADSIZE;
- } else {
- readlen = *len - bytes;
- }
+ /* attach to the server {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIServerAttach, (connection->server, OCI_G(err), (text*)dbname, dbname_len, (ub4) OCI_DEFAULT));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
+ connection->is_attached = 1;
- if (connection->error == OCI_NEED_DATA) {
- buf = erealloc(buf,bytes + LOBREADSIZE + 1);
- continue;
- } else {
- break;
- }
- }
+ /* allocate our session handle {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(connection->session), OCI_HTYPE_SESSION, 0, NULL));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- /* moving current position */
- mydescr->lob_current_position = siz;
+ /* allocate our private error-handle {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
- if (connection->error) {
- oci_error(connection->pError, "OCILobRead", connection->error);
- oci_handle_error(connection, connection->error);
- efree(buf);
- return -1;
- }
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- if (mydescr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileClose(
- connection->pServiceContext,
- connection->pError,
- mydescr->ocidescr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileClose", connection->error);
- oci_handle_error(connection, connection->error);
- efree(buf);
- return -1;
- }
- }
+ /* allocate our service-context {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(connection->svc), OCI_HTYPE_SVCCTX, 0, NULL));
- buf = erealloc(buf,bytes+1);
- buf[ bytes ] = 0;
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- *buffer = buf;
- *len = bytes;
+ /* set the username {{{ */
+ if (username) {
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) username_len, (ub4) OCI_ATTR_USERNAME, OCI_G(err)));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ }
+ }/* }}} */
- oci_debug("oci_readlob: size=%d",bytes);
+ /* set the password {{{ */
+ if (password) {
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) password_len, (ub4) OCI_ATTR_PASSWORD, OCI_G(err)));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ }
+ }/* }}} */
- return 0;
-}
-/* }}} */
+ /* set the server handle in the service handle {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err)));
-/* {{{ oci_failover_callback()
-*/
-#if 0 /* not needed yet ! */
-static sb4 oci_failover_callback(dvoid *svchp, dvoid *envhp, dvoid *fo_ctx, ub4 fo_type, ub4 fo_event)
-{
- /*
- this stuff is from an oci sample - it will get cleaned up as soon as i understand it!!! (thies@thieso.net 990420)
- right now i cant get oracle to even call it;-(((((((((((
- */
-
- switch (fo_event) {
- case OCI_FO_BEGIN: {
- printf(" Failing Over ... Please stand by \n");
- printf(" Failover type was found to be %s \n",
- ((fo_type==OCI_FO_NONE) ? "NONE"
- :(fo_type==OCI_FO_SESSION) ? "SESSION"
- :(fo_type==OCI_FO_SELECT) ? "SELECT"
- : "UNKNOWN!"));
- printf(" Failover Context is :%s\n",
- (fo_ctx?(char *)fo_ctx:"NULL POINTER!"));
- break;
- }
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- case OCI_FO_ABORT: {
- printf(" Failover aborted. Failover will not take place.\n");
- break;
- }
+ /* set the authentication handle in the service handle {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->session, 0, OCI_ATTR_SESSION, OCI_G(err)));
- case OCI_FO_END: {
- printf(" Failover ended ...resuming services\n");
- break;
- }
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
- case OCI_FO_REAUTH: {
- printf(" Failed over user. Resuming services\n");
-
- /* Application can check the OCI_ATTR_SESSION attribute of
- the service handle to find out the user being
- re-authenticated.
-
- After this, the application can replay any ALTER SESSION
- commands associated with this session. These must have
- been saved by the application in the fo_ctx
- */
- break;
- }
+ if (new_password) {
+ /* try to change password if new one was provided {{{ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIPasswordChange, (connection->svc, OCI_G(err), (text *)username, username_len+1, (text *)password, password_len+1, (text *)new_password, new_password_len+1, OCI_AUTH));
- case OCI_FO_ERROR: {
- printf(" Failover error gotten. Sleeping...\n");
- php_sleep(3);
- /* cannot find this blody define !!! return OCI_FO_RETRY; */
- break;
- }
-
- default: {
- printf("Bad Failover Event: %ld.\n", fo_event);
- break;
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
}
- }
-
- return 0;
-}
-#endif
-/* }}} */
-
-/* {{{ oci_bind_in_callback()
-*/
-static sb4 oci_bind_in_callback(
- dvoid *ictxp, /* context pointer */
- OCIBind *bindp, /* bind handle */
- ub4 iter, /* 0-based execute iteration value */
- ub4 index, /* index of current array for PL/SQL or row index for SQL */
- dvoid **bufpp, /* pointer to data */
- ub4 *alenp, /* size after value/piece has been read */
- ub1 *piecep, /* which piece */
- dvoid **indpp) /* indicator value */
-{
- oci_bind *phpbind;
- zval *val;
- TSRMLS_FETCH();
-
- if (!(phpbind=(oci_bind *)ictxp) || !(val = phpbind->zval)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "!phpbind || !phpbind->val");
- return OCI_ERROR;
- }
-
- if (ZVAL_IS_NULL(val)) {
- /* we're going to insert a NULL column */
- phpbind->indicator = -1;
- *bufpp = 0;
- *alenp = -1;
- *indpp = (dvoid *)&phpbind->indicator;
- } else if ((phpbind->descr == 0) && (phpbind->pStmt == 0)) {
- /* "normal string bind */
- convert_to_string(val);
-
- *bufpp = Z_STRVAL_P(val);
- *alenp = Z_STRLEN_P(val);
- *indpp = (dvoid *)&phpbind->indicator;
- } else if (phpbind->pStmt != 0) {
- /* RSET */
- *bufpp = phpbind->pStmt;
- *alenp = -1; /* seems to be allright */
- *indpp = (dvoid *)&phpbind->indicator;
- } else {
- /* descriptor bind */
- *bufpp = phpbind->descr;
- *alenp = -1; /* seems to be allright */
- *indpp = (dvoid *)&phpbind->indicator;
- }
-
- *piecep = OCI_ONE_PIECE; /* pass all data in one go */
-
- return OCI_CONTINUE;
-}
-/* }}} */
-
-/* {{{ oci_bind_out_callback() */
-static sb4 oci_bind_out_callback(
- dvoid *octxp, /* context pointer */
- OCIBind *bindp, /* bind handle */
- ub4 iter, /* 0-based execute iteration value */
- ub4 index, /* index of current array for PL/SQL or row index for SQL */
- dvoid **bufpp, /* pointer to data */
- ub4 **alenpp, /* size after value/piece has been read */
- ub1 *piecep, /* which piece */
- dvoid **indpp, /* indicator value */
- ub2 **rcodepp) /* return code */
-{
- oci_bind *phpbind;
- zval *val;
- sb4 retval = OCI_ERROR;
- TSRMLS_FETCH();
-
- if (!(phpbind=(oci_bind *)octxp) || !(val = phpbind->zval)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "!phpbind || !phpbind->val");
- return retval;
- }
-
- if ((Z_TYPE_P(val) == IS_OBJECT) || (Z_TYPE_P(val) == IS_RESOURCE)) {
- retval = OCI_CONTINUE;
- } else {
- convert_to_string(val);
- zval_dtor(val);
-
- Z_STRLEN_P(val) = OCI_PIECE_SIZE; /* 64K-1 is max XXX */
- Z_STRVAL_P(val) = emalloc(Z_STRLEN_P(phpbind->zval));
-
- /* XXX we assume that zend-zval len has 4 bytes */
- *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval);
- *bufpp = Z_STRVAL_P(phpbind->zval);
- *piecep = OCI_ONE_PIECE;
- *rcodepp = &phpbind->retcode;
- *indpp = &phpbind->indicator;
- retval = OCI_CONTINUE;
- }
-
- return retval;
-}
-/* }}} */
-
-/* {{{ _oci_open_session()
-*/
-#include "ext/standard/php_smart_str.h"
-static oci_session *_oci_open_session(oci_server* server,char *username,char *password,int persistent,int exclusive,char *charset)
-{
- zend_llist *session_list;
- oci_session *session = NULL;
- OCISvcCtx *svchp = NULL;
- smart_str hashed_details = {0};
-#ifdef HAVE_OCI_9_2
- ub2 charsetid = 0;
-#endif
- TSRMLS_FETCH();
- /*
- check if we already have this user authenticated
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err)));
- we will reuse authenticated users within a request no matter if the user requested a persistent
- connections or not!
-
- but only as persistent requested connections will be kept between requests!
- */
-
-#if defined(HAVE_OCI_9_2)
- if (*charset) {
- smart_str_appends_ex(&hashed_details, charset, 1);
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ } /* }}} */
} else {
- size_t rsize;
-
- /* Safe, charsetid is initialized to 0 */
- CALL_OCI(
- OCINlsEnvironmentVariableGet(
- &charsetid,
- 2,
- OCI_NLS_CHARSET_ID,
- 0,
- &rsize
- )
- );
-
- smart_str_append_unsigned_ex(&hashed_details, charsetid, 1);
-
- charsetid = 0;
- }
+ /* start the session {{{ */
+ switch (session_mode) {
+ case OCI_DEFAULT:
+#if HAVE_OCI_STMT_PREPARE2
+ /* statement caching is suported only in Oracle 9+ */
+ OCI_G(errcode) = PHP_OCI_CALL(OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_RDBMS, (ub4) OCI_STMT_CACHE));
#else
- {
- char *nls_lang = getenv("NLS_LANG");
-
- /* extract charset from NLS_LANG=LANUAGE_TERRITORY.CHARSET */
- if (nls_lang) {
- char *p = strchr(nls_lang, '.');
-
- if (p) {
- smart_str_appends_ex(&hashed_details, p + 1, 1);
- }
- }
- }
+ /* others cannot use stmt caching, so we call OCISessionBegin() with OCI_DEFAULT */
+ OCI_G(errcode) = PHP_OCI_CALL(OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_RDBMS, (ub4) OCI_DEFAULT));
#endif
-
- smart_str_appends_ex(&hashed_details, SAFE_STRING(username), 1);
- smart_str_appends_ex(&hashed_details, SAFE_STRING(password), 1);
- smart_str_appends_ex(&hashed_details, SAFE_STRING(server->dbname), 1);
- smart_str_0(&hashed_details);
-
- if (!exclusive) {
- mutex_lock(mx_lock);
- if (zend_ts_hash_find(persistent_sessions, hashed_details.c, hashed_details.len+1, (void **) &session_list) != SUCCESS) {
- zend_llist tmp;
- /* first session, set up a session list */
- zend_llist_init(&tmp, sizeof(oci_session), (llist_dtor_func_t) _session_pcleanup, 1);
- zend_ts_hash_update(persistent_sessions, hashed_details.c, hashed_details.len+1, &tmp, sizeof(zend_llist), (void **) &session_list);
- } else {
-
- /* session list found, search for an idle session or an already opened session by the current thread */
- session = zend_llist_get_first(session_list);
- while ((session != NULL) && session->thread && (session->thread != thread_id())) {
- session = zend_llist_get_next(session_list);
- }
-
- if (session != NULL) {
- /* mark session as busy */
- session->thread = thread_id();
- }
-
+ break;
+ case OCI_SYSDBA:
+ case OCI_SYSOPER:
+ default:
+ OCI_G(errcode) = PHP_OCI_CALL(OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_EXT, (ub4) session_mode));
+ break;
}
- if (session) {
- if (session->is_open) {
- if (persistent) {
- session->persistent = 1;
- }
- smart_str_free_ex(&hashed_details, 1);
- mutex_unlock(mx_lock);
- return session;
- } else {
- _oci_close_session(session);
- /* breakthru to open */
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ /* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
+ * user's password has expired, but is still usable.
+ * */
+ if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
}
- }
- mutex_unlock(mx_lock);
+ } /* }}} */
}
- session = ecalloc(1,sizeof(oci_session));
-
- if (!session) {
- goto CLEANUP;
- }
+#if HAVE_OCI_STMT_PREPARE2
+ if (connection->is_persistent) {
+ ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
- session->persistent = persistent;
- session->server = server;
- session->exclusive = exclusive;
- session->sessions_list = session_list;
- session->thread = thread_id();
-
-#ifdef HAVE_OCI_9_2
-
- /* following chunk is Oracle 9i+ ONLY */
- if (*charset) {
- /*
- get ub2 charset id based on charset
- this is pretty secure, since if we don't have a valid character set name,
- 0 comes back and we can still use the 0 in all further statements -> OCI uses NLS_LANG
- setting in that case
- */
- CALL_OCI_RETURN(charsetid,
- OCINlsCharSetNameToId(
- OCI(pEnv),
- charset
- )
- );
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &statement_cache_size, 0, (ub4) OCI_ATTR_STMTCACHESIZE, OCI_G(err)));
- oci_debug("oci_do_connect: using charset id=%d",charsetid);
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ php_oci_connection_close(connection TSRMLS_CC);
+ return NULL;
+ }
}
-
- session->charsetId = charsetid;
+#endif
- /* create an environment using the character set id, Oracle 9i+ ONLY */
- CALL_OCI(
- OCIEnvNlsCreate(
- &session->pEnv,
- PHP_OCI_INIT_MODE,
- 0,
- NULL,
- NULL,
- NULL,
- 0,
- NULL,
- charsetid,
- charsetid
- )
- );
-
-#else
-
- /* fallback solution (simply use global env and charset, same behaviour as always been) */
- session->pEnv = OCI(pEnv);
- session->charsetId = 0;
-
-#endif /* HAVE_OCI_9_2 */
-
- /* allocate temporary Service Context */
- CALL_OCI_RETURN(OCI(error),
- OCIHandleAlloc(
- session->pEnv,
- (dvoid **)&svchp,
- OCI_HTYPE_SVCCTX,
- 0,
- NULL
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error));
- goto CLEANUP;
- }
-
- /* allocate private session-handle */
- CALL_OCI_RETURN(OCI(error),
- OCIHandleAlloc(
- session->pEnv,
- (dvoid **)&session->pSession,
- OCI_HTYPE_SESSION,
- 0,
- NULL
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SESSION", OCI(error));
- goto CLEANUP;
- }
-
- /* Set the server handle in service handle */
- CALL_OCI_RETURN(OCI(error),
- OCIAttrSet(
- svchp,
- OCI_HTYPE_SVCCTX,
- server->pServer,
- 0,
- OCI_ATTR_SERVER,
- OCI(pError)
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_open_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error));
- goto CLEANUP;
- }
+ /* mark it as open */
+ connection->is_open = 1;
- /* set the username in user handle */
- CALL_OCI_RETURN(OCI(error),
- OCIAttrSet(
- (dvoid *) session->pSession,
- (ub4) OCI_HTYPE_SESSION,
- (dvoid *) username,
- (ub4) strlen(username),
- (ub4) OCI_ATTR_USERNAME,
- OCI(pError)
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "OCIAttrSet OCI_ATTR_USERNAME", OCI(error));
- goto CLEANUP;
+ /* add to the appropriate hash */
+ if (connection->is_persistent) {
+ new_le.ptr = connection;
+ new_le.type = le_pconnection;
+ connection->used_this_request = 1;
+ connection->rsrc_id = zend_list_insert(connection, le_pconnection);
+ zend_hash_update(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(list_entry), NULL);
+ OCI_G(num_persistent)++;
}
-
- /* set the password in user handle */
- CALL_OCI_RETURN(OCI(error),
- OCIAttrSet(
- (dvoid *) session->pSession,
- (ub4) OCI_HTYPE_SESSION,
- (dvoid *) password,
- (ub4) strlen(password),
- (ub4) OCI_ATTR_PASSWORD,
- OCI(pError)
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "OCIAttrSet OCI_ATTR_PASSWORD", OCI(error));
- goto CLEANUP;
+ else if (!exclusive) {
+ connection->rsrc_id = zend_list_insert(connection, le_connection);
+ new_le.ptr = (void *)connection->rsrc_id;
+ new_le.type = le_index_ptr;
+ zend_hash_update(&EG(regular_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(list_entry), NULL);
+ OCI_G(num_links)++;
}
-
- CALL_OCI_RETURN(OCI(error),
- OCISessionBegin(
- svchp,
- OCI(pError),
- session->pSession,
- (ub4) OCI_CRED_RDBMS,
- (ub4) OCI_DEFAULT
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "OCISessionBegin", OCI(error));
- /* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
- * user's password has expired, but is still usable.
- * */
- if (OCI(error) != OCI_SUCCESS_WITH_INFO) {
- goto CLEANUP;
- }
+ else {
+ connection->rsrc_id = zend_list_insert(connection, le_connection);
+ OCI_G(num_links)++;
}
-
- /* Free Temporary Service Context */
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) svchp,
- (ub4) OCI_HTYPE_SVCCTX
- )
- );
-
- session->is_open = 1;
-
- mutex_lock(mx_lock);
- num_links++;
- if (!exclusive) {
- zend_llist_add_element(session_list, session);
- efree(session);
- session = (oci_session*) session_list->tail->data;
- num_persistent++;
- }
- mutex_unlock(mx_lock);
-
- session->num = zend_list_insert(session, le_session);
- oci_debug("_oci_open_session new sess=%d user=%s",session->num,username);
-
- return session;
-
-CLEANUP:
- oci_debug("_oci_open_session: FAILURE -> CLEANUP called");
-
- _oci_close_session(session);
-
- return 0;
+ return connection;
}
/* }}} */
-/* {{{ _oci_close_session()
-*/
-static int _session_compare(void *a, void *b)
-{
- oci_session *sess1 = (oci_session*) a;
- oci_session *sess2 = (oci_session*) b;
-
- return sess1->num == sess2->num;
-}
-
-static void _oci_close_session(oci_session *session)
+/* {{{ php_oci_connection_ping()
+ * Ping connection. Uses OCIPing() or OCIServerVersion() depending on the Oracle Client version */
+static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
{
- OCISvcCtx *svchp;
- TSRMLS_FETCH();
-
- if (!session) {
- return;
- }
-
- oci_debug("START _oci_close_session: logging-off sess=%d",session->num);
-
- if (session->is_open) {
- /* Temporary Service Context */
- CALL_OCI_RETURN(OCI(error),
- OCIHandleAlloc(
- session->pEnv,
- (dvoid **) &svchp,
- (ub4) OCI_HTYPE_SVCCTX,
- (size_t) 0,
- (dvoid **) 0
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_close_session OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error));
- }
-
- /* Set the server handle in service handle */
- CALL_OCI_RETURN(OCI(error),
- OCIAttrSet(
- svchp,
- OCI_HTYPE_SVCCTX,
- session->server->pServer,
- 0,
- OCI_ATTR_SERVER,
- OCI(pError)
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error));
- }
-
- /* Set the Authentication handle in the service handle */
- CALL_OCI_RETURN(OCI(error),
- OCIAttrSet(
- svchp,
- OCI_HTYPE_SVCCTX,
- session->pSession,
- 0,
- OCI_ATTR_SESSION,
- OCI(pError)
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SESSION", OCI(error));
- }
-
- CALL_OCI_RETURN(OCI(error),
- OCISessionEnd(
- svchp,
- OCI(pError),
- session->pSession,
- (ub4) 0
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "_oci_close_session: OCISessionEnd", OCI(error));
- }
-
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) svchp,
- (ub4) OCI_HTYPE_SVCCTX
- )
- );
-
- } else {
- oci_debug("_oci_close_session: logging-off DEAD session");
- }
-
- if (session->pSession) {
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) session->pSession,
- (ub4) OCI_HTYPE_SESSION
- )
- );
- }
-
- mutex_lock(mx_lock);
- num_links--;
- if (!OCI(shutdown) && session->persistent) {
- zend_llist_del_element(session->sessions_list, session, _session_compare);
- num_persistent--;
- }
- mutex_unlock(mx_lock);
-
-#ifdef HAVE_OCI_9_2
- /* free environment handle (and fix bug #29652 with growing .msb FD number under weirdie Solarises) */
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) session->pEnv,
- OCI_HTYPE_ENV
- )
- );
+#if OCI_MAJOR_VERSION >= 10 && OCI_MINOR_VERSION >= 2
+ /* OCIPing() is usable only in 10.2 */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
+#else
+ char version[256];
+ /* use good old OCIServerVersion() by default */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIServerVersion, (connection->server, OCI_G(err), (text*)version, sizeof(version), OCI_HTYPE_SERVER));
#endif
- if (session->exclusive) {
- efree(session);
- }
-}
-/* }}} */
-
-/* {{{ _oci_open_server()
-*/
-static oci_server *_oci_open_server(char *dbname,int persistent)
-{
- oci_server *server, *pserver = NULL;
- TSRMLS_FETCH();
-
- /*
- check if we already have this server open
-
- we will reuse servers within a request no matter if the user requested persistent
- connections or not!
-
- but only as pesistent requested connections will be kept between requests!
- */
-
- /* TODO either keep servers global or don't reuse them at all */
- zend_ts_hash_find(persistent_servers, dbname, strlen(dbname)+1, (void **) &pserver);
-
- if (pserver) {
- /* XXX ini-flag */
- /*
- if (!oci_ping(pserver)) {
- pserver->is_open = 0;
- }
- */
- if (pserver->is_open) {
- /* if our new users uses this connection persistent, we're keeping it! */
- if (persistent) {
- pserver->persistent = persistent;
- }
-
- return pserver;
- } else { /* server "died" in the meantime - try to reconnect! */
- _oci_close_server(pserver);
- /* breakthru to open */
- }
- }
-
- server = ecalloc(1,sizeof(oci_server));
-
- server->persistent = persistent;
- server->dbname = strdup(SAFE_STRING(dbname));
-
- CALL_OCI(
- OCIHandleAlloc(
- OCI(pEnv),
- (dvoid **)&server->pServer,
- OCI_HTYPE_SERVER,
- 0,
- NULL
- )
- );
-
- CALL_OCI_RETURN(OCI(error),
- OCIServerAttach(
- server->pServer,
- OCI(pError),
- (text*)server->dbname,
- strlen(server->dbname),
- (ub4) OCI_DEFAULT
- )
- );
-
- if (OCI(error)) {
- oci_error(OCI(pError), "_oci_open_server", OCI(error));
- goto CLEANUP;
- }
- zend_ts_hash_update(persistent_servers,
- server->dbname,
- strlen(server->dbname)+1,
- (void *)server,
- sizeof(oci_server),
- (void**)&pserver);
-
- pserver->num = zend_list_insert(pserver,le_server);
- pserver->is_open = 1;
-
- oci_debug("_oci_open_server new conn=%d dname=%s",server->num,server->dbname);
-
- efree(server);
-
- return pserver;
-
-CLEANUP:
- oci_debug("_oci_open_server: FAILURE -> CLEANUP called");
-
- _oci_close_server(server);
-
- return 0;
-}
-
-#if 0
- server->failover.fo_ctx = (dvoid *) server;
- server->failover.callback_function = oci_failover_callback;
-
- error = OCIAttrSet((dvoid *)server->pServer,
- (ub4) OCI_HTYPE_SERVER,
- (dvoid *) &server->failover,
- (ub4) 0,
- (ub4) OCI_ATTR_FOCBK,
- OCI(pError));
-
- if (error) {
- oci_error(OCI(pError), "_oci_open_server OCIAttrSet OCI_ATTR_FOCBK", error);
- goto CLEANUP;
+ if (OCI_G(errcode) == OCI_SUCCESS) {
+ return 1;
}
-#endif
-/* }}} */
-
-/* {{{ _oci_close_server()
-*/
-static int _oci_session_cleanup(void *data TSRMLS_DC)
-{
- zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) data;
- if (le->type == le_session) {
- oci_server *server = ((oci_session*) le->ptr)->server;
- if (server && server->is_open == 2)
- return 1;
- }
+ /* ignore errors here, just return failure
+ * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
return 0;
}
-
-static void _oci_close_server(oci_server *server)
-{
- char *dbname;
- int oldopen;
- TSRMLS_FETCH();
-
- oldopen = server->is_open;
- server->is_open = 2;
- if (!OCI(shutdown)) {
- zend_hash_apply(&EG(regular_list), (apply_func_t) _oci_session_cleanup TSRMLS_CC);
- }
- server->is_open = oldopen;
-
- oci_debug("START _oci_close_server: detaching conn=%d dbname=%s",server->num,server->dbname);
-
- /* XXX close server here */
-
- if (server->is_open) {
- if (server->pServer && OCI(pError)) {
- CALL_OCI_RETURN(OCI(error),
- OCIServerDetach(
- server->pServer,
- OCI(pError),
- OCI_DEFAULT
- )
- );
-
- if (OCI(error)) {
- oci_error(OCI(pError), "oci_close_server OCIServerDetach", OCI(error));
- }
- }
- } else {
- oci_debug("_oci_close_server: closing DEAD server");
- }
-
- if (server->pServer) {
- CALL_OCI(
- OCIHandleFree(
- (dvoid *) server->pServer,
- (ub4) OCI_HTYPE_SERVER
- )
- );
- }
-
- dbname = server->dbname;
-
- if (!OCI(shutdown)) {
- zend_ts_hash_del(persistent_servers, dbname, strlen(dbname)+1);
- }
-
- free(dbname);
-}
/* }}} */
-/* {{{ oci_do_connect()
- Connect to an Oracle database and log on. returns a new session. */
-static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclusive)
+/* {{{ php_oci_connection_status()
+ Check connection status (pre-ping check) */
+static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
{
- char *username, *password, *dbname, *charset;
- zval **userParam, **passParam, **dbParam, **charParam;
- oci_server *server = 0;
- oci_session *session = 0;
- oci_connection *connection = 0;
-
- /* if a forth parameter is handed over, it is the charset identifier (but is only used in Oracle 9i+) */
- if (zend_get_parameters_ex(4, &userParam, &passParam, &dbParam, &charParam) == SUCCESS) {
- convert_to_string_ex(userParam);
- convert_to_string_ex(passParam);
- convert_to_string_ex(dbParam);
- convert_to_string_ex(charParam);
-
- username = Z_STRVAL_PP(userParam);
- password = Z_STRVAL_PP(passParam);
- dbname = Z_STRVAL_PP(dbParam);
- charset = Z_STRVAL_PP(charParam);
- oci_debug("oci_do_connect: using charset=%s",charset);
- } else if (zend_get_parameters_ex(3, &userParam, &passParam, &dbParam) == SUCCESS) {
- convert_to_string_ex(userParam);
- convert_to_string_ex(passParam);
- convert_to_string_ex(dbParam);
-
- username = Z_STRVAL_PP(userParam);
- password = Z_STRVAL_PP(passParam);
- dbname = Z_STRVAL_PP(dbParam);
- charset = "";
- } else if (zend_get_parameters_ex(2, &userParam, &passParam) == SUCCESS) {
- convert_to_string_ex(userParam);
- convert_to_string_ex(passParam);
-
- username = Z_STRVAL_PP(userParam);
- password = Z_STRVAL_PP(passParam);
- dbname = "";
- charset = "";
- } else {
- WRONG_PARAM_COUNT;
- }
-
- connection = (oci_connection *) ecalloc(1,sizeof(oci_connection));
-
- if (!connection) {
- goto CLEANUP;
- }
-
- server = _oci_open_server(dbname,persistent);
-
- if (!server) {
- goto CLEANUP;
- }
-
- if (exclusive) {
- /* exlusive session can never be persistent!*/
- persistent = 0;
- } else {
- /* if our server-context is not persistent we can't */
- persistent = (server->persistent) ? persistent : 0;
- }
-
- session = _oci_open_session(server,username,password,persistent,exclusive,charset);
-
- if (!session) {
- goto CLEANUP;
- }
-
- /* set our session */
- connection->session = session;
-
- /* allocate our private error-handle */
- CALL_OCI_RETURN(OCI(error),
- OCIHandleAlloc(
- connection->session->pEnv,
- (dvoid **)&connection->pError,
- OCI_HTYPE_ERROR,
- 0,
- NULL
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "oci_do_connect: OCIHandleAlloc OCI_HTYPE_ERROR",OCI(error));
- goto CLEANUP;
- }
-
- /* allocate our service-context */
- CALL_OCI_RETURN(OCI(error),
- OCIHandleAlloc(
- connection->session->pEnv,
- (dvoid **)&connection->pServiceContext,
- OCI_HTYPE_SVCCTX,
- 0,
- NULL
- )
- );
-
- if (OCI(error) != OCI_SUCCESS) {
- oci_error(OCI(pError), "oci_do_connect: OCIHandleAlloc OCI_HTYPE_SVCCTX",OCI(error));
- goto CLEANUP;
- }
-
- /* Set the server handle in service handle */
- CALL_OCI_RETURN(connection->error,
- OCIAttrSet(
- connection->pServiceContext,
- OCI_HTYPE_SVCCTX,
- server->pServer,
- 0,
- OCI_ATTR_SERVER,
- connection->pError
- )
- );
-
- if (connection->error != OCI_SUCCESS) {
- oci_error(connection->pError, "oci_do_connect: OCIAttrSet OCI_ATTR_SERVER", connection->error);
- goto CLEANUP;
- }
-
- /* Set the Authentication handle in the service handle */
- CALL_OCI_RETURN(connection->error,
- OCIAttrSet(
- connection->pServiceContext,
- OCI_HTYPE_SVCCTX,
- session->pSession,
- 0,
- OCI_ATTR_SESSION,
- connection->pError
- )
- );
-
- if (connection->error != OCI_SUCCESS) {
- oci_error(connection->pError, "oci_do_connect: OCIAttrSet OCI_ATTR_SESSION", connection->error);
- goto CLEANUP;
- }
+ ub4 ss = 0;
- /*
- OCIAttrSet((dvoid *)session->server->pServer,
- OCI_HTYPE_SERVER,
- (dvoid *) "demo",
- 0,
- OCI_ATTR_EXTERNAL_NAME,
- connection->pError);
-
- OCIAttrSet((dvoid *)session->server->pServer,
- OCI_HTYPE_SERVER,
- (dvoid *) "txn demo2",
- 0,
- OCI_ATTR_INTERNAL_NAME,
- connection->pError);
- */
-
- connection->id = zend_list_insert(connection, le_conn);
-
- connection->is_open = 1;
-
- oci_debug("oci_do_connect: id=%d",connection->id);
-
- RETURN_RESOURCE(connection->id);
+ /* get OCI_ATTR_SERVER_STATUS */
+ OCI_G(errcode) = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err)));
-CLEANUP:
- oci_debug("oci_do_connect: FAILURE -> CLEANUP called");
-
- if (connection->id) {
- zend_list_delete(connection->id);
- } else {
- _oci_conn_list_dtor(connection TSRMLS_CC);
+ if (OCI_G(errcode) == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
+ return 1;
}
- RETURN_FALSE;
+ /* ignore errors here, just return failure
+ * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
+ return 0;
}
/* }}} */
-/* {{{ oci_lob_flush()
-*/
-static int oci_lob_flush(oci_descriptor* descr, int flush_flag TSRMLS_DC)
+/* {{{ php_oci_connection_rollback()
+ Rollback connection */
+int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
{
- OCILobLocator *mylob;
- oci_connection *connection;
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- return 0;
- }
+ connection->errcode = PHP_OCI_CALL(OCITransRollback, (connection->svc, connection->err, (ub4) 0));
+ connection->needs_commit = 0;
- /* do not really flush buffer, but reporting success
- * to suppress OCI error when flushing not used buffer
- * */
- if (descr->buffering != 2) {
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
return 1;
}
+ return 0;
+} /* }}} */
- connection = descr->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCILobFlushBuffer(
- connection->pServiceContext,
- connection->pError,
- mylob,
- flush_flag
- )
- );
-
- oci_debug("oci_lob_flush: flush_flag=%d",flush_flag);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFlushBuffer", connection->error);
- oci_handle_error(connection, connection->error);
- return 0;
- }
-
- /* marking buffer as enabled and not used */
- descr->buffering = 1;
- return 1;
-}
-/* }}} */
-
-/* {{{ php_oci_fetch_row()
-*/
-static void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args)
+/* {{{ php_oci_connection_commit()
+ Commit connection */
+int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
{
- zval **stmt, **arg2, **arg3;
- oci_statement *statement;
- oci_out_column *column;
- ub4 nrows = 1;
- int i;
-
- if (ZEND_NUM_ARGS() > expected_args) {
- WRONG_PARAM_COUNT;
+ if (connection->descriptors) {
+ zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
}
- if (expected_args > 2) {
- /* only for ocifetchinto BC */
-
- switch (ZEND_NUM_ARGS()) {
- case 2:
- if (zend_get_parameters_ex(2, &stmt, &arg2) == FAILURE) {
- RETURN_FALSE;
- }
- if (!mode) {
- mode = OCI_NUM;
- }
- break;
-
- case 3:
- if (zend_get_parameters_ex(3, &stmt, &arg2, &arg3) == FAILURE) {
- RETURN_FALSE;
- }
- convert_to_long_ex(arg3);
- mode = Z_LVAL_PP(arg3);
- break;
-
- default:
- WRONG_PARAM_COUNT;
- break;
- }
-
- } else {
-
- switch (ZEND_NUM_ARGS()) {
- case 1:
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- RETURN_FALSE;
- }
- if (!mode) {
- mode = OCI_BOTH;
- }
- break;
+ connection->errcode = PHP_OCI_CALL(OCITransCommit, (connection->svc, connection->err, (ub4) 0));
+ connection->needs_commit = 0;
- case 2:
- if (zend_get_parameters_ex(2, &stmt, &arg2)==FAILURE) {
- RETURN_FALSE;
- }
- convert_to_long_ex(arg2);
- mode = Z_LVAL_PP(arg2);
- break;
-
- default:
- WRONG_PARAM_COUNT;
- break;
- }
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
}
+ return 0;
+} /* }}} */
- OCI_GET_STMT(statement,stmt);
+/* {{{ php_oci_connection_close()
+ Close the connection and free all its resources */
+static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC)
+{
+ int result = 0;
- if (!oci_fetch(statement, nrows, "OCIFetchInto" TSRMLS_CC)) {
- RETURN_FALSE;
+ if (connection->descriptors) {
+ zend_hash_destroy(connection->descriptors);
+ efree(connection->descriptors);
}
- array_init(return_value);
-
- for (i = 0; i < statement->ncolumns; i++) {
- column = oci_get_col(statement, i + 1, 0);
- if (column == NULL) {
- continue;
- }
- if ((column->indicator == -1) && ((mode & OCI_RETURN_NULLS) == 0)) {
- continue;
- }
-
- if (!(column->indicator == -1)) {
- zval *element;
-
- MAKE_STD_ZVAL(element);
- _oci_make_zval(element,statement,column,"OCIFetchInto",mode TSRMLS_CC);
-
- if (mode & OCI_NUM || !(mode & OCI_ASSOC)) {
- add_index_zval(return_value, i, element);
- }
- if (mode & OCI_ASSOC) {
- if (mode & OCI_NUM) {
- ZVAL_ADDREF(element);
- }
- add_assoc_zval(return_value, column->name, element);
- }
-
- } else {
- if (mode & OCI_NUM || !(mode & OCI_ASSOC)) {
- add_index_null(return_value, i);
- }
- if (mode & OCI_ASSOC) {
- add_assoc_null(return_value, column->name);
+ if (connection->svc) {
+ /* rollback outstanding transactions */
+ if (connection->needs_commit) {
+ if (php_oci_connection_rollback(connection TSRMLS_CC)) {
+ /* rollback failed */
+ result = 1;
}
}
}
- if (expected_args > 2) {
- /* only for ocifetchinto BC
- * in all other cases we return array, not long
- */
- REPLACE_ZVAL_VALUE(arg2, return_value, 1); /* copy return_value to given reference */
- zval_dtor(return_value);
- RETURN_LONG(statement->ncolumns);
- }
-}
-/* }}} */
-
-/************************* EXTENSION FUNCTIONS *************************/
-
-/* {{{ proto bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])
- Define a PHP variable to an Oracle column by name */
-/* if you want to define a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE defining!!! */
-PHP_FUNCTION(oci_define_by_name)
-{
- zval **stmt, **name, **var, **type;
- oci_statement *statement;
- oci_define *define, *tmp_define;
- ub2 ocitype = SQLT_CHR; /* zero terminated string */
- int ac = ZEND_NUM_ARGS();
-
- if (ac < 3 || ac > 4 || zend_get_parameters_ex(ac, &stmt, &name, &var, &type) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- switch (ac) {
- case 4:
- convert_to_long_ex(type);
- ocitype = (ub2) Z_LVAL_PP(type);
- /* possible breakthru */
- }
-
- OCI_GET_STMT(statement,stmt);
-
- convert_to_string_ex(name);
-
- if (statement->defines == NULL) {
- ALLOC_HASHTABLE(statement->defines);
- zend_hash_init(statement->defines, 13, NULL, _oci_define_hash_dtor, 0);
- }
-
- define = ecalloc(1,sizeof(oci_define));
-
- if (zend_hash_add(statement->defines,
- Z_STRVAL_PP(name),
- Z_STRLEN_PP(name),
- define,
- sizeof(oci_define),
- (void **)&tmp_define) == SUCCESS) {
- efree(define);
- define = tmp_define;
- } else {
- efree(define);
- RETURN_FALSE;
- }
-
- define->name = (text*) estrndup(Z_STRVAL_PP(name),Z_STRLEN_PP(name));
- define->name_len = Z_STRLEN_PP(name);
- define->type = ocitype;
- define->zval = *var;
- zval_add_ref(var);
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_bind_by_name(resource stmt, string name, mixed &var, [, int maxlength [, int type]])
- Bind a PHP variable to an Oracle placeholder by name */
-/* if you want to bind a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE binding!!! */
-PHP_FUNCTION(oci_bind_by_name)
-{
- zval **stmt, **name, **var, **maxlen, **type;
- oci_statement *statement;
- oci_statement *bindstmt;
- oci_bind bind, *bindp;
- oci_descriptor *descr;
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
- oci_collection *coll;
- dvoid *mycoll = 0;
-#endif
- int mode = OCI_DATA_AT_EXEC;
- ub2 ocitype = SQLT_CHR; /* unterminated string */
- OCIStmt *mystmt = 0;
- dvoid *mydescr = 0;
- sb4 value_sz = -1;
- int ac = ZEND_NUM_ARGS(), inx;
-
- if (ac < 3 || ac > 5 || zend_get_parameters_ex(ac, &stmt, &name, &var, &maxlen, &type) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- switch (ac) {
- case 5:
- convert_to_long_ex(type);
- ocitype = (ub2) Z_LVAL_PP(type);
- /* possible breakthru */
- case 4:
- convert_to_long_ex(maxlen);
- value_sz = Z_LVAL_PP(maxlen);
- /* possible breakthru */
- }
-
- OCI_GET_STMT(statement,stmt);
-
- switch (ocitype) {
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
- case SQLT_NTY:
- if (Z_TYPE_PP(var) != IS_OBJECT) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variable must be allocated using OCINewCollection()");
- RETURN_FALSE;
- }
- if ((inx = _oci_get_ocicoll(*var,&coll TSRMLS_CC)) == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variable must be allocated using OCINewCollection()");
- RETURN_FALSE;
- }
- if (!(mycoll = (dvoid *) coll->coll)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Collection empty");
- RETURN_FALSE;
- }
- value_sz = sizeof(void*);
- mode = OCI_DEFAULT;
-break;
-#endif
- case SQLT_BFILEE:
- case SQLT_CFILEE:
- case SQLT_CLOB:
- case SQLT_BLOB:
- case SQLT_RDD:
- if (Z_TYPE_PP(var) != IS_OBJECT) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variable must be allocated using OCINewDescriptor()");
- RETURN_FALSE;
- }
-
- if ((inx = _oci_get_ocidesc(*var,&descr TSRMLS_CC)) == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variable must be allocated using OCINewDescriptor()");
- RETURN_FALSE;
- }
-
- if (!(mydescr = (dvoid *) descr->ocidescr)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Descriptor empty");
- RETURN_FALSE;
- }
- value_sz = sizeof(void*);
- break;
-
- case SQLT_RSET:
- OCI_GET_STMT(bindstmt,var);
-
- if (!(mystmt = bindstmt->pStmt)) {
- RETURN_FALSE;
- }
- value_sz = sizeof(void*);
- break;
- case SQLT_CHR:
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %u", ocitype);
- RETURN_FALSE;
- break;
+ if (connection->svc && connection->session && connection->is_open) {
+ PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0));
}
- if ((ocitype == SQLT_CHR) && (value_sz == -1)) {
- convert_to_string_ex(var);
- value_sz = Z_STRLEN_PP(var);
+ if (connection->session) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->session, OCI_HTYPE_SESSION));
}
-
- if (value_sz == 0) {
- value_sz = 1;
+
+ if (connection->is_attached) {
+ PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT));
}
-
- convert_to_string_ex(name);
-
- if (!statement->binds) {
- ALLOC_HASHTABLE(statement->binds);
- zend_hash_init(statement->binds, 13, NULL, _oci_bind_hash_dtor, 0);
+
+ if (connection->svc) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX));
}
-
- memset((void*)&bind,0,sizeof(oci_bind));
- zend_hash_update(statement->binds, Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, &bind, sizeof(oci_bind), (void **)&bindp);
- bindp->descr = mydescr;
- bindp->pStmt = mystmt;
- bindp->zval = *var;
- zval_add_ref(var);
+ if (connection->err) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR));
+ }
- CALL_OCI_RETURN(statement->error,
- OCIBindByName(
- statement->pStmt, /* statement handle */
- (OCIBind **)&bindp->pBind, /* bind hdl (will alloc) */
- statement->pError, /* error handle */
- (text*) Z_STRVAL_PP(name), /* placeholder name */
- Z_STRLEN_PP(name), /* placeholder length */
- (dvoid *)0, /* in/out data */
- value_sz, /* OCI_MAX_DATA_SIZE, */ /* max size of input/output data */
- (ub2)ocitype, /* in/out data type */
- (dvoid *)&bindp->indicator, /* indicator (ignored) */
- (ub2 *)0, /* size array (ignored) */
- (ub2 *)&bindp->retcode, /* return code (ignored) */
- (ub4)0, /* maxarr_len (PL/SQL only?) */
- (ub4 *)0, /* actual array size (PL/SQL only?) */
- mode /* mode */
- )
- );
-
- if (statement->error != OCI_SUCCESS) {
- oci_error(statement->pError, "OCIBindByName", statement->error);
- oci_handle_error(statement->conn, statement->error);
- RETURN_FALSE;
+ if (connection->server) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER));
}
-
- if (mode == OCI_DATA_AT_EXEC) {
- CALL_OCI_RETURN(statement->error,
- OCIBindDynamic(
- bindp->pBind,
- statement->pError,
- (dvoid *)bindp,
- oci_bind_in_callback,
- (dvoid *)bindp,
- oci_bind_out_callback
- )
- );
-
- if (statement->error != OCI_SUCCESS) {
- oci_error(statement->pError, "OCIBindDynamic", statement->error);
- oci_handle_error(statement->conn, statement->error);
- RETURN_FALSE;
- }
+
+ if (connection->env) {
+ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV));
}
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
- if (ocitype == SQLT_NTY) {
- /* Bind object */
- CALL_OCI_RETURN(statement->error,
- OCIBindObject(
- bindp->pBind,
- statement->pError,
- coll->tdo,
- (dvoid **) &(coll->coll),
- (ub4 *) 0,
- (dvoid **) 0,
- (ub4 *) 0
- )
- );
-
- if (statement->error) {
- oci_error(statement->pError, "OCIBindObject", statement->error);
- RETURN_FALSE;
+ if (connection->is_persistent) {
+ if (connection->hash_key) {
+ free(connection->hash_key);
}
+ free(connection);
}
-#endif
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_free_descriptor()
- Deletes large object description */
-PHP_FUNCTION(oci_free_descriptor)
-{
- zval *id;
- int inx;
- oci_descriptor *descriptor;
-
- if ((id = getThis()) != 0) {
- inx = _oci_get_ocidesc(id,&descriptor TSRMLS_CC);
- if (inx) {
- oci_debug("oci_free_descriptor: descr=%d",inx);
- zend_list_delete(inx);
- RETURN_TRUE;
+ else {
+ if (connection->hash_key) {
+ efree(connection->hash_key);
}
+ efree(connection);
}
+ connection = NULL;
+ return result;
+} /* }}} */
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_free_descriptor() should not be called like this. Use $somelob->free() to free a LOB");
-
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_save( string data [, int offset ])
- Saves a large object */
-PHP_FUNCTION(oci_lob_save)
+/* {{{ php_oci_password_change()
+ Change password for the user with the username given */
+int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len TSRMLS_DC)
{
- zval *id, **arg,**oarg;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int offparam,inx;
- ub4 loblen;
- ub4 curloblen;
- ub4 offset;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
+ connection->errcode = PHP_OCI_CALL(OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len+1, (text *)pass_old, pass_old_len+1, (text *)pass_new, pass_new_len+1, OCI_DEFAULT));
- connection = descr->conn;
-
- offset = 0;
- if (zend_get_parameters_ex(2, &arg, &oarg) == SUCCESS) {
- convert_to_long_ex(oarg);
- offparam = Z_LVAL_PP(oarg);
-
- CALL_OCI_RETURN(connection->error,
- OCILobGetLength(
- connection->pServiceContext,
- connection->pError,
- mylob,
- &curloblen
- )
- );
-
- oci_debug("oci_lob_save: curloblen=%d",curloblen);
-
- if (offparam == -1) {
- offset = curloblen;
- } else if ((ub4)offparam >= curloblen) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is bigger than current LOB-Size - appending");
- offset = curloblen;
- } else {
- offset = (ub4)offparam;
- }
- } else if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_string_ex(arg);
- loblen = Z_STRLEN_PP(arg);
-
- if (loblen < 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot save a lob which size is less than 1 byte");
- RETURN_FALSE;
- }
-
- if (offset <= 0) {
- offset = 1;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobWrite(
- connection->pServiceContext,
- connection->pError,
- mylob,
- &loblen,
- (ub4) offset,
- (dvoid *) Z_STRVAL_PP(arg),
- (ub4) loblen,
- OCI_ONE_PIECE,
- (dvoid *)0,
- (OCICallbackLobWrite) 0,
- (ub2) 0,
- (ub1) SQLCS_IMPLICIT
- )
- );
-
- oci_debug("oci_lob_save: size=%d offset=%d",loblen,offset);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobWrite", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
}
+ return 0;
+} /* }}} */
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_import( string filename )
- Saves a large object to file */
-PHP_FUNCTION(oci_lob_import)
+/* {{{ php_oci_server_get_version()
+ Get Oracle server version */
+int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC)
{
- zval *id, **arg;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- char *filename;
- int fp,inx;
- char buf[8192];
- ub4 offset = 1;
- ub4 loblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- mylob = (OCILobLocator *) descr->ocidescr;
+ char version_buff[256];
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_string_ex(arg);
-
- if (php_check_open_basedir(Z_STRVAL_PP(arg) TSRMLS_CC)) {
- RETURN_FALSE;
- }
-
- filename = Z_STRVAL_PP(arg);
-
- if ((fp = VCWD_OPEN(filename, O_RDONLY|O_BINARY)) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't open file %s", filename);
- RETURN_FALSE;
- }
-
- while ((loblen = read(fp, &buf, sizeof(buf))) > 0) {
- CALL_OCI_RETURN(connection->error,
- OCILobWrite(
- connection->pServiceContext,
- connection->pError,
- mylob,
- &loblen,
- (ub4) offset,
- (dvoid *) &buf,
- (ub4) loblen,
- OCI_ONE_PIECE,
- (dvoid *)0,
- (OCICallbackLobWrite) 0,
- (ub2) 0,
- (ub1) SQLCS_IMPLICIT
- )
- );
-
- oci_debug("oci_lob_import: size=%d",loblen);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobWrite", connection->error);
- oci_handle_error(connection, connection->error);
- close(fp);
- RETURN_FALSE;
- }
-
- offset += loblen;
- }
- close(fp);
-
- RETURN_TRUE;
+ connection->errcode = PHP_OCI_CALL(OCIServerVersion, (connection->svc, connection->err, (text*)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
}
+
+ *version = estrdup(version_buff);
+ return 0;
+} /* }}} */
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto string oci_lob_load()
- Loads a large object */
-PHP_FUNCTION(oci_lob_load)
+/* {{{ php_oci_column_to_zval()
+ Convert php_oci_out_column struct into zval */
+int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSRMLS_DC)
{
- zval *id;
- oci_descriptor *descr;
- char *buffer;
- int inx;
- ub4 loblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (!oci_loadlob(descr->conn,descr,&buffer,&loblen)) {
- if (loblen > 0) {
- RETURN_STRINGL(buffer,loblen,0);
- }
- else {
- RETURN_EMPTY_STRING();
- }
- } else {
- RETURN_FALSE;
- }
+ php_oci_descriptor *descriptor;
+ ub4 lob_length;
+ int column_size;
+ char *lob_buffer;
+
+ if (column->indicator == -1) { /* column is NULL */
+ ZVAL_NULL(value);
+ return 0;
}
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_load() should not be called like this. Use $somelob->load() to load a LOB");
-
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto string oci_lob_read( int length )
- Reads particular part of a large object */
-PHP_FUNCTION(oci_lob_read)
-{
- zval *id;
- zval **len;
- oci_descriptor *descr;
- char *buffer;
- int inx;
- ub4 loblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
+
+ if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
+ ZVAL_RESOURCE(value, column->stmtid);
+ zend_list_addref(column->stmtid);
+ }
+ else if (column->is_descr) {
- if (zend_get_parameters_ex(1, &len) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
+ if (column->data_type != SQLT_RDD) {
+ int rsrc_type;
+
+ /* reset descriptor's length */
+ descriptor = (php_oci_descriptor *) zend_list_find(column->descid, &rsrc_type);
- loblen = Z_LVAL_PP(len);
- if (oci_readlob(descr->conn,descr,&buffer,&loblen) == 0) {
- if (loblen > 0) {
- RETURN_STRINGL(buffer,loblen,0);
- }
- else {
- RETURN_EMPTY_STRING();
+ if (!descriptor || rsrc_type != le_descriptor) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find LOB descriptor #%d", column->descid);
+ return 1;
}
- } else {
- RETURN_FALSE;
+
+ descriptor->lob_size = -1;
+ descriptor->lob_current_position = 0;
+ descriptor->buffering = 0;
}
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_read() should not be called like this. Use $somelob->read($len) to read a LOB");
- RETURN_FALSE;
-}
-/* }}} */
-/* {{{ proto bool oci_lob_eof()
- Checks if EOF is reached */
-PHP_FUNCTION(oci_lob_eof)
-{
- zval *id;
- oci_descriptor *descr;
- int inx;
- int len;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (oci_lobgetlen(descr->conn,descr,&len) == 0 && descr->lob_size >= 0) {
- if (descr->lob_size == descr->lob_current_position) {
- RETURN_TRUE;
+ if (column->data_type != SQLT_RDD && (mode & PHP_OCI_RETURN_LOBS)) {
+ /* PHP_OCI_RETURN_LOBS means that we want the content of the LOB back instead of the locator */
+
+ if (php_oci_lob_read(descriptor, -1, 0, &lob_buffer, &lob_length TSRMLS_CC)) {
+ ZVAL_FALSE(value);
+ return 1;
} else {
- RETURN_FALSE;
- }
- }
- RETURN_FALSE;
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_eof() should not be called like this. Use $somelob->eof() to check if end of LOB is reached");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_lob_tell()
- Tells LOB pointer position */
-PHP_FUNCTION(oci_lob_tell)
-{
- zval *id;
- oci_descriptor *descr;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
- RETURN_LONG(descr->lob_current_position);
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_tell() should not be called like this. Use $somelob->tell() to get current position of LOB pointer");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_rewind()
- Rewind pointer of a LOB */
-PHP_FUNCTION(oci_lob_rewind)
-{
- zval *id;
- oci_descriptor *descr;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
- descr->lob_current_position = 0;
- RETURN_TRUE;
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_rewind() should not be called like this. Use $somelob->rewind() to set current position of LOB pointer to beginning");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_seek( int offset [, int whence ])
- Moves the pointer of a LOB */
-PHP_FUNCTION(oci_lob_seek)
-{
- zval *id;
- zval **arg1, **arg2;
- int argcount = ZEND_NUM_ARGS(), whence = OCI_SEEK_SET;
- oci_descriptor *descr;
- int inx, len;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (argcount < 1 || argcount > 2 || zend_get_parameters_ex(argcount, &arg1, &arg2) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_long_ex(arg1);
-
- if (oci_lobgetlen(descr->conn,descr,&len) == 0 && descr->lob_size >= 0) {
- if (argcount > 1) {
- convert_to_long_ex(arg2);
- whence = Z_LVAL_PP(arg2);
- switch (whence) {
- case OCI_SEEK_CUR:
- descr->lob_current_position += Z_LVAL_PP(arg1);
- break;
-
- case OCI_SEEK_END:
- if (descr->lob_size + Z_LVAL_PP(arg1) >= 0) {
- descr->lob_current_position = descr->lob_size + Z_LVAL_PP(arg1);
- } else {
- descr->lob_current_position = 0;
- }
- break;
-
- case OCI_SEEK_SET:
- default:
- descr->lob_current_position = Z_LVAL_PP(arg1);
- break;
+ if (lob_length > 0) {
+ ZVAL_STRINGL(value, lob_buffer, lob_length, 0);
}
- } else {
- /* OCI_SEEK_SET by default */
- descr->lob_current_position = Z_LVAL_PP(arg1);
+ else {
+ ZVAL_EMPTY_STRING(value);
+ }
+ return 0;
}
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_seek() should not be called like this. Use $somelob->seek($offset) to move pointer");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_lob_size()
- Returns size of a large object */
-PHP_FUNCTION(oci_lob_size)
-{
- zval *id;
- oci_descriptor *descr;
- int inx;
- ub4 loblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (!oci_lobgetlen(descr->conn,descr,&loblen)) {
- RETURN_LONG(loblen);
- } else {
- RETURN_FALSE;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_size() should not be called like this. Use $somelob->size() to get size of a LOB");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_lob_write( string string [, int length ])
- Writes data to current position of a LOB */
-PHP_FUNCTION(oci_lob_write)
-{
- zval *id, **data,**length;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int write_length,inx;
- ub4 loblen;
- ub4 curloblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
+ } else {
+ /* return the locator */
+ object_init_ex(value, oci_lob_class_entry_ptr);
+ add_property_resource(value, "descriptor", column->descid);
+ zend_list_addref(column->descid);
}
-
- IS_LOB_INTERNAL(descr);
+ }
+ else {
+ switch (column->retcode) {
+ case 0:
+ /* intact value */
+ if (column->piecewise) {
+ column_size = column->retlen4;
+ } else {
+ column_size = column->retlen;
+ }
+ break;
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0) {
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(2, &data, &length) == SUCCESS) {
- convert_to_string_ex(data);
- convert_to_long_ex(length);
- write_length = Z_LVAL_PP(length);
- } else if (zend_get_parameters_ex(1, &data) == SUCCESS) {
- convert_to_string_ex(data);
- write_length = Z_STRLEN_PP(data);
- } else {
- WRONG_PARAM_COUNT;
- }
-
- if (write_length < 1) {
- RETURN_LONG(0);
- }
-
- loblen = write_length;
-
- CALL_OCI_RETURN(connection->error,
- OCILobWrite(
- connection->pServiceContext,
- connection->pError,
- mylob,
- &loblen,
- (ub4) descr->lob_current_position+1,
- (dvoid *) Z_STRVAL_PP(data),
- (ub4) loblen,
- OCI_ONE_PIECE,
- (dvoid *)0,
- (OCICallbackLobWrite) 0,
- (ub2) 0,
- (ub1) SQLCS_IMPLICIT
- )
- );
-
- oci_debug("oci_lob_write: size=%d offset=%d",loblen,descr->lob_current_position);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobWrite", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- descr->lob_current_position += loblen;
-
- if (descr->lob_current_position > descr->lob_size) {
- descr->lob_size = descr->lob_current_position;
+ default:
+ ZVAL_FALSE(value);
+ return 0;
}
- /* marking buffer as used */
- if (descr->buffering == 1) {
- descr->buffering = 2;
- }
- RETURN_LONG(loblen);
+ ZVAL_STRINGL(value, column->data, column_size, 1);
}
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_write() should not be called like this. Use $somelob->write($data,$len) to write to a LOB");
- RETURN_FALSE;
+ return 0;
}
/* }}} */
-/* {{{ proto bool oci_lob_append( object lob )
- Appends data from a LOB to another LOB */
-PHP_FUNCTION(oci_lob_append)
+/* {{{ php_oci_fetch_row()
+ Fetch the next row from the given statement */
+void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args)
{
- zval *id, **arg;
- OCILobLocator *mylob,*my_fromlob;
- oci_connection *connection;
- oci_descriptor *descr,*from_descr;
- int inx;
- ub4 curloblen,from_curloblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
+ zval *z_statement, *array;
+ php_oci_statement *statement;
+ php_oci_out_column *column;
+ ub4 nrows = 1;
+ int i;
+ long fetch_mode = 0;
- connection = descr->conn;
+ if (expected_args > 2) {
+ /* only for ocifetchinto BC */
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0) {
- RETURN_FALSE;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|l", &z_statement, &array, &fetch_mode) == FAILURE) {
+ return;
}
- if (zend_get_parameters_ex(1, &arg) == SUCCESS) {
- convert_to_object_ex(arg);
- if ((inx = _oci_get_ocidesc(*arg,&from_descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- my_fromlob = (OCILobLocator *) from_descr->ocidescr;
-
- if (!my_fromlob) {
- RETURN_FALSE;
- }
-
- if (oci_lobgetlen(from_descr->conn,from_descr,&from_curloblen) != 0) {
- RETURN_FALSE;
- }
- } else {
- WRONG_PARAM_COUNT;
+ if (ZEND_NUM_ARGS() == 2) {
+ fetch_mode = mode;
}
-
- if (from_descr->lob_size == 0) {
- RETURN_LONG(0);
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobAppend(
- connection->pServiceContext,
- connection->pError,
- mylob,
- my_fromlob
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobAppend", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
}
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_append() should not be called like this. Use $somelob->append($LOB_from) to append data from a LOB to another LOB");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_truncate( [ int length ])
- Truncates a LOB */
-PHP_FUNCTION(oci_lob_truncate)
-{
- zval *id, **length;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int inx;
- ub4 trim_length;
- ub4 curloblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
+ else if (expected_args == 2) {
+ /* only for oci_fetch_array() */
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0) {
- RETURN_FALSE;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &fetch_mode) == FAILURE) {
+ return;
}
- if (zend_get_parameters_ex(1, &length) == SUCCESS) {
- convert_to_long_ex(length);
- trim_length = Z_LVAL_PP(length);
- } else {
- trim_length = 0;
- }
-
- if (trim_length < 0) {
- /* negative length is not allowed */
- RETURN_FALSE;
+ if (ZEND_NUM_ARGS() == 1) {
+ fetch_mode = mode;
}
+ }
+ else {
+ /* for all oci_fetch_*() */
- CALL_OCI_RETURN(connection->error,
- OCILobTrim(
- connection->pServiceContext,
- connection->pError,
- mylob,
- trim_length
- )
- );
-
- oci_debug("oci_lob_truncate: trim_length=%d",trim_length);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobTrim", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
}
-
- descr->lob_size = trim_length;
- RETURN_TRUE;
- }
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_truncate() should not be called like this. Use $somelob->truncate($length) to truncate a LOB to a specified length");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_lob_erase( [ int offset [, int length ] ] )
- Erases a specified portion of the internal LOB, starting at a specified offset */
-PHP_FUNCTION(oci_lob_erase)
-{
- zval *id, **length, **offset;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int inx;
- ub4 erase_length, erase_offset;
- ub4 curloblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0) {
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(2, &offset, &length) == SUCCESS) {
- convert_to_long_ex(offset);
- convert_to_long_ex(length);
-
- erase_offset = Z_LVAL_PP(offset);
- erase_length = Z_LVAL_PP(length);
- } else if (zend_get_parameters_ex(1, &offset) == SUCCESS) {
- convert_to_long_ex(offset);
-
- erase_offset = Z_LVAL_PP(offset);
- erase_length = descr->lob_size - erase_offset;
- } else {
- erase_offset = 0;
- erase_length = descr->lob_size;
- }
-
- if (erase_length < 1) {
- RETURN_LONG(0);
- }
-
- if (erase_offset > descr->lob_size) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "oci_lob_erase(): offset is greater than LOB's length");
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobErase(
- connection->pServiceContext,
- connection->pError,
- mylob,
- &erase_length,
- erase_offset+1
- )
- );
-
- oci_debug("oci_lob_erase: erase_length=%d, erase_offset=%d",erase_length,erase_offset);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobErase", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_LONG(erase_length);
+ fetch_mode = mode;
}
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_erase() should not be called like this. Use $somelob->erase($offset, $length) to erase specified part of LOB");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_flush( [ int flag ] )
- Flushes the LOB buffer */
-PHP_FUNCTION(oci_lob_flush)
-{
- zval *id, **flag;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int inx, flush_flag;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
- connection = descr->conn;
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
- if (zend_get_parameters_ex(1, &flag) == SUCCESS) {
- convert_to_long_ex(flag);
- flush_flag = Z_LVAL_PP(flag);
- } else {
- flush_flag = 0;
- }
-
- if (descr->buffering == 0) {
- /* buffering wasn't enabled, there is nothing to flush */
- RETURN_FALSE;
- }
-
- if (oci_lob_flush(descr,flush_flag TSRMLS_CC) == 1) {
- RETURN_TRUE;
- }
+ if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
RETURN_FALSE;
}
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_flush() should not be called like this. Use $somelob->flush() to flush LOB buffer");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool ocisetbufferinglob( boolean flag )
- Enables/disables buffering for a LOB */
-PHP_FUNCTION(ocisetbufferinglob)
-{
- zval *id, **flag;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- int inx, buffering_flag;
- ub4 curloblen;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
- connection = descr->conn;
-
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0) {
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(1, &flag) == SUCCESS) {
- convert_to_boolean_ex(flag);
- buffering_flag = Z_LVAL_PP(flag);
- } else {
- WRONG_PARAM_COUNT;
- }
-
- /* we'll return true if function was called twice with the same parameter */
- if (buffering_flag == 0 && descr->buffering == 0) {
- RETURN_TRUE;
- } else if (buffering_flag == 1 && descr->buffering > 0) {
- RETURN_TRUE;
- }
-
- switch (buffering_flag) {
- case 0:
- CALL_OCI_RETURN(connection->error,
- OCILobDisableBuffering(
- connection->pServiceContext,
- connection->pError,
- mylob
- )
- );
- break;
- case 1:
- CALL_OCI_RETURN(connection->error,
- OCILobEnableBuffering(
- connection->pServiceContext,
- connection->pError,
- mylob
- )
- );
- break;
- }
-
- oci_debug("oci_lob_set_buffering: buffering_flag=%d",buffering_flag);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFlushBuffer", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- descr->buffering = buffering_flag;
- RETURN_TRUE;
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OCISetBufferingLob() should not be called like this. Use $somelob->setBuffering($flag) to set buffering on/off for a LOB");
- RETURN_FALSE;
-}
-/* }}} */
+ array_init(return_value);
-/* {{{ proto bool ocigetbufferinglob()
- Returns current state of buffering for a LOB */
-PHP_FUNCTION(ocigetbufferinglob)
-{
- zval *id;
- OCILobLocator *mylob;
- oci_descriptor *descr;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
+ for (i = 0; i < statement->ncolumns; i++) {
- IS_LOB_INTERNAL(descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- switch (descr->buffering) {
- case 1:
- case 2:
- RETURN_TRUE;
- break;
-
- case 0:
- default:
- RETURN_FALSE;
- break;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OCIGetBufferingLob() should not be called like this. Use $somelob->getBuffering() to get current state of buffering for a LOB");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_copy( object lob_to, object lob_from [, int length ] )
- Copies data from a LOB to another LOB */
-PHP_FUNCTION(oci_lob_copy)
-{
- zval **arg1, **arg2, **arg3;
- OCILobLocator *mylob,*my_fromlob;
- oci_connection *connection;
- oci_descriptor *descr,*from_descr;
- int inx, ac = ZEND_NUM_ARGS();
- ub4 curloblen,from_curloblen, copylen;
-
- if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &arg1, &arg2, &arg3) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_object_ex(arg1);
- convert_to_object_ex(arg2);
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
- if ((inx = _oci_get_ocidesc(*arg1,&descr TSRMLS_CC)) == 0 || (inx = _oci_get_ocidesc(*arg2,&from_descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- IS_LOB_INTERNAL(descr);
- IS_LOB_INTERNAL(from_descr);
-
- mylob = (OCILobLocator *) descr->ocidescr;
- my_fromlob = (OCILobLocator *) from_descr->ocidescr;
-
- if (!mylob || !my_fromlob) {
- RETURN_FALSE;
- }
-
- if (oci_lobgetlen(descr->conn,descr,&curloblen) != 0 || oci_lobgetlen(from_descr->conn,from_descr,&from_curloblen) != 0) {
- RETURN_FALSE;
- }
-
- if (ac == 3) {
- convert_to_long_ex(arg3);
- copylen = Z_LVAL_PP(arg3);
- } else {
- copylen = from_descr->lob_size - from_descr->lob_current_position;
- }
-
- if ((int)copylen <= 0) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCILobCopy(
- connection->pServiceContext,
- connection->pError,
- mylob,
- my_fromlob,
- copylen,
- descr->lob_current_position+1,
- from_descr->lob_current_position+1
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobCopy", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
+ if (column == NULL) {
+ continue;
}
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_is_equal( object lob1, object lob2 )
- Tests to see if two LOB/FILE locators are equal */
-PHP_FUNCTION(oci_lob_is_equal)
-{
- zval **arg1, **arg2;
- OCILobLocator *first_lob,*second_lob;
- oci_connection *connection;
- oci_descriptor *first_descr,*second_descr;
- int inx;
- boolean is_equal;
-
- if (zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
- WRONG_PARAM_COUNT;
+ if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) {
+ continue;
}
- convert_to_object_ex(arg1);
- convert_to_object_ex(arg2);
-
- if ((inx = _oci_get_ocidesc(*arg1,&first_descr TSRMLS_CC)) == 0 || (inx = _oci_get_ocidesc(*arg2,&second_descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- first_lob = (OCILobLocator *) first_descr->ocidescr;
- second_lob = (OCILobLocator *) second_descr->ocidescr;
-
- if (!first_lob || !second_lob) {
- RETURN_FALSE;
- }
+ if (!(column->indicator == -1)) {
+ zval *element;
- connection = first_descr->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCILobIsEqual(
- connection->session->pEnv,
- first_lob,
- second_lob,
- &is_equal
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobIsEqual", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- if (is_equal == TRUE) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_export([string filename [, int start [, int length]]])
- Writes a large object into a file */
-PHP_FUNCTION(oci_lob_export)
-{
- zval *id, **zfilename, **zstart, **zlength;
- char *filename = NULL;
- int start = -1;
- ub4 length = -1;
- oci_connection *connection;
- oci_descriptor *descr;
- char *buffer=0;
- ub4 loblen;
- int ac = ZEND_NUM_ARGS();
- int fp = -1,inx;
- OCILobLocator *mylob;
- int coffs;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocidesc(id,&descr TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (ac < 0 || ac > 3 || zend_get_parameters_ex(ac, &zfilename, &zstart, &zlength) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- switch (ac) {
- case 3:
- convert_to_long_ex(zlength);
- length = Z_LVAL_PP(zlength);
- case 2:
- convert_to_long_ex(zstart);
- start = Z_LVAL_PP(zstart);
- case 1:
- convert_to_string_ex(zfilename);
- filename = Z_STRVAL_PP(zfilename);
- }
-
- if (filename && *filename) {
- if (php_check_open_basedir(filename TSRMLS_CC)) {
- goto bail;
- }
-
- if ((fp = VCWD_OPEN_MODE(filename,O_CREAT | O_RDWR | O_BINARY | O_TRUNC, 0600)) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create file %s", filename);
- goto bail;
- }
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobGetLength(
- connection->pServiceContext,
- connection->pError,
- descr->ocidescr,
- &loblen
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobGetLength", connection->error);
- oci_handle_error(connection, connection->error);
- goto bail;
- }
-
- if (descr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileOpen(
- connection->pServiceContext,
- connection->pError,
- descr->ocidescr,
- OCI_FILE_READONLY
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileOpen",connection->error);
- oci_handle_error(connection, connection->error);
- goto bail;
- }
- }
-
- if (start == -1) {
- start = 0;
- }
-
- if (length == -1) {
- length = loblen - start;
- }
-
- if ((start + length) > loblen) {
- length = loblen - start;
- }
-
-#define OCI_LOB_READ_BUFFER 128*1024
-
- buffer = emalloc(OCI_LOB_READ_BUFFER);
-
- coffs = start;
-
- oci_debug("oci_lob_export(start = %d, length = %d, loblen = %d",start,length,loblen);
-
- while (length > 0) {
- ub4 toread;
-
- if (length > OCI_LOB_READ_BUFFER) {
- toread = OCI_LOB_READ_BUFFER;
- } else {
- toread = length;
- }
+ MAKE_STD_ZVAL(element);
+ php_oci_column_to_zval(column, element, fetch_mode TSRMLS_CC);
- oci_debug("oci_lob_read(coffs = %d, toread = %d",coffs,toread);
-
- CALL_OCI_RETURN(connection->error,
- OCILobRead(
- connection->pServiceContext,
- connection->pError,
- descr->ocidescr,
- &toread, /* IN/OUT bytes toread/read */
- coffs+1, /* offset (starts with 1) */
- (dvoid *) buffer,
- toread, /* size of buffer */
- (dvoid *)0,
- (OCICallbackLobRead) 0, /* callback... */
- (ub2) 0, /* The character set ID of the buffer data. */
- (ub1) SQLCS_IMPLICIT /* The character set form of the buffer data. */
- )
- );
-
- oci_debug("oci_lob_read(read - %d",toread);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobRead", connection->error);
- oci_handle_error(connection, connection->error);
- goto bail;
+ if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
+ add_index_zval(return_value, i, element);
}
-
- if (fp != -1) {
- if ((ub4) write(fp,buffer,toread) != toread) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot write file!");
- goto bail;
+ if (fetch_mode & PHP_OCI_ASSOC) {
+ if (fetch_mode & PHP_OCI_NUM) {
+ ZVAL_ADDREF(element);
}
- } else {
- PHPWRITE(buffer,toread);
+ add_assoc_zval(return_value, column->name, element);
}
-
- length -= toread;
- coffs += toread;
- }
-
- efree(buffer);
- buffer = 0;
- if (fp != -1) {
- close(fp);
- fp = 0;
- }
-
- if (descr->type == OCI_DTYPE_FILE) {
- CALL_OCI_RETURN(connection->error,
- OCILobFileClose(
- connection->pServiceContext,
- connection->pError,
- descr->ocidescr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFileClose", connection->error);
- oci_handle_error(connection, connection->error);
- goto bail;
- }
- }
- RETURN_TRUE;
- }
-
-bail:
- if (fp != -1) {
- close(fp);
- }
-
- if (buffer) {
- efree(buffer);
- }
-
- RETURN_FALSE;
-}
-/* }}} */
-
-#ifdef HAVE_OCI8_TEMP_LOB
-/* {{{ proto bool oci_lob_write_temporary(string var [, int lob_type])
- Writes temporary blob */
-PHP_FUNCTION(oci_lob_write_temporary)
-{
- zval *id, *var;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descr;
- ub4 offset = 1;
- ub4 loblen;
- long lob_type = OCI_TEMP_CLOB;
-
- oci_debug ("oci_write_temporary_lob");
-
- if ((id = getThis()) == 0) {
- RETURN_FALSE;
- }
-
- if (_oci_get_ocidesc(id,&descr TSRMLS_CC) == 0) {
- RETURN_FALSE;
- }
-
- mylob = (OCILobLocator *) descr->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descr->conn;
-
- if (ZEND_NUM_ARGS() < 1) WRONG_PARAM_COUNT;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &var, &lob_type) == FAILURE) {
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobCreateTemporary(
- connection->pServiceContext,
- connection->pError,
- mylob,
- OCI_DEFAULT,
- OCI_DEFAULT,
- lob_type,
- OCI_ATTR_NOCACHE,
- OCI_DURATION_SESSION
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobCreateTemporary", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobOpen(
- connection->pServiceContext,
- connection->pError,
- mylob,
- OCI_LOB_READWRITE
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobOpen", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- convert_to_string_ex(&var);
- loblen = Z_STRLEN_P(var);
-
- if (loblen < 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot save a lob that is less than 1 byte");
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCILobWrite(
- connection->pServiceContext,
- connection->pError,
- mylob,
- (ub4 *) &loblen,
- (ub4) offset,
- (dvoid *) Z_STRVAL_P(var),
- (ub4) loblen,
- OCI_ONE_PIECE,
- (dvoid *)0,
- (sb4 (*)(dvoid *, dvoid *, ub4 *, ub1 *)) 0,
- (ub2) 0,
- (ub1) SQLCS_IMPLICIT
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobWrite", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_lob_close()
- Closes lob descriptor */
-PHP_FUNCTION(oci_lob_close)
-{
- zval *id;
- int inx;
- OCILobLocator *mylob;
- oci_connection *connection;
- oci_descriptor *descriptor;
- int is_temporary;
-
- if ((id = getThis()) != 0) {
- inx = _oci_get_ocidesc(id,&descriptor TSRMLS_CC);
- if (inx) {
-
- mylob = (OCILobLocator *) descriptor->ocidescr;
-
- if (!mylob) {
- RETURN_FALSE;
- }
-
- connection = descriptor->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCILobClose(
- connection->pServiceContext,
- connection->pError,
- mylob
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobClose", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
+ } else {
+ if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
+ add_index_null(return_value, i);
}
-
- connection->error =
- OCILobIsTemporary(connection->session->pEnv,
- connection->pError,
- mylob,
- &is_temporary);
- if (is_temporary) {
- connection->error =
- OCILobFreeTemporary(connection->pServiceContext,
- connection->pError,
- mylob);
-
- if (connection->error) {
- oci_error(connection->pError, "OCILobFreeTemporary",
- connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
- oci_debug("oci_lob_free_temporary: descr=%d",inx);
+ if (fetch_mode & PHP_OCI_ASSOC) {
+ add_assoc_null(return_value, column->name);
}
-
- oci_debug("oci_close_lob: descr=%d",inx);
- RETURN_TRUE;
}
}
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_lob_close() should not be called like this. Use $somelob->close() to close a LOB");
-
- RETURN_FALSE;
-}
-/* }}} */
-#endif
-
-/* {{{ proto object oci_new_descriptor(resource connection [, int type])
- Initialize a new empty descriptor LOB/FILE (LOB is default) */
-PHP_FUNCTION(oci_new_descriptor)
-{
- zval **conn, **type;
- oci_connection *connection;
- oci_descriptor *descr;
- int dtype;
-
- dtype = OCI_DTYPE_LOB;
-
- if (zend_get_parameters_ex(2, &conn, &type) == SUCCESS) {
- convert_to_long_ex(type);
- dtype = Z_LVAL_PP(type);
- } else if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- descr = oci_new_desc(dtype,connection);
-
- if (!descr) {
- RETURN_NULL();
- }
-
- object_init_ex(return_value, oci_lob_class_entry_ptr);
- add_property_resource(return_value, "descriptor", descr->id);
-}
-/* }}} */
-
-/* {{{ proto bool oci_rollback(resource conn)
- Rollback the current context */
-PHP_FUNCTION(oci_rollback)
-{
- zval **conn;
- oci_connection *connection;
-
- if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- if (connection->descriptors) {
- zend_hash_apply(connection->descriptors,(apply_func_t) _oci_desc_flush_hash_dtor TSRMLS_CC);
- }
-
- oci_debug("<OCITransRollback");
-
- CALL_OCI_RETURN(connection->error,
- OCITransRollback(
- connection->pServiceContext,
- connection->pError,
- (ub4) 0
- )
- );
-
- connection->needs_commit = 0;
-
- oci_debug(">OCITransRollback");
-
- if (connection->error) {
- oci_error(connection->pError, "OCIRollback", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_commit(resource conn)
- Commit the current context */
-PHP_FUNCTION(oci_commit)
-{
- zval **conn;
- oci_connection *connection;
-
- if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- if (connection->descriptors) {
- zend_hash_apply(connection->descriptors,(apply_func_t) _oci_desc_flush_hash_dtor TSRMLS_CC);
- }
-
- oci_debug("<OCITransCommit");
-
- CALL_OCI_RETURN(connection->error,
- OCITransCommit(
- connection->pServiceContext,
- connection->pError,
- (ub4) 0
- )
- );
-
- connection->needs_commit = 0;
-
- oci_debug(">OCITransCommit");
-
- if (connection->error) {
- oci_error(connection->pError, "OCICommit", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto string oci_field_name(resource stmt, int col)
- Tell the name of a column */
-PHP_FUNCTION(oci_field_name)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
-
- RETURN_STRINGL(outcol->name, outcol->name_len, 1);
-}
-/* }}} */
-
-/* {{{ proto int oci_field_size(resource stmt, int col)
- Tell the maximum data size of a column */
-PHP_FUNCTION(oci_field_size)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
-
- oci_debug("oci_field_size: %16s, retlen = %4d, retlen4 = %d, data_size = %4d, storage_size4 = %4d, indicator %4d, retcode = %4d",
- outcol->name,outcol->retlen,outcol->retlen4,outcol->data_size,outcol->storage_size4,outcol->indicator,outcol->retcode);
-
- /* Handle data type of LONG */
- if (outcol->data_type == SQLT_LNG){
- RETURN_LONG(outcol->storage_size4);
- } else {
- RETURN_LONG(outcol->data_size);
- }
-}
-/* }}} */
-
-/* {{{ proto int oci_field_scale(resource stmt, int col)
- Tell the scale of a column */
-PHP_FUNCTION(oci_field_scale)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
- RETURN_LONG(outcol->scale);
-}
-/* }}} */
-
-/* {{{ proto int oci_field_precision(resource stmt, int col)
- Tell the precision of a column */
-PHP_FUNCTION(oci_field_precision)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
- RETURN_LONG(outcol->precision);
-}
-/* }}} */
-
-/* {{{ proto mixed oci_field_type(resource stmt, int col)
- Tell the data type of a column */
-PHP_FUNCTION(oci_field_type)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
- switch (outcol->data_type) {
-#ifdef SQLT_TIMESTAMP
- case SQLT_TIMESTAMP:
- RETVAL_STRING("TIMESTAMP",1);
- break;
-#endif
-#ifdef SQLT_TIMESTAMP_TZ
- case SQLT_TIMESTAMP_TZ:
- RETVAL_STRING("TIMESTAMP_TZ",1);
- break;
-#endif
- case SQLT_DAT:
- RETVAL_STRING("DATE",1);
- break;
- case SQLT_NUM:
- RETVAL_STRING("NUMBER",1);
- break;
- case SQLT_LNG:
- RETVAL_STRING("LONG",1);
- break;
- case SQLT_BIN:
- RETVAL_STRING("RAW",1);
- break;
- case SQLT_LBI:
- RETVAL_STRING("LONG RAW",1);
- break;
- case SQLT_CHR:
- RETVAL_STRING("VARCHAR",1);
- break;
- case SQLT_RSET:
- RETVAL_STRING("REFCURSOR",1);
- break;
- case SQLT_AFC:
- RETVAL_STRING("CHAR",1);
- break;
- case SQLT_BLOB:
- RETVAL_STRING("BLOB",1);
- break;
- case SQLT_CLOB:
- RETVAL_STRING("CLOB",1);
- break;
- case SQLT_BFILE:
- RETVAL_STRING("BFILE",1);
- break;
- case SQLT_RDD:
- RETVAL_STRING("ROWID",1);
- break;
- default:
- RETVAL_LONG(outcol->data_type);
- }
-}
-/* }}} */
-
-/* {{{ proto int oci_field_type_raw(resource stmt, int col)
- Tell the raw oracle data type of a column */
-PHP_FUNCTION(oci_field_type_raw)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
- RETVAL_LONG(outcol->data_type);
-}
-/* }}} */
-
-/* {{{ proto bool oci_field_is_null(resource stmt, int col)
- Tell whether a column is NULL */
-PHP_FUNCTION(oci_field_is_null)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
- if (outcol == NULL) {
- RETURN_FALSE;
- }
- if (outcol->indicator == -1) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto void oci_internal_debug(int onoff)
- Toggle internal debugging output for the OCI extension */
-PHP_FUNCTION(oci_internal_debug)
-{
- zval **arg;
-
- if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- convert_to_long_ex(arg);
- OCI(debug_mode) = Z_LVAL_PP(arg);
-}
-/* }}} */
-
-/* {{{ proto bool oci_execute(resource stmt [, int mode])
- Execute a parsed statement */
-PHP_FUNCTION(oci_execute)
-{
- zval **stmt,**mode;
- oci_statement *statement;
- ub4 execmode;
-
- if (zend_get_parameters_ex(2, &stmt, &mode) == SUCCESS) {
- convert_to_long_ex(mode);
- execmode = Z_LVAL_PP(mode);
- } else if (zend_get_parameters_ex(1, &stmt) == SUCCESS) {
- execmode = OCI_COMMIT_ON_SUCCESS;
- } else {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- if (oci_execute(statement, "OCIExecute",execmode)) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto bool oci_cancel(resource stmt)
- Cancel reading from a cursor */
-PHP_FUNCTION(oci_cancel)
-{
- zval **stmt;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- if (oci_fetch(statement, 0, "OCICancel" TSRMLS_CC)) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto bool oci_fetch(resource stmt)
- Prepare a new row of data for reading */
-PHP_FUNCTION(oci_fetch)
-{
- zval **stmt;
- oci_statement *statement;
- ub4 nrows = 1; /* only one row at a time is supported for now */
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- if (oci_fetch(statement, nrows, "OCIFetch" TSRMLS_CC)) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
+ if (expected_args > 2) {
+ /* only for ocifetchinto BC
+ * in all other cases we return array, not long
+ */
+ REPLACE_ZVAL_VALUE(&array, return_value, 1); /* copy return_value to given reference */
+ zval_dtor(return_value);
+ RETURN_LONG(statement->ncolumns);
}
}
/* }}} */
-/* {{{ proto int ocifetchinto(resource stmt, array &output [, int mode])
- Fetch a row of result data into an array */
-PHP_FUNCTION(ocifetchinto)
+/* {{{ php_oci_persistent_helper()
+ Helper function to close/rollback persistent connections at the end of request */
+static int php_oci_persistent_helper(list_entry *le TSRMLS_DC)
{
- php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 3);
-}
-/* }}} */
+ time_t timestamp;
+ php_oci_connection *connection;
-/* {{{ proto int oci_fetch_all(resource stmt, array &output[, int skip[, int maxrows[, int flags]]])
- Fetch all rows of result data into an array */
-PHP_FUNCTION(oci_fetch_all)
-{
- zval **stmt, **array, *element, **zskip, **zmaxrows, **zflags, *tmp;
- oci_statement *statement;
- oci_out_column **columns;
- zval ***outarrs;
- ub4 nrows = 1;
- int i;
- int skip = 0, maxrows = -1;
- int flags = 0;
- int rows = 0;
- int ac = ZEND_NUM_ARGS();
-
- if (ac < 2 || ac > 5 || zend_get_parameters_ex(ac, &stmt, &array, &zskip, &zmaxrows, &zflags) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
+ timestamp = time(NULL);
- switch (ac) {
- case 5:
- convert_to_long_ex(zflags);
- flags = Z_LVAL_PP(zflags);
- case 4:
- convert_to_long_ex(zmaxrows);
- maxrows = Z_LVAL_PP(zmaxrows);
- case 3:
- convert_to_long_ex(zskip);
- skip = Z_LVAL_PP(zskip);
- }
-
- OCI_GET_STMT(statement,stmt);
-
- zval_dtor(*array);
- array_init(*array);
-
- while (skip--) {
- if (!oci_fetch(statement, nrows, "OCIFetchStatement" TSRMLS_CC)) {
- RETURN_LONG(0);
- }
- }
-
- if (flags & OCI_FETCHSTATEMENT_BY_ROW) {
- columns = safe_emalloc(statement->ncolumns, sizeof(oci_out_column *), 0);
-
- for (i = 0; i < statement->ncolumns; i++) {
- columns[ i ] = oci_get_col(statement, i + 1, 0);
- }
-
- while (oci_fetch(statement, nrows, "OCIFetchStatement" TSRMLS_CC)) {
- zval *row;
-
- MAKE_STD_ZVAL(row);
- array_init(row);
-
- for (i = 0; i < statement->ncolumns; i++) {
- MAKE_STD_ZVAL(element);
-
- _oci_make_zval(element,statement,columns[ i ], "OCIFetchStatement",OCI_RETURN_LOBS TSRMLS_CC);
-
- if (flags & OCI_NUM) {
- zend_hash_next_index_insert(Z_ARRVAL_P(row), &element, sizeof(zval*), NULL);
- } else { /* default to ASSOC */
- zend_hash_update(Z_ARRVAL_P(row),
- columns[ i ]->name, columns[ i ]->name_len+1,
- &element, sizeof(zval*), NULL);
- }
- }
-
- zend_hash_next_index_insert(Z_ARRVAL_PP(array), &row, sizeof(zval*), NULL);
-
- rows++;
-
- if ((maxrows != -1) && (rows == maxrows)) {
- oci_fetch(statement, 0, "OCIFetchStatement" TSRMLS_CC);
- break;
- }
- }
- efree(columns);
-
- } else { /* default to BY_COLUMN */
- columns = safe_emalloc(statement->ncolumns, sizeof(oci_out_column *), 0);
- outarrs = safe_emalloc(statement->ncolumns, sizeof(zval*), 0);
-
- if (flags & OCI_NUM) {
- for (i = 0; i < statement->ncolumns; i++) {
- columns[ i ] = oci_get_col(statement, i + 1, 0);
-
- MAKE_STD_ZVAL(tmp);
- array_init(tmp);
-
- zend_hash_next_index_insert(Z_ARRVAL_PP(array),
- &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
- }
- } else { /* default to ASSOC */
- for (i = 0; i < statement->ncolumns; i++) {
- columns[ i ] = oci_get_col(statement, i + 1, 0);
-
- MAKE_STD_ZVAL(tmp);
- array_init(tmp);
-
- zend_hash_update(Z_ARRVAL_PP(array),
- columns[ i ]->name, columns[ i ]->name_len+1,
- (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
- }
- }
+ if (le->type == le_pconnection) {
+ connection = (php_oci_connection *)le->ptr;
- while (oci_fetch(statement, nrows, "OCIFetchStatement" TSRMLS_CC)) {
- for (i = 0; i < statement->ncolumns; i++) {
- MAKE_STD_ZVAL(element);
-
- _oci_make_zval(element,statement,columns[ i ], "OCIFetchStatement",OCI_RETURN_LOBS TSRMLS_CC);
-
- zend_hash_index_update((*(outarrs[ i ]))->value.ht, rows, (void *)&element, sizeof(zval*), NULL);
+ if (connection->used_this_request) {
+ php_oci_connection_rollback(connection TSRMLS_CC);
+
+ if (connection->descriptors) {
+ zend_hash_destroy(connection->descriptors);
+ efree(connection->descriptors);
+ connection->descriptors = NULL;
}
-
- rows++;
-
- if ((maxrows != -1) && (rows == maxrows)) {
- oci_fetch(statement, 0, "OCIFetchStatement" TSRMLS_CC);
- break;
+
+ if (OCI_G(persistent_timeout) > 0) {
+ connection->idle_expiry = timestamp + OCI_G(persistent_timeout);
}
- }
- efree(columns);
- efree(outarrs);
- }
-
- RETURN_LONG(rows);
-}
-/* }}} */
-
-/* {{{ proto object oci_fetch_object( resource stmt )
- Fetch a result row as an object */
-PHP_FUNCTION(oci_fetch_object)
-{
- php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, OCI_ASSOC, 2);
-
- if (Z_TYPE_P(return_value) == IS_ARRAY) {
- object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
- }
-}
-/* }}} */
-
-/* {{{ proto array oci_fetch_row( resource stmt )
- Fetch a result row as an enumerated array */
-PHP_FUNCTION(oci_fetch_row)
-{
- php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, OCI_NUM, 1);
-}
-/* }}} */
-
-/* {{{ proto array oci_fetch_assoc( resource stmt )
- Fetch a result row as an associative array */
-PHP_FUNCTION(oci_fetch_assoc)
-{
- php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, OCI_ASSOC, 1);
-}
-/* }}} */
-
-/* {{{ proto array oci_fetch_array( resource stmt [, int mode ])
- Fetch a result row as an array */
-PHP_FUNCTION(oci_fetch_array)
-{
- php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, OCI_BOTH, 2);
-}
-/* }}} */
-
-/* {{{ proto bool oci_free_statement(resource stmt)
- Free all resources associated with a statement */
-PHP_FUNCTION(oci_free_statement)
-{
- zval **stmt;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- zend_list_delete(statement->id);
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_close(resource conn)
- Disconnect from database */
-PHP_FUNCTION(oci_close)
-{
-#if 0
- this function does nothing any more. server-connections get automagiclly closed on
- request-end. connection handles will "dissappear" as soon as they are no longer
- referenced. as this module makes heavy use of zends reference-counting mechanism
- this is the desired behavior. it has always been a bad idea to close a connection that
- has outstanding transactions. this way we have a nice-clean approach.
- (thies@thieso.net 20000110)
-
- oci_connection *connection;
- zval **conn;
-
- if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- connection->is_open = 0;
-
- zend_hash_apply(list, (apply_func_t) _stmt_cleanup TSRMLS_CC);
-
- if (zend_list_delete(connection->id) == SUCCESS) {
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-#endif
-}
-/* }}} */
-
-/* {{{ proto resource oci_new_connect(string user, string pass [, string db])
- Connect to an Oracle database and log on. Returns a new session. */
-PHP_FUNCTION(oci_new_connect)
-{
- oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
-}
-/* }}} */
-
-/* {{{ proto resource oci_connect(string user, string pass [, string db])
- Connect to an Oracle database and log on. Returns a new session. */
-PHP_FUNCTION(oci_connect)
-{
- oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
-}
-/* }}} */
-
-/* {{{ proto resource oci_pconnect(string user, string pass [, string db])
- Connect to an Oracle database using a persistent connection and log on. Returns a new session. */
-PHP_FUNCTION(oci_pconnect)
-{
- oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1,0);
-}
-/* }}} */
-
-/* {{{ proto array oci_error([resource stmt|conn|global])
- Return the last error of stmt|conn|global. If no error happened returns false. */
-PHP_FUNCTION(oci_error)
-{
- zval **arg;
- oci_statement *statement;
- oci_connection *connection;
- text errbuf[512];
- sb4 errcode = 0;
- sword error = 0;
- dvoid *errh = NULL;
-#ifdef HAVE_OCI8_ATTR_STATEMENT
- ub2 errorofs = 0;
- text *sqltext = NULL;
-#endif
-
- if (zend_get_parameters_ex(1, &arg) == SUCCESS) {
- statement = (oci_statement *) zend_fetch_resource(arg TSRMLS_CC, -1, NULL, NULL, 1, le_stmt);
- if (statement) {
- errh = statement->pError;
- error = statement->error;
-
-#ifdef HAVE_OCI8_ATTR_STATEMENT
- CALL_OCI_RETURN(statement->error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (text *) &sqltext,
- (ub4 *)0,
- OCI_ATTR_STATEMENT,
- statement->pError
- )
- );
-
- CALL_OCI_RETURN(statement->error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (ub2 *)&errorofs,
- (ub4 *)0,
- OCI_ATTR_PARSE_ERROR_OFFSET,
- statement->pError
- )
- );
-#endif
-
- } else {
- connection = (oci_connection *) zend_fetch_resource(arg TSRMLS_CC, -1, NULL, NULL, 1, le_conn);
- if (connection) {
- errh = connection->pError;
- error = connection->error;
- }
- }
- } else {
- errh = OCI(pError);
- error = OCI(error);
- }
-
- if (!error) { /* no error set in the handle */
- RETURN_FALSE;
- }
-
- if (!errh) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIError: unable to find Error handle");
- RETURN_FALSE;
- }
-
- CALL_OCI(
- OCIErrorGet(
- errh,
- 1,
- NULL,
- &errcode,
- errbuf,
- (ub4) sizeof(errbuf),
- (ub4) OCI_HTYPE_ERROR
- )
- );
-
- if (errcode) {
- array_init(return_value);
- add_assoc_long(return_value, "code", errcode);
- add_assoc_string(return_value, "message", (char*) errbuf, 1);
-#ifdef HAVE_OCI8_ATTR_STATEMENT
- add_assoc_long(return_value, "offset", errorofs);
- add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : "", 1);
-#endif
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto int oci_num_fields(resource stmt)
- Return the number of result columns in a statement */
-PHP_FUNCTION(oci_num_fields)
-{
- zval **stmt;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- RETURN_LONG(statement->ncolumns);
-}
-/* }}} */
-
-/* {{{ proto resource oci_parse(resource conn, string query)
- Parse a query and return a statement */
-PHP_FUNCTION(oci_parse)
-{
- zval **conn, **query;
- oci_connection *connection;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(2, &conn, &query) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- convert_to_string_ex(query);
-
- statement = oci_parse(connection,Z_STRVAL_PP(query),Z_STRLEN_PP(query));
-
- if (statement) {
- RETURN_RESOURCE(statement->id);
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto bool oci_set_prefetch(resource stmt, int prefetch_rows)
- Sets the number of rows to be prefetched on execute to prefetch_rows for stmt */
-PHP_FUNCTION(oci_set_prefetch)
-{
- zval **stmt, **size;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(2, &stmt, &size) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_long_ex(size);
-
- OCI_GET_STMT(statement,stmt);
-
- oci_setprefetch(statement,Z_LVAL_PP(size));
-
- RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_password_change(resource conn, string username, string old_password, string new_password)
- Changes the password of an account */
-PHP_FUNCTION(oci_password_change)
-{
- zval **conn, **user_param, **pass_old_param, **pass_new_param;
- text *user, *pass_old, *pass_new;
- oci_connection *connection;
-
- /* Disable in Safe Mode */
- if (PG(safe_mode)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "is disabled in Safe Mode");
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(4, &conn, &user_param, &pass_old_param, &pass_new_param) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_string_ex(user_param);
- convert_to_string_ex(pass_old_param);
- convert_to_string_ex(pass_new_param);
-
- user = Z_STRVAL_PP(user_param);
- pass_old = Z_STRVAL_PP(pass_old_param);
- pass_new = Z_STRVAL_PP(pass_new_param);
-
- OCI_GET_CONN(connection, conn);
-
- CALL_OCI_RETURN(connection->error,
- OCIPasswordChange(
- connection->pServiceContext,
- connection->pError,
- user,
- strlen(user)+1,
- pass_old,
- strlen(pass_old)+1,
- pass_new,
- strlen(pass_new)+1,
- OCI_DEFAULT
- )
- );
-
- if (connection->error == OCI_SUCCESS) {
- RETURN_TRUE;
- } else {
- oci_error(connection->pError, "OCIPasswordChange", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto resource oci_new_cursor(resource conn)
- Return a new cursor (Statement-Handle) - use this to bind ref-cursors! */
-PHP_FUNCTION(oci_new_cursor)
-{
- zval **conn;
- oci_connection *connection;
- oci_statement *statement;
-
- if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- statement = oci_parse(connection,0,0);
-
- RETURN_RESOURCE(statement->id);
-}
-/* }}} */
-
-/* {{{ proto string oci_result(resource stmt, mixed column)
- Return a single column of result data */
-PHP_FUNCTION(oci_result)
-{
- zval **stmt, **col;
- oci_statement *statement;
- oci_out_column *outcol = NULL;
-
- if (zend_get_parameters_ex(2, &stmt, &col) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- outcol = oci_get_col(statement, -1, col);
-
- if (outcol == NULL) {
- RETURN_FALSE;
- }
-
- _oci_make_zval(return_value,statement,outcol, "OCIResult",0 TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto string oci_server_version(resource conn)
- Return a string containing server version information */
-PHP_FUNCTION(oci_server_version)
-{
- oci_connection *connection;
- zval **conn;
- char version[256];
-
- if (zend_get_parameters_ex(1, &conn) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_CONN(connection,conn);
-
- CALL_OCI_RETURN(connection->error,
- OCIServerVersion(
- connection->pServiceContext,
- connection->pError,
- (text*)version,
- sizeof(version),
- OCI_HTYPE_SVCCTX
- )
- );
-
- if (connection->error != OCI_SUCCESS) {
- oci_error(connection->pError, "OCIServerVersion", connection->error);
- oci_handle_error(connection, connection->error);
- RETURN_FALSE;
- }
-
- RETURN_STRING(version,1);
-}
-/* }}} */
-
-/* {{{ proto string oci_statement_type(resource stmt)
- Return the query type of an OCI statement */
-/* XXX it would be better with a general interface to OCIAttrGet() */
-PHP_FUNCTION(oci_statement_type)
-{
- zval **stmt;
- oci_statement *statement;
- ub2 stmttype;
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- CALL_OCI_RETURN(statement->error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (ub2 *)&stmttype,
- (ub4 *)0,
- OCI_ATTR_STMT_TYPE,
- statement->pError
- )
- );
-
- if (statement->error != OCI_SUCCESS) {
- oci_error(statement->pError, "OCIStatementType", statement->error);
- oci_handle_error(statement->conn, statement->error);
- RETURN_FALSE;
- }
-
- switch (stmttype) {
- case OCI_STMT_SELECT:
- RETVAL_STRING("SELECT",1);
- break;
- case OCI_STMT_UPDATE:
- RETVAL_STRING("UPDATE",1);
- break;
- case OCI_STMT_DELETE:
- RETVAL_STRING("DELETE",1);
- break;
- case OCI_STMT_INSERT:
- RETVAL_STRING("INSERT",1);
- break;
- case OCI_STMT_CREATE:
- RETVAL_STRING("CREATE",1);
- break;
- case OCI_STMT_DROP:
- RETVAL_STRING("DROP",1);
- break;
- case OCI_STMT_ALTER:
- RETVAL_STRING("ALTER",1);
- break;
- case OCI_STMT_BEGIN:
- RETVAL_STRING("BEGIN",1);
- break;
- case OCI_STMT_DECLARE:
- RETVAL_STRING("DECLARE",1);
- break;
- default:
- RETVAL_STRING("UNKNOWN",1);
- }
-}
-/* }}} */
-
-/* {{{ proto int oci_num_rows(resource stmt)
- Return the row count of an OCI statement */
-PHP_FUNCTION(oci_num_rows)
-{
- zval **stmt;
- oci_statement *statement;
- ub4 rowcount;
-
- if (zend_get_parameters_ex(1, &stmt) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- OCI_GET_STMT(statement,stmt);
-
- CALL_OCI_RETURN(statement->error,
- OCIAttrGet(
- (dvoid *)statement->pStmt,
- OCI_HTYPE_STMT,
- (ub2 *)&rowcount,
- (ub4 *)0,
- OCI_ATTR_ROW_COUNT,
- statement->pError
- )
- );
-
- if (statement->error != OCI_SUCCESS) {
- oci_error(statement->pError, "OCIRowCount", statement->error);
- oci_handle_error(statement->conn, statement->error);
- RETURN_FALSE;
- }
-
- RETURN_LONG(rowcount);
-}
-/* }}} */
-
-#ifdef PHP_OCI8_HAVE_COLLECTIONS
-/* {{{ oci_get_coll() */
-static oci_collection *oci_get_coll(int ind TSRMLS_DC)
-{
- oci_collection *collection;
- int actual_resource_type;
-
- collection = (oci_collection *) zend_list_find(ind, &actual_resource_type);
-
- if (collection && (actual_resource_type == le_coll)) {
- return collection;
- } else {
- return (oci_collection *) NULL;
- }
-}
-/* }}} */
-
-/* {{{ proto bool oci_free_collection()
- Deletes collection object*/
-PHP_FUNCTION(oci_free_collection)
-{
- zval *id;
- int inx;
- oci_collection *coll;
- oci_connection *connection;
-
- if ((id = getThis()) != 0) {
- inx = _oci_get_ocicoll(id,&coll TSRMLS_CC);
- if (inx) {
- /*
- * Do we need to free the object?
- *
- */
- connection = coll->conn;
- oci_debug("oci_free_collection: coll=%d",inx);
-
- CALL_OCI_RETURN(connection->error,
- OCIObjectFree(
- connection->session->pEnv,
- connection->pError,
- (dvoid *)coll->coll,
- (ub2)(OCI_OBJECTFREE_FORCE)
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIObjectFree", connection->error);
- RETURN_FALSE;
+ if (OCI_G(ping_interval) >= 0) {
+ connection->next_ping = timestamp + OCI_G(ping_interval);
}
-
- zend_list_delete(inx);
- RETURN_TRUE;
- }
- }
-
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_collection_append(string value)
- Append an object to the collection */
-PHP_FUNCTION(oci_collection_append)
-{
- zval *id, **arg;
- oci_connection *connection;
- oci_collection *coll;
- OCINumber num;
- OCIString *ocistr = (OCIString *)0;
- OCIInd new_ind = OCI_IND_NOTNULL;
- OCIInd null_ind = OCI_IND_NULL;
- OCIDate dt;
- int inx;
- double ndx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- connection = coll->conn;
- if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- /*
- * Handle NULLS. For consistency with the rest of the OCI8 library, when
- * a value passed in is a 0 length string, consider it a null
- */
- convert_to_string_ex(arg);
- if (Z_STRLEN_PP(arg) == 0) {
- CALL_OCI_RETURN(connection->error,
- OCICollAppend(
- connection->session->pEnv,
- connection->pError,
- (dvoid *)0,
- &null_ind,
- coll->coll
- )
- );
- if (connection->error) {
- oci_error(connection->pError, "OCICollAppend - NULL", connection->error);
- RETURN_FALSE;
+ else {
+ /* ping_interval is -1 */
+ connection->next_ping = 0;
}
- RETURN_TRUE;
- }
-
- switch(coll->element_typecode) {
- case OCI_TYPECODE_DATE:
- convert_to_string_ex(arg);
-
- CALL_OCI_RETURN(connection->error,
- OCIDateFromText(
- connection->pError,
- Z_STRVAL_PP(arg),
- Z_STRLEN_PP(arg),
- 0,
- 0,
- 0,
- 0,
- &dt
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIDateFromText", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAppend(
- connection->session->pEnv,
- connection->pError,
- (dvoid *) &dt,
- (dvoid *) &new_ind,
- (OCIColl *) coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAppend", connection->error);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- break;
- case OCI_TYPECODE_VARCHAR2 :
- convert_to_string_ex(arg);
-
- CALL_OCI_RETURN(connection->error,
- OCIStringAssignText(
- connection->session->pEnv,
- connection->pError,
- Z_STRVAL_PP(arg),
- Z_STRLEN_PP(arg),
- &ocistr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIStringAssignText", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAppend(
- connection->session->pEnv,
- connection->pError,
- (dvoid *) ocistr,
- (dvoid *) &new_ind,
- (OCIColl *) coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAppend", connection->error);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- break;
- case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
- case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
- case OCI_TYPECODE_REAL : /* REAL */
- case OCI_TYPECODE_DOUBLE : /* DOUBLE */
- case OCI_TYPECODE_INTEGER : /* INT */
- case OCI_TYPECODE_SIGNED16 : /* SHORT */
- case OCI_TYPECODE_SIGNED32 : /* LONG */
- case OCI_TYPECODE_DECIMAL : /* DECIMAL */
- case OCI_TYPECODE_FLOAT : /* FLOAT */
- case OCI_TYPECODE_NUMBER : /* NUMBER */
- case OCI_TYPECODE_SMALLINT : /* SMALLINT */
- convert_to_double_ex(arg);
- ndx = (double)Z_DVAL_PP(arg);
-
- CALL_OCI_RETURN(connection->error,
- OCINumberFromReal(
- connection->pError,
- &ndx,
- sizeof(double),
- &num
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCINumberFromReal", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAppend(
- connection->session->pEnv,
- connection->pError,
- (dvoid *) &num,
- (dvoid *) &new_ind,
- (OCIColl *) coll->coll
- )
- );
-
- RETURN_TRUE;
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element");
- RETURN_FALSE;
- break;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_append() should not be called like this. Use $collection->append($element) to append an element to the collection");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto string oci_collection_element_get(int ndx)
- Retrieve the value at collection index ndx */
-PHP_FUNCTION(oci_collection_element_get)
-{
- zval *id,**arg;
- oci_connection *connection;
- oci_collection *coll;
- ub4 ndx;
- int inx;
- dvoid *elem;
- OCIInd *elemind;
- boolean exists;
- OCIString *ocistr = (OCIString *)0;
- text *str;
- char buff[1024];
- int len;
- double dnum;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
- if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_long_ex(arg);
- ndx = Z_LVAL_PP(arg);
-
- connection = coll->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCICollGetElem(
- connection->session->pEnv,
- connection->pError,
- coll->coll,
- ndx,
- &exists,
- &elem,
- (dvoid **)&elemind
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollGetElem", connection->error);
- RETURN_NULL();
- }
-
- /* Return false if value does not exist at that location */
- if (exists == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCICollGetElem - Invalid index %d", ndx);
- RETURN_FALSE;
- }
-
- /* Return null if the value is null */
- if (*elemind == OCI_IND_NULL) {
- RETURN_NULL();
- }
-
- switch (coll->element_typecode) {
- case OCI_TYPECODE_DATE:
- len = 1024;
- CALL_OCI(
- OCIDateToText(
- connection->pError,
- elem,
- 0, /* fmt */
- 0, /* fmt_length */
- 0, /* lang_name */
- 0, /* lang_length */
- &len,
- buff
- )
- );
-
- RETURN_STRINGL(buff,len,1);
- case OCI_TYPECODE_VARCHAR2 :
- ocistr = *(OCIString **)elem;
- str = OCIStringPtr(connection->session->pEnv,ocistr); /* XXX not protected against recursion! */
- RETURN_STRINGL(str,strlen(str),1);
- break;
- case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
- case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
- case OCI_TYPECODE_REAL : /* REAL */
- case OCI_TYPECODE_DOUBLE : /* DOUBLE */
- case OCI_TYPECODE_INTEGER : /* INT */
- case OCI_TYPECODE_SIGNED16 : /* SHORT */
- case OCI_TYPECODE_SIGNED32 : /* LONG */
- case OCI_TYPECODE_DECIMAL : /* DECIMAL */
- case OCI_TYPECODE_FLOAT : /* FLOAT */
- case OCI_TYPECODE_NUMBER : /* NUMBER */
- case OCI_TYPECODE_SMALLINT : /* SMALLINT */
- CALL_OCI_RETURN(connection->error,
- OCINumberToReal(
- connection->pError,
- (CONST OCINumber *) elem,
- (uword) sizeof(dnum),
- (dvoid *) &dnum
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCINumberToReal", connection->error);
- RETURN_FALSE;
- }
- RETURN_DOUBLE(dnum);
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element");
- RETURN_FALSE;
- break;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_element_get() should not be called like this. Use $collection->getelem($index) to get an element of the collection with the given index");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_collection_assign(object from)
- Assign a collection from another existing collection */
-PHP_FUNCTION(oci_collection_assign)
-{
- zval *id,**from;
- oci_connection *connection;
- oci_collection *coll,*from_coll;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(1, &from) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- if ((inx = _oci_get_ocicoll(*from,&from_coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- connection = coll->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCICollAssign(
- connection->session->pEnv,
- connection->pError,
- from_coll->coll,
- coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem", connection->error);
- RETURN_FALSE;
+ connection->used_this_request = 0;
}
- RETURN_TRUE;
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_assign() should not be called like this. Use $collection->assign($collection_value) to assign value to the collection");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_collection_element_assign(int index, string val)
- Assign element val to collection at index ndx */
-PHP_FUNCTION(oci_collection_element_assign)
-{
- zval *id,**index,**val;
- oci_connection *connection;
- oci_collection *coll;
- OCINumber num;
- OCIInd new_ind = OCI_IND_NOTNULL;
- OCIInd null_ind = OCI_IND_NULL;
- ub4 ndx;
- int inx;
- OCIString *ocistr = (OCIString *)0;
- OCIDate dt;
- double dnum;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
-
- if (zend_get_parameters_ex(2, &index,&val) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_long_ex(index);
- ndx = Z_LVAL_PP(index);
-
- connection = coll->conn;
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem", connection->error);
- RETURN_FALSE;
- }
-
- /*
- * Handle NULLs. For consistency with the rest of the OCI8 library, when
- * a value passed in is a 0 length string, consider it a null
- */
- convert_to_string_ex(val);
-
- if (Z_STRLEN_PP(val) == 0) {
- CALL_OCI_RETURN(connection->error,
- OCICollAssignElem(
- connection->session->pEnv,
- connection->pError,
- ndx,
- (dvoid *)0,
- &null_ind,
- coll->coll
- )
- );
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem - NULL", connection->error);
- RETURN_FALSE;
+ else if (OCI_G(persistent_timeout) != -1) {
+ if (connection->idle_expiry < timestamp) {
+ /* connection has timed out */
+ return 1;
}
-
- RETURN_TRUE;
- }
-
- switch (coll->element_typecode) {
- case OCI_TYPECODE_DATE:
- convert_to_string_ex(val);
- CALL_OCI_RETURN(connection->error,
- OCIDateFromText(
- connection->pError,
- Z_STRVAL_PP(val),
- Z_STRLEN_PP(val),
- 0,
- 0,
- 0,
- 0,
- &dt
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIDateFromText", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAssignElem(
- connection->session->pEnv,
- connection->pError,
- ndx,
- (dvoid *)&dt,
- &new_ind,
- coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem", connection->error);
- RETURN_FALSE;
- }
- break;
- case OCI_TYPECODE_VARCHAR2 :
- convert_to_string_ex(val);
-
- CALL_OCI_RETURN(connection->error,
- OCIStringAssignText(
- connection->session->pEnv,
- connection->pError,
- Z_STRVAL_PP(val),
- Z_STRLEN_PP(val),
- &ocistr
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIStringAssignText", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAssignElem(
- connection->session->pEnv,
- connection->pError,
- ndx,
- (dvoid *)ocistr,
- &new_ind,
- coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem", connection->error);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- break;
- case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
- case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
- case OCI_TYPECODE_REAL : /* REAL */
- case OCI_TYPECODE_DOUBLE : /* DOUBLE */
- case OCI_TYPECODE_INTEGER : /* INT */
- case OCI_TYPECODE_SIGNED16 : /* SHORT */
- case OCI_TYPECODE_SIGNED32 : /* LONG */
- case OCI_TYPECODE_DECIMAL : /* DECIMAL */
- case OCI_TYPECODE_FLOAT : /* FLOAT */
- case OCI_TYPECODE_NUMBER : /* NUMBER */
- case OCI_TYPECODE_SMALLINT : /* SMALLINT */
- convert_to_double_ex(val);
- dnum = (double)Z_DVAL_PP(val);
-
- CALL_OCI_RETURN(connection->error,
- OCINumberFromReal(
- connection->pError,
- &dnum,
- sizeof(double),
- &num
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCINumberFromReal", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCICollAssignElem(
- connection->session->pEnv,
- connection->pError,
- ndx,
- (dvoid *)&num,
- &new_ind,
- coll->coll
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollAssignElem", connection->error);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- break;
- }
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_element_assign() should not be called like this. Use $collection->assignelem($index, $value) to assign value to an element of the collection");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_collection_size()
- Return the size of a collection */
-PHP_FUNCTION(oci_collection_size)
-{
- zval *id;
- oci_connection *connection;
- oci_collection *coll;
- sb4 sz;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
}
- connection = coll->conn;
-
- CALL_OCI_RETURN(connection->error,
- OCICollSize(
- connection->session->pEnv,
- coll->conn->pError,
- coll->coll,
- &sz
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCICollSize", connection->error);
- RETURN_FALSE;
- }
-
- RETURN_LONG(sz);
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_size() should not be called like this. Use $collection->size() to get size of the collection");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto int oci_collection_max()
- Return the max value of a collection. For a varray this is the maximum length of the array */
-PHP_FUNCTION(oci_collection_max)
-{
- zval *id;
- oci_collection *coll;
- sb4 sz;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
- sz = OCICollMax(OCI(pEnv),coll->coll); /* XXX not protected against recursion */
-
- RETURN_LONG(sz);
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_max() should not be called like this. Use $collection->max() to get maximum number of elements in the collection");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool oci_collection_trim(int num)
- Trim num elements from the end of a collection */
-PHP_FUNCTION(oci_collection_trim)
-{
- zval *id,**arg;
- oci_collection *coll;
- int inx;
-
- if ((id = getThis()) != 0) {
- if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
- RETURN_FALSE;
- }
- if (zend_get_parameters_ex(1, &arg) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- convert_to_long_ex(arg);
-
- CALL_OCI_RETURN(coll->conn->error,
- OCICollTrim(
- OCI(pEnv),
- coll->conn->pError,
- Z_LVAL_PP(arg),
- coll->coll
- )
- );
-
- if (coll->conn->error) {
- oci_error(coll->conn->pError, "OCICollTrim", coll->conn->error);
- RETURN_FALSE;
- }
- RETURN_TRUE;
- }
-
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "oci_collection_trim() should not be called like this. Use $collection->trim($length) to trim collection to the given length");
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto object oci_new_collection(resource connection, string tdo [, string schema])
- Initialize a new collection */
-PHP_FUNCTION(oci_new_collection)
-{
- dvoid *dschp1;
- dvoid *parmp1;
- dvoid *parmp2;
- zval **conn, **tdo, **schema;
- oci_connection *connection;
- oci_collection *coll;
- int ac = ZEND_NUM_ARGS();
-
- if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &conn, &tdo, &schema) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_string_ex(tdo);
-
- if (ac == 3) {
- convert_to_string_ex(schema);
}
-
- coll = emalloc(sizeof(oci_collection));
-
- OCI_GET_CONN(connection,conn);
-
- coll->conn = connection;
- coll->id = zend_list_insert(coll,le_coll);
- zend_list_addref(connection->id);
-
- CALL_OCI_RETURN(connection->error,
- OCITypeByName(
- connection->session->pEnv,
- connection->pError,
- connection->pServiceContext,
- ac == 3 ? (text *) Z_STRVAL_PP(schema) : (text *) 0,
- ac == 3 ? (ub4) Z_STRLEN_PP(schema) : (ub4) 0,
- (text *) Z_STRVAL_PP(tdo),
- (ub4) Z_STRLEN_PP(tdo),
- (CONST text *) 0,
- (ub4) 0,
- OCI_DURATION_SESSION,
- OCI_TYPEGET_ALL,
- &(coll->tdo)
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCITypeByName", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCIHandleAlloc(
- connection->session->pEnv,
- (dvoid **) &dschp1,
- (ub4) OCI_HTYPE_DESCRIBE,
- (size_t) 0,
- (dvoid **) 0
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_HTYPE_DESCRIBE", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCIDescribeAny(
- connection->pServiceContext,
- connection->pError,
- (dvoid *) coll->tdo,
- (ub4) 0,
- OCI_OTYPE_PTR,
- (ub1)1,
- (ub1) OCI_PTYPE_TYPE,
- dschp1
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_OTYPE_PTR", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCIAttrGet(
- (dvoid *) dschp1,
- (ub4) OCI_HTYPE_DESCRIBE,
- (dvoid *)&parmp1,
- (ub4 *)0,
- (ub4)OCI_ATTR_PARAM,
- connection->pError
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_ATTR_PARAM", connection->error);
- RETURN_FALSE;
- }
-
- /* get the collection type code of the attribute */
-
- CALL_OCI_RETURN(connection->error,
- OCIAttrGet(
- (dvoid*) parmp1,
- (ub4) OCI_DTYPE_PARAM,
- (dvoid*) &(coll->coll_typecode),
- (ub4 *) 0,
- (ub4) OCI_ATTR_COLLECTION_TYPECODE,
- connection->pError
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_ATTR_COLLECTION_TYPECODE", connection->error);
- RETURN_FALSE;
- }
-
- switch(coll->coll_typecode) {
- case OCI_TYPECODE_TABLE:
- case OCI_TYPECODE_VARRAY:
- CALL_OCI_RETURN(connection->error,
- OCIAttrGet(
- (dvoid*) parmp1,
- (ub4) OCI_DTYPE_PARAM,
- (dvoid*) &parmp2,
- (ub4 *) 0,
- (ub4) OCI_ATTR_COLLECTION_ELEMENT,
- connection->pError
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_ATTR_COLLECTION_ELEMENT", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCIAttrGet(
- (dvoid*) parmp2,
- (ub4) OCI_DTYPE_PARAM,
- (dvoid*) &(coll->elem_ref),
- (ub4 *) 0,
- (ub4) OCI_ATTR_REF_TDO,
- connection->pError
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_ATTR_REF_TDO", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCITypeByRef(
- connection->session->pEnv,
- connection->pError,
- coll->elem_ref,
- OCI_DURATION_SESSION,
- OCI_TYPEGET_HEADER,
- &(coll->element_type)
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_TYPEGET_HEADER", connection->error);
- RETURN_FALSE;
- }
-
- CALL_OCI_RETURN(connection->error,
- OCIAttrGet(
- (dvoid*) parmp2,
- (ub4) OCI_DTYPE_PARAM,
- (dvoid*) &(coll->element_typecode),
- (ub4 *) 0,
- (ub4) OCI_ATTR_TYPECODE,
- connection->pError
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCI_ATTR_TYPECODE", connection->error);
- RETURN_FALSE;
- }
- break;
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCINewCollection - Unknown Type %d", coll->coll_typecode);
- break;
- }
-
- /* Create object to hold return table */
- CALL_OCI_RETURN(connection->error,
- OCIObjectNew(
- connection->session->pEnv,
- connection->pError,
- connection->pServiceContext,
- OCI_TYPECODE_TABLE,
- coll->tdo,
- (dvoid *)0,
- OCI_DURATION_DEFAULT,
- TRUE,
- (dvoid **) &(coll->coll)
- )
- );
-
- if (connection->error) {
- oci_error(connection->pError, "OCIObjectNew", connection->error);
- RETURN_FALSE;
- }
-
- object_init_ex(return_value, oci_coll_class_entry_ptr);
- add_property_resource(return_value, "collection",coll->id);
-}
-/* }}} */
-#endif
+ return 0;
+} /* }}} */
#endif /* HAVE_OCI8 */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/ext/oci8/oci8.dsp b/ext/oci8/oci8.dsp
index 73c05346e3..f0b27fa824 100644
--- a/ext/oci8/oci8.dsp
+++ b/ext/oci8/oci8.dsp
@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D ZTS=1 /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\oci805\include" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OCI8=1 /D HAVE_OCI8_TEMP_LOB=1 /D HAVE_OCI8_ATTR_STATEMENT=1 /D COMPILE_DL_OCI8=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\include\instantclient" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OCI8=1 /D HAVE_OCI8_TEMP_LOB=1 /D HAVE_OCI8_ATTR_STATEMENT=1 /D COMPILE_DL_OCI8=1 /D PHP_OCI8_HAVE_COLLECTIONS=1 /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x406 /d "NDEBUG"
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
-# ADD LINK32 php5ts.lib oci.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_oci8.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\..\php_build\oci805\lib" /libpath:"..\..\Release_TS_Inline"
+# ADD LINK32 php4ts.lib oci.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_oci8.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\..\php_build\lib\instantclient" /libpath:"..\..\Release_TS_Inline"
!ELSEIF "$(CFG)" == "oci8 - Win32 Debug_TS"
@@ -71,7 +71,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D ZTS=1 /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\include\oci805" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FTP_EXPORTS" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OCI8=1 /D HAVE_OCI8_TEMP_LOB=1 /D HAVE_OCI8_ATTR_STATEMENT=1 /D COMPILE_DL_OCI8=1 /FR /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\..\\" /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "..\..\..\php_build\include\instantclient" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FTP_EXPORTS" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OCI8=1 /D HAVE_OCI8_TEMP_LOB=1 /D HAVE_OCI8_ATTR_STATEMENT=1 /D COMPILE_DL_OCI8=1 /D PHP_OCI8_HAVE_COLLECTIONS=1 /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x406 /d "NDEBUG"
@@ -81,7 +81,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
-# ADD LINK32 php5ts_debug.lib oci.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/php_oci8.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\lib\oci805"
+# ADD LINK32 php4ts_debug.lib oci.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/php_oci8.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\lib\instantclient"
!ENDIF
@@ -96,6 +96,22 @@ LINK32=link.exe
SOURCE=.\oci8.c
# End Source File
+# Begin Source File
+
+SOURCE=.\oci8_collection.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\oci8_interface.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\oci8_lob.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\oci8_statement.c
+# End Source File
# End Group
# Begin Group "Header Files"
@@ -104,6 +120,10 @@ SOURCE=.\oci8.c
SOURCE=.\php_oci8.h
# End Source File
+# Begin Source File
+
+SOURCE=.\php_oci8_int.h
+# End Source File
# End Group
# Begin Group "Resource Files"
diff --git a/ext/oci8/oci8_collection.c b/ext/oci8/oci8_collection.c
new file mode 100644
index 0000000000..c17712ae3a
--- /dev/null
+++ b/ext/oci8/oci8_collection.c
@@ -0,0 +1,611 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@php.net> |
+ | Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "ext/standard/info.h"
+#include "php_ini.h"
+
+#if HAVE_OCI8
+
+#include "php_oci8.h"
+#include "php_oci8_int.h"
+
+/* {{{ php_oci_collection_create()
+ Create and return connection handle */
+php_oci_collection * php_oci_collection_create(php_oci_connection* connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC)
+{
+ dvoid *dschp1;
+ dvoid *parmp1;
+ dvoid *parmp2;
+ php_oci_collection *collection;
+
+ collection = emalloc(sizeof(php_oci_collection));
+
+ collection->connection = connection;
+ collection->collection = NULL;
+
+ /* get type handle by name */
+ connection->errcode = PHP_OCI_CALL(OCITypeByName, (connection->env, connection->err, connection->svc, (text *) schema, (ub4) schema_len, (text *) tdo, (ub4) tdo_len, (CONST text *) 0, (ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_ALL, &(collection->tdo)));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* allocate describe handle */
+ connection->errcode = PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* describe TDO */
+ connection->errcode = PHP_OCI_CALL(OCIDescribeAny, (connection->svc, connection->err, (dvoid *) collection->tdo, (ub4) 0, OCI_OTYPE_PTR, (ub1) OCI_DEFAULT, (ub1) OCI_PTYPE_TYPE, dschp1));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* get first parameter handle */
+ connection->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *) dschp1, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM, connection->err));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* get the collection type code of the attribute */
+ connection->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->coll_typecode), (ub4 *) 0, (ub4) OCI_ATTR_COLLECTION_TYPECODE, connection->err));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ switch(collection->coll_typecode) {
+ case OCI_TYPECODE_TABLE:
+ case OCI_TYPECODE_VARRAY:
+ /* get collection element handle */
+ connection->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, (dvoid*) &parmp2, (ub4 *) 0, (ub4) OCI_ATTR_COLLECTION_ELEMENT, connection->err));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* get REF of the TDO for the type */
+ connection->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->elem_ref), (ub4 *) 0, (ub4) OCI_ATTR_REF_TDO, connection->err));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* get the TDO (only header) */
+ connection->errcode = PHP_OCI_CALL(OCITypeByRef, (connection->env, connection->err, collection->elem_ref, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, &(collection->element_type)));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ /* get typecode */
+ connection->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, (dvoid*) &(collection->element_typecode), (ub4 *) 0, (ub4) OCI_ATTR_TYPECODE, connection->err));
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+ break;
+ /* we only support VARRAYs and TABLEs */
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCINewCollection - Unknown Type %d", collection->coll_typecode);
+ break;
+ }
+
+ /* Create object to hold return table */
+ connection->errcode = PHP_OCI_CALL(OCIObjectNew,
+ (
+ connection->env,
+ connection->err,
+ connection->svc,
+ OCI_TYPECODE_TABLE,
+ collection->tdo,
+ (dvoid *)0,
+ OCI_DURATION_DEFAULT,
+ TRUE,
+ (dvoid **) &(collection->collection)
+ )
+ );
+
+ if (connection->errcode) {
+ goto CLEANUP;
+ }
+
+ PHP_OCI_REGISTER_RESOURCE(collection, le_collection);
+ return collection;
+
+CLEANUP:
+
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ php_oci_collection_close(collection TSRMLS_CC);
+ return NULL;
+} /* }}} */
+
+/* {{{ php_oci_collection_size()
+ Return size of the collection */
+int php_oci_collection_size(php_oci_collection *collection, sb4 *size TSRMLS_DC)
+{
+ php_oci_connection *connection = collection->connection;
+
+ connection->errcode = PHP_OCI_CALL(OCICollSize, (connection->env, connection->err, collection->collection, (sb4 *)size));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_max()
+ Return max number of elements in the collection */
+int php_oci_collection_max(php_oci_collection *collection, long *max TSRMLS_DC)
+{
+ php_oci_connection *connection = collection->connection;
+
+ *max = PHP_OCI_CALL(OCICollMax, (connection->env, collection->collection));
+
+ /* error handling is not necessary here? */
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_trim()
+ Trim collection to the given number of elements */
+int php_oci_collection_trim(php_oci_collection *collection, long trim_size TSRMLS_DC)
+{
+ php_oci_connection *connection = collection->connection;
+
+ connection->errcode = PHP_OCI_CALL(OCICollTrim, (connection->env, connection->err, trim_size, collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_append_null()
+ Append NULL element to the end of the collection */
+int php_oci_collection_append_null(php_oci_collection *collection TSRMLS_DC)
+{
+ OCIInd null_index = OCI_IND_NULL;
+ php_oci_connection *connection = collection->connection;
+
+ /* append NULL element */
+ connection->errcode = PHP_OCI_CALL(OCICollAppend, (connection->env, connection->err, (dvoid *)0, &null_index, collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_append_date()
+ Append DATE element to the end of the collection (use "DD-MON-YY" format) */
+int php_oci_collection_append_date(php_oci_collection *collection, char *date, int date_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ OCIDate oci_date;
+ php_oci_connection *connection = collection->connection;
+
+ /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */
+ connection->errcode = PHP_OCI_CALL(OCIDateFromText, (connection->err, date, date_len, NULL, 0, NULL, 0, &oci_date));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ /* failed to convert string to date */
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAppend, (connection->env, connection->err, (dvoid *) &oci_date, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_append_number()
+ Append NUMBER to the end of the collection */
+int php_oci_collection_append_number(php_oci_collection *collection, char *number, int number_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ double element_double;
+ OCINumber oci_number;
+ php_oci_connection *connection = collection->connection;
+
+ element_double = zend_strtod(number, NULL);
+
+ connection->errcode = PHP_OCI_CALL(OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAppend, (connection->env, connection->err, (dvoid *) &oci_number, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_append_string()
+ Append STRING to the end of the collection */
+int php_oci_collection_append_string(php_oci_collection *collection, char *element, int element_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ OCIString *ocistr = (OCIString *)0;
+ php_oci_connection *connection = collection->connection;
+
+ connection->errcode = PHP_OCI_CALL(OCIStringAssignText, (connection->env, connection->err, element, element_len, &ocistr));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAppend, (connection->env, connection->err, (dvoid *) ocistr, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_append()
+ Append wrapper. Appends any supported element to the end of the collection */
+int php_oci_collection_append(php_oci_collection *collection, char *element, int element_len TSRMLS_DC)
+{
+ if (element_len == 0) {
+ return php_oci_collection_append_null(collection TSRMLS_CC);
+ }
+
+ switch(collection->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ return php_oci_collection_append_date(collection, element, element_len TSRMLS_CC);
+ break;
+
+ case OCI_TYPECODE_VARCHAR2 :
+ return php_oci_collection_append_string(collection, element, element_len TSRMLS_CC);
+ break;
+
+ case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
+ case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
+ case OCI_TYPECODE_REAL : /* REAL */
+ case OCI_TYPECODE_DOUBLE : /* DOUBLE */
+ case OCI_TYPECODE_INTEGER : /* INT */
+ case OCI_TYPECODE_SIGNED16 : /* SHORT */
+ case OCI_TYPECODE_SIGNED32 : /* LONG */
+ case OCI_TYPECODE_DECIMAL : /* DECIMAL */
+ case OCI_TYPECODE_FLOAT : /* FLOAT */
+ case OCI_TYPECODE_NUMBER : /* NUMBER */
+ case OCI_TYPECODE_SMALLINT : /* SMALLINT */
+ return php_oci_collection_append_number(collection, element, element_len TSRMLS_CC);
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
+ return 1;
+ break;
+ }
+ /* never reached */
+ return 1;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_get()
+ Get the element with the given index */
+int php_oci_collection_element_get(php_oci_collection *collection, long index, zval **result_element TSRMLS_DC)
+{
+ php_oci_connection *connection = collection->connection;
+ dvoid *element;
+ OCIInd *element_index;
+ boolean exists;
+ char buff[1024];
+ int buff_len = 1024;
+
+ MAKE_STD_ZVAL(*result_element);
+ ZVAL_NULL(*result_element);
+
+ connection->errcode = PHP_OCI_CALL(OCICollGetElem, (connection->env, connection->err, collection->collection, (ub4)index, &exists, &element, (dvoid **)&element_index));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ FREE_ZVAL(*result_element);
+ return 1;
+ }
+
+ if (exists == 0) {
+ /* element doesn't exist */
+ FREE_ZVAL(*result_element);
+ return 1;
+ }
+
+ if (*element_index == OCI_IND_NULL) {
+ /* this is not an error, we're returning NULL here */
+ return 0;
+ }
+
+ switch (collection->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ connection->errcode = PHP_OCI_CALL(OCIDateToText, (connection->err, element, 0, 0, 0, 0, &buff_len, buff));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ FREE_ZVAL(*result_element);
+ return 1;
+ }
+
+ ZVAL_STRINGL(*result_element, buff, buff_len, 1);
+ Z_STRVAL_P(*result_element)[buff_len] = '\0';
+
+ return 0;
+ break;
+
+ case OCI_TYPECODE_VARCHAR2:
+ {
+ OCIString *oci_string = *(OCIString **)element;
+ text *str;
+
+ str = (text *)PHP_OCI_CALL(OCIStringPtr, (connection->env, oci_string));
+
+ if (str) {
+ ZVAL_STRING(*result_element, str, 1);
+ }
+ return 0;
+ }
+ break;
+
+ case OCI_TYPECODE_UNSIGNED16: /* UNSIGNED SHORT */
+ case OCI_TYPECODE_UNSIGNED32: /* UNSIGNED LONG */
+ case OCI_TYPECODE_REAL: /* REAL */
+ case OCI_TYPECODE_DOUBLE: /* DOUBLE */
+ case OCI_TYPECODE_INTEGER: /* INT */
+ case OCI_TYPECODE_SIGNED16: /* SHORT */
+ case OCI_TYPECODE_SIGNED32: /* LONG */
+ case OCI_TYPECODE_DECIMAL: /* DECIMAL */
+ case OCI_TYPECODE_FLOAT: /* FLOAT */
+ case OCI_TYPECODE_NUMBER: /* NUMBER */
+ case OCI_TYPECODE_SMALLINT: /* SMALLINT */
+ {
+ double double_number;
+
+ connection->errcode = PHP_OCI_CALL(OCINumberToReal, (connection->err, (CONST OCINumber *) element, (uword) sizeof(double), (dvoid *) &double_number));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ FREE_ZVAL(*result_element);
+ return 1;
+ }
+
+ ZVAL_DOUBLE(*result_element, double_number);
+
+ return 0;
+ }
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
+ FREE_ZVAL(*result_element);
+ return 1;
+ break;
+ }
+ /* never reached */
+ return 1;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_set_null()
+ Set the element with the given index to NULL */
+int php_oci_collection_element_set_null(php_oci_collection *collection, long index TSRMLS_DC)
+{
+ OCIInd null_index = OCI_IND_NULL;
+ php_oci_connection *connection = collection->connection;
+
+ /* set NULL element */
+ connection->errcode = PHP_OCI_CALL(OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *)"", &null_index, collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_set_date()
+ Change element's value to the given DATE */
+int php_oci_collection_element_set_date(php_oci_collection *collection, long index, char *date, int date_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ OCIDate oci_date;
+ php_oci_connection *connection = collection->connection;
+
+ /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */
+ connection->errcode = PHP_OCI_CALL(OCIDateFromText, (connection->err, date, date_len, NULL, 0, NULL, 0, &oci_date));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ /* failed to convert string to date */
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAssignElem, (connection->env, connection->err, (ub4)index, (dvoid *) &oci_date, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_set_number()
+ Change element's value to the given NUMBER */
+int php_oci_collection_element_set_number(php_oci_collection *collection, long index, char *number, int number_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ double element_double;
+ OCINumber oci_number;
+ php_oci_connection *connection = collection->connection;
+
+ element_double = zend_strtod(number, NULL);
+
+ connection->errcode = PHP_OCI_CALL(OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *) &oci_number, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_set_string()
+ Change element's value to the given string */
+int php_oci_collection_element_set_string(php_oci_collection *collection, long index, char *element, int element_len TSRMLS_DC)
+{
+ OCIInd new_index = OCI_IND_NOTNULL;
+ OCIString *ocistr = (OCIString *)0;
+ php_oci_connection *connection = collection->connection;
+
+ connection->errcode = PHP_OCI_CALL(OCIStringAssignText, (connection->env, connection->err, element, element_len, &ocistr));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCICollAssignElem, (connection->env, connection->err, (ub4)index, (dvoid *) ocistr, (dvoid *) &new_index, (OCIColl *) collection->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_element_set()
+ Collection element setter */
+int php_oci_collection_element_set(php_oci_collection *collection, long index, char *value, int value_len TSRMLS_DC)
+{
+ if (value_len == 0) {
+ return php_oci_collection_element_set_null(collection, index TSRMLS_CC);
+ }
+
+ switch(collection->element_typecode) {
+ case OCI_TYPECODE_DATE:
+ return php_oci_collection_element_set_date(collection, index, value, value_len TSRMLS_CC);
+ break;
+
+ case OCI_TYPECODE_VARCHAR2 :
+ return php_oci_collection_element_set_string(collection, index, value, value_len TSRMLS_CC);
+ break;
+
+ case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
+ case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
+ case OCI_TYPECODE_REAL : /* REAL */
+ case OCI_TYPECODE_DOUBLE : /* DOUBLE */
+ case OCI_TYPECODE_INTEGER : /* INT */
+ case OCI_TYPECODE_SIGNED16 : /* SHORT */
+ case OCI_TYPECODE_SIGNED32 : /* LONG */
+ case OCI_TYPECODE_DECIMAL : /* DECIMAL */
+ case OCI_TYPECODE_FLOAT : /* FLOAT */
+ case OCI_TYPECODE_NUMBER : /* NUMBER */
+ case OCI_TYPECODE_SMALLINT : /* SMALLINT */
+ return php_oci_collection_element_set_number(collection, index, value, value_len TSRMLS_CC);
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
+ return 1;
+ break;
+ }
+ /* never reached */
+ return 1;
+} /* }}} */
+
+/* {{{ php_oci_collection_assign()
+ Assigns a value to the collection from another collection */
+int php_oci_collection_assign(php_oci_collection *collection_dest, php_oci_collection *collection_from TSRMLS_DC)
+{
+ php_oci_connection *connection = collection_dest->connection;
+
+ connection->errcode = PHP_OCI_CALL(OCICollAssign, (connection->env, connection->err, collection_from->collection, collection_dest->collection));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_collection_close()
+ Destroy collection and all associated resources */
+void php_oci_collection_close(php_oci_collection *collection TSRMLS_DC)
+{
+ php_oci_connection *connection = collection->connection;
+
+ if (collection->collection) {
+ connection->errcode = PHP_OCI_CALL(OCIObjectFree, (connection->env, connection->err, (dvoid *)collection->collection, (ub2)OCI_OBJECTFREE_FORCE));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ }
+ }
+
+ zend_list_delete(collection->connection->rsrc_id);
+
+ efree(collection);
+ return;
+} /* }}} */
+
+#endif /* HAVE_OCI8 */
diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c
new file mode 100644
index 0000000000..1c460877cf
--- /dev/null
+++ b/ext/oci8/oci8_interface.c
@@ -0,0 +1,2125 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@php.net> |
+ | Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "ext/standard/info.h"
+#include "php_ini.h"
+
+#if HAVE_OCI8
+
+#include "php_oci8.h"
+#include "php_oci8_int.h"
+
+/* {{{ proto bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])
+ Define a PHP variable to an Oracle column by name */
+/* if you want to define a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE defining!!! */
+PHP_FUNCTION(oci_define_by_name)
+{
+ zval *stmt, *var;
+ char *name;
+ int name_len;
+ long type = SQLT_CHR;
+ php_oci_statement *statement;
+ php_oci_define *define, *tmp_define;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/|l", &stmt, &name, &name_len, &var, &type) == FAILURE) {
+ return;
+ }
+
+ if (!name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Column name cannot be empty");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(stmt, statement);
+
+ if (statement->defines == NULL) {
+ ALLOC_HASHTABLE(statement->defines);
+ zend_hash_init(statement->defines, 13, NULL, php_oci_define_hash_dtor, 0);
+ }
+
+ define = ecalloc(1,sizeof(php_oci_define));
+
+ if (zend_hash_add(statement->defines, name, name_len, define, sizeof(php_oci_define), (void **)&tmp_define) == SUCCESS) {
+ efree(define);
+ define = tmp_define;
+ } else {
+ efree(define);
+ RETURN_FALSE;
+ }
+
+ define->name = (text*) estrndup(name, name_len);
+ define->name_len = name_len;
+ define->type = type;
+ define->zval = var;
+ zval_add_ref(&var);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_bind_by_name(resource stmt, string name, mixed &var, [, int maxlength [, int type]])
+ Bind a PHP variable to an Oracle placeholder by name */
+/* if you want to bind a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE binding!!! */
+PHP_FUNCTION(oci_bind_by_name)
+{
+ ub2 bind_type = SQLT_CHR; /* unterminated string */
+ int name_len;
+ long maxlen = -1, type = 0;
+ char *name;
+ zval *z_statement;
+ zval *bind_var = NULL;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/|ll", &z_statement, &name, &name_len, &bind_var, &maxlen, &type) == FAILURE) {
+ return;
+ }
+
+ if (type) {
+ bind_type = (ub2) type;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_bind_by_name(statement, name, name_len, bind_var, maxlen, bind_type TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_bind_array_by_name(resource stmt, string name, array &var, int max_table_length [, int max_item_length [, int type ]])
+ Bind a PHP array to an Oracle PL/SQL type by name */
+PHP_FUNCTION(oci_bind_array_by_name)
+{
+ int name_len;
+ long max_item_len = -1;
+ long max_array_len = 0;
+ long type = SQLT_AFC;
+ char *name;
+ zval *z_statement;
+ zval *bind_var = NULL;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/l|ll", &z_statement, &name, &name_len, &bind_var, &max_array_len, &max_item_len, &type) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (ZEND_NUM_ARGS() == 5 && max_item_len <= 0) {
+ max_item_len = -1;
+ }
+
+ if (max_array_len <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum array length must be greater than zero");
+ RETURN_FALSE;
+ }
+
+ if (php_oci_bind_array_by_name(statement, name, name_len, bind_var, max_array_len, max_item_len, type TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_free_descriptor()
+ Deletes large object description */
+PHP_FUNCTION(oci_free_descriptor)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ zend_list_delete(descriptor->id);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_save( string data [, int offset ])
+ Saves a large object */
+PHP_FUNCTION(oci_lob_save)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ char *data;
+ int data_len;
+ long offset = 0;
+ ub4 bytes_written;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &offset) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &offset) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (offset < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset parameter must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+
+ if (php_oci_lob_write(descriptor, offset, data, data_len, &bytes_written TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_import( string filename )
+ Loads file into a LOB */
+PHP_FUNCTION(oci_lob_import)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ char *filename;
+ int filename_len;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_import(descriptor, filename TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string oci_lob_load()
+ Loads a large object */
+PHP_FUNCTION(oci_lob_load)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ char *buffer = NULL;
+ ub4 buffer_len;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_read(descriptor, -1, 0, &buffer, &buffer_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ if (buffer_len > 0) {
+ RETURN_STRINGL(buffer, buffer_len, 0);
+ }
+ else {
+ RETURN_EMPTY_STRING();
+ }
+}
+/* }}} */
+
+/* {{{ proto string oci_lob_read( int length )
+ Reads particular part of a large object */
+PHP_FUNCTION(oci_lob_read)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ long length;
+ char *buffer;
+ ub4 buffer_len;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_descriptor, oci_lob_class_entry_ptr, &length) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (length <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
+ RETURN_FALSE;
+ }
+
+ if (php_oci_lob_read(descriptor, length, descriptor->lob_current_position, &buffer, &buffer_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ if (buffer_len > 0) {
+ RETURN_STRINGL(buffer, buffer_len, 0);
+ }
+ else {
+ RETURN_EMPTY_STRING();
+ }
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_eof()
+ Checks if EOF is reached */
+PHP_FUNCTION(oci_lob_eof)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ ub4 lob_length;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (!php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC) && lob_length >= 0) {
+ if (lob_length == descriptor->lob_current_position) {
+ RETURN_TRUE;
+ }
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int oci_lob_tell()
+ Tells LOB pointer position */
+PHP_FUNCTION(oci_lob_tell)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ RETURN_LONG(descriptor->lob_current_position);
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_rewind()
+ Rewind pointer of a LOB */
+PHP_FUNCTION(oci_lob_rewind)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ descriptor->lob_current_position = 0;
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_seek( int offset [, int whence ])
+ Moves the pointer of a LOB */
+PHP_FUNCTION(oci_lob_seek)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ long offset, whence = PHP_OCI_SEEK_SET;
+ ub4 lob_length;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &offset, &whence) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|l", &z_descriptor, oci_lob_class_entry_ptr, &offset, &whence) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ switch(whence) {
+ case PHP_OCI_SEEK_CUR:
+ descriptor->lob_current_position += offset;
+ break;
+ case PHP_OCI_SEEK_END:
+ if (descriptor->lob_size + offset >= 0) {
+ descriptor->lob_current_position = descriptor->lob_size + offset;
+ }
+ else {
+ descriptor->lob_current_position = 0;
+ }
+ break;
+ case PHP_OCI_SEEK_SET:
+ default:
+ descriptor->lob_current_position = (offset > 0) ? offset : 0;
+ break;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int oci_lob_size()
+ Returns size of a large object */
+PHP_FUNCTION(oci_lob_size)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ ub4 lob_length;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(lob_length);
+}
+/* }}} */
+
+/* {{{ proto int oci_lob_write( string string [, int length ])
+ Writes data to current position of a LOB */
+PHP_FUNCTION(oci_lob_write)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ int data_len;
+ long write_len = 0;
+ ub4 bytes_written;
+ char *data;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &write_len) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() == 2) {
+ data_len = MIN(data_len, write_len);
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &write_len) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() == 3) {
+ data_len = MIN(data_len, write_len);
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (data_len <= 0) {
+ RETURN_LONG(0);
+ }
+
+ if (php_oci_lob_write(descriptor, descriptor->lob_current_position, data, data_len, &bytes_written TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes_written);
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_append( object lob )
+ Appends data from a LOB to another LOB */
+PHP_FUNCTION(oci_lob_append)
+{
+ zval **tmp_dest, **tmp_from, *z_descriptor_dest = getThis(), *z_descriptor_from;
+ php_oci_descriptor *descriptor_dest, *descriptor_from;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor_from, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor"), (void **)&tmp_dest) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor"), (void **)&tmp_from) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_dest, descriptor_dest);
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_from, descriptor_from);
+
+ if (php_oci_lob_append(descriptor_dest, descriptor_from TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ /* XXX should we increase lob_size here ? */
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_truncate( [ int length ])
+ Truncates a LOB */
+PHP_FUNCTION(oci_lob_truncate)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ ub4 trim_length = 0;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &trim_length) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &z_descriptor, oci_lob_class_entry_ptr, &trim_length) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_truncate(descriptor, trim_length TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int oci_lob_erase( [ int offset [, int length ] ] )
+ Erases a specified portion of the internal LOB, starting at a specified offset */
+PHP_FUNCTION(oci_lob_erase)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ ub4 bytes_erased;
+ long offset = -1, length = -1;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &offset, &length) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 0 && offset < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+
+ if (ZEND_NUM_ARGS() > 1 && length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &z_descriptor, oci_lob_class_entry_ptr, &offset, &length) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 1 && offset < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+
+ if (ZEND_NUM_ARGS() > 2 && length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_erase(descriptor, offset, length, &bytes_erased TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes_erased);
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_flush( [ int flag ] )
+ Flushes the LOB buffer */
+PHP_FUNCTION(oci_lob_flush)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ ub4 flush_flag = 0;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flush_flag) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &z_descriptor, oci_lob_class_entry_ptr, &flush_flag) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
+ /* buffering wasn't enabled, there is nothing to flush */
+ RETURN_FALSE;
+ }
+
+ if (php_oci_lob_flush(descriptor, flush_flag TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ocisetbufferinglob( boolean flag )
+ Enables/disables buffering for a LOB */
+PHP_FUNCTION(ocisetbufferinglob)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ zend_bool flag;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &flag) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ob", &z_descriptor, oci_lob_class_entry_ptr, &flag) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_set_buffering(descriptor, flag TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ocigetbufferinglob()
+ Returns current state of buffering for a LOB */
+PHP_FUNCTION(ocigetbufferinglob)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_copy( object lob_to, object lob_from [, int length ] )
+ Copies data from a LOB to another LOB */
+PHP_FUNCTION(oci_lob_copy)
+{
+ zval **tmp_dest, **tmp_from, *z_descriptor_dest, *z_descriptor_from;
+ php_oci_descriptor *descriptor_dest, *descriptor_from;
+ long length = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO|l", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr, &length) == FAILURE) {
+ return;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor"), (void **)&tmp_dest) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor"), (void **)&tmp_from) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_dest, descriptor_dest);
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_from, descriptor_from);
+
+ if (ZEND_NUM_ARGS() == 3 && length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
+ RETURN_FALSE;
+ }
+
+ if (ZEND_NUM_ARGS() == 2) {
+ /* indicate that we want to copy from the current position to the end of the LOB */
+ length = -1;
+ }
+
+ if (php_oci_lob_copy(descriptor_dest, descriptor_from, length TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_is_equal( object lob1, object lob2 )
+ Tests to see if two LOB/FILE locators are equal */
+PHP_FUNCTION(oci_lob_is_equal)
+{
+ zval **tmp_first, **tmp_second, *z_descriptor_first, *z_descriptor_second;
+ php_oci_descriptor *descriptor_first, *descriptor_second;
+ boolean is_equal;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &z_descriptor_first, oci_lob_class_entry_ptr, &z_descriptor_second, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_first), "descriptor", sizeof("descriptor"), (void **)&tmp_first) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor_second), "descriptor", sizeof("descriptor"), (void **)&tmp_second) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_first, descriptor_first);
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_second, descriptor_second);
+
+ if (php_oci_lob_is_equal(descriptor_first, descriptor_second, &is_equal TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ if (is_equal == TRUE) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_export([string filename [, int start [, int length]]])
+ Writes a large object into a file */
+PHP_FUNCTION(oci_lob_export)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ char *filename, *buffer;
+ int filename_len;
+ long start = -1, length = -1, block_length;
+ php_stream *stream;
+ ub4 lob_length;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &start, &length) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 1 && start < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start parameter must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ if (ZEND_NUM_ARGS() > 2 && length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 2 && start < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start parameter must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ if (ZEND_NUM_ARGS() > 3 && length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ if (start == -1) {
+ start = 0;
+ }
+
+ if (length == -1) {
+ length = lob_length - descriptor->lob_current_position;
+ }
+
+ if (length == 0) {
+ /* nothing to write, fail silently */
+ RETURN_FALSE;
+ }
+
+ if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+ RETURN_FALSE;
+ }
+
+ if (php_check_open_basedir(filename TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ stream = php_stream_open_wrapper_ex(filename, "w", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL);
+
+ block_length = PHP_OCI_LOB_BUFFER_SIZE;
+ if (block_length > length) {
+ block_length = length;
+ }
+
+ while(length > 0) {
+ ub4 tmp_bytes_read = 0;
+ if (php_oci_lob_read(descriptor, block_length, start, &buffer, &tmp_bytes_read TSRMLS_CC)) {
+ php_stream_close(stream);
+ RETURN_FALSE;
+ }
+ if (tmp_bytes_read && !php_stream_write(stream, buffer, tmp_bytes_read)) {
+ php_stream_close(stream);
+ efree(buffer);
+ RETURN_FALSE;
+ }
+ if (buffer) {
+ efree(buffer);
+ }
+
+ length -= tmp_bytes_read;
+ descriptor->lob_current_position += tmp_bytes_read;
+ start += tmp_bytes_read;
+
+ if (block_length > length) {
+ block_length = length;
+ }
+ }
+
+ php_stream_close(stream);
+ RETURN_TRUE;
+}
+/* }}} */
+
+#ifdef HAVE_OCI8_TEMP_LOB
+/* {{{ proto bool oci_lob_write_temporary(string var [, int lob_type])
+ Writes temporary blob */
+PHP_FUNCTION(oci_lob_write_temporary)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+ char *data;
+ int data_len;
+ long type = OCI_TEMP_CLOB;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &type) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &type) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_write_tmp(descriptor, type, data, data_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_lob_close()
+ Closes lob descriptor */
+PHP_FUNCTION(oci_lob_close)
+{
+ zval **tmp, *z_descriptor = getThis();
+ php_oci_descriptor *descriptor;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
+
+ if (php_oci_lob_close(descriptor TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+#endif
+
+/* {{{ proto object oci_new_descriptor(resource connection [, int type])
+ Initialize a new empty descriptor LOB/FILE (LOB is default) */
+PHP_FUNCTION(oci_new_descriptor)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+ php_oci_descriptor *descriptor;
+ long type = OCI_DTYPE_LOB;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_connection, &type) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ /* php_oci_lob_create() checks type */
+ descriptor = php_oci_lob_create(connection, type TSRMLS_CC);
+
+ if (!descriptor) {
+ RETURN_NULL();
+ }
+
+ object_init_ex(return_value, oci_lob_class_entry_ptr);
+ add_property_resource(return_value, "descriptor", descriptor->id);
+}
+/* }}} */
+
+/* {{{ proto bool oci_rollback(resource connection)
+ Rollback the current context */
+PHP_FUNCTION(oci_rollback)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ if (connection->descriptors) {
+ zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
+ }
+
+ if (php_oci_connection_rollback(connection TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_commit(resource connection)
+ Commit the current context */
+PHP_FUNCTION(oci_commit)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ if (connection->descriptors) {
+ zend_hash_apply(connection->descriptors,(apply_func_t) php_oci_descriptor_flush_hash_dtor TSRMLS_CC);
+ }
+
+ if (php_oci_connection_commit(connection TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string oci_field_name(resource stmt, int col)
+ Tell the name of a column */
+PHP_FUNCTION(oci_field_name)
+{
+ php_oci_out_column *column;
+
+ if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU) ) ) {
+ RETURN_STRINGL(column->name, column->name_len, 1);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int oci_field_size(resource stmt, int col)
+ Tell the maximum data size of a column */
+PHP_FUNCTION(oci_field_size)
+{
+ php_oci_out_column *column;
+
+ if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU) ) ) {
+ /* Handle data type of LONG */
+ if (column->data_type == SQLT_LNG){
+ RETURN_LONG(column->storage_size4);
+ }
+ RETURN_LONG(column->data_size);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int oci_field_scale(resource stmt, int col)
+ Tell the scale of a column */
+PHP_FUNCTION(oci_field_scale)
+{
+ php_oci_out_column *column;
+
+ if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU) ) ) {
+ RETURN_LONG(column->scale);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int oci_field_precision(resource stmt, int col)
+ Tell the precision of a column */
+PHP_FUNCTION(oci_field_precision)
+{
+ php_oci_out_column *column;
+
+ if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU) ) ) {
+ RETURN_LONG(column->precision);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto mixed oci_field_type(resource stmt, int col)
+ Tell the data type of a column */
+PHP_FUNCTION(oci_field_type)
+{
+ php_oci_out_column *column;
+
+ column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (!column) {
+ RETURN_FALSE;
+ }
+
+ switch (column->data_type) {
+#ifdef SQLT_TIMESTAMP
+ case SQLT_TIMESTAMP:
+ RETVAL_STRING("TIMESTAMP",1);
+ break;
+#endif
+#ifdef SQLT_TIMESTAMP_TZ
+ case SQLT_TIMESTAMP_TZ:
+ RETVAL_STRING("TIMESTAMP_TZ",1);
+ break;
+#endif
+ case SQLT_DAT:
+ RETVAL_STRING("DATE",1);
+ break;
+ case SQLT_NUM:
+ RETVAL_STRING("NUMBER",1);
+ break;
+ case SQLT_LNG:
+ RETVAL_STRING("LONG",1);
+ break;
+ case SQLT_BIN:
+ RETVAL_STRING("RAW",1);
+ break;
+ case SQLT_LBI:
+ RETVAL_STRING("LONG RAW",1);
+ break;
+ case SQLT_CHR:
+ RETVAL_STRING("VARCHAR",1);
+ break;
+ case SQLT_RSET:
+ RETVAL_STRING("REFCURSOR",1);
+ break;
+ case SQLT_AFC:
+ RETVAL_STRING("CHAR",1);
+ break;
+ case SQLT_BLOB:
+ RETVAL_STRING("BLOB",1);
+ break;
+ case SQLT_CLOB:
+ RETVAL_STRING("CLOB",1);
+ break;
+ case SQLT_BFILE:
+ RETVAL_STRING("BFILE",1);
+ break;
+ case SQLT_RDD:
+ RETVAL_STRING("ROWID",1);
+ break;
+ default:
+ RETVAL_LONG(column->data_type);
+ }
+}
+/* }}} */
+
+/* {{{ proto int oci_field_type_raw(resource stmt, int col)
+ Tell the raw oracle data type of a column */
+PHP_FUNCTION(oci_field_type_raw)
+{
+ php_oci_out_column *column;
+
+ column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (column) {
+ RETURN_LONG(column->data_type);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_field_is_null(resource stmt, int col)
+ Tell whether a column is NULL */
+PHP_FUNCTION(oci_field_is_null)
+{
+ php_oci_out_column *column;
+
+ if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU) ) ) {
+ if (column->indicator == -1) {
+ RETURN_TRUE;
+ }
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto void oci_internal_debug(int onoff)
+ Toggle internal debugging output for the OCI extension */
+PHP_FUNCTION(oci_internal_debug)
+{
+ zend_bool on_off;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &on_off) == FAILURE) {
+ return;
+ }
+ OCI_G(debug_mode) = on_off;
+}
+/* }}} */
+
+/* {{{ proto bool oci_execute(resource stmt [, int mode])
+ Execute a parsed statement */
+PHP_FUNCTION(oci_execute)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+ long mode = OCI_COMMIT_ON_SUCCESS;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &mode) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_execute(statement, mode TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_cancel(resource stmt)
+ Cancel reading from a cursor */
+PHP_FUNCTION(oci_cancel)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_cancel(statement TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_fetch(resource stmt)
+ Prepare a new row of data for reading */
+PHP_FUNCTION(oci_fetch)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+ ub4 nrows = 1; /* only one row at a time is supported for now */
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ocifetchinto(resource stmt, array &output [, int mode])
+ Fetch a row of result data into an array */
+PHP_FUNCTION(ocifetchinto)
+{
+ php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM, 3);
+}
+/* }}} */
+
+/* {{{ proto int oci_fetch_all(resource stmt, array &output[, int skip[, int maxrows[, int flags]]])
+ Fetch all rows of result data into an array */
+PHP_FUNCTION(oci_fetch_all)
+{
+ zval *z_statement, *array, *element, *tmp;
+ php_oci_statement *statement;
+ php_oci_out_column **columns;
+ zval ***outarrs;
+ ub4 nrows = 1;
+ int i;
+ long rows = 0, flags = 0, skip = 0, maxrows = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|lll", &z_statement, &array, &skip, &maxrows, &flags) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ zval_dtor(array);
+ array_init(array);
+
+ while (skip--) {
+ if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
+ RETURN_LONG(0);
+ }
+ }
+
+ if (flags & PHP_OCI_FETCHSTATEMENT_BY_ROW) {
+ columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
+
+ for (i = 0; i < statement->ncolumns; i++) {
+ columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ }
+
+ while (!php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
+ zval *row;
+
+ MAKE_STD_ZVAL(row);
+ array_init(row);
+
+ for (i = 0; i < statement->ncolumns; i++) {
+ MAKE_STD_ZVAL(element);
+ php_oci_column_to_zval(columns[ i ], element, PHP_OCI_RETURN_LOBS TSRMLS_CC);
+
+ if (flags & PHP_OCI_NUM) {
+ zend_hash_next_index_insert(Z_ARRVAL_P(row), &element, sizeof(zval*), NULL);
+ } else { /* default to ASSOC */
+ zend_hash_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL);
+ }
+ }
+
+ zend_hash_next_index_insert(Z_ARRVAL_P(array), &row, sizeof(zval*), NULL);
+ rows++;
+
+ if (maxrows != -1 && rows == maxrows) {
+ php_oci_statement_cancel(statement TSRMLS_CC);
+ break;
+ }
+ }
+ efree(columns);
+
+ } else { /* default to BY_COLUMN */
+ columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
+ outarrs = safe_emalloc(statement->ncolumns, sizeof(zval*), 0);
+
+ if (flags & PHP_OCI_NUM) {
+ for (i = 0; i < statement->ncolumns; i++) {
+ columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+
+ MAKE_STD_ZVAL(tmp);
+ array_init(tmp);
+ zend_hash_next_index_insert(Z_ARRVAL_P(array), &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
+ }
+ } else { /* default to ASSOC */
+ for (i = 0; i < statement->ncolumns; i++) {
+ columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+
+ MAKE_STD_ZVAL(tmp);
+ array_init(tmp);
+ zend_hash_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
+ }
+ }
+
+ while (!php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
+ for (i = 0; i < statement->ncolumns; i++) {
+ MAKE_STD_ZVAL(element);
+ php_oci_column_to_zval(columns[ i ], element, PHP_OCI_RETURN_LOBS TSRMLS_CC);
+ zend_hash_index_update((*(outarrs[ i ]))->value.ht, rows, (void *)&element, sizeof(zval*), NULL);
+ }
+
+ rows++;
+
+ if (maxrows != -1 && rows == maxrows) {
+ php_oci_statement_cancel(statement TSRMLS_CC);
+ break;
+ }
+ }
+
+ efree(columns);
+ efree(outarrs);
+ }
+
+ RETURN_LONG(rows);
+}
+/* }}} */
+
+/* {{{ proto object oci_fetch_object( resource stmt )
+ Fetch a result row as an object */
+PHP_FUNCTION(oci_fetch_object)
+{
+ php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC, 2);
+
+ if (Z_TYPE_P(return_value) == IS_ARRAY) {
+ object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
+ }
+}
+/* }}} */
+
+/* {{{ proto array oci_fetch_row( resource stmt )
+ Fetch a result row as an enumerated array */
+PHP_FUNCTION(oci_fetch_row)
+{
+ php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM, 1);
+}
+/* }}} */
+
+/* {{{ proto array oci_fetch_assoc( resource stmt )
+ Fetch a result row as an associative array */
+PHP_FUNCTION(oci_fetch_assoc)
+{
+ php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC, 1);
+}
+/* }}} */
+
+/* {{{ proto array oci_fetch_array( resource stmt [, int mode ])
+ Fetch a result row as an array */
+PHP_FUNCTION(oci_fetch_array)
+{
+ php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_BOTH, 2);
+}
+/* }}} */
+
+/* {{{ proto bool oci_free_statement(resource stmt)
+ Free all resources associated with a statement */
+PHP_FUNCTION(oci_free_statement)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+ zend_list_delete(statement->id);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_close(resource connection)
+ Disconnect from database */
+PHP_FUNCTION(oci_close)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+
+ if (OCI_G(old_oci_close_semantics)) {
+ /* do nothing to keep BC */
+ return;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+ zend_list_delete(connection->rsrc_id);
+ ZVAL_NULL(z_connection);
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto resource oci_new_connect(string user, string pass [, string db])
+ Connect to an Oracle database and log on. Returns a new session. */
+PHP_FUNCTION(oci_new_connect)
+{
+ php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto resource oci_connect(string user, string pass [, string db])
+ Connect to an Oracle database and log on. Returns a new session. */
+PHP_FUNCTION(oci_connect)
+{
+ php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
+}
+/* }}} */
+
+/* {{{ proto resource oci_pconnect(string user, string pass [, string db])
+ Connect to an Oracle database using a persistent connection and log on. Returns a new session. */
+PHP_FUNCTION(oci_pconnect)
+{
+ php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
+}
+/* }}} */
+
+/* {{{ proto array oci_error([resource stmt|connection|global])
+ Return the last error of stmt|connection|global. If no error happened returns false. */
+PHP_FUNCTION(oci_error)
+{
+ zval *arg;
+ php_oci_statement *statement;
+ php_oci_connection *connection;
+ text *errbuf;
+ sb4 errcode = 0;
+ sword error = 0;
+ dvoid *errh = NULL;
+#ifdef HAVE_OCI8_ATTR_STATEMENT
+ ub2 error_offset = 0;
+ text *sqltext = NULL;
+#endif
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 0) {
+ statement = (php_oci_statement *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_statement);
+
+ if (statement) {
+ errh = statement->err;
+ error = statement->errcode;
+
+#ifdef HAVE_OCI8_ATTR_STATEMENT
+ if (php_oci_fetch_sqltext_offset(statement, &sqltext, &error_offset TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+#endif
+ } else {
+ connection = (php_oci_connection *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_connection);
+
+ if (connection) {
+ errh = connection->err;
+ error = connection->errcode;
+ }
+ }
+ } else {
+ errh = OCI_G(err);
+ error = OCI_G(errcode);
+ }
+
+ if (error == OCI_SUCCESS) { /* no error set in the handle */
+ RETURN_FALSE;
+ }
+
+ if (!errh) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIError: unable to find error handle");
+ RETURN_FALSE;
+ }
+
+ errcode = php_oci_fetch_errmsg(errh, &errbuf TSRMLS_CC);
+
+ if (errcode) {
+ array_init(return_value);
+ add_assoc_long(return_value, "code", errcode);
+ add_assoc_string(return_value, "message", (char*) errbuf, 0);
+#ifdef HAVE_OCI8_ATTR_STATEMENT
+ add_assoc_long(return_value, "offset", error_offset);
+ add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : "", 1);
+#endif
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto int oci_num_fields(resource stmt)
+ Return the number of result columns in a statement */
+PHP_FUNCTION(oci_num_fields)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ RETURN_LONG(statement->ncolumns);
+}
+/* }}} */
+
+/* {{{ proto resource oci_parse(resource connection, string query)
+ Parse a query and return a statement */
+PHP_FUNCTION(oci_parse)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+ php_oci_statement *statement;
+ char *query;
+ int query_len;
+ zend_bool cached = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &z_connection, &query, &query_len, &cached) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ statement = php_oci_statement_create(connection, query, query_len, cached TSRMLS_CC);
+
+ if (statement) {
+ RETURN_RESOURCE(statement->id);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_set_prefetch(resource stmt, int prefetch_rows)
+ Sets the number of rows to be prefetched on execute to prefetch_rows for stmt */
+PHP_FUNCTION(oci_set_prefetch)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+ long size;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &z_statement, &size) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_set_prefetch(statement, size TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password)
+ Changes the password of an account */
+PHP_FUNCTION(oci_password_change)
+{
+ zval *z_connection;
+ text *user, *pass_old, *pass_new, *dbname;
+ int user_len, pass_old_len, pass_new_len, dbname_len;
+ php_oci_connection *connection;
+
+ /* Disable in Safe Mode */
+ if (PG(safe_mode)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "is disabled in Safe Mode");
+ RETURN_FALSE;
+ }
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &z_connection, &user, &user_len, &pass_old, &pass_old_len, &pass_new, &pass_new_len) == SUCCESS) {
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ if (php_oci_password_change(connection, user, user_len, pass_old, pass_old_len, pass_new, pass_new_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+ } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ssss", &dbname, &dbname_len, &user, &user_len, &pass_old, &pass_old_len, &pass_new, &pass_new_len) == SUCCESS) {
+
+ connection = php_oci_do_connect_ex(user, user_len, pass_old, pass_old_len, pass_new, pass_new_len, dbname, dbname_len, NULL, OCI_DEFAULT, 0, 0 TSRMLS_CC);
+ if (!connection) {
+ RETURN_FALSE;
+ }
+ RETURN_RESOURCE(connection->rsrc_id);
+ }
+ WRONG_PARAM_COUNT;
+}
+/* }}} */
+
+/* {{{ proto resource oci_new_cursor(resource connection)
+ Return a new cursor (Statement-Handle) - use this to bind ref-cursors! */
+PHP_FUNCTION(oci_new_cursor)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+ php_oci_statement *statement;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ statement = php_oci_statement_create(connection, NULL, 0, 0 TSRMLS_CC);
+
+ if (statement) {
+ RETURN_RESOURCE(statement->id);
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string oci_result(resource stmt, mixed column)
+ Return a single column of result data */
+PHP_FUNCTION(oci_result)
+{
+ php_oci_out_column *column;
+
+ column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if(column) {
+ php_oci_column_to_zval(column, return_value, 0 TSRMLS_CC);
+ }
+ else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string oci_server_version(resource connection)
+ Return a string containing server version information */
+PHP_FUNCTION(oci_server_version)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+ char *version = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ if (php_oci_server_get_version(connection, &version TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(version, 0);
+}
+/* }}} */
+
+/* {{{ proto string oci_statement_type(resource stmt)
+ Return the query type of an OCI statement */
+PHP_FUNCTION(oci_statement_type)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+ ub2 type;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_get_type(statement, &type TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ switch (type) {
+ case OCI_STMT_SELECT:
+ RETVAL_STRING("SELECT",1);
+ break;
+ case OCI_STMT_UPDATE:
+ RETVAL_STRING("UPDATE",1);
+ break;
+ case OCI_STMT_DELETE:
+ RETVAL_STRING("DELETE",1);
+ break;
+ case OCI_STMT_INSERT:
+ RETVAL_STRING("INSERT",1);
+ break;
+ case OCI_STMT_CREATE:
+ RETVAL_STRING("CREATE",1);
+ break;
+ case OCI_STMT_DROP:
+ RETVAL_STRING("DROP",1);
+ break;
+ case OCI_STMT_ALTER:
+ RETVAL_STRING("ALTER",1);
+ break;
+ case OCI_STMT_BEGIN:
+ RETVAL_STRING("BEGIN",1);
+ break;
+ case OCI_STMT_DECLARE:
+ RETVAL_STRING("DECLARE",1);
+ break;
+ default:
+ RETVAL_STRING("UNKNOWN",1);
+ }
+}
+/* }}} */
+
+/* {{{ proto int oci_num_rows(resource stmt)
+ Return the row count of an OCI statement */
+PHP_FUNCTION(oci_num_rows)
+{
+ zval *z_statement;
+ php_oci_statement *statement;
+ ub4 rowcount;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
+
+ if (php_oci_statement_get_numrows(statement, &rowcount TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(rowcount);
+}
+/* }}} */
+
+#ifdef PHP_OCI8_HAVE_COLLECTIONS
+/* {{{ proto bool oci_free_collection()
+ Deletes collection object*/
+PHP_FUNCTION(oci_free_collection)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ zend_list_delete(collection->id);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_collection_append(string value)
+ Append an object to the collection */
+PHP_FUNCTION(oci_collection_append)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ char *value;
+ int value_len;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &z_collection, oci_coll_class_entry_ptr, &value, &value_len) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_append(collection, value, value_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto string oci_collection_element_get(int ndx)
+ Retrieve the value at collection index ndx */
+PHP_FUNCTION(oci_collection_element_get)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ long element_index;
+ zval *value;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &element_index) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_collection, oci_coll_class_entry_ptr, &element_index) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_element_get(collection, element_index, &value TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+
+ *return_value = *value;
+ zval_copy_ctor(return_value);
+ zval_ptr_dtor(&value);
+}
+/* }}} */
+
+/* {{{ proto bool oci_collection_assign(object from)
+ Assign a collection from another existing collection */
+PHP_FUNCTION(oci_collection_assign)
+{
+ zval **tmp_dest, **tmp_from, *z_collection_dest = getThis(), *z_collection_from;
+ php_oci_collection *collection_dest, *collection_from;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection_from, oci_coll_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &z_collection_dest, oci_coll_class_entry_ptr, &z_collection_from, oci_coll_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection_dest), "collection", sizeof("collection"), (void **)&tmp_dest) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property. The first argument should be valid collection object");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection_from), "collection", sizeof("collection"), (void **)&tmp_from) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property. The second argument should be valid collection object");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp_dest, collection_dest);
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp_from, collection_from);
+
+ if (php_oci_collection_assign(collection_dest, collection_from TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool oci_collection_element_assign(int index, string val)
+ Assign element val to collection at index ndx */
+PHP_FUNCTION(oci_collection_element_assign)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ int value_len;
+ long element_index;
+ char *value;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element_index, &value, &value_len) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ols", &z_collection, oci_coll_class_entry_ptr, &element_index, &value, &value_len) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_element_set(collection, element_index, value, value_len TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int oci_collection_size()
+ Return the size of a collection */
+PHP_FUNCTION(oci_collection_size)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ sb4 size = 0;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_size(collection, &size TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(size);
+}
+/* }}} */
+
+/* {{{ proto int oci_collection_max()
+ Return the max value of a collection. For a varray this is the maximum length of the array */
+PHP_FUNCTION(oci_collection_max)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ long max;
+
+ if (!getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_max(collection, &max TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(max);
+}
+/* }}} */
+
+/* {{{ proto bool oci_collection_trim(int num)
+ Trim num elements from the end of a collection */
+PHP_FUNCTION(oci_collection_trim)
+{
+ zval **tmp, *z_collection = getThis();
+ php_oci_collection *collection;
+ long trim_size;
+
+ if (getThis()) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &trim_size) == FAILURE) {
+ return;
+ }
+ }
+ else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_collection, oci_coll_class_entry_ptr, &trim_size) == FAILURE) {
+ return;
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ RETURN_FALSE;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
+
+ if (php_oci_collection_trim(collection, trim_size TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto object oci_new_collection(resource connection, string tdo [, string schema])
+ Initialize a new collection */
+PHP_FUNCTION(oci_new_collection)
+{
+ zval *z_connection;
+ php_oci_connection *connection;
+ php_oci_collection *collection;
+ char *tdo, *schema = NULL;
+ int tdo_len, schema_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &z_connection, &tdo, &tdo_len, &schema, &schema_len) == FAILURE) {
+ return;
+ }
+
+ PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
+
+ if ( (collection = php_oci_collection_create(connection, tdo, tdo_len, schema, schema_len TSRMLS_CC)) ) {
+ object_init_ex(return_value, oci_coll_class_entry_ptr);
+ add_property_resource(return_value, "collection", collection->id);
+ }
+ else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+#endif
+
+#endif /* HAVE_OCI8 */
diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c
new file mode 100644
index 0000000000..ded9ba6df2
--- /dev/null
+++ b/ext/oci8/oci8_lob.c
@@ -0,0 +1,702 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@php.net> |
+ | Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "ext/standard/info.h"
+#include "php_ini.h"
+
+#if HAVE_OCI8
+
+#include "php_oci8.h"
+#include "php_oci8_int.h"
+
+/* for import/export functions */
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* {{{ php_oci_lob_create()
+ Create LOB descriptor and allocate all the resources needed */
+php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long type TSRMLS_DC)
+{
+ php_oci_descriptor *descriptor;
+
+ switch (type) {
+ case OCI_DTYPE_FILE:
+ case OCI_DTYPE_LOB:
+ case OCI_DTYPE_ROWID:
+ /* these three are allowed */
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown descriptor type %ld.", type);
+ return NULL;
+ break;
+ }
+
+ descriptor = emalloc(sizeof(php_oci_descriptor));
+ descriptor->type = type;
+
+ OCI_G(errcode) = PHP_OCI_CALL(OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0));
+
+ if (OCI_G(errcode) != OCI_SUCCESS) {
+ connection->errcode = php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ efree(descriptor);
+ return NULL;
+ }
+
+ descriptor->connection = connection;
+
+ PHP_OCI_REGISTER_RESOURCE(descriptor, le_descriptor);
+
+ descriptor->lob_current_position = 0;
+ descriptor->lob_size = -1; /* we should set it to -1 to know, that it's just not initialized */
+ descriptor->buffering = PHP_OCI_LOB_BUFFER_DISABLED; /* buffering is off by default */
+
+ if (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE) {
+ /* add Lobs & Files to hash. we'll flush them at the end */
+ if (!connection->descriptors) {
+ ALLOC_HASHTABLE(connection->descriptors);
+ zend_hash_init(connection->descriptors, 13, NULL, php_oci_descriptor_flush_hash_dtor, 0);
+ }
+
+ zend_hash_next_index_insert(connection->descriptors,&descriptor,sizeof(php_oci_descriptor *),NULL);
+ }
+ return descriptor;
+
+} /* }}} */
+
+/* {{{ php_oci_lob_get_length()
+ Get length of the LOB. The length is cached so we don't need to ask Oracle every time */
+int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+
+ *length = 0;
+
+ if (descriptor->lob_size >= 0) {
+ *length = descriptor->lob_size;
+ return 0;
+ } else {
+ if (descriptor->type == OCI_DTYPE_FILE) {
+ connection->errcode = PHP_OCI_CALL(OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobGetLength, (connection->svc, connection->err, descriptor->descriptor, (ub4 *)length));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ descriptor->lob_size = *length;
+
+ if (descriptor->type == OCI_DTYPE_FILE) {
+ connection->errcode = PHP_OCI_CALL(OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ }
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_read()
+ Read specified portion of the LOB into the buffer */
+int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long initial_offset, char **data, ub4 *data_len TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+ ub4 length = 0;
+ ub4 block_length = PHP_OCI_LOB_BUFFER_SIZE;
+ int bytes_read, bytes_total = 0, offset = 0, data_len_chars = 0;
+ int requested_len = read_length; /* this is by default */
+
+ *data_len = 0;
+ *data = NULL;
+
+ if (php_oci_lob_get_length(descriptor, &length TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (length <= 0) {
+ return 0;
+ }
+
+ if (initial_offset > length) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be less than size of the LOB");
+ return 1;
+ }
+
+ if (read_length == -1) {
+ requested_len = length;
+ }
+
+ if (requested_len > (length - initial_offset)) {
+ requested_len = length - initial_offset;
+ }
+
+ if (requested_len == 0) {
+ return 0;
+ }
+
+ if (requested_len < block_length) {
+ block_length = requested_len;
+ }
+
+ if (descriptor->type == OCI_DTYPE_FILE) {
+ connection->errcode = PHP_OCI_CALL(OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ }
+
+ *data = (char *)emalloc(block_length + 1);
+ bytes_read = block_length;
+ offset = initial_offset;
+
+ do {
+ connection->errcode = PHP_OCI_CALL(OCILobRead,
+ (
+ connection->svc,
+ connection->err,
+ descriptor->descriptor,
+ &bytes_read, /* IN/OUT bytes toread/read */
+ offset + 1, /* offset (starts with 1) */
+ (dvoid *) ((char *) *data + *data_len),
+ block_length, /* size of buffer */
+ (dvoid *)0,
+ (OCICallbackLobRead) 0, /* callback... */
+ (ub2) connection->charset, /* The character set ID of the buffer data. */
+ (ub1) SQLCS_IMPLICIT /* The character set form of the buffer data. */
+ )
+ );
+
+ bytes_total += bytes_read;
+ /*
+ * Oracle doesn't tell use how many CHARS were read,
+ * so we have to count them to get the correct offset for CLOBS */
+ data_len_chars = OCIMultiByteStrnDisplayLength(connection->env, *data, bytes_total);
+ offset = initial_offset + data_len_chars;
+
+ *data_len += bytes_read;
+ block_length = PHP_OCI_LOB_BUFFER_SIZE;
+
+ if (connection->errcode != OCI_NEED_DATA) {
+ break;
+ }
+ *data = erealloc(*data, *data_len + PHP_OCI_LOB_BUFFER_SIZE + 1);
+ } while (connection->errcode == OCI_NEED_DATA);
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ efree(*data);
+ *data = NULL;
+ return 1;
+ }
+
+ descriptor->lob_current_position += data_len_chars;
+
+ if (descriptor->type == OCI_DTYPE_FILE) {
+ connection->errcode = PHP_OCI_CALL(OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ efree(*data);
+ *data = NULL;
+ return 1;
+ }
+ }
+
+ *data = erealloc(*data, *data_len + 1);
+ (*data)[ *data_len ] = 0;
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_write()
+ Write data to the LOB */
+int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, int data_len, ub4 *bytes_written TSRMLS_DC)
+{
+ OCILobLocator *lob = (OCILobLocator *) descriptor->descriptor;
+ php_oci_connection *connection = (php_oci_connection *) descriptor->connection;
+ ub4 lob_length;
+
+ *bytes_written = 0;
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (!data || data_len <= 0) {
+ return 0;
+ }
+
+ if (offset < 0) {
+ offset = 0;
+ }
+
+ if (offset > descriptor->lob_current_position) {
+ offset = descriptor->lob_current_position;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobWrite, (connection->svc, connection->err, lob, (ub4 *)&data_len, (ub4) offset + 1, (dvoid *) data, (ub4) data_len, OCI_ONE_PIECE, (dvoid *)0, (OCICallbackLobWrite) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT));
+
+ if (connection->errcode) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ *bytes_written = 0;
+ return 1;
+ }
+ *bytes_written = data_len;
+ descriptor->lob_current_position += data_len;
+
+ if (descriptor->lob_current_position > descriptor->lob_size) {
+ descriptor->lob_size = descriptor->lob_current_position;
+ }
+
+ /* marking buffer as used */
+ if (descriptor->buffering == PHP_OCI_LOB_BUFFER_ENABLED) {
+ descriptor->buffering = PHP_OCI_LOB_BUFFER_USED;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_set_buffering()
+ Turn buffering off/onn for this particular LOB */
+int php_oci_lob_set_buffering (php_oci_descriptor *descriptor, int on_off TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+
+ if (!on_off && descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
+ /* disabling when it's already off */
+ return 0;
+ }
+
+ if (on_off && descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
+ /* enabling when it's already on */
+ return 0;
+ }
+
+ if (on_off) {
+ connection->errcode = PHP_OCI_CALL(OCILobEnableBuffering, (connection->svc, connection->err, descriptor->descriptor));
+ }
+ else {
+ connection->errcode = PHP_OCI_CALL(OCILobDisableBuffering, (connection->svc, connection->err, descriptor->descriptor));
+ }
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ descriptor->buffering = on_off ? PHP_OCI_LOB_BUFFER_ENABLED : PHP_OCI_LOB_BUFFER_DISABLED;
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_get_buffering()
+ Return current buffering state for the LOB */
+int php_oci_lob_get_buffering (php_oci_descriptor *descriptor TSRMLS_DC)
+{
+ if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+} /* }}} */
+
+/* {{{ php_oci_lob_copy()
+ Copy one LOB (or its part) to another one */
+int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from, long length TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor_dest->connection;
+ int length_dest, length_from, copy_len;
+
+ if (php_oci_lob_get_length(descriptor_dest, &length_dest TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (php_oci_lob_get_length(descriptor_from, &length_from TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (length == -1) {
+ copy_len = length_from - descriptor_from->lob_current_position;
+ }
+ else {
+ copy_len = length;
+ }
+
+ if ((int)copy_len <= 0) {
+ /* silently fail, there is nothing to copy */
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobCopy, (connection->svc, connection->err, descriptor_dest->descriptor, descriptor_from->descriptor, copy_len, descriptor_dest->lob_current_position+1, descriptor_from->lob_current_position+1));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_close()
+ Close LOB */
+int php_oci_lob_close (php_oci_descriptor *descriptor TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+ int is_temporary;
+
+ connection->errcode = PHP_OCI_CALL(OCILobClose, (connection->svc, connection->err, descriptor->descriptor));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobIsTemporary, (connection->env,connection->err, descriptor->descriptor, &is_temporary));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ if (is_temporary) {
+
+ connection->errcode = PHP_OCI_CALL(OCILobFreeTemporary, (connection->svc, connection->err, descriptor->descriptor));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_flush()
+ Flush buffers for the LOB (only if they have been used) */
+int php_oci_lob_flush(php_oci_descriptor *descriptor, int flush_flag TSRMLS_DC)
+{
+ OCILobLocator *lob = descriptor->descriptor;
+ php_oci_connection *connection = descriptor->connection;
+
+ if (!lob) {
+ return 1;
+ }
+
+ switch (flush_flag) {
+ case 0:
+ case OCI_LOB_BUFFER_FREE:
+ /* only these two are allowed */
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid flag value: %d", flush_flag);
+ return 1;
+ break;
+ }
+
+ /* do not really flush buffer, but report success
+ * to suppress OCI error when flushing not used buffer
+ * */
+ if (descriptor->buffering != PHP_OCI_LOB_BUFFER_USED) {
+ return 0;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobFlushBuffer, (connection->svc, connection->err, lob, flush_flag));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ /* marking buffer as enabled and not used */
+ descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_free()
+ Close LOB descriptor and free associated resources */
+void php_oci_lob_free (php_oci_descriptor *descriptor TSRMLS_DC)
+{
+ /* flushing Lobs & Files with buffering enabled */
+ if ((descriptor->type == OCI_DTYPE_FILE || descriptor->type == OCI_DTYPE_LOB) && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED) {
+ php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
+ }
+
+ PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type));
+
+ zend_list_delete(descriptor->connection->rsrc_id);
+ efree(descriptor);
+} /* }}} */
+
+/* {{{ php_oci_lob_import()
+ Import LOB contents from the given file */
+int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename TSRMLS_DC)
+{
+ int fp, loblen;
+ OCILobLocator *lob = (OCILobLocator *)descriptor->descriptor;
+ php_oci_connection *connection = descriptor->connection;
+ char buf[8192];
+ ub4 offset = 1;
+
+ if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) {
+ return 1;
+ }
+
+ if ((fp = VCWD_OPEN(filename, O_RDONLY|O_BINARY)) == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't open file %s", filename);
+ return 1;
+ }
+
+ while ((loblen = read(fp, &buf, sizeof(buf))) > 0) {
+ connection->errcode = PHP_OCI_CALL(
+ OCILobWrite,
+ (
+ connection->svc,
+ connection->err,
+ lob,
+ &loblen,
+ (ub4) offset,
+ (dvoid *) &buf,
+ (ub4) loblen,
+ OCI_ONE_PIECE,
+ (dvoid *)0,
+ (OCICallbackLobWrite) 0,
+ (ub2) 0,
+ (ub1) SQLCS_IMPLICIT
+ )
+ );
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ close(fp);
+ return 1;
+ }
+ offset += loblen;
+ }
+ close(fp);
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_append()
+ Append data to the end of the LOB */
+int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor_dest->connection;
+ OCILobLocator *lob_dest = descriptor_dest->descriptor;
+ OCILobLocator *lob_from = descriptor_from->descriptor;
+ ub4 dest_len, from_len;
+
+ if (php_oci_lob_get_length(descriptor_dest, &dest_len TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (php_oci_lob_get_length(descriptor_from, &from_len TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (from_len <= 0) {
+ return 0;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_truncate()
+ Truncate LOB to the given length */
+int php_oci_lob_truncate (php_oci_descriptor *descriptor, long new_lob_length TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+ OCILobLocator *lob = descriptor->descriptor;
+ ub4 lob_length;
+
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (lob_length <= 0) {
+ return 0;
+ }
+
+ if (new_lob_length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size must be greater than or equal to 0");
+ return 1;
+ }
+
+ if (new_lob_length > lob_length) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size must be less than or equal to the current LOB size");
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobTrim, (connection->svc, connection->err, lob, new_lob_length));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ descriptor->lob_size = new_lob_length;
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_erase()
+ Erase (or fill with whitespaces, depending on LOB type) the LOB (or its part) */
+int php_oci_lob_erase (php_oci_descriptor *descriptor, long offset, long length, ub4 *bytes_erased TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+ OCILobLocator *lob = descriptor->descriptor;
+ ub4 lob_length;
+
+ *bytes_erased = 0;
+
+ if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
+ return 1;
+ }
+
+ if (offset == -1) {
+ offset = descriptor->lob_current_position;
+ }
+
+ if (length == -1) {
+ length = lob_length;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobErase, (connection->svc, connection->err, lob, (ub4 *)&length, offset+1));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ *bytes_erased = length;
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_is_equal()
+ Compare to LOB descriptors and figure out if they are pointing to the same LOB */
+int php_oci_lob_is_equal (php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor_first->connection;
+ OCILobLocator *first_lob = descriptor_first->descriptor;
+ OCILobLocator *second_lob = descriptor_second->descriptor;
+
+ connection->errcode = PHP_OCI_CALL(OCILobIsEqual, (connection->env, first_lob, second_lob, result));
+
+ if (connection->errcode) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_lob_write_tmp()
+ Create temporary LOB and write data to it */
+int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, ub1 type, char *data, int data_len TSRMLS_DC)
+{
+ php_oci_connection *connection = descriptor->connection;
+ OCILobLocator *lob = descriptor->descriptor;
+ ub4 bytes_written = 0;
+
+ switch (type) {
+ case OCI_TEMP_BLOB:
+ case OCI_TEMP_CLOB:
+ /* only these two are allowed */
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid temporary lob type: %d", type);
+ return 1;
+ break;
+ }
+
+ if (!data || data_len <= 0) {
+ /* nothing to write, silently fail */
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobCreateTemporary, (connection->svc, connection->err, lob, OCI_DEFAULT, OCI_DEFAULT, type, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION));
+
+ if (connection->errcode) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ connection->errcode = PHP_OCI_CALL(OCILobOpen, (connection->svc, connection->err, lob, OCI_LOB_READWRITE));
+
+ if (connection->errcode) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return 1;
+ }
+
+ return php_oci_lob_write(descriptor, 0, data, data_len, &bytes_written TSRMLS_CC);
+} /* }}} */
+
+#endif /* HAVE_OCI8 */
diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c
new file mode 100644
index 0000000000..3927392e30
--- /dev/null
+++ b/ext/oci8/oci8_statement.c
@@ -0,0 +1,1347 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@php.net> |
+ | Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "ext/standard/info.h"
+#include "php_ini.h"
+
+#if HAVE_OCI8
+
+#include "php_oci8.h"
+#include "php_oci8_int.h"
+
+/* {{{ php_oci_statement_create()
+ Create statemend handle and allocate necessary resources */
+php_oci_statement *php_oci_statement_create (php_oci_connection *connection, char *query, long query_len, zend_bool cached TSRMLS_DC)
+{
+ php_oci_statement *statement;
+
+ statement = ecalloc(1,sizeof(php_oci_statement));
+
+#if HAVE_OCI_STMT_PREPARE2
+ if (!query_len) {
+ /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */
+ PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
+ }
+#else
+ PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
+#endif
+
+ PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL));
+
+ if (query_len > 0) {
+#if HAVE_OCI_STMT_PREPARE2
+ connection->errcode = PHP_OCI_CALL(OCIStmtPrepare2, (connection->svc, &(statement->stmt), connection->err, (text *)query, query_len, NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT));
+#else
+ connection->errcode = PHP_OCI_CALL(OCIStmtPrepare, (statement->stmt, connection->err, (text *)query, query_len, OCI_NTV_SYNTAX, OCI_DEFAULT));
+#endif
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+
+#if HAVE_OCI_STMT_PREPARE2
+ PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, OCI_DEFAULT));
+ PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
+#else
+ PHP_OCI_CALL(OCIHandleFree,(statement->stmt, OCI_HTYPE_STMT));
+ PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
+#endif
+
+ efree(statement);
+ PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
+ return NULL;
+ }
+ }
+
+ if (query && query_len) {
+ statement->last_query = estrndup(query, query_len);
+ statement->last_query_len = query_len;
+ }
+ else {
+ statement->last_query = NULL;
+ statement->last_query_len = 0;
+ }
+
+ statement->connection = connection;
+ statement->has_data = 0;
+
+ if (OCI_G(default_prefetch) > 0) {
+ php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC);
+ }
+
+ PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
+
+ return statement;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_set_prefetch()
+ Set prefetch buffer size for the statement (we're assuming that one row is ~1K sized) */
+int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 size TSRMLS_DC)
+{
+ ub4 prefetch = size * 1024;
+
+ if (size < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows has to be greater than or equal to 1");
+ return 1;
+ }
+
+ statement->errcode = PHP_OCI_CALL (OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_MEMORY, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ prefetch = size;
+ statement->errcode = PHP_OCI_CALL (OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_fetch()
+ Fetch a row from the statement */
+int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
+{
+ int i;
+ php_oci_out_column *column;
+
+ statement->errcode = PHP_OCI_CALL(OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
+
+ if ( statement->errcode == OCI_NO_DATA || nrows == 0 ) {
+ if (statement->last_query == NULL) {
+ /* reset define-list for refcursors */
+ if (statement->columns) {
+ zend_hash_destroy(statement->columns);
+ efree(statement->columns);
+ statement->columns = NULL;
+ statement->ncolumns = 0;
+ }
+ statement->executed = 0;
+ }
+
+ statement->errcode = 0; /* OCI_NO_DATA is NO error for us!!! */
+ statement->has_data = 0;
+
+ if (nrows == 0) {
+ /* this is exactly what we requested */
+ return 0;
+ }
+
+ return 1;
+ }
+
+ /* reset length for all piecewise columns */
+ for (i = 0; i < statement->ncolumns; i++) {
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ if (column->piecewise) {
+ column->retlen4 = 0;
+ }
+ }
+
+ while (statement->errcode == OCI_NEED_DATA) {
+ for (i = 0; i < statement->ncolumns; i++) {
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ if (column->piecewise) {
+ if (!column->data) {
+ column->data = (text *) emalloc(PHP_OCI_PIECE_SIZE);
+ } else {
+ column->data = erealloc(column->data, column->retlen4 + PHP_OCI_PIECE_SIZE);
+ }
+
+ column->cb_retlen = PHP_OCI_PIECE_SIZE;
+
+ PHP_OCI_CALL( OCIStmtSetPieceInfo, ((void *) column->oci_define, OCI_HTYPE_DEFINE, statement->err, ((char*)column->data) + column->retlen4, &(column->cb_retlen), OCI_NEXT_PIECE, &column->indicator, &column->retcode));
+ }
+ }
+
+ statement->errcode = PHP_OCI_CALL( OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
+
+ for (i = 0; i < statement->ncolumns; i++) {
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ if (column && column->piecewise) {
+ column->retlen4 += column->cb_retlen;
+ }
+ }
+ }
+
+ if (statement->errcode == OCI_SUCCESS_WITH_INFO || statement->errcode == OCI_SUCCESS) {
+ statement->has_data = 1;
+
+ /* do the stuff needed for OCIDefineByName */
+ for (i = 0; i < statement->ncolumns; i++) {
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ if (column == NULL) {
+ continue;
+ }
+
+ if (!column->define) {
+ continue;
+ }
+
+ zval_dtor(column->define->zval);
+ php_oci_column_to_zval(column, column->define->zval, 0 TSRMLS_CC);
+ }
+
+ return 0;
+ }
+
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+
+ statement->has_data = 0;
+
+ return 1;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_get_column()
+ Get column from the result set */
+php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, long column_index, char *column_name, long column_name_len TSRMLS_DC)
+{
+ php_oci_out_column *column = NULL;
+ int i;
+
+ if (statement->columns == NULL) { /* we release the columns at the end of a fetch */
+ return NULL;
+ }
+
+ if (column_name) {
+ for (i = 0; i < statement->ncolumns; i++) {
+ column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
+ if (column == NULL) {
+ continue;
+ } else if (((int) column->name_len == column_name_len) && (!strncmp(column->name, column_name, column_name_len))) {
+ return column;
+ }
+ }
+ } else if (column_index != -1) {
+ if (zend_hash_index_find(statement->columns, column_index, (void **)&column) == FAILURE) {
+ return NULL;
+ }
+ return column;
+ }
+
+ return NULL;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_execute()
+ Execute statement */
+int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
+{
+ php_oci_out_column *outcol;
+ php_oci_out_column column;
+ OCIParam *param = NULL;
+ text *colname;
+ ub4 counter;
+ ub2 define_type;
+ ub4 iters;
+ ub4 colcount;
+ ub2 dynamic;
+ int dtype;
+ dvoid *buf;
+ php_oci_descriptor *descr;
+
+ switch (mode) {
+ case OCI_COMMIT_ON_SUCCESS:
+ case OCI_DEFAULT:
+ /* only these two are allowed */
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid execute mode given: %d", mode);
+ return 1;
+ break;
+ }
+
+ if (!statement->stmttype) {
+ /* get statement type */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+ }
+
+ if (statement->stmttype == OCI_STMT_SELECT) {
+ iters = 0;
+ } else {
+ iters = 1;
+ }
+
+ if (statement->last_query) {
+ /* if we execute refcursors we don't have a query and
+ we don't want to execute!!! */
+
+ if (statement->binds) {
+ zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_pre_exec TSRMLS_CC);
+ }
+
+ /* execute statement */
+ statement->errcode = PHP_OCI_CALL(OCIStmtExecute, (statement->connection->svc, statement->stmt, statement->err, iters, 0, NULL, NULL, mode));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ if (statement->binds) {
+ zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec TSRMLS_CC);
+ }
+
+ if (mode & OCI_COMMIT_ON_SUCCESS) {
+ statement->connection->needs_commit = 0;
+ } else {
+ statement->connection->needs_commit = 1;
+ }
+ }
+
+ if (statement->stmttype == OCI_STMT_SELECT && statement->executed == 0) {
+ /* we only need to do the define step is this very statement is executed the first time! */
+ statement->executed = 1;
+
+ ALLOC_HASHTABLE(statement->columns);
+ zend_hash_init(statement->columns, 13, NULL, php_oci_column_hash_dtor, 0);
+
+ counter = 1;
+
+ /* get number of columns */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ statement->ncolumns = colcount;
+
+ for (counter = 1; counter <= colcount; counter++) {
+ memset(&column,0,sizeof(php_oci_out_column));
+
+ if (zend_hash_index_update(statement->columns, counter, &column, sizeof(php_oci_out_column), (void**) &outcol) == FAILURE) {
+ efree(statement->columns);
+ /* out of memory */
+ return 1;
+ }
+
+ outcol->statement = statement;
+
+ /* get column */
+ statement->errcode = PHP_OCI_CALL(OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)&param, counter));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ /* get column datatype */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ /* get size of the column */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ outcol->storage_size4 = outcol->data_size;
+ outcol->retlen = outcol->data_size;
+
+ /* get scale of the column */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ /* get precision of the column */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ /* get name of the column */
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+ PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
+
+ outcol->name = estrndup((char*) colname, outcol->name_len);
+
+ /* find a user-setted define */
+ if (statement->defines) {
+ zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define);
+ }
+
+ buf = 0;
+ switch (outcol->data_type) {
+ case SQLT_RSET:
+ outcol->statement = php_oci_statement_create(statement->connection, NULL, 0, 0 TSRMLS_CC);
+ outcol->stmtid = outcol->statement->id;
+
+ define_type = SQLT_RSET;
+ outcol->is_cursor = 1;
+ outcol->storage_size4 = -1;
+ outcol->retlen = -1;
+ dynamic = OCI_DEFAULT;
+ buf = &(outcol->statement->stmt);
+ break;
+
+ case SQLT_RDD: /* ROWID */
+ case SQLT_BLOB: /* binary LOB */
+ case SQLT_CLOB: /* character LOB */
+ case SQLT_BFILE: /* binary file LOB */
+ define_type = outcol->data_type;
+ outcol->is_descr = 1;
+ outcol->storage_size4 = -1;
+ dynamic = OCI_DEFAULT;
+
+ if (outcol->data_type == SQLT_BFILE) {
+ dtype = OCI_DTYPE_FILE;
+ } else if (outcol->data_type == SQLT_RDD ) {
+ dtype = OCI_DTYPE_ROWID;
+ } else {
+ dtype = OCI_DTYPE_LOB;
+ }
+
+ descr = php_oci_lob_create(statement->connection, dtype TSRMLS_CC);
+ if (!descr) {
+ efree(outcol->name);
+ return 1;
+ }
+ outcol->descid = descr->id;
+ buf = &(descr->descriptor);
+ break;
+
+ case SQLT_LNG:
+ case SQLT_LBI:
+ if (outcol->data_type == SQLT_LBI) {
+ define_type = SQLT_BIN;
+ } else {
+ define_type = SQLT_CHR;
+ }
+ outcol->storage_size4 = PHP_OCI_MAX_DATA_SIZE;
+ outcol->piecewise = 1;
+ dynamic = OCI_DYNAMIC_FETCH;
+ break;
+
+ case SQLT_BIN:
+ default:
+ define_type = SQLT_CHR;
+ if ((outcol->data_type == SQLT_DAT) || (outcol->data_type == SQLT_NUM)
+#ifdef SQLT_TIMESTAMP
+ || (outcol->data_type == SQLT_TIMESTAMP)
+#endif
+#ifdef SQLT_TIMESTAMP_TZ
+ || (outcol->data_type == SQLT_TIMESTAMP_TZ)
+#endif
+ ) {
+ outcol->storage_size4 = 512; /* XXX this should fit "most" NLS date-formats and Numbers */
+ } else {
+ outcol->storage_size4++; /* add one for string terminator */
+ }
+
+ outcol->storage_size4 *= 3;
+
+ dynamic = OCI_DEFAULT;
+ buf = outcol->data = (text *) emalloc(outcol->storage_size4);
+ break;
+ }
+
+ if (dynamic == OCI_DYNAMIC_FETCH) {
+ statement->errcode = PHP_OCI_CALL(
+ OCIDefineByPos,
+ (
+ statement->stmt, /* IN/OUT handle to the requested SQL query */
+ (OCIDefine **)&outcol->oci_define, /* IN/OUT pointer to a pointer to a define handle */
+ statement->err, /* IN/OUT An error handle */
+ counter, /* IN position in the select list */
+ (dvoid *)NULL, /* IN/OUT pointer to a buffer */
+ outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
+ define_type, /* IN The data type */
+ (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
+ (ub2 *)NULL, /* IN/OUT Pointer to array of length of data fetched */
+ (ub2 *)NULL, /* OUT Pointer to array of column-level return codes */
+ OCI_DYNAMIC_FETCH /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+ )
+ );
+
+ } else {
+ statement->errcode = PHP_OCI_CALL(
+ OCIDefineByPos,
+ (
+ statement->stmt, /* IN/OUT handle to the requested SQL query */
+ (OCIDefine **)&outcol->oci_define, /* IN/OUT pointer to a pointer to a define handle */
+ statement->err, /* IN/OUT An error handle */
+ counter, /* IN position in the select list */
+ (dvoid *)buf, /* IN/OUT pointer to a buffer */
+ outcol->storage_size4, /* IN The size of each valuep buffer in bytes */
+ define_type, /* IN The data type */
+ (dvoid *)&outcol->indicator, /* IN pointer to an indicator variable or arr */
+ (ub2 *)&outcol->retlen, /* IN/OUT Pointer to array of length of data fetched */
+ (ub2 *)&outcol->retcode, /* OUT Pointer to array of column-level return codes */
+ OCI_DEFAULT /* IN mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+ )
+ );
+
+ }
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_cancel()
+ Cancel statement */
+int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC)
+{
+
+ return php_oci_statement_fetch(statement, 0 TSRMLS_CC);
+
+} /* }}} */
+
+/* {{{ php_oci_statement_free()
+ Destroy statement handle and free associated resources */
+void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC)
+{
+ if (statement->stmt) {
+#if HAVE_OCI_STMT_PREPARE2
+ if (statement->last_query_len) { /* FIXME: magical */
+ PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, OCI_DEFAULT));
+ }
+ else {
+ PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
+ }
+#else
+ PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
+#endif
+ statement->stmt = 0;
+ }
+
+ if (statement->err) {
+ PHP_OCI_CALL(OCIHandleFree, (statement->err, OCI_HTYPE_ERROR));
+ statement->err = 0;
+ }
+
+ if (statement->last_query) {
+ efree(statement->last_query);
+ }
+
+ if (statement->columns) {
+ zend_hash_destroy(statement->columns);
+ efree(statement->columns);
+ }
+
+ if (statement->binds) {
+ zend_hash_destroy(statement->binds);
+ efree(statement->binds);
+ }
+
+ if (statement->defines) {
+ zend_hash_destroy(statement->defines);
+ efree(statement->defines);
+ }
+
+ zend_list_delete(statement->connection->rsrc_id);
+ efree(statement);
+} /* }}} */
+
+/* {{{ php_oci_bind_pre_exec()
+ Helper function */
+int php_oci_bind_pre_exec(void *data TSRMLS_DC)
+{
+ php_oci_bind *bind = (php_oci_bind *) data;
+
+ /* reset all bind stuff to a normal state..-. */
+
+ bind->indicator = 0;
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ php_oci_bind_post_exec()
+ Helper function */
+int php_oci_bind_post_exec(void *data TSRMLS_DC)
+{
+ php_oci_bind *bind = (php_oci_bind *) data;
+ php_oci_connection *connection = bind->parent_statement->connection;
+
+ if (bind->indicator == -1) { /* NULL */
+ zval *val = bind->zval;
+ if (Z_TYPE_P(val) == IS_STRING) {
+ *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */
+ }
+ zval_dtor(val);
+ ZVAL_NULL(val);
+ } else if (Z_TYPE_P(bind->zval) == IS_STRING && Z_STRLEN_P(bind->zval) > 0) {
+ Z_STRVAL_P(bind->zval) = erealloc(Z_STRVAL_P(bind->zval), Z_STRLEN_P(bind->zval)+1);
+ Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0';
+ }
+ else if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
+ int i;
+ zval **entry;
+ HashTable *hash = HASH_OF(bind->zval);
+
+ switch (bind->array.type) {
+ case SQLT_NUM:
+ case SQLT_INT:
+ case SQLT_LNG:
+ for (i = 0; i < bind->array.current_length; i++) {
+ if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ zval_dtor(*entry);
+ ZVAL_LONG(*entry, ((ub4 *)(bind->array.elements))[i]);
+ zend_hash_move_forward(hash);
+ }
+ else {
+ add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
+ }
+ }
+ break;
+ case SQLT_FLT:
+ for (i = 0; i < bind->array.current_length; i++) {
+ if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ zval_dtor(*entry);
+ ZVAL_DOUBLE(*entry, ((double *)(bind->array.elements))[i]);
+ zend_hash_move_forward(hash);
+ }
+ else {
+ add_next_index_double(bind->zval, ((double *)(bind->array.elements))[i]);
+ }
+ }
+ break;
+ case SQLT_ODT:
+ for (i = 0; i < bind->array.current_length; i++) {
+ char buff[1024];
+ int buff_len = 1024;
+
+ memset((void*)buff,0,sizeof(buff));
+
+ if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ connection->errcode = PHP_OCI_CALL(OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
+ zval_dtor(*entry);
+
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ ZVAL_NULL(*entry);
+ }
+ ZVAL_STRINGL(*entry, buff, buff_len, 1);
+ zend_hash_move_forward(hash);
+ }
+ else {
+ connection->errcode = PHP_OCI_CALL(OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
+ if (connection->errcode != OCI_SUCCESS) {
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ add_next_index_null(bind->zval);
+ }
+ add_next_index_stringl(bind->zval, buff, buff_len, 1);
+ }
+ }
+ break;
+
+ case SQLT_AFC:
+ case SQLT_CHR:
+ case SQLT_VCS:
+ case SQLT_AVC:
+ case SQLT_STR:
+ case SQLT_LVC:
+ for (i = 0; i < bind->array.current_length; i++) {
+ if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ zval_dtor(*entry);
+ ZVAL_STRINGL(*entry, ((text *)bind->array.elements)+i*bind->array.max_length, bind->array.max_length, 1);
+ Z_STRVAL_PP(entry)[ bind->array.max_length ] = '\0';
+ zend_hash_move_forward(hash);
+ }
+ else {
+ add_next_index_stringl(bind->zval, ((text *)bind->array.elements)+i*bind->array.max_length, bind->array.max_length, 1);
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ php_oci_bind_by_name()
+ Bind zval to the given placeholder */
+int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long maxlength, long type TSRMLS_DC)
+{
+ php_oci_collection *bind_collection = NULL;
+ php_oci_descriptor *bind_descriptor = NULL;
+ php_oci_statement *bind_statement = NULL;
+ dvoid *oci_desc = NULL;
+ /* dvoid *php_oci_collection = NULL; */
+ OCIStmt *oci_stmt = NULL;
+ dvoid *bind_data = NULL;
+ php_oci_bind bind, *bindp;
+ int mode = OCI_DATA_AT_EXEC;
+ sb4 value_sz = -1;
+
+ switch (type) {
+#ifdef PHP_OCI8_HAVE_COLLECTIONS
+ case SQLT_NTY:
+ {
+ zval **tmp;
+
+ if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
+ return 1;
+ }
+
+ PHP_OCI_ZVAL_TO_COLLECTION_EX(*tmp, bind_collection);
+ value_sz = sizeof(void*);
+ mode = OCI_DEFAULT;
+
+ if (!bind_collection->collection) {
+ return 1;
+ }
+ }
+ break;
+#endif
+ case SQLT_BFILEE:
+ case SQLT_CFILEE:
+ case SQLT_CLOB:
+ case SQLT_BLOB:
+ case SQLT_RDD:
+ {
+ zval **tmp;
+
+ if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
+ return 1;
+ }
+
+ PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, bind_descriptor);
+
+ value_sz = sizeof(void*);
+
+ oci_desc = bind_descriptor->descriptor;
+
+ if (!oci_desc) {
+ return 1;
+ }
+ }
+ break;
+
+ case SQLT_INT:
+ case SQLT_NUM:
+ convert_to_long(var);
+ bind_data = (ub4 *)&Z_LVAL_P(var);
+ value_sz = sizeof(ub4);
+ mode = OCI_DEFAULT;
+ break;
+
+ case SQLT_CHR:
+ /* this is the default case when type was not specified */
+ convert_to_string(var);
+ if (maxlength == -1) {
+ value_sz = Z_STRLEN_P(var);
+ }
+ else {
+ value_sz = maxlength;
+ }
+ break;
+
+ case SQLT_RSET:
+ PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement);
+ value_sz = sizeof(void*);
+
+ oci_stmt = bind_statement->stmt;
+
+ if (!oci_stmt) {
+ return 1;
+ }
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %ld", type);
+ return 1;
+ break;
+ }
+
+ if (value_sz == 0) {
+ value_sz = 1;
+ }
+
+ if (!statement->binds) {
+ ALLOC_HASHTABLE(statement->binds);
+ zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
+ }
+
+ memset((void*)&bind,0,sizeof(php_oci_bind));
+ zend_hash_update(statement->binds, name, name_len + 1, &bind, sizeof(php_oci_bind), (void **)&bindp);
+
+ bindp->descriptor = oci_desc;
+ bindp->statement = oci_stmt;
+ bindp->parent_statement = statement;
+ bindp->zval = var;
+ zval_add_ref(&var);
+
+ statement->errcode = PHP_OCI_CALL(
+ OCIBindByName,
+ (
+ statement->stmt, /* statement handle */
+ (OCIBind **)&bindp->bind, /* bind hdl (will alloc) */
+ statement->err, /* error handle */
+ (text*) name, /* placeholder name */
+ name_len, /* placeholder length */
+ (dvoid *)bind_data, /* in/out data */
+ value_sz, /* PHP_OCI_MAX_DATA_SIZE, */ /* max size of input/output data */
+ (ub2)type, /* in/out data type */
+ (dvoid *)&bindp->indicator, /* indicator (ignored) */
+ (ub2 *)0, /* size array (ignored) */
+ (ub2 *)&bindp->retcode, /* return code (ignored) */
+ (ub4)0, /* maxarr_len (PL/SQL only?) */
+ (ub4 *)0, /* actual array size (PL/SQL only?) */
+ mode /* mode */
+ )
+ );
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ if (mode == OCI_DATA_AT_EXEC) {
+ statement->errcode = PHP_OCI_CALL(OCIBindDynamic, (bindp->bind, statement->err, (dvoid *)bindp, php_oci_bind_in_callback, (dvoid *)bindp, php_oci_bind_out_callback));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+ }
+
+#ifdef PHP_OCI8_HAVE_COLLECTIONS
+ if (type == SQLT_NTY) {
+ /* Bind object */
+ statement->errcode = PHP_OCI_CALL(OCIBindObject, (bindp->bind, statement->err, bind_collection->tdo, (dvoid **) &(bind_collection->collection), (ub4 *) 0, (dvoid **) 0, (ub4 *) 0));
+
+ if (statement->errcode) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+ }
+#endif
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_bind_in_callback()
+ Callback used when binding LOBs and VARCHARs */
+sb4 php_oci_bind_in_callback(
+ dvoid *ictxp, /* context pointer */
+ OCIBind *bindp, /* bind handle */
+ ub4 iter, /* 0-based execute iteration value */
+ ub4 index, /* index of current array for PL/SQL or row index for SQL */
+ dvoid **bufpp, /* pointer to data */
+ ub4 *alenp, /* size after value/piece has been read */
+ ub1 *piecep, /* which piece */
+ dvoid **indpp) /* indicator value */
+{
+ php_oci_bind *phpbind;
+ zval *val;
+ TSRMLS_FETCH();
+
+ if (!(phpbind=(php_oci_bind *)ictxp) || !(val = phpbind->zval)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
+ return OCI_ERROR;
+ }
+
+ if (ZVAL_IS_NULL(val)) {
+ /* we're going to insert a NULL column */
+ phpbind->indicator = -1;
+ *bufpp = 0;
+ *alenp = -1;
+ *indpp = (dvoid *)&phpbind->indicator;
+ } else if ((phpbind->descriptor == 0) && (phpbind->statement == 0)) {
+ /* "normal string bind */
+ convert_to_string(val);
+
+ *bufpp = Z_STRVAL_P(val);
+ *alenp = Z_STRLEN_P(val);
+ *indpp = (dvoid *)&phpbind->indicator;
+ } else if (phpbind->statement != 0) {
+ /* RSET */
+ *bufpp = phpbind->statement;
+ *alenp = -1; /* seems to be allright */
+ *indpp = (dvoid *)&phpbind->indicator;
+ } else {
+ /* descriptor bind */
+ *bufpp = phpbind->descriptor;
+ *alenp = -1; /* seems to be allright */
+ *indpp = (dvoid *)&phpbind->indicator;
+ }
+
+ *piecep = OCI_ONE_PIECE; /* pass all data in one go */
+
+ return OCI_CONTINUE;
+}/* }}} */
+
+/* {{{ php_oci_bind_out_callback()
+ Callback used when binding LOBs and VARCHARs */
+sb4 php_oci_bind_out_callback(
+ dvoid *octxp, /* context pointer */
+ OCIBind *bindp, /* bind handle */
+ ub4 iter, /* 0-based execute iteration value */
+ ub4 index, /* index of current array for PL/SQL or row index for SQL */
+ dvoid **bufpp, /* pointer to data */
+ ub4 **alenpp, /* size after value/piece has been read */
+ ub1 *piecep, /* which piece */
+ dvoid **indpp, /* indicator value */
+ ub2 **rcodepp) /* return code */
+{
+ php_oci_bind *phpbind;
+ zval *val;
+ sb4 retval = OCI_ERROR;
+ TSRMLS_FETCH();
+
+ if (!(phpbind=(php_oci_bind *)octxp) || !(val = phpbind->zval)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
+ return retval;
+ }
+
+ if ((Z_TYPE_P(val) == IS_OBJECT) || (Z_TYPE_P(val) == IS_RESOURCE)) {
+ retval = OCI_CONTINUE;
+ } else {
+ convert_to_string(val);
+ zval_dtor(val);
+
+ Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */
+ Z_STRVAL_P(val) = emalloc(Z_STRLEN_P(phpbind->zval));
+
+ /* XXX we assume that zend-zval len has 4 bytes */
+ *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval);
+ *bufpp = Z_STRVAL_P(phpbind->zval);
+ *piecep = OCI_ONE_PIECE;
+ *rcodepp = &phpbind->retcode;
+ *indpp = &phpbind->indicator;
+ retval = OCI_CONTINUE;
+ }
+
+ return retval;
+}
+/* }}} */
+
+/* {{{ php_oci_statement_get_column_helper()
+ Helper function to get column by name and index */
+php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *z_statement, *column_index;
+ php_oci_statement *statement;
+ php_oci_out_column *column;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_statement, &column_index) == FAILURE) {
+ return NULL;
+ }
+
+ statement = (php_oci_statement *) zend_fetch_resource(&z_statement TSRMLS_CC, -1, "oci8 statement", NULL, 1, le_statement);
+
+ if (!statement) {
+ return NULL;
+ }
+
+ if (Z_TYPE_P(column_index) == IS_STRING) {
+ column = php_oci_statement_get_column(statement, -1, Z_STRVAL_P(column_index), Z_STRLEN_P(column_index) TSRMLS_CC);
+ if (!column) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column name \"%s\"", Z_STRVAL_P(column_index));
+ return NULL;
+ }
+ }
+ else {
+ convert_to_long(column_index);
+ column = php_oci_statement_get_column(statement, Z_LVAL_P(column_index), NULL, 0 TSRMLS_CC);
+ if (!column) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column index \"%ld\"", Z_LVAL_P(column_index));
+ return NULL;
+ }
+ }
+ return column;
+} /* }}} */
+
+/* {{{ php_oci_statement_get_type()
+ Return type of the statement */
+int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC)
+{
+ ub2 statement_type;
+
+ *type = 0;
+
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ *type = statement_type;
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_statement_get_numrows()
+ Get the number of rows fetched to the clientside (NOT the number of rows in the result set) */
+int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC)
+{
+ ub4 statement_numrows;
+
+ *numrows = 0;
+
+ statement->errcode = PHP_OCI_CALL(OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err));
+
+ if (statement->errcode != OCI_SUCCESS) {
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+
+ *numrows = statement_numrows;
+
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_bind_array_by_name()
+ Bind arrays to PL/SQL types */
+int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC)
+{
+ php_oci_bind *bind, *bindp;
+
+ convert_to_array(var);
+
+ if (maxlength < -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid max length value (%ld)", maxlength);
+ return 1;
+ }
+
+ switch(type) {
+ case SQLT_NUM:
+ case SQLT_INT:
+ case SQLT_LNG:
+ bind = php_oci_bind_array_helper_number(var, max_table_length TSRMLS_CC);
+ break;
+
+ case SQLT_FLT:
+ bind = php_oci_bind_array_helper_double(var, max_table_length TSRMLS_CC);
+ break;
+
+ case SQLT_AFC:
+ case SQLT_CHR:
+ case SQLT_VCS:
+ case SQLT_AVC:
+ case SQLT_STR:
+ case SQLT_LVC:
+ if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(var)) == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must provide max length value for empty arrays");
+ return 1;
+ }
+ bind = php_oci_bind_array_helper_string(var, max_table_length, maxlength TSRMLS_CC);
+ break;
+ case SQLT_ODT:
+ bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection TSRMLS_CC);
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported bind type (%ld)", type);
+ return 1;
+ break;
+ }
+
+ if (bind == NULL) {
+ /* failed to generate bind struct */
+ return 1;
+ }
+
+ if (!statement->binds) {
+ ALLOC_HASHTABLE(statement->binds);
+ zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
+ }
+
+ zend_hash_update(statement->binds, name, name_len + 1, bind, sizeof(php_oci_bind), (void **)&bindp);
+
+ bindp->descriptor = NULL;
+ bindp->statement = NULL;
+ bindp->parent_statement = statement;
+ bindp->bind = NULL;
+ bindp->zval = var;
+ bindp->array.type = type;
+ zval_add_ref(&var);
+
+ statement->errcode = PHP_OCI_CALL(
+ OCIBindByName,
+ (
+ statement->stmt,
+ (OCIBind **)&bindp->bind,
+ statement->err,
+ (text *)name,
+ name_len,
+ (dvoid *) bindp->array.elements,
+ (sb4) bind->array.max_length,
+ type,
+ (dvoid *)0, /* bindp->array.indicators, */
+ (ub2 *)0, /* bindp->array.element_lengths, */
+ (ub2 *)0, /* bindp->array.retcodes, */
+ (ub4) max_table_length,
+ (ub4 *) &(bindp->array.current_length),
+ (ub4) OCI_DEFAULT
+ )
+ );
+
+
+ if (statement->errcode != OCI_SUCCESS) {
+ efree(bind);
+ php_oci_error(statement->err, statement->errcode TSRMLS_CC);
+ PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
+ return 1;
+ }
+ efree(bind);
+ return 0;
+} /* }}} */
+
+/* {{{ php_oci_bind_array_helper_string()
+ Bind arrays to PL/SQL types */
+php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC)
+{
+ php_oci_bind *bind;
+ ub4 i;
+ HashTable *hash;
+ zval **entry;
+
+ hash = HASH_OF(var);
+
+ if (maxlength == -1) {
+ zend_hash_internal_pointer_reset(hash);
+ while (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
+ convert_to_string_ex(entry);
+ if (Z_STRLEN_PP(entry) > maxlength) {
+ maxlength = Z_STRLEN_PP(entry);
+ }
+ zend_hash_move_forward(hash);
+ }
+ }
+
+ bind = emalloc(sizeof(php_oci_bind));
+ bind->array.elements = (text *)emalloc(max_table_length * sizeof(text) * (maxlength + 1));
+ bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
+ bind->array.old_length = bind->array.current_length;
+ bind->array.max_length = maxlength;
+
+ zend_hash_internal_pointer_reset(hash);
+ for (i = 0; i < max_table_length; i++) {
+ if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ int element_length;
+
+ convert_to_string_ex(entry);
+ element_length = (maxlength > Z_STRLEN_PP(entry)) ? Z_STRLEN_PP(entry) : maxlength;
+
+ memcpy(bind->array.elements + i*maxlength, Z_STRVAL_PP(entry), element_length);
+ ((text *)bind->array.elements)[i*maxlength + element_length] = '\0';
+
+ zend_hash_move_forward(hash);
+ }
+ else {
+ ((text *)bind->array.elements)[i*maxlength] = '\0';
+ }
+ }
+ zend_hash_internal_pointer_reset(hash);
+
+ return bind;
+} /* }}} */
+
+/* {{{ php_oci_bind_array_helper_number()
+ Bind arrays to PL/SQL types */
+php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC)
+{
+ php_oci_bind *bind;
+ ub4 i;
+ HashTable *hash;
+ zval **entry;
+
+ hash = HASH_OF(var);
+
+ bind = emalloc(sizeof(php_oci_bind));
+ bind->array.elements = (ub4 *)emalloc(max_table_length * sizeof(ub4));
+ bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
+ bind->array.old_length = bind->array.current_length;
+ bind->array.max_length = sizeof(ub4);
+
+ zend_hash_internal_pointer_reset(hash);
+ for (i = 0; i < max_table_length; i++) {
+ if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ convert_to_long_ex(entry);
+ ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_PP(entry);
+ zend_hash_move_forward(hash);
+ }
+ else {
+ ((ub4 *)bind->array.elements)[i] = 0;
+ }
+ }
+ zend_hash_internal_pointer_reset(hash);
+
+ return bind;
+} /* }}} */
+
+/* {{{ php_oci_bind_array_helper_double()
+ Bind arrays to PL/SQL types */
+php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC)
+{
+ php_oci_bind *bind;
+ ub4 i;
+ HashTable *hash;
+ zval **entry;
+
+ hash = HASH_OF(var);
+
+ bind = emalloc(sizeof(php_oci_bind));
+ bind->array.elements = (double *)emalloc(max_table_length * sizeof(double));
+ bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
+ bind->array.old_length = bind->array.current_length;
+ bind->array.max_length = sizeof(double);
+
+ zend_hash_internal_pointer_reset(hash);
+ for (i = 0; i < max_table_length; i++) {
+ if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+ convert_to_double_ex(entry);
+ ((double *)bind->array.elements)[i] = (double) Z_DVAL_PP(entry);
+ zend_hash_move_forward(hash);
+ }
+ else {
+ ((double *)bind->array.elements)[i] = 0;
+ }
+ }
+ zend_hash_internal_pointer_reset(hash);
+
+ return bind;
+} /* }}} */
+
+/* {{{ php_oci_bind_array_helper_date()
+ Bind arrays to PL/SQL types */
+php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC)
+{
+ php_oci_bind *bind;
+ ub4 i;
+ HashTable *hash;
+ zval **entry;
+
+ hash = HASH_OF(var);
+
+ bind = emalloc(sizeof(php_oci_bind));
+ bind->array.elements = (OCIDate *)emalloc(max_table_length * sizeof(OCIDate));
+ bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var));
+ bind->array.old_length = bind->array.current_length;
+ bind->array.max_length = sizeof(OCIDate);
+
+ zend_hash_internal_pointer_reset(hash);
+ for (i = 0; i < max_table_length; i++) {
+ OCIDate oci_date;
+ if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
+
+ convert_to_string_ex(entry);
+ connection->errcode = PHP_OCI_CALL(OCIDateFromText, (connection->err, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ /* failed to convert string to date */
+ efree(bind->array.elements);
+ efree(bind);
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return NULL;
+ }
+
+ ((OCIDate *)bind->array.elements)[i] = oci_date;
+ zend_hash_move_forward(hash);
+ }
+ else {
+ connection->errcode = PHP_OCI_CALL(OCIDateFromText, (connection->err, "01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date));
+
+ if (connection->errcode != OCI_SUCCESS) {
+ /* failed to convert string to date */
+ efree(bind->array.elements);
+ efree(bind);
+ php_oci_error(connection->err, connection->errcode TSRMLS_CC);
+ return NULL;
+ }
+
+ ((OCIDate *)bind->array.elements)[i] = oci_date;
+ }
+ }
+ zend_hash_internal_pointer_reset(hash);
+
+ return bind;
+} /* }}} */
+
+#endif /* HAVE_OCI8 */
diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml
index b0b168a028..ce9ff36ffd 100644
--- a/ext/oci8/package.xml
+++ b/ext/oci8/package.xml
@@ -2,84 +2,200 @@
<!DOCTYPE package SYSTEM "../pear/package.dtd">
<package>
<name>oci8</name>
- <summary>Oracle 8 call interface functions</summary>
+ <summary>OCI8 functions</summary>
<maintainers>
<maintainer>
<user>tony2001</user>
<name>Antony Dovgal</name>
<email>tony2001@php.net</email>
- <role>developer</role>
+ <role>lead</role>
</maintainer>
<maintainer>
- <user>ssb</user>
- <name>Stig Bakken</name>
- <email>ssb@php.net</email>
- <role>developer</role>
+ <user>wez</user>
+ <name>Wez Furlong</name>
+ <email>wez@php.net</email>
+ <role>lead</role>
</maintainer>
<maintainer>
- <user>thies</user>
- <name>Thies C. Arntzen</name>
- <email>thies@php.net</email>
- <role>developer</role>
- </maintainer>
- <maintainer>
- <user>asautins</user>
- <name>Andy Sautins</name>
- <email>asautins@php.net</email>
- <role>developer</role>
- </maintainer>
- <maintainer>
- <user>dbenson</user>
- <name>David Benson</name>
- <email>dbenson@php.net</email>
- <role>developer</role>
- </maintainer>
- <maintainer>
- <user>maxim</user>
- <name>Maxim Maletsky</name>
- <email>maxim@php.net</email>
- <role>developer</role>
- </maintainer>
- <maintainer>
- <user>phanto</user>
- <name>Harald Radi</name>
- <email>phanto@php.net</email>
- <role>developer</role>
+ <user>andi</user>
+ <name>Andi Gutmans</name>
+ <email>andi@zend.com</email>
+ <role>lead</role>
</maintainer>
</maintainers>
<description>
-These functions allow you to access Oracle database servers using
-the Oracle 8 call interface.
+ These functions allow you to access Oracle database servers using
+ the Oracle Call Interface (OCI8).
</description>
<license>PHP</license>
<release>
<state>beta</state>
- <version>5.0.0rc1</version>
- <date>2004-03-19</date>
+ <version>1.2</version>
+ <date>2005-??-??</date>
<notes>
-package.xml added to support intallation using pear installer
+ Fixed PECL bug #5571 (oci_new_connect() not closed by oci_close())
+ Fixed bug #33383 (crash when retrieving empty BLOBs)
</notes>
- <configureoptions>
- <configureoption name="with-oci8" default="autodetect" prompt="ORACLE_HOME directory?"/>
- </configureoptions>
- <filelist>
- <file role="doc" name="CREDITS"/>
- <file role="src" name="config.m4"/>
- <file role="src" name="config.w32"/>
- <file role="src" name="oci8.dsp"/>
- <file role="src" name="oci8.c"/>
- <file role="src" name="php_oci8.h"/>
- <file role="test" name="tests/bug26133.phpt"/>
- <file role="test" name="tests/connect.inc"/>
- <file role="test" name="tests/create_table.inc"/>
- <file role="test" name="tests/drop_table.inc"/>
- <file role="test" name="tests/skipif.inc"/>
- </filelist>
- <deps>
- <dep type="php" rel="ge" version="5" />
- </deps>
</release>
-</package>
+ <filelist>
+ <file role="doc" name="CREDITS"/>
+ <file role="doc" name="README"/>
+ <file role="src" name="config.m4"/>
+ <file role="src" name="config.w32"/>
+ <file role="src" name="oci8.dsp"/>
+ <file role="src" name="oci8.c"/>
+ <file role="src" name="oci8_interface.c"/>
+ <file role="src" name="oci8_lob.c"/>
+ <file role="src" name="oci8_statement.c"/>
+ <file role="src" name="oci8_collection.c"/>
+ <file role="src" name="php_oci8.h"/>
+ <file role="src" name="php_oci8_int.h"/>
+ <file role="test" name="tests/bug26133.phpt"/>
+ <file role="test" name="tests/bug27303_2.phpt"/>
+ <file role="test" name="tests/bug27303_3.phpt"/>
+ <file role="test" name="tests/bug27303_4.phpt"/>
+ <file role="test" name="tests/bug27303.phpt"/>
+ <file role="test" name="tests/bug32325.phpt"/>
+ <file role="test" name="tests/close.phpt"/>
+ <file role="test" name="tests/coll_001.phpt"/>
+ <file role="test" name="tests/coll_002_func.phpt"/>
+ <file role="test" name="tests/coll_002.phpt"/>
+ <file role="test" name="tests/coll_003_func.phpt"/>
+ <file role="test" name="tests/coll_003.phpt"/>
+ <file role="test" name="tests/coll_004_func.phpt"/>
+ <file role="test" name="tests/coll_004.phpt"/>
+ <file role="test" name="tests/coll_005.phpt"/>
+ <file role="test" name="tests/coll_006_func.phpt"/>
+ <file role="test" name="tests/coll_006.phpt"/>
+ <file role="test" name="tests/coll_007.phpt"/>
+ <file role="test" name="tests/coll_008.phpt"/>
+ <file role="test" name="tests/coll_009_func.phpt"/>
+ <file role="test" name="tests/coll_009.phpt"/>
+ <file role="test" name="tests/coll_010_func.phpt"/>
+ <file role="test" name="tests/coll_010.phpt"/>
+ <file role="test" name="tests/coll_011_func.phpt"/>
+ <file role="test" name="tests/coll_011.phpt"/>
+ <file role="test" name="tests/coll_012_func.phpt"/>
+ <file role="test" name="tests/coll_012.phpt"/>
+ <file role="test" name="tests/coll_013_func.phpt"/>
+ <file role="test" name="tests/coll_013.phpt"/>
+ <file role="test" name="tests/coll_014_func.phpt"/>
+ <file role="test" name="tests/coll_014.phpt"/>
+ <file role="test" name="tests/coll_015_func.phpt"/>
+ <file role="test" name="tests/coll_015.phpt"/>
+ <file role="test" name="tests/coll_016_func.phpt"/>
+ <file role="test" name="tests/coll_016.phpt"/>
+ <file role="test" name="tests/coll_017_func.phpt"/>
+ <file role="test" name="tests/coll_017.phpt"/>
+ <file role="test" name="tests/commit_old.phpt"/>
+ <file role="test" name="tests/commit.phpt"/>
+ <file role="test" name="tests/connect_1_old.phpt"/>
+ <file role="test" name="tests/connect_1.phpt"/>
+ <file role="test" name="tests/connect.inc"/>
+ <file role="test" name="tests/connect_old.phpt"/>
+ <file role="test" name="tests/connect.phpt"/>
+ <file role="test" name="tests/connect_without_oracle_home_old.phpt"/>
+ <file role="test" name="tests/connect_without_oracle_home.phpt"/>
+ <file role="test" name="tests/create_table.inc"/>
+ <file role="test" name="tests/create_type.inc"/>
+ <file role="test" name="tests/cursor_bind_err.phpt"/>
+ <file role="test" name="tests/cursors_old.phpt"/>
+ <file role="test" name="tests/cursors.phpt"/>
+ <file role="test" name="tests/debug.phpt"/>
+ <file role="test" name="tests/default_prefetch1.phpt"/>
+ <file role="test" name="tests/default_prefetch2.phpt"/>
+ <file role="test" name="tests/default_prefetch.phpt"/>
+ <file role="test" name="tests/define_old.phpt"/>
+ <file role="test" name="tests/define.phpt"/>
+ <file role="test" name="tests/drop_table.inc"/>
+ <file role="test" name="tests/drop_type.inc"/>
+ <file role="test" name="tests/error_old.phpt"/>
+ <file role="test" name="tests/error.phpt"/>
+ <file role="test" name="tests/exec_fetch.phpt"/>
+ <file role="test" name="tests/fetch_all.phpt"/>
+ <file role="test" name="tests/fetch_array.phpt"/>
+ <file role="test" name="tests/fetch_assoc.phpt"/>
+ <file role="test" name="tests/fetch_into1.phpt"/>
+ <file role="test" name="tests/fetch_into2.phpt"/>
+ <file role="test" name="tests/fetch_into.phpt"/>
+ <file role="test" name="tests/fetch_object.phpt"/>
+ <file role="test" name="tests/fetch.phpt"/>
+ <file role="test" name="tests/fetch_row.phpt"/>
+ <file role="test" name="tests/field_funcs_old.phpt"/>
+ <file role="test" name="tests/field_funcs.phpt"/>
+ <file role="test" name="tests/lob_001.phpt"/>
+ <file role="test" name="tests/lob_002.phpt"/>
+ <file role="test" name="tests/lob_003.phpt"/>
+ <file role="test" name="tests/lob_004.phpt"/>
+ <file role="test" name="tests/lob_005.phpt"/>
+ <file role="test" name="tests/lob_006.phpt"/>
+ <file role="test" name="tests/lob_007.phpt"/>
+ <file role="test" name="tests/lob_008.phpt"/>
+ <file role="test" name="tests/lob_009.phpt"/>
+ <file role="test" name="tests/lob_009.txt"/>
+ <file role="test" name="tests/lob_010.phpt"/>
+ <file role="test" name="tests/lob_011.phpt"/>
+ <file role="test" name="tests/lob_012.phpt"/>
+ <file role="test" name="tests/lob_013.phpt"/>
+ <file role="test" name="tests/lob_014.phpt"/>
+ <file role="test" name="tests/lob_015.phpt"/>
+ <file role="test" name="tests/lob_016.phpt"/>
+ <file role="test" name="tests/lob_017.phpt"/>
+ <file role="test" name="tests/lob_018.phpt"/>
+ <file role="test" name="tests/lob_temp1.phpt"/>
+ <file role="test" name="tests/lob_temp.phpt"/>
+ <file role="test" name="tests/num.phpt"/>
+ <file role="test" name="tests/oci_execute_segfault.phpt"/>
+ <file role="test" name="tests/old_oci_close1.phpt"/>
+ <file role="test" name="tests/old_oci_close.phpt"/>
+ <file role="test" name="tests/password_new.phpt"/>
+ <file role="test" name="tests/password_old.phpt"/>
+ <file role="test" name="tests/password.phpt"/>
+ <file role="test" name="tests/persistent.phpt"/>
+ <file role="test" name="tests/prefetch_old.phpt"/>
+ <file role="test" name="tests/prefetch.phpt"/>
+ <file role="test" name="tests/privileged_connect1.phpt"/>
+ <file role="test" name="tests/privileged_connect.phpt"/>
+ <file role="test" name="tests/serverversion.phpt"/>
+ <file role="test" name="tests/skipif.inc"/>
+ <file role="test" name="tests/statement_cache.phpt"/>
+ <file role="test" name="tests/statement_type_old.phpt"/>
+ <file role="test" name="tests/statement_type.phpt"/>
+ <file role="test" name="tests/uncommitted.phpt"/>
+ </filelist>
+ <configureoptions>
+ <configureoption name="with-oci8" default="autodetect" prompt="Please provide the path to ORACLE_HOME dir. Use 'instantclient,/path/to/instant/client/lib' if you're compiling against Oracle Instant Client"/>
+ </configureoptions>
+ <changelog>
+ <release>
+ <state>beta</state>
+ <version>1.1.1</version>
+ <date>2005-09-22</date>
+ <notes>
+ Fixed segfault when binding empty values.
+ Fixed problem with oci_error() without arguments.
+ </notes>
+ </release>
+ <release>
+ <state>beta</state>
+ <version>1.1</version>
+ <date>2005-09-07</date>
+ <notes>
+ This release fixes a huge amount of bugs and adds support of
+ statement caching, external credentials etc.
+ See official announce for details.
+ </notes>
+ </release>
+ <release>
+ <state>beta</state>
+ <version>1.0</version>
+ <date>2004-03-19</date>
+ <notes>
+ package.xml added to support installation using pear installer
+ </notes>
+ </release>
+ </changelog>
+ </package>
<!--
vim:et:ts=1:sw=1
-->
diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h
index 9da34f85f1..6397d3fede 100644
--- a/ext/oci8/php_oci8.h
+++ b/ext/oci8/php_oci8.h
@@ -14,6 +14,14 @@
+----------------------------------------------------------------------+
| Authors: Stig Sæther Bakken <ssb@php.net> |
| Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+----------------------------------------------------------------------+
*/
@@ -22,19 +30,6 @@
#if HAVE_OCI8
# ifndef PHP_OCI8_H
# define PHP_OCI8_H
-# endif
-
-# if (defined(__osf__) && defined(__alpha))
-# ifndef A_OSF
-# define A_OSF
-# endif
-# ifndef OSF1
-# define OSF1
-# endif
-# ifndef _INTRINSICS
-# define _INTRINSICS
-# endif
-# endif /* osf alpha */
#ifdef PHP_WIN32
#define PHP_OCI_API __declspec(dllexport)
@@ -42,175 +37,21 @@
#define PHP_OCI_API
#endif
-#if defined(min)
-#undef min
-#endif
-#if defined(max)
-#undef max
-#endif
-
-#include <oci.h>
-
-#define OCI_SEEK_SET 0
-#define OCI_SEEK_CUR 1
-#define OCI_SEEK_END 2
-
-typedef struct {
- int num;
- int persistent;
- int is_open;
- char *dbname;
- OCIServer *pServer;
-#if 0
- OCIFocbkStruct failover;
-#endif
-} oci_server;
-
-typedef struct {
- int num;
- zend_bool persistent;
- zend_bool is_open;
- zend_bool exclusive;
-#if ZTS
- THREAD_T thread;
-#else
- zend_bool thread;
+#ifdef ZTS
+# include "TSRM.h"
#endif
- zend_llist *sessions_list;
- oci_server *server;
- OCISession *pSession;
- OCIEnv *pEnv; /* sessions own environment */
- ub2 charsetId; /* sessions used character set (mostly this will be 0, so NLS_LANG will be used. */
-} oci_session;
-
-typedef struct {
- int id;
- int is_open;
- oci_session *session;
- OCISvcCtx *pServiceContext;
- sword error;
- OCIError *pError;
- int needs_commit;
- HashTable *descriptors;
-} oci_connection;
-
-typedef struct {
- int id;
- oci_connection *conn;
- dvoid *ocidescr;
- ub4 type;
- int lob_current_position;
- int lob_size; /* -1 = Lob wasn't initialized yet */
- int buffering; /* 0 - off, 1 - on, 2 - on and buffer was used */
-} oci_descriptor;
-
-typedef struct {
- int id;
- oci_connection *conn;
- OCIType *tdo;
- OCITypeCode coll_typecode;
- OCIRef *elem_ref;
- OCIType *element_type;
- OCITypeCode element_typecode;
- OCIColl *coll;
-} oci_collection;
-
-typedef struct {
- zval *zval;
- text *name;
- ub4 name_len;
- ub4 type;
-} oci_define;
-
-typedef struct {
- int id;
- oci_connection *conn;
- sword error;
- OCIError *pError;
- OCIStmt *pStmt;
- char *last_query;
- HashTable *columns;
- HashTable *binds;
- HashTable *defines;
- int ncolumns;
- int executed;
- int has_data;
- ub2 stmttype;
-} oci_statement;
-
-typedef struct {
- OCIBind *pBind;
- zval *zval;
- dvoid *descr; /* used for binding of LOBS etc */
- OCIStmt *pStmt; /* used for binding REFCURSORs */
- sb2 indicator;
- ub2 retcode;
-} oci_bind;
-
-typedef struct {
- oci_statement *statement;
- OCIDefine *pDefine;
- char *name;
- ub4 name_len;
- ub2 data_type;
- ub2 data_size;
- ub4 storage_size4;
- sb2 indicator;
- ub2 retcode;
- ub2 retlen;
- ub4 retlen4;
- ub2 is_descr;
- ub2 is_cursor;
- int descr;
- oci_statement *pstmt;
- int stmtid;
- int descid;
- void *data;
- oci_define *define;
- int piecewise;
- ub4 cb_retlen;
- ub2 scale;
- ub2 precision;
-} oci_out_column;
-
-typedef struct {
- sword error;
- OCIError *pError;
-
- /*
- char *default_username;
- char *default_password;
- char *default_dbname;
- */
-
- long debug_mode;
-
- int shutdown;
-
- /* XXX NYI
- long allow_persistent;
- long max_persistent;
- long max_links;
- */
-
- OCIEnv *pEnv;
-
- int in_call;
-} php_oci_globals;
extern zend_module_entry oci8_module_entry;
#define phpext_oci8_ptr &oci8_module_entry
-#define OCI_MAX_NAME_LEN 64
-#define OCI_MAX_DATA_SIZE INT_MAX
-#define OCI_PIECE_SIZE (64*1024)-1
-#ifdef ZTS
-#define OCI(v) TSRMG(oci_globals_id, php_oci_globals *, v)
-#else
-#define OCI(v) (oci_globals.v)
-#endif
+PHP_MINIT_FUNCTION(oci);
+PHP_RINIT_FUNCTION(oci);
+PHP_MSHUTDOWN_FUNCTION(oci);
+PHP_RSHUTDOWN_FUNCTION(oci);
+PHP_MINFO_FUNCTION(oci);
+# endif /* !PHP_OCI8_H */
#else /* !HAVE_OCI8 */
# define oci8_module_ptr NULL
@@ -223,3 +64,5 @@ extern zend_module_entry oci8_module_entry;
* c-basic-offset: 4
* End:
*/
+
+
diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
new file mode 100644
index 0000000000..0b42e09498
--- /dev/null
+++ b/ext/oci8/php_oci8_int.h
@@ -0,0 +1,422 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stig Sæther Bakken <ssb@php.net> |
+ | Thies C. Arntzen <thies@thieso.net> |
+ | |
+ | Collection support by Andy Sautins <asautins@veripost.net> |
+ | Temporary LOB support by David Benson <dbenson@mancala.com> |
+ | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
+ | |
+ | Redesigned by: Antony Dovgal <antony@zend.com> |
+ | Andi Gutmans <andi@zend.com> |
+ | Wez Furlong <wez@omniti.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#if HAVE_OCI8
+# ifndef PHP_OCI8_INT_H
+# define PHP_OCI8_INT_H
+
+/* misc defines {{{ */
+# if (defined(__osf__) && defined(__alpha))
+# ifndef A_OSF
+# define A_OSF
+# endif
+# ifndef OSF1
+# define OSF1
+# endif
+# ifndef _INTRINSICS
+# define _INTRINSICS
+# endif
+# endif /* osf alpha */
+
+#if defined(min)
+#undef min
+#endif
+#if defined(max)
+#undef max
+#endif
+/* }}} */
+
+#include "ext/standard/php_string.h"
+#include <oci.h>
+
+extern int le_connection;
+extern int le_pconnection;
+extern int le_statement;
+extern int le_descriptor;
+#ifdef PHP_OCI8_HAVE_COLLECTIONS
+extern int le_collection;
+#endif
+extern int le_server;
+extern int le_session;
+
+extern zend_class_entry *oci_lob_class_entry_ptr;
+#ifdef PHP_OCI8_HAVE_COLLECTIONS
+extern zend_class_entry *oci_coll_class_entry_ptr;
+#endif
+
+/* constants {{{ */
+#define PHP_OCI_SEEK_SET 0
+#define PHP_OCI_SEEK_CUR 1
+#define PHP_OCI_SEEK_END 2
+
+#define PHP_OCI_MAX_NAME_LEN 64
+#define PHP_OCI_MAX_DATA_SIZE INT_MAX
+#define PHP_OCI_PIECE_SIZE (64*1024)-1
+#define PHP_OCI_LOB_BUFFER_SIZE 1048576l
+
+#define PHP_OCI_ASSOC 1<<0
+#define PHP_OCI_NUM 1<<1
+#define PHP_OCI_BOTH (PHP_OCI_ASSOC|PHP_OCI_NUM)
+
+#define PHP_OCI_RETURN_NULLS 1<<2
+#define PHP_OCI_RETURN_LOBS 1<<3
+
+#define PHP_OCI_FETCHSTATEMENT_BY_COLUMN 1<<4
+#define PHP_OCI_FETCHSTATEMENT_BY_ROW 1<<5
+#define PHP_OCI_FETCHSTATEMENT_BY (PHP_OCI_FETCHSTATEMENT_BY_COLUMN | PHP_OCI_FETCHSTATEMENT_BY_ROW)
+
+#define PHP_OCI_LOB_BUFFER_DISABLED 0
+#define PHP_OCI_LOB_BUFFER_ENABLED 1
+#define PHP_OCI_LOB_BUFFER_USED 2
+
+/* }}} */
+
+typedef struct { /* php_oci_connection {{{ */
+ OCIEnv *env; /* private env handle */
+ ub2 charset; /* charset ID */
+ OCIServer *server; /* private server handle */
+ OCISvcCtx *svc; /* private service context handle */
+ OCISession *session; /* private session handle */
+ OCIError *err; /* private error handle */
+ sword errcode; /* last errcode */
+
+ HashTable *descriptors; /* descriptors hash, used to flush all the LOBs using this connection on commit */
+ unsigned is_open:1; /* hels to determine if the connection is dead or not */
+ unsigned is_attached:1; /* hels to determine if we should detach from the server when closing/freeing the connection */
+ unsigned is_persistent:1; /* self-descriptive */
+ unsigned used_this_request:1; /* helps to determine if we should reset connection's next ping time and check its timeout */
+ unsigned needs_commit:1; /* helps to determine if we should rollback this connection on close/shutdown */
+ int rsrc_id; /* resource ID */
+ time_t idle_expiry; /* time when the connection will be considered as expired */
+ time_t next_ping; /* time of the next ping */
+ char *hash_key; /* hashed details of the connection */
+} php_oci_connection; /* }}} */
+
+typedef struct { /* php_oci_descriptor {{{ */
+ int id;
+ php_oci_connection *connection; /* parent connection handle */
+ dvoid *descriptor; /* OCI descriptor handle */
+ ub4 type; /* descriptor type */
+ int lob_current_position; /* LOB internal pointer */
+ int lob_size; /* cached LOB size. -1 = Lob wasn't initialized yet */
+ int buffering; /* cached buffering flag. 0 - off, 1 - on, 2 - on and buffer was used */
+} php_oci_descriptor; /* }}} */
+
+typedef struct { /* php_oci_collection {{{ */
+ int id;
+ php_oci_connection *connection; /* parent connection handle */
+ OCIType *tdo; /* collection's type handle */
+ OCITypeCode coll_typecode; /* collection's typecode handle */
+ OCIRef *elem_ref; /* element's reference handle */
+ OCIType *element_type; /* element's type handle */
+ OCITypeCode element_typecode; /* element's typecode handle */
+ OCIColl *collection; /* collection handle */
+} php_oci_collection; /* }}} */
+
+typedef struct { /* php_oci_define {{{ */
+ zval *zval; /* zval used in define */
+ text *name; /* placeholder's name */
+ ub4 name_len; /* placeholder's name length */
+ ub4 type; /* define type */
+} php_oci_define; /* }}} */
+
+typedef struct { /* php_oci_statement {{{ */
+ int id;
+ php_oci_connection *connection; /* parent connection handle */
+ sword errcode; /* last errcode*/
+ OCIError *err; /* private error handle */
+ OCIStmt *stmt; /* statement handle */
+ char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor recieved from Oracle */
+ long last_query_len; /* last query length */
+ HashTable *columns; /* hash containing all the result columns */
+ HashTable *binds; /* binds hash */
+ HashTable *defines; /* defines hash */
+ int ncolumns; /* number of columns in the result */
+ unsigned executed:1; /* statement executed flag */
+ unsigned has_data:1; /* statement has more data flag */
+ ub2 stmttype; /* statement type */
+} php_oci_statement; /* }}} */
+
+typedef struct { /* php_oci_bind {{{ */
+ OCIBind *bind; /* bind handle */
+ zval *zval; /* value */
+ dvoid *descriptor; /* used for binding of LOBS etc */
+ OCIStmt *statement; /* used for binding REFCURSORs */
+ php_oci_statement *parent_statement; /* pointer to the parent statement */
+ struct {
+ void *elements;
+/* ub2 *indicators;
+ ub2 *element_lengths;
+ ub2 *retcodes; */
+ long current_length;
+ long old_length;
+ long max_length;
+ long type;
+ } array;
+ sb2 indicator; /* */
+ ub2 retcode; /* */
+} php_oci_bind; /* }}} */
+
+typedef struct { /* php_oci_out_column {{{ */
+ php_oci_statement *statement; /* statement handle. used when fetching REFCURSORS */
+ OCIDefine *oci_define; /* define handle */
+ char *name; /* column name */
+ ub4 name_len; /* column name length */
+ ub2 data_type; /* column data type */
+ ub2 data_size; /* data size */
+ ub4 storage_size4; /* size used when allocating buffers */
+ sb2 indicator; /* */
+ ub2 retcode; /* code returned when fetching this particular column */
+ ub2 retlen; /* */
+ ub4 retlen4; /* */
+ ub2 is_descr; /* column contains a descriptor */
+ ub2 is_cursor; /* column contains a cursor */
+ int stmtid; /* statement id for cursors */
+ int descid; /* descriptor id for descriptors */
+ void *data; /* */
+ php_oci_define *define; /* define handle */
+ int piecewise; /* column is fetched piece-by-piece */
+ ub4 cb_retlen; /* */
+ ub2 scale; /* column scale */
+ ub2 precision; /* column precision */
+} php_oci_out_column; /* }}} */
+
+/* {{{ macros */
+
+#define PHP_OCI_CALL(func, params) \
+ func params; \
+ if (OCI_G(debug_mode)) { \
+ php_printf ("OCI8 DEBUG: " #func " at (%s:%d) \n", __FILE__, __LINE__); \
+ }
+
+#define PHP_OCI_HANDLE_ERROR(connection, errcode) \
+{ \
+ switch (errcode) { \
+ case 1013: \
+ zend_bailout(); \
+ break; \
+ case 22: \
+ case 1012: \
+ case 3113: \
+ case 604: \
+ case 1041: \
+ case 3114: \
+ connection->is_open = 0; \
+ break; \
+ } \
+} \
+
+#define PHP_OCI_REGISTER_RESOURCE(resource, le_resource) \
+ resource->id = ZEND_REGISTER_RESOURCE(NULL, resource, le_resource); \
+ zend_list_addref(resource->connection->rsrc_id);
+
+#define PHP_OCI_ZVAL_TO_CONNECTION(zval, connection) \
+ ZEND_FETCH_RESOURCE2(connection, php_oci_connection *, &zval, -1, "oci8 connection", le_connection, le_pconnection);
+
+#define PHP_OCI_ZVAL_TO_STATEMENT(zval, statement) \
+ ZEND_FETCH_RESOURCE(statement, php_oci_statement *, &zval, -1, "oci8 statement", le_statement)
+
+#define PHP_OCI_ZVAL_TO_DESCRIPTOR(zval, descriptor) \
+ ZEND_FETCH_RESOURCE(descriptor, php_oci_descriptor *, &zval, -1, "oci8 descriptor", le_descriptor)
+
+#define PHP_OCI_ZVAL_TO_COLLECTION(zval, collection) \
+ ZEND_FETCH_RESOURCE(collection, php_oci_collection *, &zval, -1, "oci8 collection", le_collection)
+
+#define PHP_OCI_FETCH_RESOURCE_EX(zval, var, type, name, resource_type) \
+ var = (type) zend_fetch_resource(&zval TSRMLS_CC, -1, name, NULL, 1, resource_type); \
+ if (!var) { \
+ return 1; \
+ }
+
+#define PHP_OCI_ZVAL_TO_CONNECTION_EX(zval, connection) \
+ PHP_OCI_FETCH_RESOURCE_EX(zval, connection, php_oci_connection *, "oci8 connection", le_connection)
+
+#define PHP_OCI_ZVAL_TO_STATEMENT_EX(zval, statement) \
+ PHP_OCI_FETCH_RESOURCE_EX(zval, statement, php_oci_statement *, "oci8 statement", le_statement)
+
+#define PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(zval, descriptor) \
+ PHP_OCI_FETCH_RESOURCE_EX(zval, descriptor, php_oci_descriptor *, "oci8 descriptor", le_descriptor)
+
+#define PHP_OCI_ZVAL_TO_COLLECTION_EX(zval, collection) \
+ PHP_OCI_FETCH_RESOURCE_EX(zval, collection, php_oci_collection *, "oci8 collection", le_collection)
+
+/* }}} */
+
+/* PROTOS */
+
+/* main prototypes {{{ */
+
+void php_oci_column_hash_dtor (void *data);
+void php_oci_define_hash_dtor (void *data);
+void php_oci_bind_hash_dtor (void *data);
+void php_oci_descriptor_flush_hash_dtor (void *data);
+
+sb4 php_oci_error (OCIError *, sword TSRMLS_DC);
+sb4 php_oci_fetch_errmsg(OCIError *, text ** TSRMLS_DC);
+#ifdef HAVE_OCI8_ATTR_STATEMENT
+int php_oci_fetch_sqltext_offset(php_oci_statement *, text **, ub2 * TSRMLS_DC);
+#endif
+
+void php_oci_do_connect (INTERNAL_FUNCTION_PARAMETERS, int , int);
+php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, long session_mode, int persistent, int exclusive TSRMLS_DC);
+
+int php_oci_connection_rollback(php_oci_connection * TSRMLS_DC);
+int php_oci_connection_commit(php_oci_connection * TSRMLS_DC);
+
+int php_oci_password_change(php_oci_connection *, char *, int, char *, int, char *, int TSRMLS_DC);
+int php_oci_server_get_version(php_oci_connection *, char ** TSRMLS_DC);
+
+void php_oci_fetch_row(INTERNAL_FUNCTION_PARAMETERS, int, int);
+int php_oci_column_to_zval(php_oci_out_column *, zval *, int TSRMLS_DC);
+
+/* }}} */
+
+/* lob related prototypes {{{ */
+
+php_oci_descriptor * php_oci_lob_create (php_oci_connection *, long TSRMLS_DC);
+int php_oci_lob_get_length (php_oci_descriptor *, ub4 * TSRMLS_DC);
+int php_oci_lob_read (php_oci_descriptor *, long, long, char **, ub4 * TSRMLS_DC);
+int php_oci_lob_write (php_oci_descriptor *, ub4, char *, int, ub4 * TSRMLS_DC);
+int php_oci_lob_flush (php_oci_descriptor *, int TSRMLS_DC);
+int php_oci_lob_set_buffering (php_oci_descriptor *, int TSRMLS_DC);
+int php_oci_lob_get_buffering (php_oci_descriptor * TSRMLS_DC);
+int php_oci_lob_copy (php_oci_descriptor *, php_oci_descriptor *, long TSRMLS_DC);
+#ifdef HAVE_OCI8_TEMP_LOB
+int php_oci_lob_close (php_oci_descriptor * TSRMLS_DC);
+int php_oci_lob_write_tmp (php_oci_descriptor *, ub1, char *, int TSRMLS_DC);
+#endif
+void php_oci_lob_free(php_oci_descriptor * TSRMLS_DC);
+int php_oci_lob_import(php_oci_descriptor *descriptor, char * TSRMLS_DC);
+int php_oci_lob_append (php_oci_descriptor *, php_oci_descriptor * TSRMLS_DC);
+int php_oci_lob_truncate (php_oci_descriptor *, long TSRMLS_DC);
+int php_oci_lob_erase (php_oci_descriptor *, long, long, ub4 * TSRMLS_DC);
+int php_oci_lob_is_equal (php_oci_descriptor *, php_oci_descriptor *, boolean * TSRMLS_DC);
+
+/* }}} */
+
+/* collection related prototypes {{{ */
+
+php_oci_collection * php_oci_collection_create(php_oci_connection *, char *, int, char *, int TSRMLS_DC);
+int php_oci_collection_size(php_oci_collection *, sb4 * TSRMLS_DC);
+int php_oci_collection_max(php_oci_collection *, long * TSRMLS_DC);
+int php_oci_collection_trim(php_oci_collection *, long TSRMLS_DC);
+int php_oci_collection_append(php_oci_collection *, char *, int TSRMLS_DC);
+int php_oci_collection_element_get(php_oci_collection *, long, zval** TSRMLS_DC);
+int php_oci_collection_element_set(php_oci_collection *, long, char*, int TSRMLS_DC);
+int php_oci_collection_element_set_null(php_oci_collection *, long TSRMLS_DC);
+int php_oci_collection_element_set_date(php_oci_collection *, long, char *, int TSRMLS_DC);
+int php_oci_collection_element_set_number(php_oci_collection *, long, char *, int TSRMLS_DC);
+int php_oci_collection_element_set_string(php_oci_collection *, long, char *, int TSRMLS_DC);
+int php_oci_collection_assign(php_oci_collection *, php_oci_collection * TSRMLS_DC);
+void php_oci_collection_close(php_oci_collection * TSRMLS_DC);
+int php_oci_collection_append_null(php_oci_collection * TSRMLS_DC);
+int php_oci_collection_append_date(php_oci_collection *, char *, int TSRMLS_DC);
+int php_oci_collection_append_number(php_oci_collection *, char *, int TSRMLS_DC);
+int php_oci_collection_append_string(php_oci_collection *, char *, int TSRMLS_DC);
+
+
+/* }}} */
+
+/* statement related prototypes {{{ */
+
+php_oci_statement * php_oci_statement_create (php_oci_connection *, char *, long, zend_bool TSRMLS_DC);
+int php_oci_statement_set_prefetch (php_oci_statement *, ub4 TSRMLS_DC);
+int php_oci_statement_fetch (php_oci_statement *, ub4 TSRMLS_DC);
+php_oci_out_column * php_oci_statement_get_column (php_oci_statement *, long, char*, long TSRMLS_DC);
+int php_oci_statement_execute (php_oci_statement *, ub4 TSRMLS_DC);
+int php_oci_statement_cancel (php_oci_statement * TSRMLS_DC);
+void php_oci_statement_free (php_oci_statement * TSRMLS_DC);
+int php_oci_bind_pre_exec(void *data TSRMLS_DC);
+int php_oci_bind_post_exec(void *data TSRMLS_DC);
+int php_oci_bind_by_name(php_oci_statement *, char *, int, zval*, long, long TSRMLS_DC);
+sb4 php_oci_bind_in_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 *, ub1 *, dvoid **);
+sb4 php_oci_bind_out_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 **, ub1 *, dvoid **, ub2 **);
+php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS);
+
+int php_oci_statement_get_type(php_oci_statement *, ub2 * TSRMLS_DC);
+int php_oci_statement_get_numrows(php_oci_statement *, ub4 * TSRMLS_DC);
+int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC);
+php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC);
+php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC);
+php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC);
+php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC);
+
+/* }}} */
+
+ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ */
+ sword errcode; /* global last error code (used when connect fails, for example) */
+ OCIError *err; /* global error handle */
+
+ /*
+ char *default_username;
+ char *default_password;
+ char *default_dbname;
+ */
+
+ zend_bool debug_mode; /* debug mode flag */
+
+ long max_persistent; /* maximum number of persistent connections per process */
+ long num_persistent; /* number of existing persistent connections */
+ long num_links; /* non-persistent + persistent connections */
+ long ping_interval; /* time interval between pings */
+ long persistent_timeout; /* time period after which idle persistent connection is considered expired */
+ long statement_cache_size; /* statement cache size. used with 9i+ clients only*/
+ long default_prefetch; /* default prefetch setting */
+ zend_bool privileged_connect; /* privileged connect flag (On/Off) */
+ zend_bool old_oci_close_semantics; /* old_oci_close_semantics flag (to determine the way oci_close() should behave) */
+
+ int shutdown; /* in shutdown flag */
+
+ OCIEnv *env; /* global environment handle */
+
+ZEND_END_MODULE_GLOBALS(oci) /* }}} */
+
+#ifdef ZTS
+#define OCI_G(v) TSRMG(oci_globals_id, zend_oci_globals *, v)
+#else
+#define OCI_G(v) (oci_globals.v)
+#endif
+
+ZEND_EXTERN_MODULE_GLOBALS(oci)
+
+# endif /* !PHP_OCI8_INT_H */
+#else /* !HAVE_OCI8 */
+
+# define oci8_module_ptr NULL
+
+#endif /* HAVE_OCI8 */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+
+
diff --git a/ext/oci8/tests/bind_empty.phpt b/ext/oci8/tests/bind_empty.phpt
new file mode 100644
index 0000000000..4088616055
--- /dev/null
+++ b/ext/oci8/tests/bind_empty.phpt
@@ -0,0 +1,44 @@
+--TEST--
+binding empty values
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$drop = "DROP table bind_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+$create = "CREATE table bind_test(name VARCHAR(10))";
+$statement = oci_parse($c, $create);
+oci_execute($statement);
+
+
+$name = null;
+$stmt = oci_parse($c, "UPDATE bind_test SET name=:name");
+oci_bind_by_name($stmt, ":name", &$name);
+
+$res = oci_execute($stmt);
+
+$name = "";
+$stmt = oci_parse($c, "UPDATE bind_test SET name=:name");
+oci_bind_by_name($stmt, ":name", &$name);
+
+$res = oci_execute($stmt);
+
+$drop = "DROP table bind_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Done
diff --git a/ext/oci8/tests/bug26133.phpt b/ext/oci8/tests/bug26133.phpt
index d3f0ed9bf3..a0492cfde6 100644
--- a/ext/oci8/tests/bug26133.phpt
+++ b/ext/oci8/tests/bug26133.phpt
@@ -1,36 +1,39 @@
--TEST--
Bug #26133 (ocifreedesc() segfault)
--SKIPIF--
-<?php
- require 'skipif.inc';
-?>
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
--FILE--
<?php
- require 'connect.inc';
- require 'create_table.inc';
-
- if ($connection) {
+
+ require dirname(__FILE__).'/connect.inc';
+ require dirname(__FILE__).'/create_table.inc';
+
+ if ($c) {
$ora_sql = "INSERT INTO
- ".$schema."php_test_table (id, value)
+ ".$schema.$table_name." (id, value)
VALUES ('1','1')
RETURNING
ROWID
INTO :v_rowid ";
- $statement = OCIParse($connection,$ora_sql);
- $rowid = OCINewDescriptor($connection,OCI_D_ROWID);
+ $statement = OCIParse($c,$ora_sql);
+ $rowid = OCINewDescriptor($c,OCI_D_ROWID);
OCIBindByName($statement,":v_rowid", $rowid,-1,OCI_B_ROWID);
if (OCIExecute($statement)) {
- OCICommit($connection);
+ OCICommit($c);
}
OCIFreeStatement($statement);
$rowid->free();
}
- require 'drop_table.inc';
+ require dirname(__FILE__).'/drop_table.inc';
echo "Done\n";
?>
---EXPECTF--
+--EXPECT--
Done
-
diff --git a/ext/oci8/tests/bug27303.phpt b/ext/oci8/tests/bug27303.phpt
new file mode 100644
index 0000000000..22a1f6d717
--- /dev/null
+++ b/ext/oci8/tests/bug27303.phpt
@@ -0,0 +1,257 @@
+--TEST--
+bug #27303 (OCIBindByName binds numeric PHP values as characters)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$create_st = array();
+$create_st[] = "drop sequence myseq";
+$create_st[] = "drop table mytab";
+$create_st[] = "create sequence myseq";
+$create_st[] = "create table mytab (mydata varchar2(20), seqcol number)";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+define('MYLIMIT', 200);
+define('INITMYBV', 11);
+
+$stmt = "insert into mytab (mydata, seqcol) values ('Some data', myseq.nextval) returning seqcol into :mybv";
+
+$stid = OCIParse($c, $stmt);
+if (!$stid) { echo "Parse error"; die; }
+
+//$mybv = INITMYBV; // Uncomment this for the 2nd test only
+$r = OCIBindByName($stid, ':MYBV', $mybv /*, 5 */); // Uncomment this for the 3rd test only
+if (!$r) { echo "Bind error"; die; }
+
+for ($i = 1; $i < MYLIMIT; $i++) {
+ $r = OCIExecute($stid, OCI_DEFAULT);
+ if (!$r) { echo "Execute error"; die; }
+ var_dump($mybv);
+}
+
+OCICommit($c);
+
+$drop_st = array();
+$drop_st[] = "drop sequence myseq";
+$drop_st[] = "drop table mytab";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(1) "1"
+string(1) "2"
+string(1) "3"
+string(1) "4"
+string(1) "5"
+string(1) "6"
+string(1) "7"
+string(1) "8"
+string(1) "9"
+string(2) "10"
+string(2) "11"
+string(2) "12"
+string(2) "13"
+string(2) "14"
+string(2) "15"
+string(2) "16"
+string(2) "17"
+string(2) "18"
+string(2) "19"
+string(2) "20"
+string(2) "21"
+string(2) "22"
+string(2) "23"
+string(2) "24"
+string(2) "25"
+string(2) "26"
+string(2) "27"
+string(2) "28"
+string(2) "29"
+string(2) "30"
+string(2) "31"
+string(2) "32"
+string(2) "33"
+string(2) "34"
+string(2) "35"
+string(2) "36"
+string(2) "37"
+string(2) "38"
+string(2) "39"
+string(2) "40"
+string(2) "41"
+string(2) "42"
+string(2) "43"
+string(2) "44"
+string(2) "45"
+string(2) "46"
+string(2) "47"
+string(2) "48"
+string(2) "49"
+string(2) "50"
+string(2) "51"
+string(2) "52"
+string(2) "53"
+string(2) "54"
+string(2) "55"
+string(2) "56"
+string(2) "57"
+string(2) "58"
+string(2) "59"
+string(2) "60"
+string(2) "61"
+string(2) "62"
+string(2) "63"
+string(2) "64"
+string(2) "65"
+string(2) "66"
+string(2) "67"
+string(2) "68"
+string(2) "69"
+string(2) "70"
+string(2) "71"
+string(2) "72"
+string(2) "73"
+string(2) "74"
+string(2) "75"
+string(2) "76"
+string(2) "77"
+string(2) "78"
+string(2) "79"
+string(2) "80"
+string(2) "81"
+string(2) "82"
+string(2) "83"
+string(2) "84"
+string(2) "85"
+string(2) "86"
+string(2) "87"
+string(2) "88"
+string(2) "89"
+string(2) "90"
+string(2) "91"
+string(2) "92"
+string(2) "93"
+string(2) "94"
+string(2) "95"
+string(2) "96"
+string(2) "97"
+string(2) "98"
+string(2) "99"
+string(3) "100"
+string(3) "101"
+string(3) "102"
+string(3) "103"
+string(3) "104"
+string(3) "105"
+string(3) "106"
+string(3) "107"
+string(3) "108"
+string(3) "109"
+string(3) "110"
+string(3) "111"
+string(3) "112"
+string(3) "113"
+string(3) "114"
+string(3) "115"
+string(3) "116"
+string(3) "117"
+string(3) "118"
+string(3) "119"
+string(3) "120"
+string(3) "121"
+string(3) "122"
+string(3) "123"
+string(3) "124"
+string(3) "125"
+string(3) "126"
+string(3) "127"
+string(3) "128"
+string(3) "129"
+string(3) "130"
+string(3) "131"
+string(3) "132"
+string(3) "133"
+string(3) "134"
+string(3) "135"
+string(3) "136"
+string(3) "137"
+string(3) "138"
+string(3) "139"
+string(3) "140"
+string(3) "141"
+string(3) "142"
+string(3) "143"
+string(3) "144"
+string(3) "145"
+string(3) "146"
+string(3) "147"
+string(3) "148"
+string(3) "149"
+string(3) "150"
+string(3) "151"
+string(3) "152"
+string(3) "153"
+string(3) "154"
+string(3) "155"
+string(3) "156"
+string(3) "157"
+string(3) "158"
+string(3) "159"
+string(3) "160"
+string(3) "161"
+string(3) "162"
+string(3) "163"
+string(3) "164"
+string(3) "165"
+string(3) "166"
+string(3) "167"
+string(3) "168"
+string(3) "169"
+string(3) "170"
+string(3) "171"
+string(3) "172"
+string(3) "173"
+string(3) "174"
+string(3) "175"
+string(3) "176"
+string(3) "177"
+string(3) "178"
+string(3) "179"
+string(3) "180"
+string(3) "181"
+string(3) "182"
+string(3) "183"
+string(3) "184"
+string(3) "185"
+string(3) "186"
+string(3) "187"
+string(3) "188"
+string(3) "189"
+string(3) "190"
+string(3) "191"
+string(3) "192"
+string(3) "193"
+string(3) "194"
+string(3) "195"
+string(3) "196"
+string(3) "197"
+string(3) "198"
+string(3) "199"
+Done
diff --git a/ext/oci8/tests/bug27303_2.phpt b/ext/oci8/tests/bug27303_2.phpt
new file mode 100644
index 0000000000..39c7c1099a
--- /dev/null
+++ b/ext/oci8/tests/bug27303_2.phpt
@@ -0,0 +1,257 @@
+--TEST--
+bug #27303 (OCIBindByName binds numeric PHP values as characters)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$create_st = array();
+$create_st[] = "drop sequence myseq";
+$create_st[] = "drop table mytab";
+$create_st[] = "create sequence myseq";
+$create_st[] = "create table mytab (mydata varchar2(20), seqcol number)";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+define('MYLIMIT', 200);
+define('INITMYBV', 11);
+
+$stmt = "insert into mytab (mydata, seqcol) values ('Some data', myseq.nextval) returning seqcol into :mybv";
+
+$stid = OCIParse($c, $stmt);
+if (!$stid) { echo "Parse error"; die; }
+
+$mybv = INITMYBV; // Uncomment this for the 2nd test only
+$r = OCIBindByName($stid, ':MYBV', $mybv /*, 5 */); // Uncomment this for the 3rd test only
+if (!$r) { echo "Bind error"; die; }
+
+for ($i = 1; $i < MYLIMIT; $i++) {
+ $r = OCIExecute($stid, OCI_DEFAULT);
+ if (!$r) { echo "Execute error"; die; }
+ var_dump($mybv);
+}
+
+OCICommit($c);
+
+$drop_st = array();
+$drop_st[] = "drop sequence myseq";
+$drop_st[] = "drop table mytab";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(1) "1"
+string(1) "2"
+string(1) "3"
+string(1) "4"
+string(1) "5"
+string(1) "6"
+string(1) "7"
+string(1) "8"
+string(1) "9"
+string(2) "10"
+string(2) "11"
+string(2) "12"
+string(2) "13"
+string(2) "14"
+string(2) "15"
+string(2) "16"
+string(2) "17"
+string(2) "18"
+string(2) "19"
+string(2) "20"
+string(2) "21"
+string(2) "22"
+string(2) "23"
+string(2) "24"
+string(2) "25"
+string(2) "26"
+string(2) "27"
+string(2) "28"
+string(2) "29"
+string(2) "30"
+string(2) "31"
+string(2) "32"
+string(2) "33"
+string(2) "34"
+string(2) "35"
+string(2) "36"
+string(2) "37"
+string(2) "38"
+string(2) "39"
+string(2) "40"
+string(2) "41"
+string(2) "42"
+string(2) "43"
+string(2) "44"
+string(2) "45"
+string(2) "46"
+string(2) "47"
+string(2) "48"
+string(2) "49"
+string(2) "50"
+string(2) "51"
+string(2) "52"
+string(2) "53"
+string(2) "54"
+string(2) "55"
+string(2) "56"
+string(2) "57"
+string(2) "58"
+string(2) "59"
+string(2) "60"
+string(2) "61"
+string(2) "62"
+string(2) "63"
+string(2) "64"
+string(2) "65"
+string(2) "66"
+string(2) "67"
+string(2) "68"
+string(2) "69"
+string(2) "70"
+string(2) "71"
+string(2) "72"
+string(2) "73"
+string(2) "74"
+string(2) "75"
+string(2) "76"
+string(2) "77"
+string(2) "78"
+string(2) "79"
+string(2) "80"
+string(2) "81"
+string(2) "82"
+string(2) "83"
+string(2) "84"
+string(2) "85"
+string(2) "86"
+string(2) "87"
+string(2) "88"
+string(2) "89"
+string(2) "90"
+string(2) "91"
+string(2) "92"
+string(2) "93"
+string(2) "94"
+string(2) "95"
+string(2) "96"
+string(2) "97"
+string(2) "98"
+string(2) "99"
+string(3) "100"
+string(3) "101"
+string(3) "102"
+string(3) "103"
+string(3) "104"
+string(3) "105"
+string(3) "106"
+string(3) "107"
+string(3) "108"
+string(3) "109"
+string(3) "110"
+string(3) "111"
+string(3) "112"
+string(3) "113"
+string(3) "114"
+string(3) "115"
+string(3) "116"
+string(3) "117"
+string(3) "118"
+string(3) "119"
+string(3) "120"
+string(3) "121"
+string(3) "122"
+string(3) "123"
+string(3) "124"
+string(3) "125"
+string(3) "126"
+string(3) "127"
+string(3) "128"
+string(3) "129"
+string(3) "130"
+string(3) "131"
+string(3) "132"
+string(3) "133"
+string(3) "134"
+string(3) "135"
+string(3) "136"
+string(3) "137"
+string(3) "138"
+string(3) "139"
+string(3) "140"
+string(3) "141"
+string(3) "142"
+string(3) "143"
+string(3) "144"
+string(3) "145"
+string(3) "146"
+string(3) "147"
+string(3) "148"
+string(3) "149"
+string(3) "150"
+string(3) "151"
+string(3) "152"
+string(3) "153"
+string(3) "154"
+string(3) "155"
+string(3) "156"
+string(3) "157"
+string(3) "158"
+string(3) "159"
+string(3) "160"
+string(3) "161"
+string(3) "162"
+string(3) "163"
+string(3) "164"
+string(3) "165"
+string(3) "166"
+string(3) "167"
+string(3) "168"
+string(3) "169"
+string(3) "170"
+string(3) "171"
+string(3) "172"
+string(3) "173"
+string(3) "174"
+string(3) "175"
+string(3) "176"
+string(3) "177"
+string(3) "178"
+string(3) "179"
+string(3) "180"
+string(3) "181"
+string(3) "182"
+string(3) "183"
+string(3) "184"
+string(3) "185"
+string(3) "186"
+string(3) "187"
+string(3) "188"
+string(3) "189"
+string(3) "190"
+string(3) "191"
+string(3) "192"
+string(3) "193"
+string(3) "194"
+string(3) "195"
+string(3) "196"
+string(3) "197"
+string(3) "198"
+string(3) "199"
+Done
diff --git a/ext/oci8/tests/bug27303_3.phpt b/ext/oci8/tests/bug27303_3.phpt
new file mode 100644
index 0000000000..137f907076
--- /dev/null
+++ b/ext/oci8/tests/bug27303_3.phpt
@@ -0,0 +1,257 @@
+--TEST--
+bug #27303 (OCIBindByName binds numeric PHP values as characters)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$create_st = array();
+$create_st[] = "drop sequence myseq";
+$create_st[] = "drop table mytab";
+$create_st[] = "create sequence myseq";
+$create_st[] = "create table mytab (mydata varchar2(20), seqcol number)";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+define('MYLIMIT', 200);
+define('INITMYBV', 11);
+
+$stmt = "insert into mytab (mydata, seqcol) values ('Some data', myseq.nextval) returning seqcol into :mybv";
+
+$stid = OCIParse($c, $stmt);
+if (!$stid) { echo "Parse error"; die; }
+
+$mybv = INITMYBV; // Uncomment this for the 2nd test only
+$r = OCIBindByName($stid, ':MYBV', $mybv, 5, SQLT_INT); // Uncomment this for the 3rd test only
+if (!$r) { echo "Bind error"; die; }
+
+for ($i = 1; $i < MYLIMIT; $i++) {
+ $r = OCIExecute($stid, OCI_DEFAULT);
+ if (!$r) { echo "Execute error"; die; }
+ var_dump($mybv);
+}
+
+OCICommit($c);
+
+$drop_st = array();
+$drop_st[] = "drop sequence myseq";
+$drop_st[] = "drop table mytab";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(1)
+int(2)
+int(3)
+int(4)
+int(5)
+int(6)
+int(7)
+int(8)
+int(9)
+int(10)
+int(11)
+int(12)
+int(13)
+int(14)
+int(15)
+int(16)
+int(17)
+int(18)
+int(19)
+int(20)
+int(21)
+int(22)
+int(23)
+int(24)
+int(25)
+int(26)
+int(27)
+int(28)
+int(29)
+int(30)
+int(31)
+int(32)
+int(33)
+int(34)
+int(35)
+int(36)
+int(37)
+int(38)
+int(39)
+int(40)
+int(41)
+int(42)
+int(43)
+int(44)
+int(45)
+int(46)
+int(47)
+int(48)
+int(49)
+int(50)
+int(51)
+int(52)
+int(53)
+int(54)
+int(55)
+int(56)
+int(57)
+int(58)
+int(59)
+int(60)
+int(61)
+int(62)
+int(63)
+int(64)
+int(65)
+int(66)
+int(67)
+int(68)
+int(69)
+int(70)
+int(71)
+int(72)
+int(73)
+int(74)
+int(75)
+int(76)
+int(77)
+int(78)
+int(79)
+int(80)
+int(81)
+int(82)
+int(83)
+int(84)
+int(85)
+int(86)
+int(87)
+int(88)
+int(89)
+int(90)
+int(91)
+int(92)
+int(93)
+int(94)
+int(95)
+int(96)
+int(97)
+int(98)
+int(99)
+int(100)
+int(101)
+int(102)
+int(103)
+int(104)
+int(105)
+int(106)
+int(107)
+int(108)
+int(109)
+int(110)
+int(111)
+int(112)
+int(113)
+int(114)
+int(115)
+int(116)
+int(117)
+int(118)
+int(119)
+int(120)
+int(121)
+int(122)
+int(123)
+int(124)
+int(125)
+int(126)
+int(127)
+int(128)
+int(129)
+int(130)
+int(131)
+int(132)
+int(133)
+int(134)
+int(135)
+int(136)
+int(137)
+int(138)
+int(139)
+int(140)
+int(141)
+int(142)
+int(143)
+int(144)
+int(145)
+int(146)
+int(147)
+int(148)
+int(149)
+int(150)
+int(151)
+int(152)
+int(153)
+int(154)
+int(155)
+int(156)
+int(157)
+int(158)
+int(159)
+int(160)
+int(161)
+int(162)
+int(163)
+int(164)
+int(165)
+int(166)
+int(167)
+int(168)
+int(169)
+int(170)
+int(171)
+int(172)
+int(173)
+int(174)
+int(175)
+int(176)
+int(177)
+int(178)
+int(179)
+int(180)
+int(181)
+int(182)
+int(183)
+int(184)
+int(185)
+int(186)
+int(187)
+int(188)
+int(189)
+int(190)
+int(191)
+int(192)
+int(193)
+int(194)
+int(195)
+int(196)
+int(197)
+int(198)
+int(199)
+Done
diff --git a/ext/oci8/tests/bug27303_4.phpt b/ext/oci8/tests/bug27303_4.phpt
new file mode 100644
index 0000000000..70b8d8f36c
--- /dev/null
+++ b/ext/oci8/tests/bug27303_4.phpt
@@ -0,0 +1,257 @@
+--TEST--
+bug #27303 (OCIBindByName binds numeric PHP values as characters)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$create_st = array();
+$create_st[] = "drop sequence myseq";
+$create_st[] = "drop table mytab";
+$create_st[] = "create sequence myseq";
+$create_st[] = "create table mytab (mydata varchar2(20), seqcol number)";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+define('MYLIMIT', 200);
+define('INITMYBV', 11);
+
+$stmt = "insert into mytab (mydata, seqcol) values ('Some data', myseq.nextval) returning seqcol into :mybv";
+
+$stid = OCIParse($c, $stmt);
+if (!$stid) { echo "Parse error"; die; }
+
+//$mybv = INITMYBV; // Uncomment this for the 2nd test only
+$r = OCIBindByName($stid, ':MYBV', $mybv, 0 ); // Uncomment this for the 3rd test only
+if (!$r) { echo "Bind error"; die; }
+
+for ($i = 1; $i < MYLIMIT; $i++) {
+ $r = OCIExecute($stid, OCI_DEFAULT);
+ if (!$r) { echo "Execute error"; die; }
+ var_dump($mybv);
+}
+
+OCICommit($c);
+
+$drop_st = array();
+$drop_st[] = "drop sequence myseq";
+$drop_st[] = "drop table mytab";
+
+foreach ($create_st as $statement) {
+ $stmt = oci_parse($c, $statement);
+ oci_execute($stmt);
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(1) "1"
+string(1) "2"
+string(1) "3"
+string(1) "4"
+string(1) "5"
+string(1) "6"
+string(1) "7"
+string(1) "8"
+string(1) "9"
+string(2) "10"
+string(2) "11"
+string(2) "12"
+string(2) "13"
+string(2) "14"
+string(2) "15"
+string(2) "16"
+string(2) "17"
+string(2) "18"
+string(2) "19"
+string(2) "20"
+string(2) "21"
+string(2) "22"
+string(2) "23"
+string(2) "24"
+string(2) "25"
+string(2) "26"
+string(2) "27"
+string(2) "28"
+string(2) "29"
+string(2) "30"
+string(2) "31"
+string(2) "32"
+string(2) "33"
+string(2) "34"
+string(2) "35"
+string(2) "36"
+string(2) "37"
+string(2) "38"
+string(2) "39"
+string(2) "40"
+string(2) "41"
+string(2) "42"
+string(2) "43"
+string(2) "44"
+string(2) "45"
+string(2) "46"
+string(2) "47"
+string(2) "48"
+string(2) "49"
+string(2) "50"
+string(2) "51"
+string(2) "52"
+string(2) "53"
+string(2) "54"
+string(2) "55"
+string(2) "56"
+string(2) "57"
+string(2) "58"
+string(2) "59"
+string(2) "60"
+string(2) "61"
+string(2) "62"
+string(2) "63"
+string(2) "64"
+string(2) "65"
+string(2) "66"
+string(2) "67"
+string(2) "68"
+string(2) "69"
+string(2) "70"
+string(2) "71"
+string(2) "72"
+string(2) "73"
+string(2) "74"
+string(2) "75"
+string(2) "76"
+string(2) "77"
+string(2) "78"
+string(2) "79"
+string(2) "80"
+string(2) "81"
+string(2) "82"
+string(2) "83"
+string(2) "84"
+string(2) "85"
+string(2) "86"
+string(2) "87"
+string(2) "88"
+string(2) "89"
+string(2) "90"
+string(2) "91"
+string(2) "92"
+string(2) "93"
+string(2) "94"
+string(2) "95"
+string(2) "96"
+string(2) "97"
+string(2) "98"
+string(2) "99"
+string(3) "100"
+string(3) "101"
+string(3) "102"
+string(3) "103"
+string(3) "104"
+string(3) "105"
+string(3) "106"
+string(3) "107"
+string(3) "108"
+string(3) "109"
+string(3) "110"
+string(3) "111"
+string(3) "112"
+string(3) "113"
+string(3) "114"
+string(3) "115"
+string(3) "116"
+string(3) "117"
+string(3) "118"
+string(3) "119"
+string(3) "120"
+string(3) "121"
+string(3) "122"
+string(3) "123"
+string(3) "124"
+string(3) "125"
+string(3) "126"
+string(3) "127"
+string(3) "128"
+string(3) "129"
+string(3) "130"
+string(3) "131"
+string(3) "132"
+string(3) "133"
+string(3) "134"
+string(3) "135"
+string(3) "136"
+string(3) "137"
+string(3) "138"
+string(3) "139"
+string(3) "140"
+string(3) "141"
+string(3) "142"
+string(3) "143"
+string(3) "144"
+string(3) "145"
+string(3) "146"
+string(3) "147"
+string(3) "148"
+string(3) "149"
+string(3) "150"
+string(3) "151"
+string(3) "152"
+string(3) "153"
+string(3) "154"
+string(3) "155"
+string(3) "156"
+string(3) "157"
+string(3) "158"
+string(3) "159"
+string(3) "160"
+string(3) "161"
+string(3) "162"
+string(3) "163"
+string(3) "164"
+string(3) "165"
+string(3) "166"
+string(3) "167"
+string(3) "168"
+string(3) "169"
+string(3) "170"
+string(3) "171"
+string(3) "172"
+string(3) "173"
+string(3) "174"
+string(3) "175"
+string(3) "176"
+string(3) "177"
+string(3) "178"
+string(3) "179"
+string(3) "180"
+string(3) "181"
+string(3) "182"
+string(3) "183"
+string(3) "184"
+string(3) "185"
+string(3) "186"
+string(3) "187"
+string(3) "188"
+string(3) "189"
+string(3) "190"
+string(3) "191"
+string(3) "192"
+string(3) "193"
+string(3) "194"
+string(3) "195"
+string(3) "196"
+string(3) "197"
+string(3) "198"
+string(3) "199"
+Done
diff --git a/ext/oci8/tests/bug32325.phpt b/ext/oci8/tests/bug32325.phpt
new file mode 100644
index 0000000000..1b5dd0d24d
--- /dev/null
+++ b/ext/oci8/tests/bug32325.phpt
@@ -0,0 +1,44 @@
+--TEST--
+bug #32325 (Can't retrieve collection using OCI8)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$create_stmt = oci_parse($c, "create or replace type ut_num_list_t as table of number");
+oci_execute($create_stmt);
+
+$collection = oci_new_collection($c, "UT_NUM_LIST_T");
+
+$sql = "
+ begin
+ select ut_num_list_t(1,2,3,4) into :list from dual;
+ end;";
+
+$stmt = oci_parse($c, $sql);
+
+oci_bind_by_name($stmt, ":list", $collection, -1, OCI_B_NTY);
+oci_execute($stmt);
+
+var_dump($collection->size());
+var_dump($collection->getelem(1));
+var_dump($collection->getelem(2));
+
+$drop_stmt = oci_parse($c, "drop type ut_num_list_t");
+oci_execute($drop_stmt);
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(4)
+float(2)
+float(3)
+Done
diff --git a/ext/oci8/tests/close.phpt b/ext/oci8/tests/close.phpt
new file mode 100644
index 0000000000..08bac05ba5
--- /dev/null
+++ b/ext/oci8/tests/close.phpt
@@ -0,0 +1,22 @@
+--TEST--
+connect/close/connect
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+oci_close($c);
+
+oci_connect($user, $password, $dbase);
+
+echo "Done\n";
+?>
+--EXPECTF--
+Done
diff --git a/ext/oci8/tests/coll_001.phpt b/ext/oci8/tests/coll_001.phpt
new file mode 100644
index 0000000000..8a223f864b
--- /dev/null
+++ b/ext/oci8/tests/coll_001.phpt
@@ -0,0 +1,33 @@
+--TEST--
+oci_new_collection()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump(oci_new_collection($c, $type_name));
+var_dump(oci_new_collection($c, "NONEXISTENT"));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+
+Warning: oci_new_collection(): OCI-22303: type ""."NONEXISTENT" not found in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_002.phpt b/ext/oci8/tests/coll_002.phpt
new file mode 100644
index 0000000000..39f0dbf065
--- /dev/null
+++ b/ext/oci8/tests/coll_002.phpt
@@ -0,0 +1,36 @@
+--TEST--
+oci_new_collection() + free()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump($coll1 = oci_new_collection($c, $type_name));
+
+var_dump($coll1->free());
+var_dump($coll1->size());
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+bool(true)
+
+Warning: OCI-Collection::size(): %d is not a valid oci8 collection resource in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_002_func.phpt b/ext/oci8/tests/coll_002_func.phpt
new file mode 100644
index 0000000000..4a7cb209c3
--- /dev/null
+++ b/ext/oci8/tests/coll_002_func.phpt
@@ -0,0 +1,36 @@
+--TEST--
+oci_new_collection() + free()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump($coll1 = oci_new_collection($c, $type_name));
+
+var_dump(oci_free_collection($coll1));
+var_dump(oci_collection_size($coll1));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+bool(true)
+
+Warning: oci_collection_size(): %d is not a valid oci8 collection resource in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_003.phpt b/ext/oci8/tests/coll_003.phpt
new file mode 100644
index 0000000000..a47816ad2c
--- /dev/null
+++ b/ext/oci8/tests/coll_003.phpt
@@ -0,0 +1,40 @@
+--TEST--
+collection methods
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = oci_new_collection($c, $type_name);
+
+var_dump($coll1->size());
+var_dump($coll1->max());
+var_dump($coll1->trim(3));
+var_dump($coll1->append(1));
+var_dump($coll1->getElem(0));
+var_dump($coll1->assignElem(0,2));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+int(0)
+int(0)
+
+Warning: OCI-Collection::trim(): OCI-22167: given trim size [3] must be less than or equal to [0] in %s on line %d
+bool(false)
+bool(true)
+float(1)
+bool(true)
+Done
diff --git a/ext/oci8/tests/coll_003_func.phpt b/ext/oci8/tests/coll_003_func.phpt
new file mode 100644
index 0000000000..2057b6361a
--- /dev/null
+++ b/ext/oci8/tests/coll_003_func.phpt
@@ -0,0 +1,40 @@
+--TEST--
+collection methods
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = oci_new_collection($c, $type_name);
+
+var_dump(oci_collection_size($coll1));
+var_dump(oci_collection_max($coll1));
+var_dump(oci_collection_trim($coll1, 3));
+var_dump(oci_collection_append($coll1, 1));
+var_dump(oci_collection_element_get($coll1, 0));
+var_dump(oci_collection_element_assign($coll1, 0, 2));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+int(0)
+int(0)
+
+Warning: oci_collection_trim(): OCI-22167: given trim size [3] must be less than or equal to [0] in %s on line %d
+bool(false)
+bool(true)
+float(1)
+bool(true)
+Done
diff --git a/ext/oci8/tests/coll_004.phpt b/ext/oci8/tests/coll_004.phpt
new file mode 100644
index 0000000000..4af6d1d907
--- /dev/null
+++ b/ext/oci8/tests/coll_004.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_collection_assign()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = oci_new_collection($c, $type_name);
+$coll2 = oci_new_collection($c, $type_name);
+
+var_dump($coll1->append(1));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+float(1)
+Done
diff --git a/ext/oci8/tests/coll_004_func.phpt b/ext/oci8/tests/coll_004_func.phpt
new file mode 100644
index 0000000000..9d7f5f6cd9
--- /dev/null
+++ b/ext/oci8/tests/coll_004_func.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_collection_assign()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = oci_new_collection($c, $type_name);
+$coll2 = oci_new_collection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, 1));
+
+var_dump(oci_collection_assign($coll2, $coll1));
+
+var_dump(oci_collection_element_get($coll2, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+float(1)
+Done
diff --git a/ext/oci8/tests/coll_005.phpt b/ext/oci8/tests/coll_005.phpt
new file mode 100644
index 0000000000..d43c856cc7
--- /dev/null
+++ b/ext/oci8/tests/coll_005.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ocinewcollection()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump(ocinewcollection($c, $type_name));
+var_dump(ocinewcollection($c, "NONEXISTENT"));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+
+Warning: ocinewcollection(): OCI-22303: type ""."NONEXISTENT" not found in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_006.phpt b/ext/oci8/tests/coll_006.phpt
new file mode 100644
index 0000000000..a1039987f9
--- /dev/null
+++ b/ext/oci8/tests/coll_006.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ocinewcollection() + free()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump($coll1 = ocinewcollection($c, $type_name));
+
+var_dump($coll1->free());
+var_dump($coll1->size());
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+bool(true)
+
+Warning: OCI-Collection::size(): %d is not a valid oci8 collection resource in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_006_func.phpt b/ext/oci8/tests/coll_006_func.phpt
new file mode 100644
index 0000000000..f43c142c40
--- /dev/null
+++ b/ext/oci8/tests/coll_006_func.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ocinewcollection() + free()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+var_dump($coll1 = ocinewcollection($c, $type_name));
+
+var_dump(oci_free_collection($coll1));
+var_dump(oci_collection_size($coll1));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+object(OCI-Collection)#%d (1) {
+ ["collection"]=>
+ resource(%d) of type (oci8 collection)
+}
+bool(true)
+
+Warning: oci_collection_size(): %d is not a valid oci8 collection resource in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_007.phpt b/ext/oci8/tests/coll_007.phpt
new file mode 100644
index 0000000000..256ce0bfa7
--- /dev/null
+++ b/ext/oci8/tests/coll_007.phpt
@@ -0,0 +1,40 @@
+--TEST--
+collection methods
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->size());
+var_dump($coll1->max());
+var_dump($coll1->trim(3));
+var_dump($coll1->append(1));
+var_dump($coll1->getElem(0));
+var_dump($coll1->assignElem(0,2));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+int(0)
+int(0)
+
+Warning: OCI-Collection::trim(): OCI-22167: given trim size [3] must be less than or equal to [0] in %s on line %d
+bool(false)
+bool(true)
+float(1)
+bool(true)
+Done
diff --git a/ext/oci8/tests/coll_008.phpt b/ext/oci8/tests/coll_008.phpt
new file mode 100644
index 0000000000..36e052b7ed
--- /dev/null
+++ b/ext/oci8/tests/coll_008.phpt
@@ -0,0 +1,35 @@
+--TEST--
+ocicollassign()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_type.inc";
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append(1));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+float(1)
+Done
diff --git a/ext/oci8/tests/coll_009.phpt b/ext/oci8/tests/coll_009.phpt
new file mode 100644
index 0000000000..1910af9efb
--- /dev/null
+++ b/ext/oci8/tests/coll_009.phpt
@@ -0,0 +1,48 @@
+--TEST--
+collections and wrong dates
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("2005-07-28"));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+Warning: OCI-Collection::append(): OCI-01861: literal does not match format string in %s on line %d
+bool(false)
+bool(true)
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_009_func.phpt b/ext/oci8/tests/coll_009_func.phpt
new file mode 100644
index 0000000000..d383abe4ad
--- /dev/null
+++ b/ext/oci8/tests/coll_009_func.phpt
@@ -0,0 +1,48 @@
+--TEST--
+collections and wrong dates
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "2005-07-28"));
+
+var_dump(oci_collection_assign($coll2, $coll1));
+
+var_dump(oci_collection_element_get($coll2, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+Warning: oci_collection_append(): OCI-01861: literal does not match format string in %s on line %d
+bool(false)
+bool(true)
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_010.phpt b/ext/oci8/tests/coll_010.phpt
new file mode 100644
index 0000000000..b23096206e
--- /dev/null
+++ b/ext/oci8/tests/coll_010.phpt
@@ -0,0 +1,47 @@
+--TEST--
+collections and nulls
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append(null));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+NULL
+Done
diff --git a/ext/oci8/tests/coll_010_func.phpt b/ext/oci8/tests/coll_010_func.phpt
new file mode 100644
index 0000000000..dff980e013
--- /dev/null
+++ b/ext/oci8/tests/coll_010_func.phpt
@@ -0,0 +1,47 @@
+--TEST--
+collections and nulls
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, null));
+
+var_dump(oci_collection_assign($coll2, $coll1));
+
+var_dump(oci_collection_element_get($coll2, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+NULL
+Done
diff --git a/ext/oci8/tests/coll_011.phpt b/ext/oci8/tests/coll_011.phpt
new file mode 100644
index 0000000000..448b7f9a6b
--- /dev/null
+++ b/ext/oci8/tests/coll_011.phpt
@@ -0,0 +1,49 @@
+--TEST--
+collections and strings
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("string"));
+var_dump($coll1->append("string"));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+string(6) "string"
+Done
diff --git a/ext/oci8/tests/coll_011_func.phpt b/ext/oci8/tests/coll_011_func.phpt
new file mode 100644
index 0000000000..3226d15b86
--- /dev/null
+++ b/ext/oci8/tests/coll_011_func.phpt
@@ -0,0 +1,49 @@
+--TEST--
+collections and strings
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "string"));
+var_dump(oci_collection_append($coll1, "string"));
+
+var_dump(oci_collection_assign($coll2, $coll1));
+
+var_dump(oci_collection_element_get($coll2, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+string(6) "string"
+Done
diff --git a/ext/oci8/tests/coll_012.phpt b/ext/oci8/tests/coll_012.phpt
new file mode 100644
index 0000000000..59383b0cbc
--- /dev/null
+++ b/ext/oci8/tests/coll_012.phpt
@@ -0,0 +1,47 @@
+--TEST--
+collections and correct dates
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("28-JUL-05"));
+
+var_dump($coll2->assign($coll1));
+
+var_dump($coll2->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(9) "28-JUL-05"
+Done
diff --git a/ext/oci8/tests/coll_012_func.phpt b/ext/oci8/tests/coll_012_func.phpt
new file mode 100644
index 0000000000..16b85097d4
--- /dev/null
+++ b/ext/oci8/tests/coll_012_func.phpt
@@ -0,0 +1,47 @@
+--TEST--
+collections and correct dates
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+$coll2 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "28-JUL-05"));
+
+var_dump(oci_collection_assign($coll2, $coll1));
+
+var_dump(oci_collection_element_get($coll2, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(9) "28-JUL-05"
+Done
diff --git a/ext/oci8/tests/coll_013.phpt b/ext/oci8/tests/coll_013.phpt
new file mode 100644
index 0000000000..cd1c851771
--- /dev/null
+++ b/ext/oci8/tests/coll_013.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and correct dates (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("28-JUL-05"));
+var_dump($coll1->assignElem(0,"01-JAN-05"));
+var_dump($coll1->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(9) "01-JAN-05"
+Done
diff --git a/ext/oci8/tests/coll_013_func.phpt b/ext/oci8/tests/coll_013_func.phpt
new file mode 100644
index 0000000000..6141105b01
--- /dev/null
+++ b/ext/oci8/tests/coll_013_func.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and correct dates (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF DATE";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "28-JUL-05"));
+var_dump(oci_collection_element_assign($coll1, 0, "01-JAN-05"));
+var_dump(oci_collection_element_get($coll1, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(9) "01-JAN-05"
+Done
diff --git a/ext/oci8/tests/coll_014.phpt b/ext/oci8/tests/coll_014.phpt
new file mode 100644
index 0000000000..abbdbff274
--- /dev/null
+++ b/ext/oci8/tests/coll_014.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and strings (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("striing"));
+var_dump($coll1->assignElem(0,"blah"));
+var_dump($coll1->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(4) "blah"
+Done
diff --git a/ext/oci8/tests/coll_014_func.phpt b/ext/oci8/tests/coll_014_func.phpt
new file mode 100644
index 0000000000..a728ee0f7d
--- /dev/null
+++ b/ext/oci8/tests/coll_014_func.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and strings (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "striing"));
+var_dump(oci_collection_element_assign($coll1, 0,"blah"));
+var_dump(oci_collection_element_get($coll1, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(4) "blah"
+Done
diff --git a/ext/oci8/tests/coll_015.phpt b/ext/oci8/tests/coll_015.phpt
new file mode 100644
index 0000000000..c9f9bda941
--- /dev/null
+++ b/ext/oci8/tests/coll_015.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and numbers (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF NUMBER";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append(1));
+var_dump($coll1->assignElem(0,2345));
+var_dump($coll1->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+float(2345)
+Done
diff --git a/ext/oci8/tests/coll_015_func.phpt b/ext/oci8/tests/coll_015_func.phpt
new file mode 100644
index 0000000000..27c4e68cd4
--- /dev/null
+++ b/ext/oci8/tests/coll_015_func.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and numbers (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF NUMBER";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, 1));
+var_dump(oci_collection_element_assign($coll1,0,2345));
+var_dump(oci_collection_element_get($coll1, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+float(2345)
+Done
diff --git a/ext/oci8/tests/coll_016.phpt b/ext/oci8/tests/coll_016.phpt
new file mode 100644
index 0000000000..3f685dd73f
--- /dev/null
+++ b/ext/oci8/tests/coll_016.phpt
@@ -0,0 +1,54 @@
+--TEST--
+collections and negative/too big element indexes
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF NUMBER";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append(1));
+var_dump($coll1->assignElem(-1,2345));
+var_dump($coll1->assignElem(5000,2345));
+var_dump($coll1->getElem(-1));
+var_dump($coll1->getElem(-100));
+var_dump($coll1->getElem(500));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+bool(true)
+
+Warning: OCI-Collection::assignelem(): OCI-22165: given index [4294967295] must be in the range of 0 to [0] in %s on line %d
+bool(false)
+
+Warning: OCI-Collection::assignelem(): OCI-22165: given index [5000] must be in the range of 0 to [0] in %s on line %d
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_016_func.phpt b/ext/oci8/tests/coll_016_func.phpt
new file mode 100644
index 0000000000..f9ba14db49
--- /dev/null
+++ b/ext/oci8/tests/coll_016_func.phpt
@@ -0,0 +1,54 @@
+--TEST--
+collections and negative/too big element indexes
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF NUMBER";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, 1));
+var_dump(oci_collection_element_assign($coll1,-1,2345));
+var_dump(oci_collection_element_assign($coll1,5000,2345));
+var_dump(oci_collection_element_get($coll1, -1));
+var_dump(oci_collection_element_get($coll1, -100));
+var_dump(oci_collection_element_get($coll1, 500));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECTF--
+bool(true)
+
+Warning: oci_collection_element_assign(): OCI-22165: given index [4294967295] must be in the range of 0 to [0] in %s on line %d
+bool(false)
+
+Warning: oci_collection_element_assign(): OCI-22165: given index [5000] must be in the range of 0 to [0] in %s on line %d
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+Done
diff --git a/ext/oci8/tests/coll_017.phpt b/ext/oci8/tests/coll_017.phpt
new file mode 100644
index 0000000000..2ba0ce5382
--- /dev/null
+++ b/ext/oci8/tests/coll_017.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and nulls (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump($coll1->append("string"));
+var_dump($coll1->assignElem(0, null));
+var_dump($coll1->getElem(0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+NULL
+Done
diff --git a/ext/oci8/tests/coll_017_func.phpt b/ext/oci8/tests/coll_017_func.phpt
new file mode 100644
index 0000000000..ada10a192d
--- /dev/null
+++ b/ext/oci8/tests/coll_017_func.phpt
@@ -0,0 +1,44 @@
+--TEST--
+collections and nulls (2)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+$statement = OCIParse($c,$ora_sql);
+@OCIExecute($statement);
+
+$ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF VARCHAR(10)";
+
+$statement = OCIParse($c,$ora_sql);
+OCIExecute($statement);
+
+
+$coll1 = ocinewcollection($c, $type_name);
+
+var_dump(oci_collection_append($coll1, "string"));
+var_dump(oci_collection_element_assign($coll1, 0, null));
+var_dump(oci_collection_element_get($coll1, 0));
+
+echo "Done\n";
+
+require dirname(__FILE__)."/drop_type.inc";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+NULL
+Done
diff --git a/ext/oci8/tests/commit.phpt b/ext/oci8/tests/commit.phpt
new file mode 100644
index 0000000000..7a44a31a9b
--- /dev/null
+++ b/ext/oci8/tests/commit.phpt
@@ -0,0 +1,153 @@
+--TEST--
+oci_commit()/oci_rollback()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s, OCI_DEFAULT)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+var_dump(oci_rollback($c));
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($select = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+/* oci_fetch_all */
+if (!oci_execute($select)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(oci_fetch_all($select, $all));
+var_dump($all);
+
+/* ocifetchstatement */
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s, OCI_DEFAULT)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+var_dump(oci_commit($c));
+
+/* oci_fetch_all */
+if (!oci_execute($select)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(oci_fetch_all($select, $all));
+var_dump($all);
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+int(0)
+array(5) {
+ ["ID"]=>
+ array(0) {
+ }
+ ["VALUE"]=>
+ array(0) {
+ }
+ ["BLOB"]=>
+ array(0) {
+ }
+ ["CLOB"]=>
+ array(0) {
+ }
+ ["STRING"]=>
+ array(0) {
+ }
+}
+bool(true)
+int(4)
+array(5) {
+ ["ID"]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "1"
+ }
+ ["VALUE"]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "1"
+ }
+ ["BLOB"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+ ["CLOB"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+ ["STRING"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+}
+Done
diff --git a/ext/oci8/tests/commit_old.phpt b/ext/oci8/tests/commit_old.phpt
new file mode 100644
index 0000000000..3dfb383113
--- /dev/null
+++ b/ext/oci8/tests/commit_old.phpt
@@ -0,0 +1,151 @@
+--TEST--
+ocicommit()/ocirollback()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("ociparse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!ociexecute($s, OCI_DEFAULT)) {
+ die("ociexecute(insert) failed!\n");
+ }
+}
+
+var_dump(ocirollback($c));
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($select = ociparse($c, $select_sql))) {
+ die("ociparse(select) failed!\n");
+}
+
+if (!oci_execute($select)) {
+ die("ociexecute(select) failed!\n");
+}
+var_dump(ocifetchstatement($select, $all));
+var_dump($all);
+
+/* ocifetchstatement */
+if (!ociexecute($s)) {
+ die("ociexecute(select) failed!\n");
+}
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("ociparse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!ociexecute($s, OCI_DEFAULT)) {
+ die("ociexecute(insert) failed!\n");
+ }
+}
+
+var_dump(ocicommit($c));
+
+if (!ociexecute($select)) {
+ die("ociexecute(select) failed!\n");
+}
+var_dump(ocifetchstatement($select, $all));
+var_dump($all);
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+int(0)
+array(5) {
+ ["ID"]=>
+ array(0) {
+ }
+ ["VALUE"]=>
+ array(0) {
+ }
+ ["BLOB"]=>
+ array(0) {
+ }
+ ["CLOB"]=>
+ array(0) {
+ }
+ ["STRING"]=>
+ array(0) {
+ }
+}
+bool(true)
+int(4)
+array(5) {
+ ["ID"]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "1"
+ }
+ ["VALUE"]=>
+ array(4) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ [3]=>
+ string(1) "1"
+ }
+ ["BLOB"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+ ["CLOB"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+ ["STRING"]=>
+ array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ }
+}
+Done
diff --git a/ext/oci8/tests/connect.inc b/ext/oci8/tests/connect.inc
index a0013e20d7..887c8fdaa1 100644
--- a/ext/oci8/tests/connect.inc
+++ b/ext/oci8/tests/connect.inc
@@ -4,29 +4,27 @@
* Please, change user, password and dbase to match your configuration.
*
* */
-
-$user = "user";
-$password = "pass";
-$dbase = "base";
+
+$user = "system";
+$password = "system";
+$dbase = "oracle";
/*
* You should have privileges to create tables in this schema
*
* */
-
-$schema = "system";
-
/*
- * Remove the last line in skipif.inc to run tests
- *
- * */
-
+$schema = "system";
+*/
+$table_name = "tb".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5);
+$type_name = strtoupper("tp".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5));
+
if (!empty($dbase)) {
- $connection = ocilogon($user,$password,$dbase);
+ $c = ocilogon($user,$password,$dbase);
}
else {
- $connection = ocilogon($user,$password);
+ $c = ocilogon($user,$password);
}
if (!empty($schema)) {
diff --git a/ext/oci8/tests/connect.phpt b/ext/oci8/tests/connect.phpt
new file mode 100644
index 0000000000..d873a7e015
--- /dev/null
+++ b/ext/oci8/tests/connect.phpt
@@ -0,0 +1,27 @@
+--TEST--
+oci_connect()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(oci_connect($user, $password, $dbase));
+}
+else {
+ var_dump(oci_connect($user, $password));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+Done
diff --git a/ext/oci8/tests/connect_1.phpt b/ext/oci8/tests/connect_1.phpt
new file mode 100644
index 0000000000..e658344496
--- /dev/null
+++ b/ext/oci8/tests/connect_1.phpt
@@ -0,0 +1,40 @@
+--TEST--
+oci_pconnect() & oci_new_connect()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump($c1 = oci_pconnect($user, $password, $dbase));
+}
+else {
+ var_dump($c1 = oci_pconnect($user, $password));
+}
+
+if (!empty($dbase)) {
+ var_dump($c2 = oci_new_connect($user, $password, $dbase));
+}
+else {
+ var_dump($c2 = oci_new_connect($user, $password));
+}
+
+var_dump(oci_close($c1));
+var_dump(ocilogoff($c2));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 persistent connection)
+resource(%d) of type (oci8 connection)
+bool(true)
+bool(true)
+Done
diff --git a/ext/oci8/tests/connect_1_old.phpt b/ext/oci8/tests/connect_1_old.phpt
new file mode 100644
index 0000000000..73c756159d
--- /dev/null
+++ b/ext/oci8/tests/connect_1_old.phpt
@@ -0,0 +1,40 @@
+--TEST--
+ociplogon() & ocinlogon()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump($c1 = ociplogon($user, $password, $dbase));
+}
+else {
+ var_dump($c1 = ociplogon($user, $password));
+}
+
+if (!empty($dbase)) {
+ var_dump($c2 = ocinlogon($user, $password, $dbase));
+}
+else {
+ var_dump($c2 = ocinlogon($user, $password));
+}
+
+var_dump(ocilogoff($c1));
+var_dump(ocilogoff($c2));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 persistent connection)
+resource(%d) of type (oci8 connection)
+bool(true)
+bool(true)
+Done
diff --git a/ext/oci8/tests/connect_old.phpt b/ext/oci8/tests/connect_old.phpt
new file mode 100644
index 0000000000..a8183d4ec8
--- /dev/null
+++ b/ext/oci8/tests/connect_old.phpt
@@ -0,0 +1,27 @@
+--TEST--
+ocilogon()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(ocilogon($user, $password, $dbase));
+}
+else {
+ var_dump(ocilogon($user, $password));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+Done
diff --git a/ext/oci8/tests/connect_without_oracle_home.phpt b/ext/oci8/tests/connect_without_oracle_home.phpt
new file mode 100644
index 0000000000..513d60cefd
--- /dev/null
+++ b/ext/oci8/tests/connect_without_oracle_home.phpt
@@ -0,0 +1,25 @@
+--TEST--
+oci_connect() without ORACLE_HOME set (OCIServerAttach() segfaults)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(oci_connect($user, $password, $dbase));
+}
+else {
+ var_dump(oci_connect($user, $password));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: ocilogon(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect.inc on line %d
+
+Warning: oci_connect(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect_without_oracle_home.php on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/connect_without_oracle_home_old.phpt b/ext/oci8/tests/connect_without_oracle_home_old.phpt
new file mode 100644
index 0000000000..68b11de155
--- /dev/null
+++ b/ext/oci8/tests/connect_without_oracle_home_old.phpt
@@ -0,0 +1,25 @@
+--TEST--
+ocilogon() without ORACLE_HOME set (OCIServerAttach() segfaults)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(ocilogon($user, $password, $dbase));
+}
+else {
+ var_dump(ocilogon($user, $password));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: ocilogon(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect.inc on line %d
+
+Warning: oci_connect(): _oci_open_server failed, check ORACLE_HOME and NLS_LANG variables: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor in %sconnect_without_oracle_home.php on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/create_table.inc b/ext/oci8/tests/create_table.inc
index c423ce577d..d6debf2339 100644
--- a/ext/oci8/tests/create_table.inc
+++ b/ext/oci8/tests/create_table.inc
@@ -1,11 +1,18 @@
<?php
- if ($connection) {
+ if ($c) {
+ $ora_sql = "DROP TABLE
+ ".$schema.$table_name."
+ ";
+
+ $statement = OCIParse($c, $ora_sql);
+ @OCIExecute($statement);
+
$ora_sql = "CREATE TABLE
- ".$schema."php_test_table (id NUMBER, value NUMBER)
+ ".$schema.$table_name." (id NUMBER, value NUMBER, blob BLOB, clob CLOB, string VARCHAR(10))
";
- $statement = OCIParse($connection,$ora_sql);
+ $statement = OCIParse($c,$ora_sql);
OCIExecute($statement);
}
diff --git a/ext/oci8/tests/create_type.inc b/ext/oci8/tests/create_type.inc
new file mode 100644
index 0000000000..e23f7cb903
--- /dev/null
+++ b/ext/oci8/tests/create_type.inc
@@ -0,0 +1,17 @@
+<?php
+
+ if ($c) {
+ $ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+ $statement = OCIParse($c,$ora_sql);
+ @OCIExecute($statement);
+
+ $ora_sql = "CREATE TYPE ".$type_name." AS TABLE OF NUMBER(11)";
+
+ $statement = OCIParse($c,$ora_sql);
+ OCIExecute($statement);
+ }
+
+?>
diff --git a/ext/oci8/tests/cursor_bind_err.phpt b/ext/oci8/tests/cursor_bind_err.phpt
new file mode 100644
index 0000000000..343167387b
--- /dev/null
+++ b/ext/oci8/tests/cursor_bind_err.phpt
@@ -0,0 +1,53 @@
+--TEST--
+binding a cursor (with errors)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_table.inc";
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$sql = "select CURSOR(select * from ".$schema.$table_name.") into :cursor from dual";
+$stmt = oci_parse($c, $sql);
+
+$cursor = oci_new_cursor($c);
+oci_bind_by_name($stmt, ":cursor", $cursor, -1, OCI_B_CURSOR);
+
+oci_execute($stmt);
+
+oci_execute($cursor);
+var_dump(oci_fetch_assoc($cursor));
+
+require dirname(__FILE__)."/drop_table.inc";
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: oci_bind_by_name(): ORA-01036: illegal variable name/number in %s on line %d
+
+Warning: oci_fetch_assoc(): ORA-24338: statement handle not executed in %s on line %d
+bool(false)
+Done
diff --git a/ext/oci8/tests/cursors.phpt b/ext/oci8/tests/cursors.phpt
new file mode 100644
index 0000000000..e69ff82dd2
--- /dev/null
+++ b/ext/oci8/tests/cursors.phpt
@@ -0,0 +1,64 @@
+--TEST--
+fetching cursor from a statement
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_table.inc";
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$sql = "select CURSOR(select * from ".$schema.$table_name.") as curs FROM dual";
+$stmt = oci_parse($c, $sql);
+
+oci_execute($stmt);
+
+while ($data = oci_fetch_assoc($stmt)) {
+ oci_execute($data["CURS"]);
+ $subdata = oci_fetch_assoc($data["CURS"]);
+ var_dump($subdata);
+ var_dump(oci_cancel($data["CURS"]));
+ $subdata = oci_fetch_assoc($data["CURS"]);
+ var_dump($subdata);
+ var_dump(oci_cancel($data["CURS"]));
+}
+
+require dirname(__FILE__)."/drop_table.inc";
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+bool(true)
+
+Warning: oci_fetch_assoc()%sORA-01002: fetch out of sequence in %scursors.php on line %d
+bool(false)
+bool(true)
+Done
diff --git a/ext/oci8/tests/cursors_old.phpt b/ext/oci8/tests/cursors_old.phpt
new file mode 100644
index 0000000000..4991ed795a
--- /dev/null
+++ b/ext/oci8/tests/cursors_old.phpt
@@ -0,0 +1,69 @@
+--TEST--
+fetching cursor from a statement
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_table.inc";
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("ociparse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!ociexecute($s)) {
+ die("ociexecute(insert) failed!\n");
+ }
+}
+
+if (!ocicommit($c)) {
+ die("ocicommit() failed!\n");
+}
+
+$sql = "select CURSOR(select * from ".$schema.$table_name.") as curs FROM dual";
+$stmt = ociparse($c, $sql);
+
+ociexecute($stmt);
+
+while ($result = ocifetchinto($stmt, $data, OCI_ASSOC)) {
+ ociexecute($data["CURS"]);
+ ocifetchinto($data["CURS"], $subdata, OCI_ASSOC);
+ var_dump($subdata);
+ var_dump(ocicancel($data["CURS"]));
+ ocifetchinto($data["CURS"], $subdata, OCI_ASSOC);
+ var_dump($subdata);
+ var_dump(ocicancel($data["CURS"]));
+}
+
+require dirname(__FILE__)."/drop_table.inc";
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+bool(true)
+
+Warning: ocifetchinto():%sORA-01002: fetch out of sequence in %scursors_old.php on line %d
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+bool(true)
+Done
diff --git a/ext/oci8/tests/debug.phpt b/ext/oci8/tests/debug.phpt
new file mode 100644
index 0000000000..2a2d2f79c2
--- /dev/null
+++ b/ext/oci8/tests/debug.phpt
@@ -0,0 +1,36 @@
+--TEST--
+oci_internal_debug()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+oci_internal_debug(true);
+
+if (!empty($dbase)) {
+ oci_connect($user, $password, $dbase);
+}
+else {
+ oci_connect($user, $password);
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+OCI8 DEBUG: OCINlsEnvironmentVariableGet in php_oci_do_connect_ex() (%s/oci8.c:%d)
+Done
+OCI8 DEBUG: OCISessionEnd in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIHandleFree in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIServerDetach in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIHandleFree in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIHandleFree in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIHandleFree in php_oci_connection_close() (%s/oci8.c:%d)
+OCI8 DEBUG: OCIHandleFree in php_oci_connection_close() (%s/oci8.c:%d)
diff --git a/ext/oci8/tests/default_prefetch.phpt b/ext/oci8/tests/default_prefetch.phpt
new file mode 100644
index 0000000000..46d2d07e4c
--- /dev/null
+++ b/ext/oci8/tests/default_prefetch.phpt
@@ -0,0 +1,55 @@
+--TEST--
+oci8.default_prefetch ini option
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--INI--
+oci8.default_prefetch=20
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(oci_fetch($s));
+
+var_dump(oci_num_rows($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+int(1)
+Done
diff --git a/ext/oci8/tests/default_prefetch1.phpt b/ext/oci8/tests/default_prefetch1.phpt
new file mode 100644
index 0000000000..8f43450c84
--- /dev/null
+++ b/ext/oci8/tests/default_prefetch1.phpt
@@ -0,0 +1,55 @@
+--TEST--
+oci8.default_prefetch ini option
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--INI--
+oci8.default_prefetch=100
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(oci_fetch($s));
+
+var_dump(oci_num_rows($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+int(1)
+Done
diff --git a/ext/oci8/tests/default_prefetch2.phpt b/ext/oci8/tests/default_prefetch2.phpt
new file mode 100644
index 0000000000..8a0939cdc1
--- /dev/null
+++ b/ext/oci8/tests/default_prefetch2.phpt
@@ -0,0 +1,58 @@
+--TEST--
+oci8.default_prefetch ini option
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--INI--
+oci8.default_prefetch=100
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+var_dump(oci_set_prefetch($s, 10));
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(oci_fetch($s));
+
+var_dump(oci_num_rows($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+bool(true)
+int(1)
+Done
diff --git a/ext/oci8/tests/define.phpt b/ext/oci8/tests/define.phpt
new file mode 100644
index 0000000000..dde5d575b3
--- /dev/null
+++ b/ext/oci8/tests/define.phpt
@@ -0,0 +1,46 @@
+--TEST--
+oci_define_by_name()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_table.inc";
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (string) VALUES ('some')";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+}
+
+$stmt = oci_parse($c, "SELECT string FROM ".$table_name."");
+
+/* the define MUST be done BEFORE ociexecute! */
+
+$strong = '';
+oci_define_by_name($stmt, "STRING", $string, 20);
+
+oci_execute($stmt);
+
+while (oci_fetch($stmt)) {
+ var_dump($string);
+}
+
+require dirname(__FILE__)."/drop_table.inc";
+
+echo "Done\n";
+
+?>
+--EXPECT--
+string(4) "some"
+Done
diff --git a/ext/oci8/tests/define_old.phpt b/ext/oci8/tests/define_old.phpt
new file mode 100644
index 0000000000..e3c8278668
--- /dev/null
+++ b/ext/oci8/tests/define_old.phpt
@@ -0,0 +1,46 @@
+--TEST--
+ocidefinebyname()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__)."/create_table.inc";
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (string) VALUES ('some')";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+if (!ociexecute($s)) {
+ die("oci_execute(insert) failed!\n");
+}
+
+$stmt = ociparse($c, "SELECT string FROM ".$table_name."");
+
+/* the define MUST be done BEFORE ociexecute! */
+
+$strong = '';
+ocidefinebyname($stmt, "STRING", $string, 20);
+
+ociexecute($stmt);
+
+while (ocifetch($stmt)) {
+ var_dump($string);
+}
+
+require dirname(__FILE__)."/drop_table.inc";
+
+echo "Done\n";
+
+?>
+--EXPECT--
+string(4) "some"
+Done
diff --git a/ext/oci8/tests/drop_table.inc b/ext/oci8/tests/drop_table.inc
index 4e558f5e33..ffd99f5af3 100644
--- a/ext/oci8/tests/drop_table.inc
+++ b/ext/oci8/tests/drop_table.inc
@@ -1,11 +1,11 @@
<?php
- if ($connection) {
+ if ($c) {
$ora_sql = "DROP TABLE
- ".$schema."php_test_table
+ ".$schema.$table_name."
";
- $statement = OCIParse($connection,$ora_sql);
+ $statement = OCIParse($c,$ora_sql);
OCIExecute($statement);
}
diff --git a/ext/oci8/tests/drop_type.inc b/ext/oci8/tests/drop_type.inc
new file mode 100644
index 0000000000..047968ef28
--- /dev/null
+++ b/ext/oci8/tests/drop_type.inc
@@ -0,0 +1,12 @@
+<?php
+
+ if ($c) {
+ $ora_sql = "DROP TYPE
+ ".$type_name."
+ ";
+
+ $statement = OCIParse($c,$ora_sql);
+ OCIExecute($statement);
+ }
+
+?>
diff --git a/ext/oci8/tests/error.phpt b/ext/oci8/tests/error.phpt
new file mode 100644
index 0000000000..594a3d1319
--- /dev/null
+++ b/ext/oci8/tests/error.phpt
@@ -0,0 +1,45 @@
+--TEST--
+oci_error()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(oci_connect($user, $password, $dbase));
+}
+else {
+ var_dump(oci_connect($user, $password));
+}
+
+var_dump($s = oci_parse($c, "WRONG SYNTAX"));
+var_dump(oci_execute($s));
+var_dump(oci_error($s));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%s) of type (oci8 connection)
+resource(%s) of type (oci8 statement)
+
+Warning: oci_execute(): ORA-00900: invalid SQL statement in %s on line %d
+bool(false)
+array(4) {
+ ["code"]=>
+ int(900)
+ ["message"]=>
+ string(32) "ORA-00900: invalid SQL statement"
+ ["offset"]=>
+ int(0)
+ ["sqltext"]=>
+ string(12) "WRONG SYNTAX"
+}
+Done
diff --git a/ext/oci8/tests/error1.phpt b/ext/oci8/tests/error1.phpt
new file mode 100644
index 0000000000..a150de8975
--- /dev/null
+++ b/ext/oci8/tests/error1.phpt
@@ -0,0 +1,23 @@
+--TEST--
+oci_error() when oci_connect() fails
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+var_dump(oci_connect("some", "some", "some"));
+var_dump(oci_error());
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: oci_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d
+bool(false)
+bool(false)
+Done
diff --git a/ext/oci8/tests/error_old.phpt b/ext/oci8/tests/error_old.phpt
new file mode 100644
index 0000000000..fbdcd9e610
--- /dev/null
+++ b/ext/oci8/tests/error_old.phpt
@@ -0,0 +1,45 @@
+--TEST--
+ocierror()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump(ocilogon($user, $password, $dbase));
+}
+else {
+ var_dump(ocilogon($user, $password));
+}
+
+var_dump($s = ociparse($c, "WRONG SYNTAX"));
+var_dump(ociexecute($s));
+var_dump(ocierror($s));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%s) of type (oci8 connection)
+resource(%s) of type (oci8 statement)
+
+Warning: ociexecute(): ORA-00900: invalid SQL statement in %s on line %d
+bool(false)
+array(4) {
+ ["code"]=>
+ int(900)
+ ["message"]=>
+ string(32) "ORA-00900: invalid SQL statement"
+ ["offset"]=>
+ int(0)
+ ["sqltext"]=>
+ string(12) "WRONG SYNTAX"
+}
+Done
diff --git a/ext/oci8/tests/exec_fetch.phpt b/ext/oci8/tests/exec_fetch.phpt
new file mode 100644
index 0000000000..e1705273aa
--- /dev/null
+++ b/ext/oci8/tests/exec_fetch.phpt
@@ -0,0 +1,24 @@
+--TEST--
+fetch after failed oci_execute()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$sql = "select 2 from nonex_dual";
+$stmt = oci_parse($c, $sql);
+
+var_dump(oci_execute($stmt));
+var_dump(oci_fetch_array($stmt));
+
+echo "Done\n";
+?>
+--EXPECTF--
+Done
diff --git a/ext/oci8/tests/fetch.phpt b/ext/oci8/tests/fetch.phpt
new file mode 100644
index 0000000000..72ca9f3f80
--- /dev/null
+++ b/ext/oci8/tests/fetch.phpt
@@ -0,0 +1,61 @@
+--TEST--
+ocifetch() & ociresult()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+while(ocifetch($s)) {
+ $i = 1;
+ while ($row = ociresult($s, $i)) {
+ $i++;
+ var_dump($row);
+ }
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+string(1) "1"
+string(1) "1"
+string(1) "1"
+string(1) "1"
+string(1) "1"
+string(1) "1"
+Done
diff --git a/ext/oci8/tests/fetch_all.phpt b/ext/oci8/tests/fetch_all.phpt
new file mode 100644
index 0000000000..49193ffc87
--- /dev/null
+++ b/ext/oci8/tests/fetch_all.phpt
@@ -0,0 +1,154 @@
+--TEST--
+oci_fetch_all()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+/* oci_fetch_all */
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(oci_fetch_all($s, $all));
+var_dump($all);
+
+/* ocifetchstatement */
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(ocifetchstatement($s, $all));
+var_dump($all);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+int(3)
+array(5) {
+ ["ID"]=>
+ array(3) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ }
+ ["VALUE"]=>
+ array(3) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ }
+ ["BLOB"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+ ["CLOB"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+ ["STRING"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+}
+int(3)
+array(5) {
+ ["ID"]=>
+ array(3) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ }
+ ["VALUE"]=>
+ array(3) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "1"
+ }
+ ["BLOB"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+ ["CLOB"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+ ["STRING"]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+ }
+}
+Done
diff --git a/ext/oci8/tests/fetch_array.phpt b/ext/oci8/tests/fetch_array.phpt
new file mode 100644
index 0000000000..ada162453d
--- /dev/null
+++ b/ext/oci8/tests/fetch_array.phpt
@@ -0,0 +1,235 @@
+--TEST--
+oci_fetch_array()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s)) {
+ var_dump($row);
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s, OCI_NUM)) {
+ var_dump($row);
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s, OCI_ASSOC)) {
+ var_dump($row);
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s, OCI_BOTH)) {
+ var_dump($row);
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s, OCI_RETURN_LOBS)) {
+ var_dump($row);
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_array($s, OCI_RETURN_NULLS)) {
+ var_dump($row);
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+Done
diff --git a/ext/oci8/tests/fetch_assoc.phpt b/ext/oci8/tests/fetch_assoc.phpt
new file mode 100644
index 0000000000..9b6866a100
--- /dev/null
+++ b/ext/oci8/tests/fetch_assoc.phpt
@@ -0,0 +1,69 @@
+--TEST--
+oci_fetch_assoc()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_assoc($s)) {
+ var_dump($row);
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+Done
diff --git a/ext/oci8/tests/fetch_into.phpt b/ext/oci8/tests/fetch_into.phpt
new file mode 100644
index 0000000000..4953a25026
--- /dev/null
+++ b/ext/oci8/tests/fetch_into.phpt
@@ -0,0 +1,87 @@
+--TEST--
+ocifetchinto()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+/* oci_fetch_all */
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(ocifetchinto($s, $all));
+var_dump($all);
+
+/* oci_fetch_all */
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(ocifetchinto($s, $all, OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS));
+var_dump($all);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+int(5)
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+int(5)
+array(10) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ ["BLOB"]=>
+ NULL
+ [3]=>
+ NULL
+ ["CLOB"]=>
+ NULL
+ [4]=>
+ NULL
+ ["STRING"]=>
+ NULL
+}
+Done
diff --git a/ext/oci8/tests/fetch_into1.phpt b/ext/oci8/tests/fetch_into1.phpt
new file mode 100644
index 0000000000..91d02e3d5c
--- /dev/null
+++ b/ext/oci8/tests/fetch_into1.phpt
@@ -0,0 +1,197 @@
+--TEST--
+various ocifetchinto() tests
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value, string) VALUES (1, 1, NULL)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<20; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(ocifetchinto($s, $all, OCI_NUM));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_ASSOC));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_RETURN_NULLS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_RETURN_LOBS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_NUM+OCI_ASSOC));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_RETURN_NULLS+OCI_RETURN_LOBS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_NUM+OCI_RETURN_NULLS+OCI_RETURN_LOBS));
+var_dump($all);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+int(5)
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+int(5)
+array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+int(5)
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+int(5)
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+int(5)
+array(4) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+int(5)
+array(10) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ ["BLOB"]=>
+ NULL
+ [3]=>
+ NULL
+ ["CLOB"]=>
+ NULL
+ [4]=>
+ NULL
+ ["STRING"]=>
+ NULL
+}
+int(5)
+array(10) {
+ [0]=>
+ string(1) "1"
+ ["ID"]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ ["BLOB"]=>
+ NULL
+ [3]=>
+ NULL
+ ["CLOB"]=>
+ NULL
+ [4]=>
+ NULL
+ ["STRING"]=>
+ NULL
+}
+int(5)
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+int(5)
+array(5) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+ ["BLOB"]=>
+ NULL
+ ["CLOB"]=>
+ NULL
+ ["STRING"]=>
+ NULL
+}
+int(5)
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+Done
diff --git a/ext/oci8/tests/fetch_into2.phpt b/ext/oci8/tests/fetch_into2.phpt
new file mode 100644
index 0000000000..27c137b429
--- /dev/null
+++ b/ext/oci8/tests/fetch_into2.phpt
@@ -0,0 +1,75 @@
+--TEST--
+ocifetchinto() & wrong number of params
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value, string) VALUES (1, 1, NULL)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<20; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+var_dump(ocifetchinto($s));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, OCI_ASSOC, 5));
+var_dump($all);
+var_dump(ocifetchinto($c, $all, OCI_RETURN_LOBS));
+var_dump($all);
+var_dump(ocifetchinto($s, $all, 1000000));
+var_dump($all);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: ocifetchinto() expects at least 2 parameters, 1 given in %s on line %d
+NULL
+
+Notice: Undefined variable: all in %s on line %d
+NULL
+
+Warning: ocifetchinto() expects at most 3 parameters, 4 given in %s on line %d
+NULL
+NULL
+
+Warning: ocifetchinto(): supplied resource is not a valid oci8 statement resource in %s on line %d
+bool(false)
+NULL
+int(5)
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+Done
diff --git a/ext/oci8/tests/fetch_object.phpt b/ext/oci8/tests/fetch_object.phpt
new file mode 100644
index 0000000000..2df0480a39
--- /dev/null
+++ b/ext/oci8/tests/fetch_object.phpt
@@ -0,0 +1,69 @@
+--TEST--
+oci_fetch_object()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_object($s)) {
+ var_dump($row);
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+object(stdClass)#1 (2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+object(stdClass)#2 (2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+object(stdClass)#1 (2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VALUE"]=>
+ string(1) "1"
+}
+Done
diff --git a/ext/oci8/tests/fetch_row.phpt b/ext/oci8/tests/fetch_row.phpt
new file mode 100644
index 0000000000..a2c0e883a0
--- /dev/null
+++ b/ext/oci8/tests/fetch_row.phpt
@@ -0,0 +1,69 @@
+--TEST--
+oci_fetch_row()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+while ($row = oci_fetch_row($s)) {
+ var_dump($row);
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+}
+Done
diff --git a/ext/oci8/tests/field_funcs.phpt b/ext/oci8/tests/field_funcs.phpt
new file mode 100644
index 0000000000..bba6632e86
--- /dev/null
+++ b/ext/oci8/tests/field_funcs.phpt
@@ -0,0 +1,110 @@
+--TEST--
+oci_field_*() family
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+$row = oci_fetch_array($s, OCI_RETURN_NULLS + OCI_RETURN_LOBS);
+var_dump($row);
+
+foreach ($row as $num => $field) {
+ $num++;
+ var_dump(oci_field_is_null($s, $num));
+ var_dump(oci_field_name($s, $num));
+ var_dump(oci_field_type($s, $num));
+ var_dump(oci_field_type_raw($s, $num));
+ var_dump(oci_field_scale($s, $num));
+ var_dump(oci_field_precision($s, $num));
+ var_dump(oci_field_size($s, $num));
+}
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+bool(false)
+string(2) "ID"
+string(6) "NUMBER"
+int(2)
+int(0)
+int(0)
+int(22)
+bool(false)
+string(5) "VALUE"
+string(6) "NUMBER"
+int(2)
+int(0)
+int(0)
+int(22)
+bool(true)
+string(4) "BLOB"
+string(4) "BLOB"
+int(113)
+int(0)
+int(0)
+int(4000)
+bool(true)
+string(4) "CLOB"
+string(4) "CLOB"
+int(112)
+int(0)
+int(0)
+int(4000)
+bool(true)
+string(6) "STRING"
+string(7) "VARCHAR"
+int(1)
+int(0)
+int(0)
+int(10)
+Done
diff --git a/ext/oci8/tests/field_funcs_old.phpt b/ext/oci8/tests/field_funcs_old.phpt
new file mode 100644
index 0000000000..c5339a7502
--- /dev/null
+++ b/ext/oci8/tests/field_funcs_old.phpt
@@ -0,0 +1,110 @@
+--TEST--
+ocicolumn*() family
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema."".$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("ociparse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!ociexecute($s)) {
+ die("ociexecute(insert) failed!\n");
+ }
+}
+
+if (!ocicommit($c)) {
+ die("ocicommit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema."".$table_name."";
+
+if (!($s = ociparse($c, $select_sql))) {
+ die("ociparse(select) failed!\n");
+}
+
+if (!ociexecute($s)) {
+ die("ociexecute(select) failed!\n");
+}
+
+ocifetchinto($s, $row, OCI_NUM + OCI_RETURN_NULLS + OCI_RETURN_LOBS);
+var_dump($row);
+
+foreach ($row as $num => $field) {
+ $num++;
+ var_dump(ocicolumnisnull($s, $num));
+ var_dump(ocicolumnname($s, $num));
+ var_dump(ocicolumntype($s, $num));
+ var_dump(ocicolumntyperaw($s, $num));
+ var_dump(ocicolumnscale($s, $num));
+ var_dump(ocicolumnprecision($s, $num));
+ var_dump(ocicolumnsize($s, $num));
+}
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+array(5) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ NULL
+ [3]=>
+ NULL
+ [4]=>
+ NULL
+}
+bool(false)
+string(2) "ID"
+string(6) "NUMBER"
+int(2)
+int(0)
+int(0)
+int(22)
+bool(false)
+string(5) "VALUE"
+string(6) "NUMBER"
+int(2)
+int(0)
+int(0)
+int(22)
+bool(true)
+string(4) "BLOB"
+string(4) "BLOB"
+int(113)
+int(0)
+int(0)
+int(4000)
+bool(true)
+string(4) "CLOB"
+string(4) "CLOB"
+int(112)
+int(0)
+int(0)
+int(4000)
+bool(true)
+string(6) "STRING"
+string(7) "VARCHAR"
+int(1)
+int(0)
+int(0)
+int(10)
+Done
diff --git a/ext/oci8/tests/lob_001.phpt b/ext/oci8/tests/lob_001.phpt
new file mode 100644
index 0000000000..405b2b814c
--- /dev/null
+++ b/ext/oci8/tests/lob_001.phpt
Binary files differ
diff --git a/ext/oci8/tests/lob_002.phpt b/ext/oci8/tests/lob_002.phpt
new file mode 100644
index 0000000000..c414905f39
--- /dev/null
+++ b/ext/oci8/tests/lob_002.phpt
@@ -0,0 +1,71 @@
+--TEST--
+oci_lob_write() and friends (with errors)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+
+var_dump($blob->write("test", -1));
+var_dump($blob->write("test", "str"));
+var_dump($blob->write("test", 1000000));
+var_dump($blob->write(str_repeat("test", 10000), 1000000));
+var_dump($blob->tell());
+var_dump($blob->seek("str", -5));
+var_dump($blob->flush());
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name."";
+$s = oci_parse($c, $select_sql);
+oci_execute($s);
+
+$row = oci_fetch_array($s, OCI_RETURN_LOBS);
+
+var_dump(strlen($row[0]));
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+}
+int(0)
+
+Warning: OCI-Lob::write() expects parameter 2 to be long, string given in %slob_002.php on line %d
+NULL
+int(4)
+int(40000)
+int(40004)
+
+Warning: OCI-Lob::seek() expects parameter 1 to be long, string given in %slob_002.php on line %d
+NULL
+bool(false)
+int(40004)
+Done
diff --git a/ext/oci8/tests/lob_003.phpt b/ext/oci8/tests/lob_003.phpt
new file mode 100644
index 0000000000..76f1a7e4b0
--- /dev/null
+++ b/ext/oci8/tests/lob_003.phpt
Binary files differ
diff --git a/ext/oci8/tests/lob_004.phpt b/ext/oci8/tests/lob_004.phpt
new file mode 100644
index 0000000000..56ccfbcd4a
--- /dev/null
+++ b/ext/oci8/tests/lob_004.phpt
@@ -0,0 +1,85 @@
+--TEST--
+oci_lob_seek()/rewind()/append()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+
+var_dump($blob->write("test"));
+var_dump($blob->rewind());
+var_dump($blob->write("str"));
+var_dump($blob->seek(10, OCI_SEEK_SET));
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_array($s));
+
+var_dump($row[0]->append($blob));
+var_dump($row[0]->read(10000));
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+$row = oci_fetch_array($s);
+
+var_dump($row[0]->read(10000));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+}
+int(4)
+bool(true)
+int(3)
+bool(true)
+array(2) {
+ [0]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+bool(true)
+string(4) "strt"
+string(8) "strtstrt"
+Done
diff --git a/ext/oci8/tests/lob_005.phpt b/ext/oci8/tests/lob_005.phpt
new file mode 100644
index 0000000000..d82400e47e
--- /dev/null
+++ b/ext/oci8/tests/lob_005.phpt
@@ -0,0 +1,57 @@
+--TEST--
+oci_lob_is_equal()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_array($s));
+
+var_dump(oci_lob_is_equal($row[0], $row['BLOB']));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+bool(true)
+Done
diff --git a/ext/oci8/tests/lob_006.phpt b/ext/oci8/tests/lob_006.phpt
new file mode 100644
index 0000000000..321d948b1a
--- /dev/null
+++ b/ext/oci8/tests/lob_006.phpt
Binary files differ
diff --git a/ext/oci8/tests/lob_007.phpt b/ext/oci8/tests/lob_007.phpt
new file mode 100644
index 0000000000..0f2920414f
--- /dev/null
+++ b/ext/oci8/tests/lob_007.phpt
@@ -0,0 +1,71 @@
+--TEST--
+oci_lob_write()/size()/load()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+
+var_dump($blob->size());
+var_dump($blob->write(str_repeat("string.", 1000)));
+var_dump($blob->size());
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_array($s));
+
+var_dump($row[0]->size());
+var_dump(strlen($row[0]->load()));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+}
+int(0)
+int(7000)
+int(7000)
+array(2) {
+ [0]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+int(7000)
+int(7000)
+Done
diff --git a/ext/oci8/tests/lob_008.phpt b/ext/oci8/tests/lob_008.phpt
new file mode 100644
index 0000000000..a0b4a557df
--- /dev/null
+++ b/ext/oci8/tests/lob_008.phpt
@@ -0,0 +1,70 @@
+--TEST--
+oci_lob_write()/read()/eof()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+
+var_dump($blob->write(str_repeat("string.", 1000)));
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_array($s));
+
+
+$len = 0;
+while (!$row[0]->eof()) {
+ $len += strlen($row[0]->read(1024));
+}
+var_dump($len);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+}
+int(7000)
+array(2) {
+ [0]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+int(7000)
+Done
diff --git a/ext/oci8/tests/lob_009.phpt b/ext/oci8/tests/lob_009.phpt
new file mode 100644
index 0000000000..9b467dd12a
--- /dev/null
+++ b/ext/oci8/tests/lob_009.phpt
@@ -0,0 +1,74 @@
+--TEST--
+oci_lob_import()/read()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+var_dump($blob->seek(10, OCI_SEEK_CUR));
+var_dump($blob->import(dirname(__FILE__)."/lob_009.txt"));
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row = oci_fetch_array($s));
+
+while (!$row[0]->eof()) {
+ var_dump($row[0]->read(1024));
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+}
+bool(true)
+bool(true)
+array(2) {
+ [0]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["BLOB"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+string(43) "this
+is
+a
+test
+file for
+test lob_009.phpt
+"
+Done
diff --git a/ext/oci8/tests/lob_009.txt b/ext/oci8/tests/lob_009.txt
new file mode 100644
index 0000000000..f57bc8af37
--- /dev/null
+++ b/ext/oci8/tests/lob_009.txt
@@ -0,0 +1,6 @@
+this
+is
+a
+test
+file for
+test lob_009.phpt
diff --git a/ext/oci8/tests/lob_010.phpt b/ext/oci8/tests/lob_010.phpt
new file mode 100644
index 0000000000..85d37dc738
--- /dev/null
+++ b/ext/oci8/tests/lob_010.phpt
@@ -0,0 +1,51 @@
+--TEST--
+oci_lob_save()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob->save("string"));
+var_dump($blob->save("string", 3));
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+$row = oci_fetch_array($s);
+
+while (!$row[0]->eof()) {
+ var_dump($row[0]->read(1024));
+}
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+string(9) "strstring"
+Done
diff --git a/ext/oci8/tests/lob_011.phpt b/ext/oci8/tests/lob_011.phpt
new file mode 100644
index 0000000000..41d54cf147
--- /dev/null
+++ b/ext/oci8/tests/lob_011.phpt
@@ -0,0 +1,81 @@
+--TEST--
+oci_lob_copy()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (id, blob)
+ VALUES (1, empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob->write("some string here. string, I said"));
+oci_commit($c);
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (id, blob)
+ VALUES (2, empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." WHERE id = 1";
+$s = oci_parse($c, $select_sql);
+oci_execute($s);
+
+$row1 = oci_fetch_array($s);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." WHERE id = 2 FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+$row2 = oci_fetch_array($s);
+
+var_dump(oci_lob_copy($row2[0], $row1[0]));
+var_dump($row1[0]->read(100));
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." WHERE id = 2 FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+var_dump($row2 = oci_fetch_array($s, OCI_RETURN_LOBS));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+int(32)
+bool(true)
+string(32) "some string here. string, I said"
+array(1) {
+ [0]=>
+ string(32) "some string here. string, I said"
+}
+Done
diff --git a/ext/oci8/tests/lob_012.phpt b/ext/oci8/tests/lob_012.phpt
new file mode 100644
index 0000000000..fb434d9260
--- /dev/null
+++ b/ext/oci8/tests/lob_012.phpt
@@ -0,0 +1,55 @@
+--TEST--
+oci_lob_export()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+$blob;
+
+var_dump($blob->write("test string is here\nnew string"));
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name." FOR UPDATE";
+$s = oci_parse($c, $select_sql);
+oci_execute($s, OCI_DEFAULT);
+
+$row = oci_fetch_array($s);
+
+var_dump($row[0]->export(dirname(__FILE__)."/lob_012.tmp", 3, 10));
+
+var_dump(file_get_contents(dirname(__FILE__)."/lob_012.tmp"));
+
+@unlink(dirname(__FILE__)."/lob_012.tmp");
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+int(30)
+bool(true)
+string(10) "t string i"
+Done
diff --git a/ext/oci8/tests/lob_013.phpt b/ext/oci8/tests/lob_013.phpt
new file mode 100644
index 0000000000..608640c7a1
--- /dev/null
+++ b/ext/oci8/tests/lob_013.phpt
@@ -0,0 +1,59 @@
+--TEST--
+lob buffering
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob->write("test"));
+var_dump($blob->getBuffering());
+var_dump($blob->setBuffering(true));
+var_dump($blob->write("test"));
+var_dump($blob->getBuffering());
+var_dump($blob->flush());
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name."";
+$s = oci_parse($c, $select_sql);
+oci_execute($s);
+
+$row = oci_fetch_array($s, OCI_RETURN_LOBS);
+
+var_dump($row[0]);
+
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+int(4)
+bool(false)
+bool(true)
+int(4)
+bool(true)
+bool(true)
+string(8) "testtest"
+Done
diff --git a/ext/oci8/tests/lob_014.phpt b/ext/oci8/tests/lob_014.phpt
new file mode 100644
index 0000000000..b0e0db5a01
--- /dev/null
+++ b/ext/oci8/tests/lob_014.phpt
@@ -0,0 +1,63 @@
+--TEST--
+oci_lob_free()/close()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($statement, OCI_DEFAULT);
+
+$blob;
+
+var_dump($blob->write("test"));
+var_dump($blob->close());
+var_dump($blob->write("test"));
+var_dump($blob->free());
+var_dump($blob->write("test"));
+
+oci_commit($c);
+
+$select_sql = "SELECT blob FROM ".$schema.$table_name."";
+$s = oci_parse($c, $select_sql);
+oci_execute($s);
+
+var_dump(oci_fetch_array($s, OCI_NUM + OCI_RETURN_LOBS));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+int(4)
+
+Warning: OCI-Lob::close(): ORA-22289: cannot perform operation on an unopened file or LOB in %slob_014.php on line %d
+bool(false)
+int(4)
+bool(true)
+
+Warning: OCI-Lob::write(): %d is not a valid oci8 descriptor resource in %slob_014.php on line %d
+bool(false)
+array(1) {
+ [0]=>
+ string(8) "testtest"
+}
+Done
diff --git a/ext/oci8/tests/lob_015.phpt b/ext/oci8/tests/lob_015.phpt
new file mode 100644
index 0000000000..5419087888
--- /dev/null
+++ b/ext/oci8/tests/lob_015.phpt
@@ -0,0 +1,56 @@
+--TEST--
+various tests with wrong param count
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$schema.$table_name." (blob)
+ VALUES (empty_blob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$statement = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB,1,2,3);
+$blob = oci_new_descriptor($c);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB,4);
+oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB,4,5);
+oci_bind_by_name($statement,":v_blob", $blob,-1);
+oci_bind_by_name($statement,":v_blob", $blob);
+oci_bind_by_name($statement,":v_blob");
+oci_bind_by_name($statement);
+oci_execute($statement, OCI_DEFAULT);
+
+var_dump($blob);
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+Warning: oci_new_descriptor() expects at most 2 parameters, 5 given in %slob_015.php on line %d
+
+Warning: oci_bind_by_name() expects at most 5 parameters, 6 given in %slob_015.php on line %d
+
+Warning: oci_bind_by_name() expects at most 5 parameters, 7 given in %slob_015.php on line %d
+
+Notice: Object of class OCI-Lob to string conversion in %slob_015.php on line %d
+
+Warning: oci_bind_by_name() expects at least 3 parameters, 2 given in %slob_015.php on line %d
+
+Warning: oci_bind_by_name() expects at least 3 parameters, 1 given in %slob_015.php on line %d
+
+Warning: oci_execute(): ORA-00932: inconsistent datatypes: expected NUMBER got BLOB in %slob_015.php on line %d
+string(6) "Object"
+Done
diff --git a/ext/oci8/tests/lob_016.phpt b/ext/oci8/tests/lob_016.phpt
new file mode 100644
index 0000000000..d021cc3ac8
--- /dev/null
+++ b/ext/oci8/tests/lob_016.phpt
@@ -0,0 +1,72 @@
+--TEST--
+returning multiple lobs
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+$create = "CREATE table lob_test(lob_1 BLOB, lob_2 BLOB)";
+$statement = oci_parse($c, $create);
+oci_execute($statement);
+
+$init = "INSERT INTO lob_test VALUES(EMPTY_BLOB(), EMPTY_BLOB())";
+$statement = oci_parse($c, $init);
+oci_execute($statement);
+
+$select = "SELECT * FROM lob_test FOR UPDATE";
+$statement = oci_parse($c, $select);
+oci_execute($statement, OCI_DEFAULT);
+
+$row = oci_fetch_assoc($statement);
+
+$row['LOB_1']->write("first");
+$row['LOB_2']->write("second");
+
+unset($row);
+
+oci_commit($c);
+
+$select = "SELECT * FROM lob_test FOR UPDATE";
+$statement = oci_parse($c, $select);
+oci_execute($statement, OCI_DEFAULT);
+
+$row = oci_fetch_assoc($statement);
+
+var_dump($row);
+var_dump($row['LOB_1']->load());
+var_dump($row['LOB_2']->load());
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+array(2) {
+ ["LOB_1"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["LOB_2"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+string(5) "first"
+string(6) "second"
+Done
diff --git a/ext/oci8/tests/lob_017.phpt b/ext/oci8/tests/lob_017.phpt
new file mode 100644
index 0000000000..43b4a513b3
--- /dev/null
+++ b/ext/oci8/tests/lob_017.phpt
@@ -0,0 +1,74 @@
+--TEST--
+returning multiple lobs (using persistent connection)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$c = oci_pconnect($user, $password, $dbase);
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+$create = "CREATE table lob_test(lob_1 BLOB, lob_2 BLOB)";
+$statement = oci_parse($c, $create);
+oci_execute($statement);
+
+$init = "INSERT INTO lob_test VALUES(EMPTY_BLOB(), EMPTY_BLOB())";
+$statement = oci_parse($c, $init);
+oci_execute($statement);
+
+$select = "SELECT * FROM lob_test FOR UPDATE";
+$statement = oci_parse($c, $select);
+oci_execute($statement, OCI_DEFAULT);
+
+$row = oci_fetch_assoc($statement);
+
+$row['LOB_1']->write("first");
+$row['LOB_2']->write("second");
+
+unset($row);
+
+oci_commit($c);
+
+$select = "SELECT * FROM lob_test FOR UPDATE";
+$statement = oci_parse($c, $select);
+oci_execute($statement, OCI_DEFAULT);
+
+$row = oci_fetch_assoc($statement);
+
+var_dump($row);
+var_dump($row['LOB_1']->load());
+var_dump($row['LOB_2']->load());
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+array(2) {
+ ["LOB_1"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+ ["LOB_2"]=>
+ object(OCI-Lob)#%d (1) {
+ ["descriptor"]=>
+ resource(%d) of type (oci8 descriptor)
+ }
+}
+string(5) "first"
+string(6) "second"
+Done
diff --git a/ext/oci8/tests/lob_018.phpt b/ext/oci8/tests/lob_018.phpt
new file mode 100644
index 0000000000..360f50f387
--- /dev/null
+++ b/ext/oci8/tests/lob_018.phpt
@@ -0,0 +1,72 @@
+--TEST--
+fetching the same lob several times
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+$create = "CREATE table lob_test(mykey NUMBER, lob_1 CLOB)";
+$statement = oci_parse($c, $create);
+oci_execute($statement);
+
+$init = "INSERT INTO lob_test (mykey, lob_1) VALUES(1, EMPTY_CLOB()) RETURNING lob_1 INTO :mylob";
+$statement = oci_parse($c, $init);
+$clob = oci_new_descriptor($c, OCI_D_LOB);
+oci_bind_by_name($statement, ":mylob", $clob, -1, OCI_B_CLOB);
+oci_execute($statement, OCI_DEFAULT);
+$clob->save("data");
+
+oci_commit($c);
+
+$init = "INSERT INTO lob_test (mykey, lob_1) VALUES(2, EMPTY_CLOB()) RETURNING lob_1 INTO :mylob";
+$statement = oci_parse($c, $init);
+$clob = oci_new_descriptor($c, OCI_D_LOB);
+oci_bind_by_name($statement, ":mylob", $clob, -1, OCI_B_CLOB);
+oci_execute($statement, OCI_DEFAULT);
+$clob->save("long data");
+
+oci_commit($c);
+
+
+$query = 'SELECT * FROM lob_test ORDER BY mykey ASC';
+$statement = oci_parse ($c, $query);
+oci_execute($statement, OCI_DEFAULT);
+
+while ($row = oci_fetch_array($statement, OCI_ASSOC)) {
+ $result = $row['LOB_1']->load();
+ var_dump($result);
+}
+
+$query = 'SELECT * FROM lob_test ORDER BY mykey DESC';
+$statement = oci_parse ($c, $query);
+oci_execute($statement, OCI_DEFAULT);
+
+while ($row = oci_fetch_array($statement, OCI_ASSOC)) {
+ $result = $row['LOB_1']->load();
+ var_dump($result);
+}
+
+$drop = "DROP table lob_test";
+$statement = oci_parse($c, $drop);
+@oci_execute($statement);
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+string(4) "data"
+string(9) "long data"
+string(9) "long data"
+string(4) "data"
+Done
diff --git a/ext/oci8/tests/lob_temp.phpt b/ext/oci8/tests/lob_temp.phpt
new file mode 100644
index 0000000000..4532d53630
--- /dev/null
+++ b/ext/oci8/tests/lob_temp.phpt
@@ -0,0 +1,41 @@
+--TEST--
+temporary lobs
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+var_dump($blob->writeTemporary("test"));
+var_dump($blob->load());
+var_dump($blob->seek(0, SEEK_SET));
+var_dump($blob->read(2));
+
+$c = oci_pconnect($user, $password, $dbase);
+
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+var_dump($blob->writeTemporary("test"));
+var_dump($blob->load());
+var_dump($blob->seek(0, SEEK_SET));
+var_dump($blob->read(2));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+bool(true)
+string(4) "test"
+bool(true)
+string(2) "te"
+bool(true)
+string(4) "test"
+bool(true)
+string(2) "te"
+Done
diff --git a/ext/oci8/tests/lob_temp1.phpt b/ext/oci8/tests/lob_temp1.phpt
new file mode 100644
index 0000000000..563a7e1f26
--- /dev/null
+++ b/ext/oci8/tests/lob_temp1.phpt
@@ -0,0 +1,37 @@
+--TEST--
+closing temporary lobs
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+var_dump($blob->writeTemporary("test"));
+var_dump($blob->load());
+var_dump($blob->close());
+
+$c = oci_pconnect($user, $password, $dbase);
+
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+var_dump($blob->writeTemporary("test"));
+var_dump($blob->load());
+var_dump($blob->close());
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+bool(true)
+string(4) "test"
+bool(true)
+bool(true)
+string(4) "test"
+bool(true)
+Done
diff --git a/ext/oci8/tests/num.phpt b/ext/oci8/tests/num.phpt
new file mode 100644
index 0000000000..34b1a9c07d
--- /dev/null
+++ b/ext/oci8/tests/num.phpt
@@ -0,0 +1,71 @@
+--TEST--
+oci_num_*() family
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(ocirowcount($s));
+var_dump(oci_num_rows($s));
+var_dump(ocinumcols($s));
+var_dump(oci_num_fields($s));
+
+$delete_sql = "DELETE FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $delete_sql))) {
+ die("oci_parse(delete) failed!\n");
+}
+
+if (!oci_execute($s)) {
+ die("oci_execute(delete) failed!\n");
+}
+oci_commit($c);
+
+var_dump(oci_num_rows($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+
+?>
+--EXPECT--
+int(0)
+int(0)
+int(5)
+int(5)
+int(3)
+Done
diff --git a/ext/oci8/tests/oci_execute_segfault.phpt b/ext/oci8/tests/oci_execute_segfault.phpt
new file mode 100644
index 0000000000..b7f0b62c85
--- /dev/null
+++ b/ext/oci8/tests/oci_execute_segfault.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_execute() segfault after repeated bind
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+require dirname(__FILE__).'/create_table.inc';
+
+$ora_sql = "INSERT INTO
+ ".$table_name." (blob, clob)
+ VALUES (empty_blob(), empty_clob())
+ RETURNING
+ blob
+ INTO :v_blob ";
+
+$s = oci_parse($c,$ora_sql);
+$blob = oci_new_descriptor($c,OCI_D_LOB);
+oci_bind_by_name($s,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($s);
+
+oci_bind_by_name($s,":v_blob", $blob,-1,OCI_B_BLOB);
+oci_execute($s);
+
+echo "Done\n";
+
+?>
+--EXPECT--
+Done
diff --git a/ext/oci8/tests/old_oci_close.phpt b/ext/oci8/tests/old_oci_close.phpt
new file mode 100644
index 0000000000..beb1b34ab5
--- /dev/null
+++ b/ext/oci8/tests/old_oci_close.phpt
@@ -0,0 +1,28 @@
+--TEST--
+oci8.old_oci_close_semantics On
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--INI--
+oci8.old_oci_close_semantics=1
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+var_dump($c);
+var_dump(oci_close($c));
+var_dump(oci_parse($c, "select 1 from dual"));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+NULL
+resource(%d) of type (oci8 statement)
+Done
diff --git a/ext/oci8/tests/old_oci_close1.phpt b/ext/oci8/tests/old_oci_close1.phpt
new file mode 100644
index 0000000000..c79eb077be
--- /dev/null
+++ b/ext/oci8/tests/old_oci_close1.phpt
@@ -0,0 +1,30 @@
+--TEST--
+oci8.old_oci_close_semantics Off
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--INI--
+oci8.old_oci_close_semantics=0
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+var_dump($c);
+var_dump(oci_close($c));
+var_dump(oci_parse($c, "select 1 from dual"));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+bool(true)
+
+Warning: oci_parse() expects parameter 1 to be resource, null given in %s on line %d
+NULL
+Done
diff --git a/ext/oci8/tests/password.phpt b/ext/oci8/tests/password.phpt
new file mode 100644
index 0000000000..37f586cd4f
--- /dev/null
+++ b/ext/oci8/tests/password.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_password_change()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$new_password = "test";
+var_dump(oci_password_change($dbase, $user, $password, $new_password));
+
+if (!empty($dbase)) {
+ var_dump($new_c = ocilogon($user,$new_password,$dbase));
+}
+else {
+ var_dump($new_c = ocilogon($user,$new_password));
+}
+
+var_dump(oci_password_change($dbase, $user, $new_password, $password));
+
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+Done
diff --git a/ext/oci8/tests/password_new.phpt b/ext/oci8/tests/password_new.phpt
new file mode 100644
index 0000000000..37f586cd4f
--- /dev/null
+++ b/ext/oci8/tests/password_new.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_password_change()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$new_password = "test";
+var_dump(oci_password_change($dbase, $user, $password, $new_password));
+
+if (!empty($dbase)) {
+ var_dump($new_c = ocilogon($user,$new_password,$dbase));
+}
+else {
+ var_dump($new_c = ocilogon($user,$new_password));
+}
+
+var_dump(oci_password_change($dbase, $user, $new_password, $password));
+
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+Done
diff --git a/ext/oci8/tests/password_old.phpt b/ext/oci8/tests/password_old.phpt
new file mode 100644
index 0000000000..3e715785b5
--- /dev/null
+++ b/ext/oci8/tests/password_old.phpt
@@ -0,0 +1,35 @@
+--TEST--
+ocipasswordchange()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$new_password = "test";
+var_dump(ocipasswordchange($c, $user, $password, $new_password));
+
+if (!empty($dbase)) {
+ var_dump($new_c = ocilogon($user,$new_password,$dbase));
+}
+else {
+ var_dump($new_c = ocilogon($user,$new_password));
+}
+
+var_dump(ocipasswordchange($new_c, $user, $new_password, $password));
+
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+bool(true)
+resource(%d) of type (oci8 connection)
+bool(true)
+Done
diff --git a/ext/oci8/tests/persistent.phpt b/ext/oci8/tests/persistent.phpt
new file mode 100644
index 0000000000..088689c722
--- /dev/null
+++ b/ext/oci8/tests/persistent.phpt
@@ -0,0 +1,32 @@
+--TEST--
+reusing persistent connections
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+var_dump(oci_pconnect($user, $password, $dbase));
+var_dump(oci_pconnect($user, $password, $dbase));
+var_dump(oci_pconnect($user, $password, $dbase));
+var_dump(oci_connect($user, $password, $dbase));
+var_dump(oci_connect($user, $password, $dbase));
+var_dump(oci_connect($user, $password, $dbase));
+
+echo "Done\n";
+?>
+--EXPECTF--
+resource(%d) of type (oci8 persistent connection)
+resource(%d) of type (oci8 persistent connection)
+resource(%d) of type (oci8 persistent connection)
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+resource(%d) of type (oci8 connection)
+Done
diff --git a/ext/oci8/tests/prefetch.phpt b/ext/oci8/tests/prefetch.phpt
new file mode 100644
index 0000000000..45d51bd4c3
--- /dev/null
+++ b/ext/oci8/tests/prefetch.phpt
@@ -0,0 +1,56 @@
+--TEST--
+oci_set_prefetch()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = oci_parse($c, $insert_sql))) {
+ die("oci_parse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!oci_execute($s)) {
+ die("oci_execute(insert) failed!\n");
+ }
+}
+
+if (!oci_commit($c)) {
+ die("oci_commit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = oci_parse($c, $select_sql))) {
+ die("oci_parse(select) failed!\n");
+}
+
+var_dump(oci_set_prefetch($s, 10));
+
+if (!oci_execute($s)) {
+ die("oci_execute(select) failed!\n");
+}
+
+var_dump(oci_fetch($s));
+
+var_dump(oci_num_rows($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+bool(true)
+int(1)
+Done
diff --git a/ext/oci8/tests/prefetch_old.phpt b/ext/oci8/tests/prefetch_old.phpt
new file mode 100644
index 0000000000..189511d051
--- /dev/null
+++ b/ext/oci8/tests/prefetch_old.phpt
@@ -0,0 +1,56 @@
+--TEST--
+ocisetprefetch()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+require dirname(__FILE__).'/create_table.inc';
+
+$insert_sql = "INSERT INTO ".$schema.$table_name." (id, value) VALUES (1,1)";
+
+if (!($s = ociparse($c, $insert_sql))) {
+ die("ociparse(insert) failed!\n");
+}
+
+for ($i = 0; $i<3; $i++) {
+ if (!ociexecute($s)) {
+ die("ociexecute(insert) failed!\n");
+ }
+}
+
+if (!ocicommit($c)) {
+ die("ocicommit() failed!\n");
+}
+
+$select_sql = "SELECT * FROM ".$schema.$table_name."";
+
+if (!($s = ociparse($c, $select_sql))) {
+ die("ociparse(select) failed!\n");
+}
+
+var_dump(ocisetprefetch($s, 10));
+
+if (!ociexecute($s)) {
+ die("ociexecute(select) failed!\n");
+}
+
+var_dump(ocifetch($s));
+
+var_dump(ocirowcount($s));
+
+require dirname(__FILE__).'/drop_table.inc';
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+bool(true)
+int(1)
+Done
diff --git a/ext/oci8/tests/privileged_connect.phpt b/ext/oci8/tests/privileged_connect.phpt
new file mode 100644
index 0000000000..aef94b79e1
--- /dev/null
+++ b/ext/oci8/tests/privileged_connect.phpt
@@ -0,0 +1,31 @@
+--TEST--
+privileged connect tests
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+oci_connect("", "", "", false, OCI_SYSOPER);
+oci_connect("", "", "", false, OCI_SYSDBA);
+oci_connect("", "", "", false, -1);
+oci_connect("", "", "", false, "qwe");
+
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: oci_connect(): Privileged connect is disabled. Enable oci8.privileged_connect to be able to connect as SYSOPER or SYSDBA in %s on line %d
+
+Warning: oci_connect(): Privileged connect is disabled. Enable oci8.privileged_connect to be able to connect as SYSOPER or SYSDBA in %s on line %d
+
+Warning: oci_connect(): Invalid session mode specified (-1) in %s on line %d
+
+Warning: oci_connect() expects parameter 5 to be long, string given in %s on line %d
+Done
diff --git a/ext/oci8/tests/privileged_connect1.phpt b/ext/oci8/tests/privileged_connect1.phpt
new file mode 100644
index 0000000000..208d0853c4
--- /dev/null
+++ b/ext/oci8/tests/privileged_connect1.phpt
@@ -0,0 +1,33 @@
+--TEST--
+privileged connect tests
+--INI--
+oci8.privileged_connect=1
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+oci_connect("", "", "", false, OCI_SYSOPER);
+oci_connect("", "", "", false, OCI_SYSDBA);
+oci_connect("", "", "", false, -1);
+oci_connect("", "", "", false, "qwe");
+
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: oci_connect(): ORA-01031: insufficient privileges in %s on line %d
+
+Warning: oci_connect(): ORA-01031: insufficient privileges in %s on line %d
+
+Warning: oci_connect(): Invalid session mode specified (-1) in %s on line %d
+
+Warning: oci_connect() expects parameter 5 to be long, string given in %s on line %d
+Done
diff --git a/ext/oci8/tests/serverversion.phpt b/ext/oci8/tests/serverversion.phpt
new file mode 100644
index 0000000000..0a8059964b
--- /dev/null
+++ b/ext/oci8/tests/serverversion.phpt
@@ -0,0 +1,35 @@
+--TEST--
+oci_server_version()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump($c = oci_connect($user, $password, $dbase));
+}
+else {
+ var_dump($c = oci_connect($user, $password));
+}
+
+$v = oci_server_version($c);
+var_dump(str_replace("\n", "", $v));
+
+$v = ociserverversion($c);
+var_dump(str_replace("\n", "", $v));
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+string(%d) "%s"
+string(%d) "%s"
+Done
diff --git a/ext/oci8/tests/statement_cache.phpt b/ext/oci8/tests/statement_cache.phpt
new file mode 100644
index 0000000000..dc49c427f2
--- /dev/null
+++ b/ext/oci8/tests/statement_cache.phpt
@@ -0,0 +1,40 @@
+--TEST--
+statement cache
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$pc = oci_pconnect($user, $password, $dbase);
+
+$stmt = oci_parse($pc, "select 1+3 from dual", true);
+oci_execute($stmt);
+var_dump(oci_fetch_array($stmt));
+
+$stmt = oci_parse($pc, "select 1+3 from dual", true);
+oci_execute($stmt);
+var_dump(oci_fetch_array($stmt));
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ string(1) "4"
+ ["1+3"]=>
+ string(1) "4"
+}
+array(2) {
+ [0]=>
+ string(1) "4"
+ ["1+3"]=>
+ string(1) "4"
+}
+Done
diff --git a/ext/oci8/tests/statement_type.phpt b/ext/oci8/tests/statement_type.phpt
new file mode 100644
index 0000000000..f3215ec31e
--- /dev/null
+++ b/ext/oci8/tests/statement_type.phpt
@@ -0,0 +1,51 @@
+--TEST--
+oci_statement_type()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump($c = oci_connect($user, $password, $dbase));
+}
+else {
+ var_dump($c = oci_connect($user, $password));
+}
+
+$sqls = Array(
+ "SELECT * FROM table",
+ "DELETE FROM table WHERE id = 1",
+ "INSERT INTO table VALUES(1)",
+ "UPDATE table SET id = 1",
+ "DROP TABLE table",
+ "CREATE TABLE table (id NUMBER)",
+ "WRONG SYNTAX",
+ ""
+);
+
+foreach ($sqls as $sql) {
+ $s = oci_parse($c, $sql);
+ var_dump(oci_statement_type($s));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+string(6) "SELECT"
+string(6) "DELETE"
+string(6) "INSERT"
+string(6) "UPDATE"
+string(4) "DROP"
+string(6) "CREATE"
+string(7) "UNKNOWN"
+string(7) "UNKNOWN"
+Done
diff --git a/ext/oci8/tests/statement_type_old.phpt b/ext/oci8/tests/statement_type_old.phpt
new file mode 100644
index 0000000000..587beb4f2c
--- /dev/null
+++ b/ext/oci8/tests/statement_type_old.phpt
@@ -0,0 +1,51 @@
+--TEST--
+ocistatementtype()
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+if (!empty($dbase)) {
+ var_dump($c = ocilogon($user, $password, $dbase));
+}
+else {
+ var_dump($c = ocilogon($user, $password));
+}
+
+$sqls = Array(
+ "SELECT * FROM table",
+ "DELETE FROM table WHERE id = 1",
+ "INSERT INTO table VALUES(1)",
+ "UPDATE table SET id = 1",
+ "DROP TABLE table",
+ "CREATE TABLE table (id NUMBER)",
+ "WRONG SYNTAX",
+ ""
+);
+
+foreach ($sqls as $sql) {
+ $s = ociparse($c, $sql);
+ var_dump(ocistatementtype($s));
+}
+
+echo "Done\n";
+
+?>
+--EXPECTF--
+resource(%d) of type (oci8 connection)
+string(6) "SELECT"
+string(6) "DELETE"
+string(6) "INSERT"
+string(6) "UPDATE"
+string(4) "DROP"
+string(6) "CREATE"
+string(7) "UNKNOWN"
+string(7) "UNKNOWN"
+Done
diff --git a/ext/oci8/tests/uncommitted.phpt b/ext/oci8/tests/uncommitted.phpt
new file mode 100644
index 0000000000..297b7b0d06
--- /dev/null
+++ b/ext/oci8/tests/uncommitted.phpt
@@ -0,0 +1,22 @@
+--TEST--
+uncommitted connection
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--ENV--
+return "
+ORACLE_HOME=".(isset($_ENV['ORACLE_HOME']) ? $_ENV['ORACLE_HOME'] : '')."
+NLS_LANG=".(isset($_ENV['NLS_LANG']) ? $_ENV['NLS_LANG'] : '')."
+TNS_ADMIN=".(isset($_ENV['TNS_ADMIN']) ? $_ENV['TNS_ADMIN'] : '')."
+";
+--FILE--
+<?php
+
+require dirname(__FILE__)."/connect.inc";
+
+$stmt = oci_parse($c, "select 1 from dual");
+oci_execute($stmt, OCI_DEFAULT);
+
+echo "Done\n";
+?>
+--EXPECTF--
+Done