PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - oci8 - oci8.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 944
Code covered: 80.3 % Executed lines: 758
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
      16                 :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17                 :    |          Maxim Maletsky <maxim@maxim.cx>                             |
      18                 :    |                                                                      |
      19                 :    | Collection support by Andy Sautins <asautins@veripost.net>           |
      20                 :    | Temporary LOB support by David Benson <dbenson@mancala.com>          |
      21                 :    | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at>        |
      22                 :    |                                                                      |
      23                 :    | Redesigned by: Antony Dovgal <antony@zend.com>                       |
      24                 :    |                Andi Gutmans <andi@zend.com>                          |
      25                 :    |                Wez Furlong <wez@omniti.com>                          |
      26                 :    +----------------------------------------------------------------------+
      27                 : */
      28                 : 
      29                 : /* $Id: oci8.c 289264 2009-10-06 22:36:32Z sixd $ */
      30                 : 
      31                 : #ifdef HAVE_CONFIG_H
      32                 : #include "config.h"
      33                 : #endif
      34                 : 
      35                 : #include "php.h"
      36                 : #include "ext/standard/info.h"
      37                 : #include "php_ini.h"
      38                 : #include "ext/standard/php_smart_str.h"
      39                 : 
      40                 : #if HAVE_OCI8
      41                 : 
      42                 : #if PHP_MAJOR_VERSION > 5
      43                 : #error This version of the PHP OCI8 extension is not compatible with PHP 6 or later
      44                 : #elif PHP_MAJOR_VERSION < 5
      45                 : #ifdef ZTS
      46                 : #error The PHP OCI8 extension does not support ZTS mode in PHP 4
      47                 : #endif
      48                 : #endif
      49                 : 
      50                 : #include "php_oci8.h"
      51                 : #include "php_oci8_int.h"
      52                 : #include "zend_hash.h"
      53                 : 
      54                 : ZEND_DECLARE_MODULE_GLOBALS(oci)
      55                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
      56                 : /* This "if" allows PECL builds from this file to be portable to older PHP releases */
      57                 : static PHP_GINIT_FUNCTION(oci);
      58                 : static PHP_GSHUTDOWN_FUNCTION(oci);
      59                 : #endif
      60                 : 
      61                 : /* Allow PHP 5.3 branch to be used in PECL for 5.x compatible builds */
      62                 : #ifndef Z_ADDREF_P
      63                 : #define Z_ADDREF_P(x) ZVAL_ADDREF(x)
      64                 : #endif
      65                 : 
      66                 : /* For a user friendly message about environment setup */
      67                 : /* TODO: add cases for SHLIB_PATH, LIBPATH, LD_LIBRARY_PATH_64 etc */
      68                 : #if defined(PHP_WIN32)
      69                 : #define PHP_OCI8_LIB_PATH_MSG "PATH"
      70                 : #elif defined(__APPLE__)
      71                 : #define PHP_OCI8_LIB_PATH_MSG "DYLD_LIBRARY_PATH"
      72                 : #else
      73                 : #define PHP_OCI8_LIB_PATH_MSG "LD_LIBRARY_PATH"
      74                 : #endif
      75                 : 
      76                 : /* True globals, no need for thread safety */
      77                 : int le_connection;
      78                 : int le_pconnection;
      79                 : int le_statement;
      80                 : int le_descriptor;
      81                 : int le_psessionpool;
      82                 : int le_collection;
      83                 : 
      84                 : zend_class_entry *oci_lob_class_entry_ptr;
      85                 : zend_class_entry *oci_coll_class_entry_ptr;
      86                 : 
      87                 : #ifndef SQLT_BFILEE
      88                 : #define SQLT_BFILEE 114
      89                 : #endif
      90                 : #ifndef SQLT_CFILEE
      91                 : #define SQLT_CFILEE 115
      92                 : #endif
      93                 : 
      94                 : #define PHP_OCI_ERRBUF_LEN 512
      95                 : 
      96                 : #if ZEND_MODULE_API_NO > 20020429
      97                 : #define ONUPDATELONGFUNC OnUpdateLong
      98                 : #else
      99                 : #define ONUPDATELONGFUNC OnUpdateInt
     100                 : #endif
     101                 : 
     102                 : #ifdef ZTS
     103                 : #define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT | OCI_THREADED | OCI_NO_MUTEX)
     104                 : #else
     105                 : #define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT)
     106                 : #endif
     107                 : 
     108                 : /* static protos {{{ */
     109                 : static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     110                 : static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     111                 : static void php_oci_pconnection_list_np_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     112                 : static void php_oci_statement_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     113                 : static void php_oci_descriptor_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     114                 : static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC);
     115                 : static void php_oci_collection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
     116                 : 
     117                 : static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC);
     118                 : static int php_oci_connection_ping(php_oci_connection * TSRMLS_DC);
     119                 : static int php_oci_connection_status(php_oci_connection * TSRMLS_DC);
     120                 : static int php_oci_connection_close(php_oci_connection * TSRMLS_DC);
     121                 : static void php_oci_spool_close(php_oci_spool *session_pool TSRMLS_DC);
     122                 : 
     123                 : static OCIEnv *php_oci_create_env(ub2 charsetid TSRMLS_DC);
     124                 : static int php_oci_create_session(php_oci_connection *connection, php_oci_spool *session_pool, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC);
     125                 : static int php_oci_old_create_session(php_oci_connection *connection, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC);
     126                 : static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, int charsetid TSRMLS_DC);
     127                 : static php_oci_spool *php_oci_create_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, char *hash_key, int hash_key_len, int charsetid TSRMLS_DC);
     128                 : static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TSRMLS_DC);
     129                 : /* }}} */
     130                 : 
     131                 : /* {{{ dynamically loadable module stuff */
     132                 : #if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G)
     133                 : ZEND_GET_MODULE(oci8)
     134                 : #endif /* COMPILE_DL */
     135                 : /* }}} */
     136                 : 
     137                 : #ifdef ZEND_ENGINE_2
     138                 : 
     139                 : /* {{{ Function arginfo */
     140                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_define_by_name, 0, 0, 3)
     141                 :         ZEND_ARG_INFO(0, statement_resource)
     142                 :         ZEND_ARG_INFO(0, column_name)
     143                 :         ZEND_ARG_INFO(1, variable)
     144                 :         ZEND_ARG_INFO(0, type)
     145                 : ZEND_END_ARG_INFO()
     146                 : 
     147                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_bind_by_name, 0, 0, 3)
     148                 :         ZEND_ARG_INFO(0, statement_resource)
     149                 :         ZEND_ARG_INFO(0, column_name)
     150                 :         ZEND_ARG_INFO(1, variable)
     151                 :         ZEND_ARG_INFO(0, maximum_length)
     152                 :         ZEND_ARG_INFO(0, type)
     153                 : ZEND_END_ARG_INFO()
     154                 : 
     155                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_bind_array_by_name, 0, 0, 4)
     156                 :         ZEND_ARG_INFO(0, statement_resource)
     157                 :         ZEND_ARG_INFO(0, column_name)
     158                 :         ZEND_ARG_INFO(1, variable)
     159                 :         ZEND_ARG_INFO(0, maximum_array_length)
     160                 :         ZEND_ARG_INFO(0, maximum_item_length)
     161                 :         ZEND_ARG_INFO(0, type)
     162                 : ZEND_END_ARG_INFO()
     163                 : 
     164                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_descriptor, 0, 0, 1)
     165                 :         ZEND_ARG_INFO(0, lob_descriptor)
     166                 : ZEND_END_ARG_INFO()
     167                 : 
     168                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_save, 0, 0, 2)
     169                 :         ZEND_ARG_INFO(0, lob_descriptor)
     170                 :         ZEND_ARG_INFO(0, data)
     171                 :         ZEND_ARG_INFO(0, offset)
     172                 : ZEND_END_ARG_INFO()
     173                 : 
     174                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_import, 0, 0, 2)
     175                 :         ZEND_ARG_INFO(0, lob_descriptor)
     176                 :         ZEND_ARG_INFO(0, filename)
     177                 : ZEND_END_ARG_INFO()
     178                 : 
     179                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_load, 0, 0, 1)
     180                 :         ZEND_ARG_INFO(0, lob_descriptor)
     181                 : ZEND_END_ARG_INFO()
     182                 : 
     183                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_read, 0, 0, 2)
     184                 :         ZEND_ARG_INFO(0, lob_descriptor)
     185                 :         ZEND_ARG_INFO(0, length)
     186                 : ZEND_END_ARG_INFO()
     187                 : 
     188                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_eof, 0, 0, 1)
     189                 :         ZEND_ARG_INFO(0, lob_descriptor)
     190                 : ZEND_END_ARG_INFO()
     191                 : 
     192                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_tell, 0, 0, 1)
     193                 :         ZEND_ARG_INFO(0, lob_descriptor)
     194                 : ZEND_END_ARG_INFO()
     195                 : 
     196                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_rewind, 0, 0, 1)
     197                 :         ZEND_ARG_INFO(0, lob_descriptor)
     198                 : ZEND_END_ARG_INFO()
     199                 : 
     200                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_seek, 0, 0, 2)
     201                 :         ZEND_ARG_INFO(0, lob_descriptor)
     202                 :         ZEND_ARG_INFO(0, offset)
     203                 :         ZEND_ARG_INFO(0, whence)
     204                 : ZEND_END_ARG_INFO()
     205                 : 
     206                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_size, 0, 0, 1)
     207                 :         ZEND_ARG_INFO(0, lob_descriptor)
     208                 : ZEND_END_ARG_INFO()
     209                 : 
     210                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write, 0, 0, 2)
     211                 :         ZEND_ARG_INFO(0, lob_descriptor)
     212                 :         ZEND_ARG_INFO(0, string)
     213                 :         ZEND_ARG_INFO(0, length)
     214                 : ZEND_END_ARG_INFO()
     215                 : 
     216                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_append, 0, 0, 2)
     217                 :         ZEND_ARG_INFO(0, lob_descriptor_to)
     218                 :         ZEND_ARG_INFO(0, lob_descriptor_from)
     219                 : ZEND_END_ARG_INFO()
     220                 : 
     221                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_truncate, 0, 0, 1)
     222                 :         ZEND_ARG_INFO(0, lob_descriptor)
     223                 :         ZEND_ARG_INFO(0, length)
     224                 : ZEND_END_ARG_INFO()
     225                 : 
     226                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_erase, 0, 0, 1)
     227                 :         ZEND_ARG_INFO(0, lob_descriptor)
     228                 :         ZEND_ARG_INFO(0, offset)
     229                 :         ZEND_ARG_INFO(0, length)
     230                 : ZEND_END_ARG_INFO()
     231                 : 
     232                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_flush, 0, 0, 1)
     233                 :         ZEND_ARG_INFO(0, lob_descriptor)
     234                 :         ZEND_ARG_INFO(0, flag)
     235                 : ZEND_END_ARG_INFO()
     236                 : 
     237                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ocisetbufferinglob, 0, 0, 2)
     238                 :         ZEND_ARG_INFO(0, lob_descriptor)
     239                 :         ZEND_ARG_INFO(0, mode)
     240                 : ZEND_END_ARG_INFO()
     241                 : 
     242                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ocigetbufferinglob, 0, 0, 1)
     243                 :         ZEND_ARG_INFO(0, lob_descriptor)
     244                 : ZEND_END_ARG_INFO()
     245                 : 
     246                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_copy, 0, 0, 2)
     247                 :         ZEND_ARG_INFO(0, lob_descriptor_to)
     248                 :         ZEND_ARG_INFO(0, lob_descriptor_from)
     249                 :         ZEND_ARG_INFO(0, length)
     250                 : ZEND_END_ARG_INFO()
     251                 : 
     252                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_is_equal, 0, 0, 2)
     253                 :         ZEND_ARG_INFO(0, lob_descriptor)
     254                 :         ZEND_ARG_INFO(0, lob_descriptor)
     255                 : ZEND_END_ARG_INFO()
     256                 : 
     257                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_export, 0, 0, 2)
     258                 :         ZEND_ARG_INFO(0, lob_descriptor)
     259                 :         ZEND_ARG_INFO(0, filename)
     260                 :         ZEND_ARG_INFO(0, start)
     261                 :         ZEND_ARG_INFO(0, length)
     262                 : ZEND_END_ARG_INFO()
     263                 : 
     264                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_descriptor, 0, 0, 1)
     265                 :         ZEND_ARG_INFO(0, connection_resource)
     266                 :         ZEND_ARG_INFO(0, type)
     267                 : ZEND_END_ARG_INFO()
     268                 : 
     269                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_rollback, 0, 0, 1)
     270                 :         ZEND_ARG_INFO(0, connection_resource)
     271                 : ZEND_END_ARG_INFO()
     272                 : 
     273                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_commit, 0, 0, 1)
     274                 :         ZEND_ARG_INFO(0, connection_resource)
     275                 : ZEND_END_ARG_INFO()
     276                 : 
     277                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_name, 0, 0, 2)
     278                 :         ZEND_ARG_INFO(0, statement_resource)
     279                 :         ZEND_ARG_INFO(0, column_number)
     280                 : ZEND_END_ARG_INFO()
     281                 : 
     282                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_size, 0, 0, 2)
     283                 :         ZEND_ARG_INFO(0, statement_resource)
     284                 :         ZEND_ARG_INFO(0, column_number_or_name)
     285                 : ZEND_END_ARG_INFO()
     286                 : 
     287                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_scale, 0, 0, 2)
     288                 :         ZEND_ARG_INFO(0, statement_resource)
     289                 :         ZEND_ARG_INFO(0, column_number)
     290                 : ZEND_END_ARG_INFO()
     291                 : 
     292                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_precision, 0, 0, 2)
     293                 :         ZEND_ARG_INFO(0, statement_resource)
     294                 :         ZEND_ARG_INFO(0, column_number)
     295                 : ZEND_END_ARG_INFO()
     296                 : 
     297                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_type, 0, 0, 2)
     298                 :         ZEND_ARG_INFO(0, statement_resource)
     299                 :         ZEND_ARG_INFO(0, column_number)
     300                 : ZEND_END_ARG_INFO()
     301                 : 
     302                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_type_raw, 0, 0, 2)
     303                 :         ZEND_ARG_INFO(0, statement_resource)
     304                 :         ZEND_ARG_INFO(0, column_number)
     305                 : ZEND_END_ARG_INFO()
     306                 : 
     307                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_field_is_null, 0, 0, 2)
     308                 :         ZEND_ARG_INFO(0, statement_resource)
     309                 :         ZEND_ARG_INFO(0, column_number_or_name)
     310                 : ZEND_END_ARG_INFO()
     311                 : 
     312                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_internal_debug, 0, 0, 1)
     313                 :         ZEND_ARG_INFO(0, mode)
     314                 : ZEND_END_ARG_INFO()
     315                 : 
     316                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_execute, 0, 0, 1)
     317                 :         ZEND_ARG_INFO(0, statement_resource)
     318                 :         ZEND_ARG_INFO(0, mode)
     319                 : ZEND_END_ARG_INFO()
     320                 : 
     321                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_cancel, 0, 0, 1)
     322                 :         ZEND_ARG_INFO(0, statement_resource)
     323                 : ZEND_END_ARG_INFO()
     324                 : 
     325                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch, 0, 0, 1)
     326                 :         ZEND_ARG_INFO(0, statement_resource)
     327                 : ZEND_END_ARG_INFO()
     328                 : 
     329                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ocifetchinto, 0, 0, 2)
     330                 :         ZEND_ARG_INFO(0, statement_resource)
     331                 :         ZEND_ARG_INFO(1, result)
     332                 :         ZEND_ARG_INFO(0, mode)
     333                 : ZEND_END_ARG_INFO()
     334                 : 
     335                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_all, 0, 0, 2)
     336                 :         ZEND_ARG_INFO(0, statement_resource)
     337                 :         ZEND_ARG_INFO(1, output)
     338                 :         ZEND_ARG_INFO(0, skip)
     339                 :         ZEND_ARG_INFO(0, maximum_rows)
     340                 :         ZEND_ARG_INFO(0, flags)
     341                 : ZEND_END_ARG_INFO()
     342                 : 
     343                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_object, 0, 0, 1)
     344                 :         ZEND_ARG_INFO(0, statement_resource)
     345                 : ZEND_END_ARG_INFO()
     346                 : 
     347                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_row, 0, 0, 1)
     348                 :         ZEND_ARG_INFO(0, statement_resource)
     349                 : ZEND_END_ARG_INFO()
     350                 : 
     351                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_assoc, 0, 0, 1)
     352                 :         ZEND_ARG_INFO(0, statement_resource)
     353                 : ZEND_END_ARG_INFO()
     354                 : 
     355                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_fetch_array, 0, 0, 1)
     356                 :         ZEND_ARG_INFO(0, statement_resource)
     357                 :         ZEND_ARG_INFO(0, mode)
     358                 : ZEND_END_ARG_INFO()
     359                 : 
     360                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_statement, 0, 0, 1)
     361                 :         ZEND_ARG_INFO(0, statement_resource)
     362                 : ZEND_END_ARG_INFO()
     363                 : 
     364                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_close, 0, 0, 1)
     365                 :         ZEND_ARG_INFO(0, connection_resource)
     366                 : ZEND_END_ARG_INFO()
     367                 : 
     368                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_connect, 0, 0, 2)
     369                 :         ZEND_ARG_INFO(0, username)
     370                 :         ZEND_ARG_INFO(0, password)
     371                 :         ZEND_ARG_INFO(0, connection_string)
     372                 :         ZEND_ARG_INFO(0, character_set)
     373                 :         ZEND_ARG_INFO(0, session_mode)
     374                 : ZEND_END_ARG_INFO()
     375                 : 
     376                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_connect, 0, 0, 2)
     377                 :         ZEND_ARG_INFO(0, username)
     378                 :         ZEND_ARG_INFO(0, password)
     379                 :         ZEND_ARG_INFO(0, connection_string)
     380                 :         ZEND_ARG_INFO(0, character_set)
     381                 :         ZEND_ARG_INFO(0, session_mode)
     382                 : ZEND_END_ARG_INFO()
     383                 : 
     384                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_pconnect, 0, 0, 2)
     385                 :         ZEND_ARG_INFO(0, username)
     386                 :         ZEND_ARG_INFO(0, password)
     387                 :         ZEND_ARG_INFO(0, connection_string)
     388                 :         ZEND_ARG_INFO(0, character_set)
     389                 :         ZEND_ARG_INFO(0, session_mode)
     390                 : ZEND_END_ARG_INFO()
     391                 : 
     392                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_error, 0, 0, 0)
     393                 :         ZEND_ARG_INFO(0, connection_or_statement_resource)
     394                 : ZEND_END_ARG_INFO()
     395                 : 
     396                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_num_fields, 0, 0, 1)
     397                 :         ZEND_ARG_INFO(0, statement_resource)
     398                 : ZEND_END_ARG_INFO()
     399                 : 
     400                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_parse, 0, 0, 2)
     401                 :         ZEND_ARG_INFO(0, connection_resource)
     402                 :         ZEND_ARG_INFO(0, sql_text)
     403                 : ZEND_END_ARG_INFO()
     404                 : 
     405                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_prefetch, 0, 0, 2)
     406                 :         ZEND_ARG_INFO(0, statement_resource)
     407                 :         ZEND_ARG_INFO(0, number_of_rows)
     408                 : ZEND_END_ARG_INFO()
     409                 : 
     410                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_identifier, 0, 0, 2)
     411                 :         ZEND_ARG_INFO(0, connection_resource)
     412                 :         ZEND_ARG_INFO(0, client_identifier)
     413                 : ZEND_END_ARG_INFO()
     414                 : 
     415                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_edition, 0, 0, 1)
     416                 :         ZEND_ARG_INFO(0, edition_name)
     417                 : ZEND_END_ARG_INFO()
     418                 : 
     419                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_module_name, 0, 0, 2)
     420                 :         ZEND_ARG_INFO(0, connection_resource)
     421                 :         ZEND_ARG_INFO(0, module_name)
     422                 : ZEND_END_ARG_INFO()
     423                 : 
     424                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_action, 0, 0, 2)
     425                 :         ZEND_ARG_INFO(0, connection_resource)
     426                 :         ZEND_ARG_INFO(0, action)
     427                 : ZEND_END_ARG_INFO()
     428                 : 
     429                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_info, 0, 0, 2)
     430                 :         ZEND_ARG_INFO(0, connection_resource)
     431                 :         ZEND_ARG_INFO(0, client_information)
     432                 : ZEND_END_ARG_INFO()
     433                 : 
     434                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_password_change, 0, 0, 4)
     435                 :         ZEND_ARG_INFO(0, connection_resource_or_connection_string)
     436                 :         ZEND_ARG_INFO(0, username)
     437                 :         ZEND_ARG_INFO(0, old_password)
     438                 :         ZEND_ARG_INFO(0, new_password)
     439                 : ZEND_END_ARG_INFO()
     440                 : 
     441                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_cursor, 0, 0, 1)
     442                 :         ZEND_ARG_INFO(0, connection_resource)
     443                 : ZEND_END_ARG_INFO()
     444                 : 
     445                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_result, 0, 0, 2)
     446                 :         ZEND_ARG_INFO(0, statement_resource)
     447                 :         ZEND_ARG_INFO(0, column_number_or_name)
     448                 : ZEND_END_ARG_INFO()
     449                 : 
     450                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_server_version, 0, 0, 1)
     451                 :         ZEND_ARG_INFO(0, connection_resource)
     452                 : ZEND_END_ARG_INFO()
     453                 : 
     454                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_statement_type, 0, 0, 1)
     455                 :         ZEND_ARG_INFO(0, statement_resource)
     456                 : ZEND_END_ARG_INFO()
     457                 : 
     458                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_num_rows, 0, 0, 1)
     459                 :         ZEND_ARG_INFO(0, statement_resource)
     460                 : ZEND_END_ARG_INFO()
     461                 : 
     462                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_free_collection, 0, 0, 1)
     463                 :         ZEND_ARG_INFO(0, collection)
     464                 : ZEND_END_ARG_INFO()
     465                 : 
     466                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_append, 0, 0, 2)
     467                 :         ZEND_ARG_INFO(0, collection)
     468                 :         ZEND_ARG_INFO(0, value)
     469                 : ZEND_END_ARG_INFO()
     470                 : 
     471                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_get, 0, 0, 2)
     472                 :         ZEND_ARG_INFO(0, collection)
     473                 :         ZEND_ARG_INFO(0, index)
     474                 : ZEND_END_ARG_INFO()
     475                 : 
     476                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_assign, 0, 0, 2)
     477                 :         ZEND_ARG_INFO(0, collection_to)
     478                 :         ZEND_ARG_INFO(0, collection_from)
     479                 : ZEND_END_ARG_INFO()
     480                 : 
     481                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_assign, 0, 0, 3)
     482                 :         ZEND_ARG_INFO(0, collection)
     483                 :         ZEND_ARG_INFO(0, index)
     484                 :         ZEND_ARG_INFO(0, value)
     485                 : ZEND_END_ARG_INFO()
     486                 : 
     487                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_size, 0, 0, 1)
     488                 :         ZEND_ARG_INFO(0, collection)
     489                 : ZEND_END_ARG_INFO()
     490                 : 
     491                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_max, 0, 0, 1)
     492                 :         ZEND_ARG_INFO(0, collection)
     493                 : ZEND_END_ARG_INFO()
     494                 : 
     495                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_trim, 0, 0, 2)
     496                 :         ZEND_ARG_INFO(0, collection)
     497                 :         ZEND_ARG_INFO(0, number)
     498                 : ZEND_END_ARG_INFO()
     499                 : 
     500                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_new_collection, 0, 0, 2)
     501                 :         ZEND_ARG_INFO(0, connection_resource)
     502                 :         ZEND_ARG_INFO(0, type_name)
     503                 :         ZEND_ARG_INFO(0, schema_name)
     504                 : ZEND_END_ARG_INFO()
     505                 : /* }}} */
     506                 : 
     507                 : /* {{{ LOB Method arginfo */
     508                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_save_method, 0, 0, 1)
     509                 :         ZEND_ARG_INFO(0, data)
     510                 :         ZEND_ARG_INFO(0, offset)
     511                 : ZEND_END_ARG_INFO()
     512                 : 
     513                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_import_method, 0, 0, 1)
     514                 :         ZEND_ARG_INFO(0, filename)
     515                 : ZEND_END_ARG_INFO()
     516                 : 
     517                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_load_method, 0)
     518                 : ZEND_END_ARG_INFO()
     519                 : 
     520                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_read_method, 0, 0, 1)
     521                 :         ZEND_ARG_INFO(0, length)
     522                 : ZEND_END_ARG_INFO()
     523                 : 
     524                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_eof_method, 0)
     525                 : ZEND_END_ARG_INFO()
     526                 : 
     527                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_tell_method, 0)
     528                 : ZEND_END_ARG_INFO()
     529                 : 
     530                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_rewind_method, 0)
     531                 : ZEND_END_ARG_INFO()
     532                 : 
     533                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_seek_method, 0, 0, 1)
     534                 :         ZEND_ARG_INFO(0, offset)
     535                 :         ZEND_ARG_INFO(0, whence)
     536                 : ZEND_END_ARG_INFO()
     537                 : 
     538                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_size_method, 0)
     539                 : ZEND_END_ARG_INFO()
     540                 : 
     541                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write_method, 0, 0, 1)
     542                 :         ZEND_ARG_INFO(0, string)
     543                 :         ZEND_ARG_INFO(0, length)
     544                 : ZEND_END_ARG_INFO()
     545                 : 
     546                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_append_method, 0, 0, 1)
     547                 :         ZEND_ARG_INFO(0, lob_descriptor_from)
     548                 : ZEND_END_ARG_INFO()
     549                 : 
     550                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_truncate_method, 0, 0, 0)
     551                 :         ZEND_ARG_INFO(0, length)
     552                 : ZEND_END_ARG_INFO()
     553                 : 
     554                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_erase_method, 0, 0, 0)
     555                 :         ZEND_ARG_INFO(0, offset)
     556                 :         ZEND_ARG_INFO(0, length)
     557                 : ZEND_END_ARG_INFO()
     558                 : 
     559                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_flush_method, 0, 0, 0)
     560                 :         ZEND_ARG_INFO(0, flag)
     561                 : ZEND_END_ARG_INFO()
     562                 : 
     563                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_setbuffering_method, 0, 0, 1)
     564                 :         ZEND_ARG_INFO(0, mode)
     565                 : ZEND_END_ARG_INFO()
     566                 : 
     567                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_getbuffering_method, 0)
     568                 : ZEND_END_ARG_INFO()
     569                 : 
     570                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_export_method, 0, 0, 1)
     571                 :         ZEND_ARG_INFO(0, filename)
     572                 :         ZEND_ARG_INFO(0, start)
     573                 :         ZEND_ARG_INFO(0, length)
     574                 : ZEND_END_ARG_INFO()
     575                 : 
     576                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_lob_write_temporary_method, 0, 0, 1)
     577                 :         ZEND_ARG_INFO(0, data)
     578                 :         ZEND_ARG_INFO(0, type)
     579                 : ZEND_END_ARG_INFO()
     580                 : 
     581                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_lob_close_method, 0)
     582                 : ZEND_END_ARG_INFO()
     583                 : 
     584                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_free_descriptor_method, 0)
     585                 : ZEND_END_ARG_INFO()
     586                 : /* }}} */
     587                 : 
     588                 : /* {{{ Collection Method arginfo */
     589                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_free_method, 0)
     590                 : ZEND_END_ARG_INFO()
     591                 : 
     592                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_append_method, 0, 0, 1)
     593                 :         ZEND_ARG_INFO(0, value)
     594                 : ZEND_END_ARG_INFO()
     595                 : 
     596                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_get_method, 0, 0, 1)
     597                 :         ZEND_ARG_INFO(0, index)
     598                 : ZEND_END_ARG_INFO()
     599                 : 
     600                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_assign_method, 0, 0, 1)
     601                 :         ZEND_ARG_INFO(0, collection_from)
     602                 : ZEND_END_ARG_INFO()
     603                 : 
     604                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_element_assign_method, 0, 0, 2)
     605                 :         ZEND_ARG_INFO(0, index)
     606                 :         ZEND_ARG_INFO(0, value)
     607                 : ZEND_END_ARG_INFO()
     608                 : 
     609                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_size_method, 0)
     610                 : ZEND_END_ARG_INFO()
     611                 : 
     612                 : ZEND_BEGIN_ARG_INFO(arginfo_oci_collection_max_method, 0)
     613                 : ZEND_END_ARG_INFO()
     614                 : 
     615                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_collection_trim_method, 0, 0, 1)
     616                 :         ZEND_ARG_INFO(0, number)
     617                 : ZEND_END_ARG_INFO()
     618                 : /* }}} */
     619                 : 
     620                 : #else /* ZEND_ENGINE_2 */
     621                 : /* {{{ Keep the old arginfo behavior when building with PHP 4 */
     622                 : 
     623                 : static unsigned char arginfo_ocifetchinto[]  = { 2, BYREF_NONE, BYREF_FORCE };
     624                 : static unsigned char arginfo_oci_fetch_all[] = { 2, BYREF_NONE, BYREF_FORCE };
     625                 : static unsigned char arginfo_oci_define_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
     626                 : static unsigned char arginfo_oci_bind_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
     627                 : static unsigned char arginfo_oci_bind_array_by_name[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
     628                 : 
     629                 : #define arginfo_oci_free_descriptor                                             NULL
     630                 : #define arginfo_oci_lob_save                                                    NULL
     631                 : #define arginfo_oci_lob_import                                                  NULL
     632                 : #define arginfo_oci_lob_load                                                    NULL
     633                 : #define arginfo_oci_lob_read                                                    NULL
     634                 : #define arginfo_oci_lob_eof                                                             NULL
     635                 : #define arginfo_oci_lob_tell                                                    NULL
     636                 : #define arginfo_oci_lob_rewind                                                  NULL
     637                 : #define arginfo_oci_lob_seek                                                    NULL
     638                 : #define arginfo_oci_lob_size                                                    NULL
     639                 : #define arginfo_oci_lob_write                                                   NULL
     640                 : #define arginfo_oci_lob_append                                                  NULL
     641                 : #define arginfo_oci_lob_truncate                                                NULL
     642                 : #define arginfo_oci_lob_erase                                                   NULL
     643                 : #define arginfo_oci_lob_flush                                                   NULL
     644                 : #define arginfo_ocisetbufferinglob                                              NULL
     645                 : #define arginfo_ocigetbufferinglob                                              NULL
     646                 : #define arginfo_oci_lob_copy                                                    NULL
     647                 : #define arginfo_oci_lob_is_equal                                                NULL
     648                 : #define arginfo_oci_lob_export                                                  NULL
     649                 : #define arginfo_oci_new_descriptor                                              NULL
     650                 : #define arginfo_oci_rollback                                                    NULL
     651                 : #define arginfo_oci_commit                                                              NULL
     652                 : #define arginfo_oci_field_name                                                  NULL
     653                 : #define arginfo_oci_field_size                                                  NULL
     654                 : #define arginfo_oci_field_scale                                                 NULL
     655                 : #define arginfo_oci_field_precision                                             NULL
     656                 : #define arginfo_oci_field_type                                                  NULL
     657                 : #define arginfo_oci_field_type_raw                                              NULL
     658                 : #define arginfo_oci_field_is_null                                               NULL
     659                 : #define arginfo_oci_internal_debug                                              NULL
     660                 : #define arginfo_oci_execute                                                             NULL
     661                 : #define arginfo_oci_cancel                                                              NULL
     662                 : #define arginfo_oci_fetch                                                               NULL
     663                 : #define arginfo_oci_fetch_object                                                NULL
     664                 : #define arginfo_oci_fetch_row                                                   NULL
     665                 : #define arginfo_oci_fetch_assoc                                                 NULL
     666                 : #define arginfo_oci_fetch_array                                                 NULL
     667                 : #define arginfo_oci_free_statement                                              NULL
     668                 : #define arginfo_oci_close                                                               NULL
     669                 : #define arginfo_oci_new_connect                                                 NULL
     670                 : #define arginfo_oci_connect                                                             NULL
     671                 : #define arginfo_oci_pconnect                                                    NULL
     672                 : #define arginfo_oci_error                                                               NULL
     673                 : #define arginfo_oci_num_fields                                                  NULL
     674                 : #define arginfo_oci_parse                                                               NULL
     675                 : #define arginfo_oci_set_prefetch                                                NULL
     676                 : #define arginfo_oci_set_client_identifier                               NULL
     677                 : #define arginfo_oci_set_edition                                                 NULL
     678                 : #define arginfo_oci_set_module_name                                             NULL
     679                 : #define arginfo_oci_set_action                                                  NULL
     680                 : #define arginfo_oci_set_client_info                                             NULL
     681                 : #define arginfo_oci_password_change                                             NULL
     682                 : #define arginfo_oci_new_cursor                                                  NULL
     683                 : #define arginfo_oci_result                                                              NULL
     684                 : #define arginfo_oci_server_version                                              NULL
     685                 : #define arginfo_oci_statement_type                                              NULL
     686                 : #define arginfo_oci_num_rows                                                    NULL
     687                 : #define arginfo_oci_free_collection                                             NULL
     688                 : #define arginfo_oci_collection_append                                   NULL
     689                 : #define arginfo_oci_collection_element_get                              NULL
     690                 : #define arginfo_oci_collection_assign                                   NULL
     691                 : #define arginfo_oci_collection_element_assign                   NULL
     692                 : #define arginfo_oci_collection_size                                             NULL
     693                 : #define arginfo_oci_collection_max                                              NULL
     694                 : #define arginfo_oci_collection_trim                                             NULL
     695                 : #define arginfo_oci_new_collection                                              NULL
     696                 : #define arginfo_oci_lob_size_method                                             NULL
     697                 : #define arginfo_oci_lob_getbuffering_method                             NULL
     698                 : #define arginfo_oci_lob_close_method                                    NULL
     699                 : #define arginfo_oci_lob_save_method                                             NULL
     700                 : #define arginfo_oci_lob_import_method                                   NULL
     701                 : #define arginfo_oci_lob_read_method                                             NULL
     702                 : #define arginfo_oci_lob_seek_method                                             NULL
     703                 : #define arginfo_oci_lob_write_method                                    NULL
     704                 : #define arginfo_oci_lob_append_method                                   NULL
     705                 : #define arginfo_oci_lob_truncate_method                                 NULL
     706                 : #define arginfo_oci_lob_erase_method                                    NULL
     707                 : #define arginfo_oci_lob_flush_method                                    NULL
     708                 : #define arginfo_oci_lob_setbuffering_method                             NULL
     709                 : #define arginfo_oci_lob_export_method                                   NULL
     710                 : #define arginfo_oci_lob_write_temporary_method                  NULL
     711                 : #define arginfo_oci_lob_load_method                                             NULL
     712                 : #define arginfo_oci_lob_tell_method                                             NULL
     713                 : #define arginfo_oci_lob_rewind_method                                   NULL
     714                 : #define arginfo_oci_lob_eof_method                                              NULL
     715                 : #define arginfo_oci_free_descriptor_method                              NULL
     716                 : #define arginfo_oci_collection_append_method                    NULL
     717                 : #define arginfo_oci_collection_element_get_method               NULL
     718                 : #define arginfo_oci_collection_assign_method                    NULL
     719                 : #define arginfo_oci_collection_size_method                              NULL
     720                 : #define arginfo_oci_collection_element_assign_method    NULL
     721                 : #define arginfo_oci_collection_max_method                               NULL
     722                 : #define arginfo_oci_collection_trim_method                              NULL
     723                 : #define arginfo_oci_collection_free_method                              NULL
     724                 : /* }}} */
     725                 : #endif /* ZEND_ENGINE_2 */
     726                 : 
     727                 : /* {{{ extension function prototypes
     728                 : */
     729                 : PHP_FUNCTION(oci_bind_by_name);
     730                 : PHP_FUNCTION(oci_bind_array_by_name);
     731                 : PHP_FUNCTION(oci_define_by_name);
     732                 : PHP_FUNCTION(oci_field_is_null);
     733                 : PHP_FUNCTION(oci_field_name);
     734                 : PHP_FUNCTION(oci_field_size);
     735                 : PHP_FUNCTION(oci_field_scale);
     736                 : PHP_FUNCTION(oci_field_precision);
     737                 : PHP_FUNCTION(oci_field_type);
     738                 : PHP_FUNCTION(oci_field_type_raw);
     739                 : PHP_FUNCTION(oci_execute);
     740                 : PHP_FUNCTION(oci_fetch);
     741                 : PHP_FUNCTION(oci_cancel);
     742                 : PHP_FUNCTION(ocifetchinto);
     743                 : PHP_FUNCTION(oci_fetch_object);
     744                 : PHP_FUNCTION(oci_fetch_row);
     745                 : PHP_FUNCTION(oci_fetch_assoc);
     746                 : PHP_FUNCTION(oci_fetch_array);
     747                 : PHP_FUNCTION(ocifetchstatement);
     748                 : PHP_FUNCTION(oci_fetch_all);
     749                 : PHP_FUNCTION(oci_free_statement);
     750                 : PHP_FUNCTION(oci_internal_debug);
     751                 : PHP_FUNCTION(oci_close);
     752                 : PHP_FUNCTION(oci_connect);
     753                 : PHP_FUNCTION(oci_new_connect);
     754                 : PHP_FUNCTION(oci_pconnect);
     755                 : PHP_FUNCTION(oci_error);
     756                 : PHP_FUNCTION(oci_free_descriptor);
     757                 : PHP_FUNCTION(oci_commit);
     758                 : PHP_FUNCTION(oci_rollback);
     759                 : PHP_FUNCTION(oci_new_descriptor);
     760                 : PHP_FUNCTION(oci_num_fields);
     761                 : PHP_FUNCTION(oci_parse);
     762                 : PHP_FUNCTION(oci_new_cursor);
     763                 : PHP_FUNCTION(oci_result);
     764                 : PHP_FUNCTION(oci_server_version);
     765                 : PHP_FUNCTION(oci_statement_type);
     766                 : PHP_FUNCTION(oci_num_rows);
     767                 : PHP_FUNCTION(oci_set_prefetch);
     768                 : PHP_FUNCTION(oci_set_client_identifier);
     769                 : PHP_FUNCTION(oci_set_edition);
     770                 : PHP_FUNCTION(oci_set_module_name);
     771                 : PHP_FUNCTION(oci_set_action);
     772                 : PHP_FUNCTION(oci_set_client_info);
     773                 : PHP_FUNCTION(oci_password_change);
     774                 : PHP_FUNCTION(oci_lob_save);
     775                 : PHP_FUNCTION(oci_lob_import);
     776                 : PHP_FUNCTION(oci_lob_export);
     777                 : PHP_FUNCTION(oci_lob_load);
     778                 : PHP_FUNCTION(oci_lob_tell);
     779                 : PHP_FUNCTION(oci_lob_write);
     780                 : PHP_FUNCTION(oci_lob_append);
     781                 : PHP_FUNCTION(oci_lob_copy);
     782                 : PHP_FUNCTION(oci_lob_truncate);
     783                 : PHP_FUNCTION(oci_lob_erase);
     784                 : PHP_FUNCTION(oci_lob_flush);
     785                 : PHP_FUNCTION(ocisetbufferinglob);
     786                 : PHP_FUNCTION(ocigetbufferinglob);
     787                 : PHP_FUNCTION(oci_lob_is_equal);
     788                 : PHP_FUNCTION(oci_lob_rewind);
     789                 : PHP_FUNCTION(oci_lob_read);
     790                 : PHP_FUNCTION(oci_lob_eof);
     791                 : PHP_FUNCTION(oci_lob_seek);
     792                 : PHP_FUNCTION(oci_lob_size);
     793                 : PHP_FUNCTION(oci_lob_write_temporary);
     794                 : PHP_FUNCTION(oci_lob_close);
     795                 : PHP_FUNCTION(oci_new_collection);
     796                 : PHP_FUNCTION(oci_free_collection);
     797                 : PHP_FUNCTION(oci_collection_append);
     798                 : PHP_FUNCTION(oci_collection_element_get);
     799                 : PHP_FUNCTION(oci_collection_element_assign);
     800                 : PHP_FUNCTION(oci_collection_assign);
     801                 : PHP_FUNCTION(oci_collection_size);
     802                 : PHP_FUNCTION(oci_collection_max);
     803                 : PHP_FUNCTION(oci_collection_trim);
     804                 : /* }}} */
     805                 : 
     806                 : /* {{{ extension definition structures
     807                 : */
     808                 : static
     809                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
     810                 : /* This "if" allows PECL builds from this file to be portable to older PHP releases */
     811                 : const
     812                 : #endif
     813                 : zend_function_entry php_oci_functions[] = {
     814                 :         PHP_FE(oci_define_by_name,                      arginfo_oci_define_by_name)
     815                 :         PHP_FE(oci_bind_by_name,                        arginfo_oci_bind_by_name)
     816                 :         PHP_FE(oci_bind_array_by_name,          arginfo_oci_bind_array_by_name)
     817                 :         PHP_FE(oci_field_is_null,                       arginfo_oci_field_is_null)
     818                 :         PHP_FE(oci_field_name,                          arginfo_oci_field_name)
     819                 :         PHP_FE(oci_field_size,                          arginfo_oci_field_size)
     820                 :         PHP_FE(oci_field_scale,                         arginfo_oci_field_scale)
     821                 :         PHP_FE(oci_field_precision,                     arginfo_oci_field_precision)
     822                 :         PHP_FE(oci_field_type,                          arginfo_oci_field_type)
     823                 :         PHP_FE(oci_field_type_raw,                      arginfo_oci_field_type_raw)
     824                 :         PHP_FE(oci_execute,                                     arginfo_oci_execute)
     825                 :         PHP_FE(oci_cancel,                                      arginfo_oci_cancel)
     826                 :         PHP_FE(oci_fetch,                                       arginfo_oci_fetch)
     827                 :         PHP_FE(oci_fetch_object,                        arginfo_oci_fetch_object)
     828                 :         PHP_FE(oci_fetch_row,                           arginfo_oci_fetch_row)
     829                 :         PHP_FE(oci_fetch_assoc,                         arginfo_oci_fetch_assoc)
     830                 :         PHP_FE(oci_fetch_array,                         arginfo_oci_fetch_array)
     831                 :         PHP_FE(ocifetchinto,                            arginfo_ocifetchinto)
     832                 :         PHP_FE(oci_fetch_all,                           arginfo_oci_fetch_all)
     833                 :         PHP_FE(oci_free_statement,                      arginfo_oci_free_statement)
     834                 :         PHP_FE(oci_internal_debug,                      arginfo_oci_internal_debug)
     835                 :         PHP_FE(oci_num_fields,                          arginfo_oci_num_fields)
     836                 :         PHP_FE(oci_parse,                                       arginfo_oci_parse)
     837                 :         PHP_FE(oci_new_cursor,                          arginfo_oci_new_cursor)
     838                 :         PHP_FE(oci_result,                                      arginfo_oci_result)
     839                 :         PHP_FE(oci_server_version,                      arginfo_oci_server_version)
     840                 :         PHP_FE(oci_statement_type,                      arginfo_oci_statement_type)
     841                 :         PHP_FE(oci_num_rows,                            arginfo_oci_num_rows)
     842                 :         PHP_FE(oci_close,                                       arginfo_oci_close)
     843                 :         PHP_FE(oci_connect,                                     arginfo_oci_connect)
     844                 :         PHP_FE(oci_new_connect,                         arginfo_oci_new_connect)
     845                 :         PHP_FE(oci_pconnect,                            arginfo_oci_pconnect)
     846                 :         PHP_FE(oci_error,                                       arginfo_oci_error)
     847                 :         PHP_FE(oci_free_descriptor,                     arginfo_oci_free_descriptor)
     848                 :         PHP_FE(oci_lob_save,                            arginfo_oci_lob_save)
     849                 :         PHP_FE(oci_lob_import,                          arginfo_oci_lob_import)
     850                 :         PHP_FE(oci_lob_size,                            arginfo_oci_lob_size)
     851                 :         PHP_FE(oci_lob_load,                            arginfo_oci_lob_load)
     852                 :         PHP_FE(oci_lob_read,                            arginfo_oci_lob_read)
     853                 :         PHP_FE(oci_lob_eof,                                     arginfo_oci_lob_eof)
     854                 :         PHP_FE(oci_lob_tell,                            arginfo_oci_lob_tell)
     855                 :         PHP_FE(oci_lob_truncate,                        arginfo_oci_lob_truncate)
     856                 :         PHP_FE(oci_lob_erase,                           arginfo_oci_lob_erase)
     857                 :         PHP_FE(oci_lob_flush,                           arginfo_oci_lob_flush)
     858                 :         PHP_FE(ocisetbufferinglob,                      arginfo_ocisetbufferinglob)
     859                 :         PHP_FE(ocigetbufferinglob,                      arginfo_ocigetbufferinglob)
     860                 :         PHP_FE(oci_lob_is_equal,                        arginfo_oci_lob_is_equal)
     861                 :         PHP_FE(oci_lob_rewind,                          arginfo_oci_lob_rewind)
     862                 :         PHP_FE(oci_lob_write,                           arginfo_oci_lob_write)
     863                 :         PHP_FE(oci_lob_append,                          arginfo_oci_lob_append)
     864                 :         PHP_FE(oci_lob_copy,                            arginfo_oci_lob_copy)
     865                 :         PHP_FE(oci_lob_export,                          arginfo_oci_lob_export)
     866                 :         PHP_FE(oci_lob_seek,                            arginfo_oci_lob_seek)
     867                 :         PHP_FE(oci_commit,                                      arginfo_oci_commit)
     868                 :         PHP_FE(oci_rollback,                            arginfo_oci_rollback)
     869                 :         PHP_FE(oci_new_descriptor,                      arginfo_oci_new_descriptor)
     870                 :         PHP_FE(oci_set_prefetch,                        arginfo_oci_set_prefetch)
     871                 :         PHP_FE(oci_set_client_identifier,       arginfo_oci_set_client_identifier)
     872                 :         PHP_FE(oci_set_edition,                         arginfo_oci_set_edition)
     873                 :         PHP_FE(oci_set_module_name,                     arginfo_oci_set_module_name)
     874                 :         PHP_FE(oci_set_action,                          arginfo_oci_set_action)
     875                 :         PHP_FE(oci_set_client_info,                     arginfo_oci_set_client_info)
     876                 :         PHP_FE(oci_password_change,                     arginfo_oci_password_change)
     877                 :         PHP_FE(oci_free_collection,                     arginfo_oci_free_collection)
     878                 :         PHP_FE(oci_collection_append,           arginfo_oci_collection_append)
     879                 :         PHP_FE(oci_collection_element_get,      arginfo_oci_collection_element_get)
     880                 :         PHP_FE(oci_collection_element_assign,   arginfo_oci_collection_element_assign)
     881                 :         PHP_FE(oci_collection_assign,           arginfo_oci_collection_assign)
     882                 :         PHP_FE(oci_collection_size,                     arginfo_oci_collection_size)
     883                 :         PHP_FE(oci_collection_max,                      arginfo_oci_collection_max)
     884                 :         PHP_FE(oci_collection_trim,                     arginfo_oci_collection_trim)
     885                 :         PHP_FE(oci_new_collection,                      arginfo_oci_new_collection)
     886                 : 
     887                 :         PHP_FALIAS(oci_free_cursor,             oci_free_statement,             arginfo_oci_free_statement)
     888                 :         PHP_FALIAS(ocifreecursor,               oci_free_statement,             arginfo_oci_free_statement)
     889                 :         PHP_FALIAS(ocibindbyname,               oci_bind_by_name,               arginfo_oci_bind_by_name)
     890                 :         PHP_FALIAS(ocidefinebyname,             oci_define_by_name,             arginfo_oci_define_by_name)
     891                 :         PHP_FALIAS(ocicolumnisnull,             oci_field_is_null,              arginfo_oci_field_is_null)
     892                 :         PHP_FALIAS(ocicolumnname,               oci_field_name,                 arginfo_oci_field_name)
     893                 :         PHP_FALIAS(ocicolumnsize,               oci_field_size,                 arginfo_oci_field_size)
     894                 :         PHP_FALIAS(ocicolumnscale,              oci_field_scale,                arginfo_oci_field_scale)
     895                 :         PHP_FALIAS(ocicolumnprecision,  oci_field_precision,    arginfo_oci_field_precision)
     896                 :         PHP_FALIAS(ocicolumntype,               oci_field_type,                 arginfo_oci_field_type)
     897                 :         PHP_FALIAS(ocicolumntyperaw,    oci_field_type_raw,             arginfo_oci_field_type_raw)
     898                 :         PHP_FALIAS(ociexecute,                  oci_execute,                    arginfo_oci_execute)
     899                 :         PHP_FALIAS(ocicancel,                   oci_cancel,                             arginfo_oci_cancel)
     900                 :         PHP_FALIAS(ocifetch,                    oci_fetch,                              arginfo_oci_fetch)
     901                 :         PHP_FALIAS(ocifetchstatement,   oci_fetch_all,                  arginfo_oci_fetch_all)
     902                 :         PHP_FALIAS(ocifreestatement,    oci_free_statement,             arginfo_oci_free_statement)
     903                 :         PHP_FALIAS(ociinternaldebug,    oci_internal_debug,             arginfo_oci_internal_debug)
     904                 :         PHP_FALIAS(ocinumcols,                  oci_num_fields,                 arginfo_oci_num_fields)
     905                 :         PHP_FALIAS(ociparse,                    oci_parse,                              arginfo_oci_parse)
     906                 :         PHP_FALIAS(ocinewcursor,                oci_new_cursor,                 arginfo_oci_new_cursor)
     907                 :         PHP_FALIAS(ociresult,                   oci_result,                             arginfo_oci_result)
     908                 :         PHP_FALIAS(ociserverversion,    oci_server_version,             arginfo_oci_server_version)
     909                 :         PHP_FALIAS(ocistatementtype,    oci_statement_type,             arginfo_oci_statement_type)
     910                 :         PHP_FALIAS(ocirowcount,                 oci_num_rows,                   arginfo_oci_num_rows)
     911                 :         PHP_FALIAS(ocilogoff,                   oci_close,                              arginfo_oci_close)
     912                 :         PHP_FALIAS(ocilogon,                    oci_connect,                    arginfo_oci_connect)
     913                 :         PHP_FALIAS(ocinlogon,                   oci_new_connect,                arginfo_oci_new_connect)
     914                 :         PHP_FALIAS(ociplogon,                   oci_pconnect,                   arginfo_oci_pconnect)
     915                 :         PHP_FALIAS(ocierror,                    oci_error,                              arginfo_oci_error)
     916                 :         PHP_FALIAS(ocifreedesc,                 oci_free_descriptor,    arginfo_oci_free_descriptor)
     917                 :         PHP_FALIAS(ocisavelob,                  oci_lob_save,                   arginfo_oci_lob_save)
     918                 :         PHP_FALIAS(ocisavelobfile,              oci_lob_import,                 arginfo_oci_lob_import)
     919                 :         PHP_FALIAS(ociwritelobtofile,   oci_lob_export,                 arginfo_oci_lob_export)
     920                 :         PHP_FALIAS(ociloadlob,                  oci_lob_load,                   arginfo_oci_lob_load)
     921                 :         PHP_FALIAS(ocicommit,                   oci_commit,                             arginfo_oci_commit)
     922                 :         PHP_FALIAS(ocirollback,                 oci_rollback,                   arginfo_oci_rollback)
     923                 :         PHP_FALIAS(ocinewdescriptor,    oci_new_descriptor,             arginfo_oci_new_descriptor)
     924                 :         PHP_FALIAS(ocisetprefetch,              oci_set_prefetch,               arginfo_oci_set_prefetch)
     925                 :         PHP_FALIAS(ocipasswordchange,   oci_password_change,    arginfo_oci_password_change)
     926                 :         PHP_FALIAS(ocifreecollection,   oci_free_collection,    arginfo_oci_free_collection)
     927                 :         PHP_FALIAS(ocinewcollection,    oci_new_collection,             arginfo_oci_new_collection)
     928                 :         PHP_FALIAS(ocicollappend,               oci_collection_append,  arginfo_oci_collection_append)
     929                 :         PHP_FALIAS(ocicollgetelem,              oci_collection_element_get,             arginfo_oci_collection_element_get)
     930                 :         PHP_FALIAS(ocicollassignelem,   oci_collection_element_assign,  arginfo_oci_collection_element_assign)
     931                 :         PHP_FALIAS(ocicollsize,                 oci_collection_size,    arginfo_oci_collection_size)
     932                 :         PHP_FALIAS(ocicollmax,                  oci_collection_max,             arginfo_oci_collection_max)
     933                 :         PHP_FALIAS(ocicolltrim,                 oci_collection_trim,    arginfo_oci_collection_trim)
     934                 :         {NULL,NULL,NULL}
     935                 : };
     936                 : 
     937                 : static
     938                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
     939                 : /* This "if" allows PECL builds from this file to be portable to older PHP releases */
     940                 : const
     941                 : #endif
     942                 : zend_function_entry php_oci_lob_class_functions[] = {
     943                 :         PHP_FALIAS(load,                oci_lob_load,                   arginfo_oci_lob_load_method)
     944                 :         PHP_FALIAS(tell,                oci_lob_tell,                   arginfo_oci_lob_tell_method)
     945                 :         PHP_FALIAS(truncate,    oci_lob_truncate,               arginfo_oci_lob_truncate_method)
     946                 :         PHP_FALIAS(erase,               oci_lob_erase,                  arginfo_oci_lob_erase_method)
     947                 :         PHP_FALIAS(flush,               oci_lob_flush,                  arginfo_oci_lob_flush_method)
     948                 :         PHP_FALIAS(setbuffering,ocisetbufferinglob,             arginfo_oci_lob_setbuffering_method)
     949                 :         PHP_FALIAS(getbuffering,ocigetbufferinglob,             arginfo_oci_lob_getbuffering_method)
     950                 :         PHP_FALIAS(rewind,              oci_lob_rewind,                 arginfo_oci_lob_rewind_method)
     951                 :         PHP_FALIAS(read,                oci_lob_read,                   arginfo_oci_lob_read_method)
     952                 :         PHP_FALIAS(eof,                 oci_lob_eof,                    arginfo_oci_lob_eof_method)
     953                 :         PHP_FALIAS(seek,                oci_lob_seek,                   arginfo_oci_lob_seek_method)
     954                 :         PHP_FALIAS(write,               oci_lob_write,                  arginfo_oci_lob_write_method)
     955                 :         PHP_FALIAS(append,              oci_lob_append,                 arginfo_oci_lob_append_method)
     956                 :         PHP_FALIAS(size,                oci_lob_size,                   arginfo_oci_lob_size_method)
     957                 :         PHP_FALIAS(writetofile, oci_lob_export,                 arginfo_oci_lob_export_method)
     958                 :         PHP_FALIAS(export,              oci_lob_export,                 arginfo_oci_lob_export_method)
     959                 :         PHP_FALIAS(import,              oci_lob_import,                 arginfo_oci_lob_import_method)
     960                 :         PHP_FALIAS(writetemporary,      oci_lob_write_temporary,        arginfo_oci_lob_write_temporary_method)
     961                 :         PHP_FALIAS(close,                       oci_lob_close,                          arginfo_oci_lob_close_method)
     962                 :         PHP_FALIAS(save,                oci_lob_save,                   arginfo_oci_lob_save_method)
     963                 :         PHP_FALIAS(savefile,    oci_lob_import,                 arginfo_oci_lob_import_method)
     964                 :         PHP_FALIAS(free,                oci_free_descriptor,    arginfo_oci_free_descriptor_method)
     965                 :         {NULL,NULL,NULL}
     966                 : };
     967                 : 
     968                 : static
     969                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2) || (PHP_MAJOR_VERSION > 5)
     970                 : /* This "if" allows PECL builds from this file to be portable to older PHP releases */
     971                 : const
     972                 : #endif
     973                 : zend_function_entry php_oci_coll_class_functions[] = {
     974                 :         PHP_FALIAS(append,                oci_collection_append,                        arginfo_oci_collection_append_method)
     975                 :         PHP_FALIAS(getelem,               oci_collection_element_get,           arginfo_oci_collection_element_get_method)
     976                 :         PHP_FALIAS(assignelem,    oci_collection_element_assign,        arginfo_oci_collection_element_assign_method)
     977                 :         PHP_FALIAS(assign,                oci_collection_assign,                        arginfo_oci_collection_assign_method)
     978                 :         PHP_FALIAS(size,                  oci_collection_size,                          arginfo_oci_collection_size_method)
     979                 :         PHP_FALIAS(max,                   oci_collection_max,                           arginfo_oci_collection_max_method)
     980                 :         PHP_FALIAS(trim,                  oci_collection_trim,                          arginfo_oci_collection_trim_method)
     981                 :         PHP_FALIAS(free,                  oci_free_collection,                          arginfo_oci_collection_free_method)
     982                 :         {NULL,NULL,NULL}
     983                 : };
     984                 : 
     985                 : zend_module_entry oci8_module_entry = {
     986                 :         STANDARD_MODULE_HEADER,
     987                 :         "oci8",                                 /* extension name */
     988                 :         php_oci_functions,        /* extension function list */
     989                 :         PHP_MINIT(oci),           /* extension-wide startup function */
     990                 :         PHP_MSHUTDOWN(oci),       /* extension-wide shutdown function */
     991                 :         PHP_RINIT(oci),           /* per-request startup function */
     992                 :         PHP_RSHUTDOWN(oci),       /* per-request shutdown function */
     993                 :         PHP_MINFO(oci),           /* information function */
     994                 :         PHP_OCI8_VERSION,
     995                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
     996                 :         /* This check allows PECL builds from this file to be portable to older PHP releases */
     997                 :         PHP_MODULE_GLOBALS(oci),  /* globals descriptor */
     998                 :         PHP_GINIT(oci),                   /* globals ctor */
     999                 :         PHP_GSHUTDOWN(oci),               /* globals dtor */
    1000                 :         NULL,                                     /* post deactivate */
    1001                 :         STANDARD_MODULE_PROPERTIES_EX
    1002                 : #else
    1003                 :         STANDARD_MODULE_PROPERTIES
    1004                 : #endif
    1005                 : };
    1006                 : /* }}} */
    1007                 : 
    1008                 : /* {{{ PHP_INI */
    1009                 : PHP_INI_BEGIN()
    1010                 :         STD_PHP_INI_ENTRY(      "oci8.max_persistent",                        "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC,       max_persistent,                 zend_oci_globals,       oci_globals)
    1011                 :         STD_PHP_INI_ENTRY(      "oci8.persistent_timeout",            "-1", PHP_INI_SYSTEM, ONUPDATELONGFUNC,       persistent_timeout,             zend_oci_globals,       oci_globals)
    1012                 :         STD_PHP_INI_ENTRY(      "oci8.ping_interval",                 "60", PHP_INI_SYSTEM, ONUPDATELONGFUNC,       ping_interval,                  zend_oci_globals,       oci_globals)
    1013                 :         STD_PHP_INI_BOOLEAN("oci8.privileged_connect",                "0",  PHP_INI_SYSTEM, OnUpdateBool,           privileged_connect,             zend_oci_globals,       oci_globals)
    1014                 :         STD_PHP_INI_ENTRY(      "oci8.statement_cache_size",  "20", PHP_INI_SYSTEM, ONUPDATELONGFUNC,       statement_cache_size,   zend_oci_globals,       oci_globals)
    1015                 :         STD_PHP_INI_ENTRY(      "oci8.default_prefetch",              "100",        PHP_INI_SYSTEM, ONUPDATELONGFUNC,       default_prefetch,               zend_oci_globals,       oci_globals)
    1016                 :         STD_PHP_INI_BOOLEAN("oci8.old_oci_close_semantics",   "0",  PHP_INI_SYSTEM, OnUpdateBool,           old_oci_close_semantics,zend_oci_globals,       oci_globals)
    1017                 :         STD_PHP_INI_ENTRY(      "oci8.connection_class",              "",           PHP_INI_ALL,    OnUpdateString,         connection_class,               zend_oci_globals,       oci_globals)
    1018                 :         STD_PHP_INI_BOOLEAN("oci8.events",                                    "0",  PHP_INI_SYSTEM, OnUpdateBool,           events,                                 zend_oci_globals,       oci_globals)
    1019                 : PHP_INI_END()
    1020                 : /* }}} */
    1021                 : 
    1022                 : /* {{{ startup, shutdown and info functions
    1023                 : */
    1024                 : 
    1025                 : /* {{{  php_oci_init_global_handles()
    1026                 :  *
    1027                 :  * Initialize global handles only when they are needed
    1028                 :  */
    1029                 : static void php_oci_init_global_handles(TSRMLS_D)
    1030             261 : {
    1031                 :         sword errstatus;
    1032             261 :         sb4   ora_error_code = 0;
    1033                 :         text  tmp_buf[PHP_OCI_ERRBUF_LEN];
    1034                 : 
    1035             261 :         errstatus = OCIEnvNlsCreate(&OCI_G(env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
    1036                 : 
    1037             261 :         if (errstatus == OCI_ERROR) {
    1038                 : #ifdef HAVE_OCI_INSTANT_CLIENT
    1039                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries");
    1040                 : #else
    1041               3 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
    1042                 : #endif
    1043               3 :                 OCI_G(env) = NULL;
    1044               3 :                 OCI_G(err) = NULL;
    1045               3 :                 return;
    1046                 :         }
    1047                 : 
    1048             258 :         errstatus = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
    1049                 : 
    1050             258 :         if (errstatus == OCI_SUCCESS) {
    1051                 : #if !defined(OCI_MAJOR_VERSION) || (OCI_MAJOR_VERSION < 11)
    1052                 :                 /* This fixes PECL bug 15988 (sqlnet.ora not being read).  The
    1053                 :                  * root cause was fixed in Oracle 10.2.0.4 but there is no
    1054                 :                  * compile time method to check for that precise patch level,
    1055                 :                  * nor can it be guaranteed that runtime will use the same
    1056                 :                  * patch level the code was compiled with.  So, we do this
    1057                 :                  * code for all non 11g versions.
    1058                 :                  */
    1059                 :                 OCICPool *cpoolh;
    1060             258 :                 ub4 cpoolmode = 0x80000000;     /* Pass invalid mode to OCIConnectionPoolCreate */
    1061             258 :                 PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **) &cpoolh, OCI_HTYPE_CPOOL, (size_t) 0, (dvoid **) 0));
    1062             258 :                 PHP_OCI_CALL(OCIConnectionPoolCreate, (OCI_G(env), OCI_G(err), cpoolh, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, NULL, 0, cpoolmode));
    1063             258 :                 PHP_OCI_CALL(OCIConnectionPoolDestroy, (cpoolh, OCI_G(err), OCI_DEFAULT));
    1064             258 :                 PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL));
    1065                 : #endif
    1066                 :         } else {
    1067               0 :                 OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
    1068                 : 
    1069               0 :                 if (ora_error_code) {
    1070               0 :                         int tmp_buf_len = strlen((char *)tmp_buf);
    1071                 :                         
    1072               0 :                         if (tmp_buf_len > 0 && tmp_buf[tmp_buf_len - 1] == '\n') {
    1073               0 :                                 tmp_buf[tmp_buf_len - 1] = '\0';
    1074                 :                         }
    1075                 :                         
    1076               0 :                         if (errstatus == OCI_SUCCESS_WITH_INFO) {
    1077               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
    1078                 :                         } else {
    1079               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Initialization error: OCI_ERROR: %s", tmp_buf);
    1080                 :                                 
    1081               0 :                                 OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
    1082                 :                                 
    1083               0 :                                 OCI_G(env) = NULL;
    1084               0 :                                 OCI_G(err) = NULL;
    1085                 :                         }
    1086                 :                 }
    1087                 :         }
    1088                 : } /* }}} */
    1089                 : 
    1090                 : /* {{{ php_oci_cleanup_global_handles()
    1091                 :  *
    1092                 :  * Free global handles (if they were initialized before)
    1093                 :  */
    1094                 : static void php_oci_cleanup_global_handles(TSRMLS_D)
    1095           17665 : {
    1096           17665 :         if (OCI_G(err)) {
    1097             258 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR));
    1098             258 :                 OCI_G(err) = NULL;
    1099                 :         }
    1100                 : 
    1101           17665 :         if (OCI_G(env)) {
    1102             258 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV));
    1103             258 :                 OCI_G(env) = NULL;
    1104                 :         }
    1105           17665 : } /* }}} */
    1106                 : 
    1107                 : /* {{{ PHP_GINIT_FUNCTION
    1108                 :  *
    1109                 :  * Zerofill globals during module init
    1110                 :  */
    1111                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
    1112                 : /* This check allows PECL builds from this file to be portable to older PHP releases */
    1113                 : static PHP_GINIT_FUNCTION(oci)
    1114                 : #else
    1115                 : static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC)
    1116                 : #endif
    1117           17633 : {
    1118           17633 :         memset(oci_globals, 0, sizeof(zend_oci_globals));
    1119           17633 : }
    1120                 : /* }}} */
    1121                 : 
    1122                 : /* {{{ PHP_GSHUTDOWN_FUNCTION
    1123                 :  *
    1124                 :  * Called for thread shutdown in ZTS, after module shutdown for non-ZTS
    1125                 :  */
    1126                 : /* This check allows PECL builds from this file to be portable to older PHP releases */
    1127                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
    1128                 : static PHP_GSHUTDOWN_FUNCTION(oci)
    1129                 : #else
    1130                 : static void php_oci_shutdown_globals(zend_oci_globals *oci_globals TSRMLS_DC)
    1131                 : #endif
    1132           17665 : {
    1133           17665 :         php_oci_cleanup_global_handles(TSRMLS_C);
    1134           17665 : }
    1135                 : /* }}} */
    1136                 : 
    1137                 : PHP_MINIT_FUNCTION(oci)
    1138           17633 : {
    1139                 :         zend_class_entry oci_lob_class_entry;
    1140                 :         zend_class_entry oci_coll_class_entry;
    1141                 : 
    1142                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
    1143                 :         /* This check allows PECL builds from this file to be portable to older PHP releases */
    1144                 :         /* this is handled by new globals management code */
    1145                 : #else
    1146                 :         ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, php_oci_shutdown_globals);
    1147                 : #endif
    1148           17633 :         REGISTER_INI_ENTRIES();
    1149                 : 
    1150           17633 :         le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
    1151           17633 :         le_connection = zend_register_list_destructors_ex(php_oci_connection_list_dtor, NULL, "oci8 connection", module_number);
    1152           17633 :         le_pconnection = zend_register_list_destructors_ex(php_oci_pconnection_list_np_dtor, php_oci_pconnection_list_dtor, "oci8 persistent connection", module_number);
    1153           17633 :         le_psessionpool = zend_register_list_destructors_ex(NULL, php_oci_spool_list_dtor, "oci8 persistent session pool", module_number);
    1154           17633 :         le_descriptor = zend_register_list_destructors_ex(php_oci_descriptor_list_dtor, NULL, "oci8 descriptor", module_number);
    1155           17633 :         le_collection = zend_register_list_destructors_ex(php_oci_collection_list_dtor, NULL, "oci8 collection", module_number);
    1156                 : 
    1157           17633 :         INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions);
    1158           17633 :         INIT_CLASS_ENTRY(oci_coll_class_entry, "OCI-Collection", php_oci_coll_class_functions);
    1159                 : 
    1160           17633 :         oci_lob_class_entry_ptr = zend_register_internal_class(&oci_lob_class_entry TSRMLS_CC);
    1161           17633 :         oci_coll_class_entry_ptr = zend_register_internal_class(&oci_coll_class_entry TSRMLS_CC);
    1162                 : 
    1163                 : /* thies@thieso.net 990203 i do not think that we will need all of them - just in here for completeness for now! */
    1164           17633 :         REGISTER_LONG_CONSTANT("OCI_DEFAULT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
    1165           17633 :         REGISTER_LONG_CONSTANT("OCI_SYSOPER",OCI_SYSOPER, CONST_CS | CONST_PERSISTENT);
    1166           17633 :         REGISTER_LONG_CONSTANT("OCI_SYSDBA",OCI_SYSDBA, CONST_CS | CONST_PERSISTENT);
    1167           17633 :         REGISTER_LONG_CONSTANT("OCI_CRED_EXT",PHP_OCI_CRED_EXT, CONST_CS | CONST_PERSISTENT);
    1168           17633 :         REGISTER_LONG_CONSTANT("OCI_DESCRIBE_ONLY",OCI_DESCRIBE_ONLY, CONST_CS | CONST_PERSISTENT);
    1169           17633 :         REGISTER_LONG_CONSTANT("OCI_COMMIT_ON_SUCCESS",OCI_COMMIT_ON_SUCCESS, CONST_CS | CONST_PERSISTENT);
    1170           17633 :         REGISTER_LONG_CONSTANT("OCI_NO_AUTO_COMMIT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
    1171           17633 :         REGISTER_LONG_CONSTANT("OCI_EXACT_FETCH",OCI_EXACT_FETCH, CONST_CS | CONST_PERSISTENT);
    1172                 : 
    1173                 : /* for $LOB->seek() */
    1174           17633 :         REGISTER_LONG_CONSTANT("OCI_SEEK_SET",PHP_OCI_SEEK_SET, CONST_CS | CONST_PERSISTENT);
    1175           17633 :         REGISTER_LONG_CONSTANT("OCI_SEEK_CUR",PHP_OCI_SEEK_CUR, CONST_CS | CONST_PERSISTENT);
    1176           17633 :         REGISTER_LONG_CONSTANT("OCI_SEEK_END",PHP_OCI_SEEK_END, CONST_CS | CONST_PERSISTENT);
    1177                 : 
    1178                 : /*      for $LOB->flush() */
    1179           17633 :         REGISTER_LONG_CONSTANT("OCI_LOB_BUFFER_FREE",OCI_LOB_BUFFER_FREE, CONST_CS | CONST_PERSISTENT);
    1180                 : 
    1181                 : /* for OCIBindByName (real "oci" names + short "php" names */
    1182           17633 :         REGISTER_LONG_CONSTANT("SQLT_BFILEE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
    1183           17633 :         REGISTER_LONG_CONSTANT("SQLT_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
    1184           17633 :         REGISTER_LONG_CONSTANT("SQLT_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
    1185           17633 :         REGISTER_LONG_CONSTANT("SQLT_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
    1186           17633 :         REGISTER_LONG_CONSTANT("SQLT_RDD",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
    1187           17633 :         REGISTER_LONG_CONSTANT("SQLT_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
    1188           17633 :         REGISTER_LONG_CONSTANT("SQLT_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
    1189           17633 :         REGISTER_LONG_CONSTANT("SQLT_RSET",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
    1190           17633 :         REGISTER_LONG_CONSTANT("SQLT_AFC",SQLT_AFC, CONST_CS | CONST_PERSISTENT);
    1191           17633 :         REGISTER_LONG_CONSTANT("SQLT_CHR",SQLT_CHR, CONST_CS | CONST_PERSISTENT);
    1192           17633 :         REGISTER_LONG_CONSTANT("SQLT_VCS",SQLT_VCS, CONST_CS | CONST_PERSISTENT);
    1193           17633 :         REGISTER_LONG_CONSTANT("SQLT_AVC",SQLT_AVC, CONST_CS | CONST_PERSISTENT);
    1194           17633 :         REGISTER_LONG_CONSTANT("SQLT_STR",SQLT_STR, CONST_CS | CONST_PERSISTENT);
    1195           17633 :         REGISTER_LONG_CONSTANT("SQLT_LVC",SQLT_LVC, CONST_CS | CONST_PERSISTENT);
    1196           17633 :         REGISTER_LONG_CONSTANT("SQLT_FLT",SQLT_FLT, CONST_CS | CONST_PERSISTENT);
    1197           17633 :         REGISTER_LONG_CONSTANT("SQLT_UIN",SQLT_UIN, CONST_CS | CONST_PERSISTENT);
    1198           17633 :         REGISTER_LONG_CONSTANT("SQLT_LNG",SQLT_LNG, CONST_CS | CONST_PERSISTENT);
    1199           17633 :         REGISTER_LONG_CONSTANT("SQLT_LBI",SQLT_LBI, CONST_CS | CONST_PERSISTENT);
    1200           17633 :         REGISTER_LONG_CONSTANT("SQLT_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
    1201           17633 :         REGISTER_LONG_CONSTANT("SQLT_ODT",SQLT_ODT, CONST_CS | CONST_PERSISTENT);
    1202                 : #if defined(HAVE_OCI_INSTANT_CLIENT) || (defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 10)
    1203           17633 :         REGISTER_LONG_CONSTANT("SQLT_BDOUBLE",SQLT_BDOUBLE, CONST_CS | CONST_PERSISTENT);
    1204           17633 :         REGISTER_LONG_CONSTANT("SQLT_BFLOAT",SQLT_BFLOAT, CONST_CS | CONST_PERSISTENT);
    1205                 : #endif
    1206                 : 
    1207           17633 :         REGISTER_LONG_CONSTANT("OCI_B_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
    1208           17633 :         REGISTER_LONG_CONSTANT("SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
    1209           17633 :         REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE", CONST_CS | CONST_PERSISTENT);
    1210                 : 
    1211           17633 :         REGISTER_LONG_CONSTANT("OCI_B_BFILE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
    1212           17633 :         REGISTER_LONG_CONSTANT("OCI_B_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
    1213           17633 :         REGISTER_LONG_CONSTANT("OCI_B_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
    1214           17633 :         REGISTER_LONG_CONSTANT("OCI_B_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
    1215           17633 :         REGISTER_LONG_CONSTANT("OCI_B_ROWID",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
    1216           17633 :         REGISTER_LONG_CONSTANT("OCI_B_CURSOR",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
    1217           17633 :         REGISTER_LONG_CONSTANT("OCI_B_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
    1218           17633 :         REGISTER_LONG_CONSTANT("OCI_B_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
    1219           17633 :         REGISTER_LONG_CONSTANT("OCI_B_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
    1220                 : 
    1221                 : /* for OCIFetchStatement */
    1222           17633 :         REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
    1223           17633 :         REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", PHP_OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT);
    1224                 : 
    1225                 : /* for OCIFetchInto & OCIResult */
    1226           17633 :         REGISTER_LONG_CONSTANT("OCI_ASSOC",PHP_OCI_ASSOC, CONST_CS | CONST_PERSISTENT);
    1227           17633 :         REGISTER_LONG_CONSTANT("OCI_NUM",PHP_OCI_NUM, CONST_CS | CONST_PERSISTENT);
    1228           17633 :         REGISTER_LONG_CONSTANT("OCI_BOTH",PHP_OCI_BOTH, CONST_CS | CONST_PERSISTENT);
    1229           17633 :         REGISTER_LONG_CONSTANT("OCI_RETURN_NULLS",PHP_OCI_RETURN_NULLS, CONST_CS | CONST_PERSISTENT);
    1230           17633 :         REGISTER_LONG_CONSTANT("OCI_RETURN_LOBS",PHP_OCI_RETURN_LOBS, CONST_CS | CONST_PERSISTENT);
    1231                 : 
    1232                 : /* for OCINewDescriptor (real "oci" names + short "php" names */
    1233           17633 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
    1234           17633 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
    1235           17633 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
    1236                 : 
    1237           17633 :         REGISTER_LONG_CONSTANT("OCI_D_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
    1238           17633 :         REGISTER_LONG_CONSTANT("OCI_D_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
    1239           17633 :         REGISTER_LONG_CONSTANT("OCI_D_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
    1240                 : 
    1241                 : /* for OCIWriteTemporaryLob */
    1242           17633 :         REGISTER_LONG_CONSTANT("OCI_TEMP_CLOB",OCI_TEMP_CLOB, CONST_CS | CONST_PERSISTENT);
    1243           17633 :         REGISTER_LONG_CONSTANT("OCI_TEMP_BLOB",OCI_TEMP_BLOB, CONST_CS | CONST_PERSISTENT);
    1244                 : 
    1245           17633 :         return SUCCESS;
    1246                 : }
    1247                 : 
    1248                 : PHP_RINIT_FUNCTION(oci)
    1249           17619 : {
    1250           17619 :         OCI_G(debug_mode) = 0; /* start "fresh" */
    1251           17619 :         OCI_G(num_links) = OCI_G(num_persistent);
    1252           17619 :         OCI_G(errcode) = 0;
    1253           17619 :         OCI_G(edition) = NULL;
    1254                 : 
    1255           17619 :         return SUCCESS;
    1256                 : }
    1257                 : 
    1258                 : PHP_MSHUTDOWN_FUNCTION(oci)
    1259           17665 : {
    1260                 : /* Work around PHP_GSHUTDOWN_FUNCTION not being called in older versions of PHP */
    1261                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) || (PHP_MAJOR_VERSION < 5)
    1262                 : #ifndef ZTS
    1263                 :         php_oci_cleanup_global_handles(TSRMLS_C);
    1264                 : #endif
    1265                 : #endif
    1266                 : 
    1267           17665 :         OCI_G(shutdown) = 1;
    1268                 : 
    1269           17665 :         UNREGISTER_INI_ENTRIES();
    1270                 : 
    1271           17665 :         return SUCCESS;
    1272                 : }
    1273                 : 
    1274                 : PHP_RSHUTDOWN_FUNCTION(oci)
    1275           17651 : {
    1276                 :         /* Check persistent connections and do the necessary actions if needed. If persistent_helper is
    1277                 :          * unable to process a pconnection because of a refcount, the processing would happen from
    1278                 :          * np-destructor which is called when refcount goes to zero - php_oci_pconnection_list_np_dtor
    1279                 :          */
    1280           17651 :         zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
    1281                 : 
    1282           17651 :         if (OCI_G(edition)) {
    1283               0 :                 efree(OCI_G(edition));
    1284                 :         }
    1285                 : 
    1286           17651 :         return SUCCESS;
    1287                 : }
    1288                 : 
    1289                 : PHP_MINFO_FUNCTION(oci)
    1290              42 : {
    1291                 :         char buf[32];
    1292                 : 
    1293              42 :         php_info_print_table_start();
    1294              42 :         php_info_print_table_row(2, "OCI8 Support", "enabled");
    1295              42 :         php_info_print_table_row(2, "Version", PHP_OCI8_VERSION);
    1296              42 :         php_info_print_table_row(2, "Revision", "$Revision: 289264 $");
    1297                 : 
    1298              42 :         snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent));
    1299              42 :         php_info_print_table_row(2, "Active Persistent Connections", buf);
    1300              42 :         snprintf(buf, sizeof(buf), "%ld", OCI_G(num_links));
    1301              42 :         php_info_print_table_row(2, "Active Connections", buf);
    1302                 : 
    1303                 : #if !defined(PHP_WIN32) && !defined(HAVE_OCI_INSTANT_CLIENT)
    1304                 : #ifdef PHP_OCI8_ORACLE_VERSION
    1305              42 :         php_info_print_table_row(2, "Oracle Version", PHP_OCI8_ORACLE_VERSION);
    1306                 : #endif
    1307                 : #ifdef PHP_OCI8_DEF_DIR
    1308              42 :         php_info_print_table_row(2, "Compile-time ORACLE_HOME", PHP_OCI8_DEF_DIR);
    1309                 : #endif
    1310                 : #ifdef PHP_OCI8_DEF_SHARED_LIBADD
    1311              42 :         php_info_print_table_row(2, "Libraries Used", PHP_OCI8_DEF_SHARED_LIBADD);
    1312                 : #endif
    1313                 : #elif defined(HAVE_OCI_INSTANT_CLIENT) && defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
    1314                 :         snprintf(buf, sizeof(buf), "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION);
    1315                 :         php_info_print_table_row(2, "Oracle Instant Client Version", buf);
    1316                 : #endif
    1317                 : 
    1318              42 :         php_info_print_table_row(2, "Temporary Lob support", "enabled");
    1319              42 :         php_info_print_table_row(2, "Collections support", "enabled");
    1320              42 :         php_info_print_table_end();
    1321              42 :         DISPLAY_INI_ENTRIES();
    1322              42 : }
    1323                 : /* }}} */
    1324                 : 
    1325                 : /* list destructors {{{ */
    1326                 : 
    1327                 : /* {{{ php_oci_connection_list_dtor()
    1328                 :  *
    1329                 :  * Non-persistent connection destructor
    1330                 :  */
    1331                 : static void php_oci_connection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1332             295 : {
    1333             295 :         php_oci_connection *connection = (php_oci_connection *)entry->ptr;
    1334                 : 
    1335             295 :         if (connection) {
    1336             295 :                 php_oci_connection_close(connection TSRMLS_CC);
    1337             295 :                 OCI_G(num_links)--;
    1338                 :         }
    1339             295 : } /* }}} */
    1340                 : 
    1341                 : /* {{{ php_oci_pconnection_list_dtor()
    1342                 :  *
    1343                 :  * Persistent connection destructor
    1344                 :  */
    1345                 : static void php_oci_pconnection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1346              30 : {
    1347              30 :         php_oci_connection *connection = (php_oci_connection *)entry->ptr;
    1348                 : 
    1349              30 :         if (connection) {
    1350              30 :                 php_oci_connection_close(connection TSRMLS_CC);
    1351              30 :                 OCI_G(num_persistent)--;
    1352              30 :                 OCI_G(num_links)--;
    1353                 :         }
    1354              30 : } /* }}} */
    1355                 : 
    1356                 : /* {{{ php_oci_pconnection_list_np_dtor()
    1357                 :  *
    1358                 :  * Non-Persistent destructor for persistent connection - This gets invoked when
    1359                 :  * the refcount of this goes to zero in the regular list
    1360                 :  */
    1361                 : static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1362              38 : {
    1363              38 :         php_oci_connection *connection = (php_oci_connection *)entry->ptr;
    1364                 :         zend_rsrc_list_entry *le;
    1365                 : 
    1366                 :         /*
    1367                 :          * We cannot get connection as NULL or as a stub in this function. This is the function that
    1368                 :          * turns a pconnection to a stub
    1369                 :          *
    1370                 :          * If oci_password_change() changed the password of a persistent connection, close the
    1371                 :          * connection and remove it from the persistent connection cache.  This means subsequent scripts
    1372                 :          * will be prevented from being able to present the old (now invalid) password to a usable
    1373                 :          * connection to the database; they must use the new password.
    1374                 :          *
    1375                 :          * Check for conditions that warrant removal of the hash entry
    1376                 :          */
    1377                 : 
    1378              39 :         if (!connection->is_open ||
    1379                 :                 connection->passwd_changed ||
    1380                 :                 (PG(connection_status) & PHP_CONNECTION_TIMEOUT) ||
    1381                 :                 OCI_G(in_call)) {
    1382                 : 
    1383                 :                 /* Remove the hash entry if present */
    1384               2 :                 if ((zend_hash_find(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void **) &le)== SUCCESS) && (le->type == le_pconnection) && (le->ptr == connection)) {
    1385               1 :                         zend_hash_del(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1);
    1386                 :                 }
    1387                 :                 else {
    1388               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1389               0 :                         OCI_G(num_persistent)--;
    1390                 :                 }
    1391                 : 
    1392               1 :                 if (OCI_G(debug_mode)) {
    1393               0 :                         php_printf ("OCI8 DEBUG L1: np_dtor cleaning up: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    1394                 :                 }
    1395                 :         }
    1396                 :         else {
    1397                 :                 /*
    1398                 :                  * Release the connection to underlying pool.  We do this unconditionally so that
    1399                 :                  * out-of-scope pconnects are now consistent with oci_close and out-of-scope new connect
    1400                 :                  * semantics. With the PECL OCI 1.3.x extensions, we release pconnections when oci_close
    1401                 :                  * takes the refcount to zero.
    1402                 :                  *
    1403                 :                  * If oci_old_close_semantics is set, we artifically bump up the refcount and decremented
    1404                 :                  * only at request shutdown.
    1405                 :                  */
    1406              37 :                 php_oci_connection_release(connection TSRMLS_CC);
    1407                 : 
    1408              37 :                 if (OCI_G(debug_mode)) {
    1409               0 :                         php_printf ("OCI8 DEBUG L1: np_dtor releasing: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    1410                 :                 }
    1411                 :         }
    1412              38 : } /* }}} */
    1413                 : 
    1414                 : /* {{{ php_oci_statement_list_dtor()
    1415                 :  *
    1416                 :  * Statement destructor
    1417                 :  */
    1418                 : static void php_oci_statement_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1419           34030 : {
    1420           34030 :         php_oci_statement *statement = (php_oci_statement *)entry->ptr;
    1421           34030 :         php_oci_statement_free(statement TSRMLS_CC);
    1422           34030 : } /* }}} */
    1423                 : 
    1424                 : /* {{{ php_oci_descriptor_list_dtor()
    1425                 :  *
    1426                 :  *      Descriptor destructor
    1427                 :  */
    1428                 : static void php_oci_descriptor_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1429          183630 : {
    1430          183630 :         php_oci_descriptor *descriptor = (php_oci_descriptor *)entry->ptr;
    1431          183630 :         php_oci_lob_free(descriptor TSRMLS_CC);
    1432          183630 : } /* }}} */
    1433                 : 
    1434                 : /* {{{ php_oci_collection_list_dtor()
    1435                 :  *
    1436                 :  * Collection destructor
    1437                 :  */
    1438                 : static void php_oci_collection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    1439           70047 : {
    1440           70047 :         php_oci_collection *collection = (php_oci_collection *)entry->ptr;
    1441           70047 :         php_oci_collection_close(collection TSRMLS_CC);
    1442           70047 : } /* }}} */
    1443                 : 
    1444                 : /* }}} */
    1445                 : 
    1446                 : /* Hash Destructors {{{ */
    1447                 : 
    1448                 : /* {{{ php_oci_define_hash_dtor()
    1449                 :  *
    1450                 :  * Define hash destructor
    1451                 :  */
    1452                 : void php_oci_define_hash_dtor(void *data)
    1453           30020 : {
    1454           30020 :         php_oci_define *define = (php_oci_define *) data;
    1455                 : 
    1456           30020 :         zval_ptr_dtor(&define->zval);
    1457                 : 
    1458           30020 :         if (define->name) {
    1459           30020 :                 efree(define->name);
    1460           30020 :                 define->name = NULL;
    1461                 :         }
    1462           30020 : }
    1463                 : /* }}} */
    1464                 : 
    1465                 : /* {{{ php_oci_bind_hash_dtor()
    1466                 :  *
    1467                 :  * Bind hash destructor
    1468                 :  */
    1469                 : void php_oci_bind_hash_dtor(void *data)
    1470             332 : {
    1471             332 :         php_oci_bind *bind = (php_oci_bind *) data;
    1472                 : 
    1473             332 :         if (bind->array.elements) {
    1474              17 :                 efree(bind->array.elements);
    1475                 :         }
    1476                 : 
    1477             332 :         if (bind->array.element_lengths) {
    1478              17 :                 efree(bind->array.element_lengths);
    1479                 :         }
    1480                 : 
    1481             332 :         if (bind->array.indicators) {
    1482               8 :                 efree(bind->array.indicators);
    1483                 :         }
    1484                 : 
    1485             332 :         zval_ptr_dtor(&bind->zval);
    1486             332 : }
    1487                 : /* }}} */
    1488                 : 
    1489                 : /* {{{ php_oci_column_hash_dtor()
    1490                 :  *
    1491                 :  * Column hash destructor
    1492                 :  */
    1493                 : void php_oci_column_hash_dtor(void *data)
    1494           63240 : {
    1495           63240 :         php_oci_out_column *column = (php_oci_out_column *) data;
    1496                 :         TSRMLS_FETCH();
    1497                 : 
    1498           63240 :         if (column->stmtid) {
    1499            1408 :                 zend_list_delete(column->stmtid);
    1500                 :         }
    1501                 : 
    1502           63240 :         if (column->is_descr) {
    1503           60134 :                 zend_list_delete(column->descid);
    1504                 :         }
    1505                 : 
    1506           63240 :         if (column->data) {
    1507            1696 :                 efree(column->data);
    1508                 :         }
    1509                 : 
    1510           63240 :         if (column->name) {
    1511           63240 :                 efree(column->name);
    1512                 :         }
    1513           63240 : }
    1514                 : /* }}} */
    1515                 : 
    1516                 : /* {{{ php_oci_descriptor_flush_hash_dtor()
    1517                 :  *
    1518                 :  * Flush descriptors on commit
    1519                 :  */
    1520                 : void php_oci_descriptor_flush_hash_dtor(void *data)
    1521          183626 : {
    1522          183626 :         php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
    1523                 :         TSRMLS_FETCH();
    1524                 : 
    1525          183626 :         if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
    1526               1 :                 php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
    1527               1 :                 descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
    1528                 :         }
    1529          183626 :         data = NULL;
    1530          183626 : }
    1531                 : /* }}} */
    1532                 : 
    1533                 : /* {{{ php_oci_descriptor_delete_from_hash()
    1534                 :  *
    1535                 :  * Delete descriptor from the hash
    1536                 :  */
    1537                 : int php_oci_descriptor_delete_from_hash(void *data, void *id TSRMLS_DC)
    1538         2516248 : {
    1539         2516248 :         php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
    1540         2516248 :         int *desc_id = (int *) id;
    1541                 : 
    1542         2516248 :         if (descriptor && desc_id && descriptor->id == *desc_id) {
    1543          183575 :                 return 1;
    1544                 :         }
    1545         2332673 :         return 0;
    1546                 : }
    1547                 : /* }}} */
    1548                 : 
    1549                 : /* }}} */
    1550                 : 
    1551                 : /* {{{ php_oci_error()
    1552                 :  *
    1553                 :  * Fetch & print out error message if we get an error
    1554                 :  */
    1555                 : sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
    1556             253 : {
    1557             253 :         text *errbuf = (text *)NULL;
    1558             253 :         sb4 errcode = 0;
    1559                 : 
    1560             253 :         switch (status) {
    1561                 :                 case OCI_SUCCESS:
    1562               0 :                         break;
    1563                 :                 case OCI_SUCCESS_WITH_INFO:
    1564               1 :                         errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
    1565               1 :                         if (errbuf) {
    1566               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf);
    1567               1 :                                 efree(errbuf);
    1568                 :                         } else {
    1569               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: failed to fetch error message");
    1570                 :                         }
    1571               1 :                         break;
    1572                 :                 case OCI_NEED_DATA:
    1573               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NEED_DATA");
    1574               0 :                         break;
    1575                 :                 case OCI_NO_DATA:
    1576               3 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA");
    1577               3 :                         errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
    1578               3 :                         if (errbuf) {
    1579               3 :                                 efree(errbuf);
    1580                 :                         } else {
    1581               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA: failed to fetch error message");
    1582                 :                         }
    1583               3 :                         break;
    1584                 :                 case OCI_ERROR:
    1585             246 :                         errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
    1586             246 :                         if (errbuf) {
    1587             246 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf);
    1588             246 :                                 efree(errbuf);
    1589                 :                         } else {
    1590               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to fetch error message");
    1591                 :                         }
    1592             246 :                         break;
    1593                 :                 case OCI_INVALID_HANDLE:
    1594               3 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_INVALID_HANDLE");
    1595               3 :                         break;
    1596                 :                 case OCI_STILL_EXECUTING:
    1597               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_STILL_EXECUTING");
    1598               0 :                         break;
    1599                 :                 case OCI_CONTINUE:
    1600               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE");
    1601               0 :                         break;
    1602                 :                 default:
    1603               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", status);
    1604                 :                         break;
    1605                 :         }
    1606             253 :         return errcode;
    1607                 : }
    1608                 : /* }}} */
    1609                 : 
    1610                 : /* {{{ php_oci_fetch_errmsg()
    1611                 :  *
    1612                 :  * Fetch error message into the buffer from the error handle provided
    1613                 :  */
    1614                 : sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC)
    1615             305 : {
    1616             305 :         sb4 error_code = 0;
    1617                 :         text err_buf[PHP_OCI_ERRBUF_LEN];
    1618                 : 
    1619             305 :         err_buf[0] = '\0';
    1620                 : 
    1621             305 :         memset(err_buf, 0, sizeof(err_buf));
    1622             305 :         PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, err_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR));
    1623                 : 
    1624             305 :         if (error_code) {
    1625             305 :                 int err_buf_len = strlen((char *)err_buf);
    1626                 : 
    1627             305 :                 if (err_buf_len && err_buf[err_buf_len - 1] == '\n') {
    1628             301 :                         err_buf[err_buf_len - 1] = '\0';
    1629                 :                 }
    1630             305 :                 if (err_buf_len && error_buf) {
    1631             305 :                         *error_buf = NULL;
    1632             305 :                         *error_buf = (text *)estrndup((char *)err_buf, err_buf_len);
    1633                 :                 }
    1634                 :         }
    1635             305 :         return error_code;
    1636                 : } /* }}} */
    1637                 : 
    1638                 : /* {{{ php_oci_fetch_sqltext_offset()
    1639                 :  *
    1640                 :  * Compute offset in the SQL statement
    1641                 :  */
    1642                 : int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset TSRMLS_DC)
    1643              34 : {
    1644              34 :         *sqltext = NULL;
    1645              34 :         *error_offset = 0;
    1646                 : 
    1647              34 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *) sqltext, (ub4 *)0, OCI_ATTR_STATEMENT, statement->err));
    1648                 : 
    1649              34 :         if (statement->errcode != OCI_SUCCESS) {
    1650               0 :                 statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1651               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1652               0 :                 return 1;
    1653                 :         }
    1654                 : 
    1655              34 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)error_offset, (ub4 *)0, OCI_ATTR_PARSE_ERROR_OFFSET, statement->err));
    1656                 : 
    1657              34 :         if (statement->errcode != OCI_SUCCESS) {
    1658               0 :                 statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1659               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1660               0 :                 return 1;
    1661                 :         }
    1662              34 :         return 0;
    1663                 : } /* }}} */
    1664                 : 
    1665                 : /* {{{ php_oci_do_connect()
    1666                 :  *
    1667                 :  * Connect wrapper
    1668                 :  */
    1669                 : void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive)
    1670             405 : {
    1671                 :         php_oci_connection *connection;
    1672                 :         char *username, *password;
    1673             405 :         char *dbname = NULL, *charset = NULL;
    1674             405 :         int username_len = 0, password_len = 0;
    1675             405 :         int dbname_len = 0, charset_len = 0;
    1676             405 :         long session_mode = OCI_DEFAULT;
    1677                 : 
    1678                 :         /* if a fourth parameter is handed over, it is the charset identifier (but is only used in Oracle 9i+) */
    1679             405 :         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) {
    1680               5 :                 return;
    1681                 :         }
    1682                 : 
    1683             400 :         if (!charset_len) {
    1684             390 :                 charset = NULL;
    1685                 :         }
    1686                 : 
    1687             400 :         connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC);
    1688                 : 
    1689             400 :         if (!connection) {
    1690              48 :                 RETURN_FALSE;
    1691                 :         }
    1692             352 :         RETURN_RESOURCE(connection->rsrc_id);
    1693                 : 
    1694                 : } /* }}} */
    1695                 : 
    1696                 : /* {{{ php_oci_do_connect_ex()
    1697                 :  *
    1698                 :  * The real connect function. Allocates all the resources needed, establishes the connection and
    1699                 :  * returns the result handle (or NULL)
    1700                 :  */
    1701                 : 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)
    1702             404 : {
    1703                 :         zend_rsrc_list_entry *le;
    1704                 :         zend_rsrc_list_entry new_le;
    1705             404 :         php_oci_connection *connection = NULL;
    1706             404 :         smart_str hashed_details = {0};
    1707                 :         time_t timestamp;
    1708             404 :         php_oci_spool *session_pool = NULL;
    1709             404 :         zend_bool use_spool = 1;           /* Default is to use client-side session pool */
    1710             404 :         zend_bool ping_done = 0;
    1711                 : 
    1712             404 :         ub2 charsetid = 0;
    1713             404 :         ub2 charsetid_nls_lang = 0;
    1714                 : 
    1715             404 :         if (session_mode & ~(OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) {
    1716               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid session mode specified (%ld)", session_mode);
    1717               2 :                 return NULL;
    1718                 :         }
    1719             402 :         if (session_mode & (OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) {
    1720              42 :                 if ((session_mode & OCI_SYSOPER) && (session_mode & OCI_SYSDBA)) {
    1721               6 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SYSDBA and OCI_SYSOPER cannot be used together");
    1722               6 :                         return NULL;
    1723                 :                 }
    1724              36 :                 if (session_mode & PHP_OCI_CRED_EXT) {
    1725                 : #ifdef PHP_WIN32
    1726                 :                         /* Disable external authentication on Windows as Impersonation is not yet handled.
    1727                 :                          * TODO: Re-enable this once OCI provides capability.
    1728                 :                          */
    1729                 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "External Authentication is not supported on Windows");
    1730                 :                         return NULL;
    1731                 : #endif
    1732              24 :                         if (username_len != 1 || username[0] != '/' || password_len != 0) {
    1733              12 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CRED_EXT can only be used with a username of \"/\" and a NULL password");
    1734              12 :                                 return NULL;
    1735                 :                         }
    1736                 :                 }
    1737              24 :                 if (session_mode & (OCI_SYSOPER | OCI_SYSDBA)) {
    1738                 :                         /* Increase security by not caching privileged oci_pconnect() connections. The
    1739                 :                          * connection becomes equivalent to oci_connect() or oci_new_connect().
    1740                 :                          */
    1741              18 :                         persistent = 0;
    1742              18 :                         if (!OCI_G(privileged_connect)) {
    1743               2 :                                 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");
    1744               2 :                                 return NULL;
    1745                 :                         }
    1746                 :                         /*      Disable privileged connections in Safe Mode (N.b. safe mode has been removed in PHP
    1747                 :                          *      6 anyway)
    1748                 :                          */
    1749              16 :                         if (PG(safe_mode)) {
    1750               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Privileged connect is disabled in Safe Mode");
    1751               1 :                                 return NULL;
    1752                 :                         }
    1753                 :                 }
    1754                 :         }
    1755                 : 
    1756                 :         /* Initialize global handles if they weren't initialized before */
    1757             381 :         if (OCI_G(env) == NULL) {
    1758             261 :                 php_oci_init_global_handles(TSRMLS_C);
    1759             261 :                 if (OCI_G(env) == NULL) {
    1760               3 :                         return NULL;
    1761                 :                 }
    1762                 :         }
    1763                 : 
    1764                 :         /* We cannot use the new session create logic (OCISessionGet from
    1765                 :          * client-side session pool) when privileged connect or password
    1766                 :          * change is attempted or OCI_CRED_EXT mode is specified.
    1767                 :          * TODO: Re-enable this when OCI provides support.
    1768                 :          */
    1769             378 :         if ((session_mode & (OCI_SYSOPER | OCI_SYSDBA | PHP_OCI_CRED_EXT)) || (new_password_len)) {
    1770              25 :                 use_spool = 0;
    1771                 :         }
    1772                 : 
    1773             378 :         smart_str_appendl_ex(&hashed_details, "oci8***", sizeof("oci8***") - 1, 0);
    1774             378 :         smart_str_appendl_ex(&hashed_details, username, username_len, 0);
    1775             378 :         smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
    1776                 : 
    1777                 :         /* DRCP: connection_class is an attribute of a connection */
    1778             378 :         if (OCI_G(connection_class)){
    1779             378 :                 smart_str_appendl_ex(&hashed_details, OCI_G(connection_class), strlen(OCI_G(connection_class)), 0);
    1780                 :         }
    1781             378 :         smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
    1782                 : 
    1783                 :         /* Add edition attribute to the hash */
    1784             378 :         if (OCI_G(edition)){
    1785               0 :                 smart_str_appendl_ex(&hashed_details, OCI_G(edition), strlen(OCI_G(edition)), 0);
    1786                 :         }
    1787             378 :         smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
    1788                 : 
    1789             378 :         if (password_len) {
    1790                 :                 ulong password_hash;
    1791             364 :                 password_hash = zend_inline_hash_func(password, password_len);
    1792             364 :                 smart_str_append_unsigned_ex(&hashed_details, password_hash, 0);
    1793                 :         }
    1794             378 :         smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
    1795                 : 
    1796             378 :         if (dbname) {
    1797             378 :                 smart_str_appendl_ex(&hashed_details, dbname, dbname_len, 0);
    1798                 :         }
    1799             378 :         smart_str_appendl_ex(&hashed_details, "**", sizeof("**") - 1, 0);
    1800                 : 
    1801             378 :         if (charset && *charset) {
    1802               9 :                 PHP_OCI_CALL_RETURN(charsetid, OCINlsCharSetNameToId, (OCI_G(env), (CONST oratext *)charset));
    1803               9 :                 if (!charsetid) {
    1804               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid character set name: %s", charset);
    1805                 :                 } else {
    1806               7 :                         smart_str_append_unsigned_ex(&hashed_details, charsetid, 0);
    1807                 :                 }
    1808                 :         }
    1809                 : 
    1810                 :         /* use NLS_LANG if no or invalid charset specified */
    1811             378 :         if (!charsetid) {
    1812             371 :                 size_t rsize = 0;
    1813                 :                 sword result;
    1814                 : 
    1815             371 :                 PHP_OCI_CALL_RETURN(result, OCINlsEnvironmentVariableGet, (&charsetid_nls_lang, 0, OCI_NLS_CHARSET_ID, 0, &rsize));
    1816             371 :                 if (result != OCI_SUCCESS) {
    1817               0 :                         charsetid_nls_lang = 0;
    1818                 :                 }
    1819             371 :                 smart_str_append_unsigned_ex(&hashed_details, charsetid_nls_lang, 0);
    1820                 :         }
    1821                 : 
    1822             378 :         timestamp = time(NULL);
    1823                 : 
    1824             378 :         smart_str_append_unsigned_ex(&hashed_details, session_mode, 0);
    1825             378 :         smart_str_0(&hashed_details);
    1826                 : 
    1827                 :         /* make it lowercase */
    1828             378 :         php_strtolower(hashed_details.c, hashed_details.len);
    1829                 : 
    1830             378 :         if (!exclusive && !new_password) {
    1831             336 :                 zend_bool found = 0;
    1832                 : 
    1833             350 :                 if (persistent && zend_hash_find(&EG(persistent_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
    1834              14 :                         found = 1;
    1835                 :                         /* found */
    1836              14 :                         if (le->type == le_pconnection) {
    1837              14 :                                 connection = (php_oci_connection *)le->ptr;
    1838                 :                         }
    1839             322 :                 } else if (!persistent && zend_hash_find(&EG(regular_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
    1840              24 :                         found = 1;
    1841              24 :                         if (le->type == le_index_ptr) {
    1842                 :                                 int type, link;
    1843                 :                                 void *ptr;
    1844                 : 
    1845              24 :                                 link = (int) le->ptr;
    1846              24 :                                 ptr = zend_list_find(link,&type);
    1847              24 :                                 if (ptr && (type == le_connection)) {
    1848              17 :                                         connection = (php_oci_connection *)ptr;
    1849                 :                                 }
    1850                 :                         }
    1851                 :                 }
    1852                 : 
    1853                 :                 /* Debug statements {{{ */
    1854             336 :                 if (OCI_G(debug_mode)) {
    1855               0 :                         if (connection && connection->is_stub) {
    1856               0 :                                 php_printf ("OCI8 DEBUG L1: Got a cached stub: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    1857               0 :                         } else if (connection) {
    1858               0 :                                 php_printf ("OCI8 DEBUG L1: Got a cached connection: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    1859                 :                         } else {
    1860               0 :                                 php_printf ("OCI8 DEBUG L1: Got NO cached connection at (%s:%d) \n", __FILE__, __LINE__);
    1861                 :                         }
    1862                 :                 } /* }}} */
    1863                 : 
    1864                 :                 /* If we got a pconnection stub, then 'load'(OCISessionGet) the real connection from its
    1865                 :                  * private spool A connection is a stub if it is only a cached structure and the real
    1866                 :                  * connection is released to its underlying private session pool.  We currently do not have
    1867                 :                  * stub support for non-persistent conns.
    1868                 :                  *
    1869                 :                  * TODO: put in negative code for non-persistent stubs
    1870                 :                  */
    1871             336 :                 if (connection && connection->is_persistent && connection->is_stub) {
    1872               8 :                         if (php_oci_create_session(connection, NULL, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
    1873               0 :                                 smart_str_free_ex(&hashed_details, 0);
    1874               0 :                                 zend_hash_del(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1);
    1875                 : 
    1876               0 :                                 return NULL;
    1877                 :                         }
    1878                 :                         /* We do the ping in php_oci_create_session, no need to ping again below */
    1879               8 :                         ping_done = 1;
    1880                 :                 }
    1881                 : 
    1882             336 :                 if (connection) {
    1883              31 :                         if (connection->is_open) {
    1884                 :                                 /* found an open connection. now ping it */
    1885              31 :                                 if (connection->is_persistent) {
    1886                 :                                         int rsrc_type;
    1887                 : 
    1888                 :                                         /* Check connection liveness in the following order:
    1889                 :                                          * 1) always check OCI_ATTR_SERVER_STATUS
    1890                 :                                          * 2) see if it's time to ping it
    1891                 :                                          * 3) ping it if needed
    1892                 :                                          */
    1893              14 :                                         if (php_oci_connection_status(connection TSRMLS_CC)) {
    1894                 :                                                 /* Only ping if:
    1895                 :                                                  *
    1896                 :                                                  * 1) next_ping > 0, which means that ping_interval is not -1 (aka "Off")
    1897                 :                                                  *
    1898                 :                                                  * 2) current_timestamp > next_ping, which means "it's time to check if it's
    1899                 :                                                  * still alive"
    1900                 :                                                  */
    1901              14 :                                                 if (!ping_done && (*(connection->next_pingp) > 0) && (timestamp >= *(connection->next_pingp)) && !php_oci_connection_ping(connection TSRMLS_CC)) {
    1902                 :                                                         /* server died */
    1903                 :                                                 } else {
    1904                 :                                                         php_oci_connection *tmp;
    1905                 : 
    1906                 :                                                         /* okay, the connection is open and the server is still alive */
    1907              14 :                                                         connection->used_this_request = 1;
    1908              14 :                                                         tmp = (php_oci_connection *)zend_list_find(connection->rsrc_id, &rsrc_type);
    1909                 : 
    1910              14 :                                                         if (tmp != NULL && rsrc_type == le_pconnection && strlen(tmp->hash_key) == hashed_details.len &&
    1911                 :                                                                 memcmp(tmp->hash_key, hashed_details.c, hashed_details.len) == 0 && zend_list_addref(connection->rsrc_id) == SUCCESS) {
    1912                 :                                                                 /* do nothing */
    1913                 :                                                         } else {
    1914               8 :                                                                 connection->rsrc_id = zend_list_insert(connection, le_pconnection);
    1915                 :                                                                 /* Persistent connections: For old close semantics we artificially
    1916                 :                                                                  * bump up the refcount to prevent the non-persistent destructor
    1917                 :                                                                  * from getting called until request shutdown. The refcount is
    1918                 :                                                                  * decremented in the persistent helper
    1919                 :                                                                  */
    1920               8 :                                                                 if (OCI_G(old_oci_close_semantics)) {
    1921               0 :                                                                         zend_list_addref(connection->rsrc_id);
    1922                 :                                                                 }
    1923                 :                                                         }
    1924              14 :                                                         smart_str_free_ex(&hashed_details, 0);
    1925              14 :                                                         return connection;
    1926                 :                                                 }
    1927                 :                                         }
    1928                 :                                         /* server died */
    1929                 :                                 } else {
    1930                 :                                         /* we do not ping non-persistent connections */
    1931              17 :                                         smart_str_free_ex(&hashed_details, 0);
    1932              17 :                                         zend_list_addref(connection->rsrc_id);
    1933              17 :                                         return connection;
    1934                 :                                 }
    1935                 :                         } /* is_open is true? */
    1936                 : 
    1937                 :                         /* Server died - connection not usable. The is_open=true can also fall through to here,
    1938                 :                          * if ping fails
    1939                 :                          */
    1940               0 :                         if (persistent){
    1941                 :                                 int rsrc_type;
    1942                 : 
    1943               0 :                                 connection->is_open = 0;
    1944               0 :                                 connection->used_this_request = 1;
    1945                 : 
    1946                 :                                 /* We have to do a hash_del but need to preserve the resource if there is a positive
    1947                 :                                  * refcount. Set the data pointer in the list entry to NULL
    1948                 :                                  */
    1949               0 :                                 if (connection == zend_list_find(connection->rsrc_id, &rsrc_type) && rsrc_type == le_pconnection) {
    1950               0 :                                         le->ptr = NULL;
    1951                 :                                 }
    1952                 : 
    1953               0 :                                 zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
    1954                 :                         } else {
    1955                 :                                 /* We only remove the hash entry. The resource and the list entry with its pointer
    1956                 :                                  * to the resource are still intact
    1957                 :                                  */
    1958               0 :                                 zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
    1959                 :                         }
    1960                 : 
    1961               0 :                         connection = NULL;
    1962             305 :                 } else if (found) {
    1963                 :                         /* found something, but it's not a connection, delete it */
    1964               7 :                         if (persistent) {
    1965               0 :                                 zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
    1966                 :                         } else {
    1967               7 :                                 zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
    1968                 :                         }
    1969                 :                 }
    1970                 :         }
    1971                 : 
    1972                 :         /* Check if we have reached max_persistent. If so, try to remove a few timed-out connections. As
    1973                 :          * a last resort, return a non-persistent connection.
    1974                 :          */
    1975             347 :         if (persistent) {
    1976              32 :                 zend_bool alloc_non_persistent = 0;
    1977                 : 
    1978              32 :                 if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
    1979                 :                         /* try to find an idle connection and kill it */
    1980               0 :                         zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
    1981                 : 
    1982               0 :                         if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
    1983                 :                                 /* all persistent connactions are in use, fallback to non-persistent connection creation */
    1984               0 :                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Too many open persistent connections (%ld)", OCI_G(num_persistent));
    1985               0 :                                 alloc_non_persistent = 1;
    1986                 :                         }
    1987                 :                 }
    1988                 : 
    1989              32 :                 if (alloc_non_persistent) {
    1990               0 :                         connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
    1991               0 :                         connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
    1992               0 :                         connection->is_persistent = 0;
    1993                 :                 } else {
    1994              32 :                         connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection));
    1995              32 :                         connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len);
    1996              32 :                         connection->is_persistent = 1;
    1997                 :                 }
    1998                 :         } else {
    1999             315 :                 connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
    2000             315 :                 connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
    2001             315 :                 connection->is_persistent = 0;
    2002                 :         }
    2003                 : 
    2004                 :         /* {{{ Get the session pool that suits this connection request from the persistent list. This
    2005                 :          * step is only for non-persistent connections as persistent connections have private session
    2006                 :          * pools. Non-persistent conns use shared session pool to allow for optimizations such as
    2007                 :          * caching the physical connection (for DRCP) even when the non-persistent php connection is
    2008                 :          * destroyed.
    2009                 :          *
    2010                 :          * TODO: Unconditionally do this once OCI provides extended OCISessionGet capability
    2011                 :          */
    2012             347 :         if (use_spool && !connection->is_persistent) {
    2013             292 :                 if ((session_pool = php_oci_get_spool(username, username_len, password, password_len, dbname, dbname_len, charsetid ? charsetid:charsetid_nls_lang TSRMLS_CC))==NULL)
    2014                 :                 {
    2015               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    2016               0 :                         smart_str_free_ex(&hashed_details, 0);
    2017               0 :                         return NULL;
    2018                 :                 }
    2019                 :         } /* }}} */
    2020                 : 
    2021             347 :         connection->idle_expiry = (OCI_G(persistent_timeout) > 0) ? (timestamp + OCI_G(persistent_timeout)) : 0;
    2022                 : 
    2023                 :         /* Mark password as unchanged by PHP during the duration of the database session */
    2024             347 :         connection->passwd_changed = 0;
    2025                 : 
    2026             347 :         smart_str_free_ex(&hashed_details, 0);
    2027                 : 
    2028             347 :         if (charsetid) {
    2029               7 :                 connection->charset = charsetid;
    2030                 :         } else {
    2031             340 :                 connection->charset = charsetid_nls_lang;
    2032                 :         }
    2033                 : 
    2034                 :         /* Old session creation semantics when session pool cannot be used Eg: privileged
    2035                 :          * connect/password change
    2036                 :          */
    2037             347 :         if (!use_spool) {
    2038              25 :                 if (php_oci_old_create_session(connection, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
    2039              21 :                         php_oci_connection_close(connection TSRMLS_CC);
    2040              21 :                         return NULL;
    2041                 :                 }
    2042                 :         } else {
    2043                 :                 /* create using the client-side session pool */
    2044             322 :                 if (php_oci_create_session(connection, session_pool, dbname, dbname_len, username, username_len, password, password_len, new_password, new_password_len, session_mode TSRMLS_CC)) {
    2045               1 :                         php_oci_connection_close(connection TSRMLS_CC);
    2046               1 :                         return NULL;
    2047                 :                 }
    2048                 :         }
    2049                 : 
    2050                 :         /* Mark it as open */
    2051             325 :         connection->is_open = 1;
    2052                 : 
    2053                 :         /* add to the appropriate hash */
    2054             325 :         if (connection->is_persistent) {
    2055              30 :                 new_le.ptr = connection;
    2056              30 :                 new_le.type = le_pconnection;
    2057              30 :                 connection->used_this_request = 1;
    2058              30 :                 connection->rsrc_id = zend_list_insert(connection, le_pconnection);
    2059                 : 
    2060                 :                 /* Persistent connections: For old close semantics we artificially bump up the refcount to
    2061                 :                  * prevent the non-persistent destructor from getting called until request shutdown. The
    2062                 :                  * refcount is decremented in the persistent helper
    2063                 :                  */
    2064              30 :                 if (OCI_G(old_oci_close_semantics)) {
    2065               4 :                         zend_list_addref(connection->rsrc_id);
    2066                 :                 }
    2067              30 :                 zend_hash_update(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
    2068              30 :                 OCI_G(num_persistent)++;
    2069              30 :                 OCI_G(num_links)++;
    2070             295 :         } else if (!exclusive) {
    2071             263 :                 connection->rsrc_id = zend_list_insert(connection, le_connection);
    2072             263 :                 new_le.ptr = (void *)connection->rsrc_id;
    2073             263 :                 new_le.type = le_index_ptr;
    2074             263 :                 zend_hash_update(&EG(regular_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
    2075             263 :                 OCI_G(num_links)++;
    2076                 :         } else {
    2077              32 :                 connection->rsrc_id = zend_list_insert(connection, le_connection);
    2078              32 :                 OCI_G(num_links)++;
    2079                 :         }
    2080                 : 
    2081                 :         /* Debug statements {{{ */
    2082             325 :         if (OCI_G(debug_mode)) {
    2083               0 :                 if (connection->is_persistent) {
    2084               0 :                         php_printf ("OCI8 DEBUG L1: New Persistent Connection address: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    2085                 :                 } else {
    2086               0 :                         php_printf ("OCI8 DEBUG L1: New Non-Persistent Connection address: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__);
    2087                 :                 }
    2088               0 :                 php_printf ("OCI8 DEBUG L1: num_persistent=(%ld), num_links=(%ld) at (%s:%d) \n", OCI_G(num_persistent), OCI_G(num_links), __FILE__, __LINE__);
    2089                 :         } /* }}} */
    2090                 : 
    2091             325 :         return connection;
    2092                 : }
    2093                 : /* }}} */
    2094                 : 
    2095                 : /* {{{ php_oci_connection_ping()
    2096                 :  *
    2097                 :  * Ping connection. Uses OCIPing() or OCIServerVersion() depending on the Oracle Client version
    2098                 :  */
    2099                 : static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
    2100               1 : {
    2101                 :         /* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
    2102                 :          * such as from Pre-10.1 servers, the error is still from the server and we would have
    2103                 :          * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
    2104                 :          * Pre-10.2 clients
    2105                 :          */
    2106                 : #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIPing available 10.2 onwards */
    2107               1 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
    2108                 : #else
    2109                 :         char version[256];
    2110                 :         /* use good old OCIServerVersion() */
    2111                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX));
    2112                 : #endif
    2113                 : 
    2114               1 :         if (OCI_G(errcode) == OCI_SUCCESS) {
    2115               1 :                 return 1;
    2116                 :         } else {
    2117               0 :                 sb4 error_code = 0;
    2118                 :                 text tmp_buf[PHP_OCI_ERRBUF_LEN];
    2119                 : 
    2120                 :                 /* Treat ORA-1010 as a successful Ping */
    2121               0 :                 OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
    2122               0 :                 if (error_code == 1010) {
    2123               0 :                         return 1;
    2124                 :                 }
    2125                 :         }
    2126                 : 
    2127                 :         /* ignore errors here, just return failure
    2128                 :          * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
    2129               0 :         return 0;
    2130                 : }
    2131                 : /* }}} */
    2132                 : 
    2133                 : /* {{{ php_oci_connection_status()
    2134                 :  *
    2135                 :  * Check connection status (pre-ping check)
    2136                 :  */
    2137                 : static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
    2138              14 : {
    2139              14 :         ub4 ss = 0;
    2140                 : 
    2141                 :         /* get OCI_ATTR_SERVER_STATUS */
    2142              14 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err)));
    2143                 : 
    2144              14 :         if (OCI_G(errcode) == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
    2145              14 :                 return 1;
    2146                 :         }
    2147                 : 
    2148                 :         /* ignore errors here, just return failure
    2149                 :          * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
    2150               0 :         return 0;
    2151                 : }
    2152                 : /* }}} */
    2153                 : 
    2154                 : /* {{{ php_oci_connection_rollback()
    2155                 :  *
    2156                 :  * Rollback connection
    2157                 :  */
    2158                 : int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
    2159              36 : {
    2160              36 :         PHP_OCI_CALL_RETURN(connection->errcode, OCITransRollback, (connection->svc, connection->err, (ub4) 0));
    2161              36 :         connection->needs_commit = 0;
    2162                 : 
    2163              36 :         if (connection->errcode != OCI_SUCCESS) {
    2164               0 :                 connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    2165               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    2166               0 :                 return 1;
    2167                 :         }
    2168              36 :         return 0;
    2169                 : } /* }}} */
    2170                 : 
    2171                 : /* {{{ php_oci_connection_commit()
    2172                 :  *
    2173                 :  * Commit connection
    2174                 :  */
    2175                 : int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
    2176              83 : {
    2177              83 :         PHP_OCI_CALL_RETURN(connection->errcode, OCITransCommit, (connection->svc, connection->err, (ub4) 0));
    2178              83 :         connection->needs_commit = 0;
    2179                 : 
    2180              83 :         if (connection->errcode != OCI_SUCCESS) {
    2181               0 :                 connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    2182               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    2183               0 :                 return 1;
    2184                 :         }
    2185              83 :         return 0;
    2186                 : } /* }}} */
    2187                 : 
    2188                 : /* {{{ php_oci_connection_close()
    2189                 :  *
    2190                 :  * Close the connection and free all its resources
    2191                 :  */
    2192                 : static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC)
    2193             347 : {
    2194             347 :         int result = 0;
    2195             347 :         zend_bool in_call_save = OCI_G(in_call);
    2196                 : 
    2197             347 :         if (!connection->is_stub) {
    2198                 :                 /* Release resources associated with connection */
    2199             318 :                 php_oci_connection_release(connection TSRMLS_CC);
    2200                 :         }
    2201                 : 
    2202             347 :         if (!connection->using_spool && connection->svc) {
    2203              11 :                         PHP_OCI_CALL(OCISessionEnd, (connection->svc, connection->err, connection->session, (ub4) 0));
    2204                 :         }
    2205                 : 
    2206             347 :         if (connection->err) {
    2207             333 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR));
    2208                 :         }
    2209             347 :         if (connection->authinfo) {
    2210             322 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->authinfo, (ub4) OCI_HTYPE_AUTHINFO));
    2211                 :         }
    2212                 : 
    2213                 :         /* No Handlefrees for session pool connections */
    2214             347 :         if (!connection->using_spool) {
    2215              25 :                 if (connection->session) {
    2216              11 :                         PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->session, OCI_HTYPE_SESSION));
    2217                 :                 }
    2218                 : 
    2219              25 :                 if (connection->is_attached) {
    2220              11 :                         PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT));
    2221                 :                 }
    2222                 : 
    2223              25 :                 if (connection->svc) {
    2224              11 :                         PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc,      (ub4) OCI_HTYPE_SVCCTX));
    2225                 :                 }
    2226                 : 
    2227              25 :                 if (connection->server) {
    2228              25 :                         PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER));
    2229                 :                 }
    2230                 : 
    2231              25 :                 if (connection->env) {
    2232              25 :                         PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV));
    2233                 :                 }
    2234             322 :         } else if (connection->private_spool) {
    2235                 :         /* Keep this as the last member to be freed, as there are dependencies
    2236                 :          * (like env) on the session pool
    2237                 :          */
    2238              30 :                 php_oci_spool_close(connection->private_spool TSRMLS_CC);
    2239                 :         }
    2240                 : 
    2241             347 :         if (connection->is_persistent) {
    2242              32 :                 if (connection->hash_key) {
    2243              32 :                         free(connection->hash_key);
    2244                 :                 }
    2245              32 :                 free(connection);
    2246                 :         } else {
    2247             315 :                 if (connection->hash_key) {
    2248             315 :                         efree(connection->hash_key);
    2249                 :                 }
    2250             315 :                 efree(connection);
    2251                 :         }
    2252             347 :         connection = NULL;
    2253             347 :         OCI_G(in_call) = in_call_save;
    2254             347 :         return result;
    2255                 : } /* }}} */
    2256                 : 
    2257                 : /* {{{ php_oci_connection_release()
    2258                 :  *
    2259                 :  * Release the connection's resources. This involves freeing descriptors and rolling back
    2260                 :  * transactions, setting timeout-related parameters etc. For session-pool using connections, the
    2261                 :  * underlying connection is released to its session pool.
    2262                 :  */
    2263                 : int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC)
    2264             355 : {
    2265             355 :         int result = 0;
    2266             355 :         zend_bool in_call_save = OCI_G(in_call);
    2267             355 :         time_t timestamp = time(NULL);
    2268                 : 
    2269             355 :         if (connection->is_stub) {
    2270               0 :                 return 0;
    2271                 :         }
    2272                 : 
    2273             355 :         if (connection->descriptors) {
    2274              69 :                 zend_hash_destroy(connection->descriptors);
    2275              69 :                 efree(connection->descriptors);
    2276              69 :                 connection->descriptors = NULL;
    2277                 :         }
    2278                 : 
    2279             355 :         if (connection->svc) {
    2280                 :                 /* rollback outstanding transactions */
    2281             340 :                 if (connection->needs_commit) {
    2282              32 :                         if (php_oci_connection_rollback(connection TSRMLS_CC)) {
    2283                 :                                 /* rollback failed */
    2284               0 :                                 result = 1;
    2285                 :                         }
    2286                 :                 }
    2287                 :         }
    2288                 : 
    2289             355 :         if (OCI_G(persistent_timeout) > 0) {
    2290               0 :                 connection->idle_expiry = timestamp + OCI_G(persistent_timeout);
    2291                 :         }
    2292                 : 
    2293                 :         /* We may have half-cooked connections to clean up */
    2294             355 :         if (connection->next_pingp) {
    2295             333 :                 if (OCI_G(ping_interval) >= 0) {
    2296             333 :                         *(connection->next_pingp) = timestamp + OCI_G(ping_interval);
    2297                 :                 } else {
    2298                 :                         /* ping_interval is -1 */
    2299               0 :                         *(connection->next_pingp) = 0;
    2300                 :                 }
    2301                 :         }
    2302                 : 
    2303                 :         /* Release the session (stubs are filtered out at the beginning)*/
    2304             355 :         if (connection->using_spool) {
    2305             330 :                 ub4 rlsMode = OCI_DEFAULT;
    2306                 : 
    2307             330 :                 if (result) {
    2308               0 :                         rlsMode |= OCI_SESSRLS_DROPSESS;
    2309                 :                 }
    2310                 : 
    2311                 :                 /* Sessions for non-persistent connections should be dropped.  For 11 and above, the session
    2312                 :                  * pool has its own mechanism for doing so for purity NEW connections. We need to do so
    2313                 :                  * explicitly for 10.2 and earlier.
    2314                 :                  */
    2315                 : #if (!(OCI_MAJOR_VERSION >= 11))
    2316             330 :                 if (!connection->is_persistent) {
    2317             292 :                         rlsMode |= OCI_SESSRLS_DROPSESS;
    2318                 :                 }
    2319                 : #endif
    2320                 : 
    2321             330 :                 if (connection->svc) {
    2322             329 :                         PHP_OCI_CALL(OCISessionRelease, (connection->svc, connection->err, NULL,
    2323                 :                                                                                  0, rlsMode));
    2324                 :                 }
    2325                 :                 /* It no longer has relation with the database session. However authinfo and env are
    2326                 :                  * cached
    2327                 :                  */
    2328             330 :                 connection->svc = NULL;
    2329             330 :                 connection->server = NULL;
    2330             330 :                 connection->session = NULL;
    2331                 : 
    2332             330 :                 connection->is_attached = connection->is_open = connection->needs_commit = connection->used_this_request = 0;
    2333             330 :                 connection->is_stub = 1;
    2334                 : 
    2335                 :                 /* Cut the link between the connection structure and the time_t structure allocated within
    2336                 :                  * the OCI session
    2337                 :                  */
    2338             330 :                 connection->next_pingp = NULL;
    2339                 :         }
    2340                 : 
    2341             355 :         OCI_G(in_call) = in_call_save;
    2342             355 :         return result;
    2343                 : } /* }}} */
    2344                 : 
    2345                 : /* {{{ php_oci_password_change()
    2346                 :  *
    2347                 :  * Change password for the user with the username given
    2348                 :  */
    2349                 : 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)
    2350               2 : {
    2351               2 :         PHP_OCI_CALL_RETURN(connection->errcode, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT));
    2352                 : 
    2353               2 :         if (connection->errcode != OCI_SUCCESS) {
    2354               0 :                 connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    2355               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    2356               0 :                 return 1;
    2357                 :         }
    2358               2 :         connection->passwd_changed = 1;
    2359               2 :         return 0;
    2360                 : } /* }}} */
    2361                 : 
    2362                 : /* {{{ php_oci_server_get_version()
    2363                 :  *
    2364                 :  * Get Oracle server version
    2365                 :  */
    2366                 : int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC)
    2367              48 : {
    2368                 :         char version_buff[256];
    2369                 : 
    2370              48 :         PHP_OCI_CALL_RETURN(connection->errcode, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
    2371                 : 
    2372              48 :         if (connection->errcode != OCI_SUCCESS) {
    2373               0 :                 connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    2374               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    2375               0 :                 return 1;
    2376                 :         }
    2377                 : 
    2378              48 :         *version = estrdup(version_buff);
    2379              48 :         return 0;
    2380                 : } /* }}} */
    2381                 : 
    2382                 : /* {{{ php_oci_column_to_zval()
    2383                 :  *
    2384                 :  * Convert php_oci_out_column struct into zval
    2385                 :  */
    2386                 : int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSRMLS_DC)
    2387          282187 : {
    2388                 :         php_oci_descriptor *descriptor;
    2389                 :         ub4 lob_length;
    2390                 :         int column_size;
    2391                 :         char *lob_buffer;
    2392                 :         int lob_fetch_status;
    2393                 : 
    2394          282187 :         if (column->indicator == -1) { /* column is NULL */
    2395              92 :                 ZVAL_NULL(value);
    2396              92 :                 return 0;
    2397                 :         }
    2398                 : 
    2399          282095 :         if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
    2400            1416 :                 ZVAL_RESOURCE(value, column->stmtid);
    2401            1416 :                 zend_list_addref(column->stmtid);
    2402          280679 :         } else if (column->is_descr) {
    2403                 : 
    2404          273319 :                 if (column->data_type != SQLT_RDD) {
    2405                 :                         int rsrc_type;
    2406                 : 
    2407                 :                         /* reset descriptor's length */
    2408          273318 :                         descriptor = (php_oci_descriptor *) zend_list_find(column->descid, &rsrc_type);
    2409                 : 
    2410          273318 :                         if (!descriptor || rsrc_type != le_descriptor) {
    2411               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find LOB descriptor #%d", column->descid);
    2412               0 :                                 return 1;
    2413                 :                         }
    2414                 : 
    2415          273318 :                         descriptor->lob_size = -1;
    2416          273318 :                         descriptor->lob_current_position = 0;
    2417          273318 :                         descriptor->buffering = 0;
    2418                 :                 }
    2419                 : 
    2420          273319 :                 if (column->data_type != SQLT_RDD && (mode & PHP_OCI_RETURN_LOBS)) {
    2421                 :                         /* PHP_OCI_RETURN_LOBS means that we want the content of the LOB back instead of the locator */
    2422                 : 
    2423            1034 :                         lob_fetch_status = php_oci_lob_read(descriptor, -1, 0, &lob_buffer, &lob_length TSRMLS_CC);
    2424            1034 :                         php_oci_temp_lob_close(descriptor TSRMLS_CC);
    2425            1034 :                         if (lob_fetch_status) {
    2426               0 :                                 ZVAL_FALSE(value);
    2427               0 :                                 return 1;
    2428                 :                         } else {
    2429            1034 :                                 if (lob_length > 0) {
    2430            1027 :                                         ZVAL_STRINGL(value, lob_buffer, lob_length, 0);
    2431                 :                                 } else {
    2432               7 :                                         ZVAL_EMPTY_STRING(value);
    2433                 :                                 }
    2434            1034 :                                 return 0;
    2435                 :                         }
    2436                 :                 } else {
    2437                 :                         /* return the locator */
    2438          272285 :                         object_init_ex(value, oci_lob_class_entry_ptr);
    2439          272285 :                         add_property_resource(value, "descriptor", column->descid);
    2440          272285 :                         zend_list_addref(column->descid);
    2441                 :                 }
    2442                 :         } else {
    2443            7360 :                 switch (column->retcode) {
    2444                 :                         case 0:
    2445                 :                                 /* intact value */
    2446            7360 :                                 if (column->piecewise) {
    2447              12 :                                         column_size = column->retlen4;
    2448                 :                                 } else {
    2449            7348 :                                         column_size = column->retlen;
    2450                 :                                 }
    2451                 :                                 break;
    2452                 : 
    2453                 :                         default:
    2454               0 :                                 ZVAL_FALSE(value);
    2455               0 :                                 return 0;
    2456                 :                 }
    2457                 : 
    2458            7360 :                 ZVAL_STRINGL(value, column->data, column_size, 1);
    2459                 :         }
    2460          281061 :         return 0;
    2461                 : }
    2462                 : /* }}} */
    2463                 : 
    2464                 : /* {{{ php_oci_fetch_row()
    2465                 :  *
    2466                 :  * Fetch the next row from the given statement
    2467                 :  */
    2468                 : void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args)
    2469          131252 : {
    2470                 :         zval *z_statement, *array;
    2471                 :         php_oci_statement *statement;
    2472                 :         php_oci_out_column *column;
    2473          131252 :         ub4 nrows = 1;
    2474                 :         int i;
    2475          131252 :         long fetch_mode = 0;
    2476                 : 
    2477          131252 :         if (expected_args > 2) {
    2478                 :                 /* only for ocifetchinto BC */
    2479                 : 
    2480            6625 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|l", &z_statement, &array, &fetch_mode) == FAILURE) {
    2481               2 :                         return;
    2482                 :                 }
    2483                 : 
    2484            6623 :                 if (ZEND_NUM_ARGS() == 2) {
    2485               1 :                         fetch_mode = mode;
    2486                 :                 }
    2487          124627 :         } else if (expected_args == 2) {
    2488                 :                 /* only for oci_fetch_array() */
    2489                 : 
    2490            4549 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &fetch_mode) == FAILURE) {
    2491               0 :                         return;
    2492                 :                 }
    2493                 : 
    2494            4549 :                 if (ZEND_NUM_ARGS() == 1) {
    2495              43 :                         fetch_mode = mode;
    2496                 :                 }
    2497                 :         } else {
    2498                 :                 /* for all oci_fetch_*() */
    2499                 : 
    2500          120078 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
    2501               0 :                         return;
    2502                 :                 }
    2503                 : 
    2504          120078 :                 fetch_mode = mode;
    2505                 :         }
    2506                 : 
    2507          131250 :         if (!(fetch_mode & PHP_OCI_NUM) && !(fetch_mode & PHP_OCI_ASSOC)) {
    2508                 :                 /* none of the modes present, use the default one */
    2509              25 :                 if (mode & PHP_OCI_ASSOC) {
    2510              20 :                         fetch_mode |= PHP_OCI_ASSOC;
    2511                 :                 }
    2512              25 :                 if (mode & PHP_OCI_NUM) {
    2513              25 :                         fetch_mode |= PHP_OCI_NUM;
    2514                 :                 }
    2515                 :         }
    2516                 : 
    2517          131250 :         PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
    2518                 : 
    2519          131249 :         if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
    2520           30069 :                 RETURN_FALSE;
    2521                 :         }
    2522                 : 
    2523          101180 :         array_init(return_value);
    2524                 : 
    2525          292967 :         for (i = 0; i < statement->ncolumns; i++) {
    2526                 : 
    2527          191787 :                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
    2528                 : 
    2529          191787 :                 if (column == NULL) {
    2530               0 :                         continue;
    2531                 :                 }
    2532          191787 :                 if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) {
    2533              51 :                         continue;
    2534                 :                 }
    2535                 : 
    2536          191736 :                 if (!(column->indicator == -1)) {
    2537                 :                         zval *element;
    2538                 : 
    2539          191672 :                         MAKE_STD_ZVAL(element);
    2540          191672 :                         php_oci_column_to_zval(column, element, fetch_mode TSRMLS_CC);
    2541                 : 
    2542          191672 :                         if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
    2543            9322 :                                 add_index_zval(return_value, i, element);
    2544                 :                         }
    2545          191672 :                         if (fetch_mode & PHP_OCI_ASSOC) {
    2546          182425 :                                 if (fetch_mode & PHP_OCI_NUM) {
    2547              75 :                                         Z_ADDREF_P(element);
    2548                 :                                 }
    2549          182425 :                                 add_assoc_zval(return_value, column->name, element);
    2550                 :                         }
    2551                 : 
    2552                 :                 } else {
    2553              64 :                         if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
    2554              40 :                                 add_index_null(return_value, i);
    2555                 :                         }
    2556              64 :                         if (fetch_mode & PHP_OCI_ASSOC) {
    2557              49 :                                 add_assoc_null(return_value, column->name);
    2558                 :                         }
    2559                 :                 }
    2560                 :         }
    2561                 : 
    2562          101180 :         if (expected_args > 2) {
    2563                 :                 /* Only for ocifetchinto BC.  In all other cases we return array, not long */
    2564            6618 :                 REPLACE_ZVAL_VALUE(&array, return_value, 1); /* copy return_value to given reference */
    2565            6618 :                 zval_dtor(return_value);
    2566            6618 :                 RETURN_LONG(statement->ncolumns);
    2567                 :         }
    2568                 : }
    2569                 : /* }}} */
    2570                 : 
    2571                 : /* {{{ php_oci_persistent_helper()
    2572                 :  *
    2573                 :  * Helper function to close/rollback persistent connections at the end of request. A return value of
    2574                 :  * 1 indicates that the connection is to be destroyed
    2575                 :  */
    2576                 : static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
    2577             328 : {
    2578                 :         time_t timestamp;
    2579                 :         php_oci_connection *connection;
    2580                 : 
    2581             328 :         timestamp = time(NULL);
    2582                 : 
    2583                 :         /* Persistent connection stubs are also counted as they have private session pools */
    2584             328 :         if (le->type == le_pconnection) {
    2585              29 :                 connection = (php_oci_connection *)le->ptr;
    2586                 : 
    2587              29 :                 if (!connection->used_this_request && OCI_G(persistent_timeout) != -1) {
    2588               0 :                         if (OCI_G(debug_mode)) {
    2589               0 :                                 php_printf ("OCI8 DEBUG L1: persistent_helper processing for timeout: (%p stub=%d) at (%s:%d) \n", connection, connection->is_stub, __FILE__, __LINE__);
    2590                 :                         }
    2591               0 :                         if (connection->idle_expiry < timestamp) {
    2592                 :                                 /* connection has timed out */
    2593               0 :                                 return ZEND_HASH_APPLY_REMOVE;
    2594                 :                         }
    2595                 :                 }
    2596                 :         }
    2597             328 :         return ZEND_HASH_APPLY_KEEP;
    2598                 : } /* }}} */
    2599                 : 
    2600                 : /* {{{ php_oci_create_spool()
    2601                 :  *
    2602                 :  *       Create(alloc + Init) Session pool for the given dbname and charsetid
    2603                 :  */
    2604                 : static php_oci_spool *php_oci_create_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, char *hash_key, int hash_key_len, int charsetid TSRMLS_DC)
    2605             292 : {
    2606             292 :         php_oci_spool *session_pool = NULL;
    2607             292 :         zend_bool iserror = 0;
    2608             292 :         ub4 poolmode = OCI_DEFAULT;     /* Mode to be passed to OCISessionPoolCreate */
    2609             292 :         OCIAuthInfo *spoolAuth = NULL;
    2610                 : 
    2611                 :         /*Allocate sessionpool out of persistent memory */
    2612             292 :         session_pool = (php_oci_spool *) calloc(1, sizeof(php_oci_spool));
    2613                 : 
    2614                 :         /* Populate key if passed */
    2615             292 :         if (hash_key_len) {
    2616             262 :                 session_pool->spool_hash_key = zend_strndup(hash_key, hash_key_len);
    2617                 :         }
    2618                 : 
    2619                 :         /* Create the session pool's env */
    2620             292 :         if (!(session_pool->env = php_oci_create_env(charsetid TSRMLS_CC))) {
    2621               0 :                 iserror = 1;
    2622               0 :                 goto exit_create_spool;
    2623                 :         }
    2624                 : 
    2625                 :         /* Allocate the pool handle */
    2626             292 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0));
    2627                 : 
    2628             292 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2629               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2630               0 :                 iserror = 1;
    2631               0 :                 goto exit_create_spool;
    2632                 :         }
    2633                 : 
    2634                 :         /* Allocate the session pool error handle - This only for use in the destructor, as there is a
    2635                 :          * generic bug which can free up the OCI_G(err) variable before destroying connections. We
    2636                 :          * cannot use this for other roundtrip calls as there is no way the user can access this error
    2637                 :          */
    2638             292 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0));
    2639                 : 
    2640             292 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2641               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2642               0 :                 iserror = 1;
    2643               0 :                 goto exit_create_spool;
    2644                 :         }
    2645                 : 
    2646                 : /* Disable RLB as we mostly have single-connection pools */
    2647                 : #if (OCI_MAJOR_VERSION > 10)
    2648                 :         poolmode = OCI_SPC_NO_RLB | OCI_SPC_HOMOGENEOUS;
    2649                 : #else
    2650             292 :         poolmode = OCI_SPC_HOMOGENEOUS;
    2651                 : #endif
    2652                 : 
    2653                 : #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
    2654                 :         /* Allocate auth handle for session pool {{{ */
    2655                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL));
    2656                 : 
    2657                 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2658                 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2659                 :                 iserror = 1;
    2660                 :                 goto exit_create_spool;
    2661                 :         } /* }}} */
    2662                 : 
    2663                 :         /* Set the edition attribute on the auth handle {{{ */
    2664                 :         if (OCI_G(edition)) {
    2665                 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err)));
    2666                 : 
    2667                 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2668                 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2669                 :                         iserror = 1;
    2670                 :                         goto exit_create_spool;
    2671                 :                 }
    2672                 :         } /* }}} */
    2673                 : 
    2674                 :         /* Set the driver name attribute on the auth handle {{{ */
    2675                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
    2676                 : 
    2677                 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2678                 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2679                 :                 iserror = 1;
    2680                 :                 goto exit_create_spool;
    2681                 :         } /* }}} */
    2682                 : 
    2683                 :         /* Set the auth handle on the session pool {{{ */
    2684                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err)));
    2685                 : 
    2686                 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2687                 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2688                 :                 iserror = 1;
    2689                 :                 goto exit_create_spool;
    2690                 :         } /* }}} */
    2691                 : #endif
    2692                 : 
    2693                 :         /* Create the homogeneous session pool - We have different session pools for every different
    2694                 :          * username, password, charset and dbname.
    2695                 :          */
    2696             292 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode));
    2697                 : 
    2698             292 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2699               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2700               0 :                 iserror = 1;
    2701               0 :                 goto exit_create_spool;
    2702                 :         }
    2703                 : 
    2704                 :         /* Set the session pool's timeout to the oci8.persistent_timeout param */
    2705             292 :         if (OCI_G(persistent_timeout)) {
    2706             292 :                 ub4 timeout = OCI_G(persistent_timeout);
    2707                 : 
    2708             292 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) session_pool->poolh, (ub4) OCI_HTYPE_SPOOL, (void *) &timeout, (ub4) sizeof(timeout), (ub4) OCI_ATTR_SPOOL_TIMEOUT, OCI_G(err)));
    2709                 : 
    2710             292 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2711               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2712               0 :                         iserror = 1;
    2713               0 :                         goto exit_create_spool;
    2714                 :                 }
    2715                 :         }
    2716                 : 
    2717             292 : exit_create_spool:
    2718             292 :         if (iserror && session_pool) {
    2719               0 :                 php_oci_spool_close(session_pool TSRMLS_CC);
    2720               0 :                 session_pool = NULL;
    2721                 :         }
    2722                 : 
    2723             292 :         if (spoolAuth) {
    2724               0 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO));
    2725                 :         }
    2726                 : 
    2727             292 :         if (OCI_G(debug_mode)) {
    2728               0 :                 php_printf ("OCI8 DEBUG L1: create_spool: (%p) at (%s:%d) \n", session_pool, __FILE__, __LINE__);
    2729                 :         }
    2730                 : 
    2731             292 :         return session_pool;
    2732                 : } /* }}} */
    2733                 : 
    2734                 : /* {{{ php_oci_get_spool()
    2735                 :  *
    2736                 :  * Get Session pool for the given dbname and charsetid from the persistent list. Function called for
    2737                 :  * non-persistent connections.
    2738                 :  */
    2739                 : static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *password, int password_len, char *dbname, int dbname_len, int charsetid TSRMLS_DC)
    2740             292 : {
    2741             292 :         smart_str spool_hashed_details = {0};
    2742             292 :         php_oci_spool *session_pool = NULL;
    2743             292 :         zend_rsrc_list_entry spool_le = {0};
    2744             292 :         zend_rsrc_list_entry *spool_out_le = NULL;
    2745             292 :         zend_bool iserror = 0;
    2746                 : 
    2747                 :         /* Create the spool hash key {{{ */
    2748             292 :         smart_str_appendl_ex(&spool_hashed_details, "oci8spool***", sizeof("oci8spool***") - 1, 0);
    2749             292 :         smart_str_appendl_ex(&spool_hashed_details, username, username_len, 0);
    2750             292 :         smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
    2751                 :         /* Add edition attribute to the hash */
    2752             292 :         if (OCI_G(edition)){
    2753               0 :                 smart_str_appendl_ex(&spool_hashed_details, OCI_G(edition), strlen(OCI_G(edition)), 0);
    2754                 :         }
    2755             292 :         smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
    2756             292 :         if (password_len) {
    2757                 :                 ulong password_hash;
    2758             292 :                 password_hash = zend_inline_hash_func(password, password_len);
    2759             292 :                 smart_str_append_unsigned_ex(&spool_hashed_details, password_hash, 0);
    2760                 :         }
    2761             292 :         smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
    2762                 : 
    2763             292 :         if (dbname_len) {
    2764             292 :                 smart_str_appendl_ex(&spool_hashed_details, dbname, dbname_len, 0);
    2765                 :         }
    2766             292 :         smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0);
    2767                 : 
    2768             292 :         smart_str_append_unsigned_ex(&spool_hashed_details, charsetid, 0);
    2769                 : 
    2770                 :         /* Session Pool Hash Key : oci8spool***username**edition**hashedpassword**dbname**charset */
    2771                 : 
    2772             292 :         smart_str_0(&spool_hashed_details);
    2773             292 :         php_strtolower(spool_hashed_details.c, spool_hashed_details.len);
    2774                 :         /* }}} */
    2775                 : 
    2776             292 :         if (zend_hash_find(&EG(persistent_list),spool_hashed_details.c, spool_hashed_details.len+1, (void **)&spool_out_le) == FAILURE) {
    2777                 : 
    2778             262 :                 session_pool = php_oci_create_spool(username, username_len, password, password_len, dbname, dbname_len, spool_hashed_details.c, spool_hashed_details.len, charsetid TSRMLS_CC);
    2779                 : 
    2780             262 :                 if (session_pool == NULL) {
    2781               0 :                         iserror = 1;
    2782               0 :                         goto exit_get_spool;
    2783                 :                 }
    2784             262 :                 spool_le.ptr  = session_pool;
    2785             262 :                 spool_le.type = le_psessionpool;
    2786             262 :                 zend_list_insert(session_pool, le_psessionpool);
    2787             262 :                 zend_hash_update(&EG(persistent_list), session_pool->spool_hash_key, strlen(session_pool->spool_hash_key)+1,(void *)&spool_le, sizeof(zend_rsrc_list_entry),NULL);
    2788              30 :         } else if (spool_out_le->type == le_psessionpool &&
    2789                 :                 strlen(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key) == spool_hashed_details.len &&
    2790                 :                 memcmp(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key, spool_hashed_details.c, spool_hashed_details.len) == 0) {
    2791                 :                 /* retrieve the cached session pool */
    2792              30 :                 session_pool = (php_oci_spool *)(spool_out_le->ptr);
    2793                 :         }
    2794                 : 
    2795             292 : exit_get_spool:
    2796             292 :         smart_str_free_ex(&spool_hashed_details, 0);
    2797             292 :         if (iserror && session_pool) {
    2798               0 :                 php_oci_spool_close(session_pool TSRMLS_CC);
    2799               0 :                 session_pool = NULL;
    2800                 :         }
    2801                 : 
    2802             292 :         return session_pool;
    2803                 : 
    2804                 : } /* }}} */
    2805                 : 
    2806                 : /* {{{ php_oci_create_env()
    2807                 :  *
    2808                 :  * Create the OCI environment choosing the correct function for the OCI version
    2809                 :  */
    2810                 : static OCIEnv *php_oci_create_env(ub2 charsetid TSRMLS_DC)
    2811             317 : {
    2812             317 :         OCIEnv *retenv = NULL;
    2813                 : 
    2814                 :         /* create an environment using the character set id */
    2815             317 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIEnvNlsCreate, (&retenv, OCI_G(events) ? PHP_OCI_INIT_MODE | OCI_EVENTS : PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, charsetid, charsetid));
    2816                 : 
    2817             317 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2818                 : #ifdef HAVE_OCI_INSTANT_CLIENT
    2819                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries");
    2820                 : #else
    2821               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories");
    2822                 : #endif
    2823               0 :                 return NULL;
    2824                 :         }
    2825             317 :         return retenv;
    2826                 : }/* }}} */
    2827                 : 
    2828                 : /* {{{ php_oci_old_create_session()
    2829                 :  *
    2830                 :  * This function is to be deprecated in future in favour of OCISessionGet which is used in
    2831                 :  * php_oci_do_connect_ex
    2832                 :  */
    2833                 : static int php_oci_old_create_session(php_oci_connection *connection, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC)
    2834              25 : {
    2835              25 :         ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
    2836                 : 
    2837              25 :         if (OCI_G(debug_mode)) {
    2838               0 :                 php_printf ("OCI8 DEBUG: Bypassing client-side session pool for session create at (%s:%d) \n", __FILE__, __LINE__);
    2839                 :         }
    2840                 : 
    2841                 :         /* Create the OCI environment separate for each connection */
    2842              25 :         if (!(connection->env = php_oci_create_env(connection->charset TSRMLS_CC))) {
    2843               0 :                 return 1;
    2844                 :         }
    2845                 : 
    2846                 :         /* Allocate our server handle {{{ */
    2847              25 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->server), OCI_HTYPE_SERVER, 0, NULL));
    2848                 : 
    2849              25 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2850               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2851               0 :                 return 1;
    2852                 :         } /* }}} */
    2853                 : 
    2854                 :         /* Attach to the server {{{ */
    2855              25 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerAttach, (connection->server, OCI_G(err), (text *)dbname, dbname_len, (ub4) OCI_DEFAULT));
    2856                 : 
    2857              25 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2858              14 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2859              14 :                 return 1;
    2860                 :         } /* }}} */
    2861              11 :         connection->is_attached = 1;
    2862                 : 
    2863                 :         /* Allocate our session handle {{{ */
    2864              11 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->session), OCI_HTYPE_SESSION, 0, NULL));
    2865                 : 
    2866              11 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2867               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2868               0 :                 return 1;
    2869                 :         } /* }}} */
    2870                 : 
    2871                 :         /* Allocate our private error-handle {{{ */
    2872              11 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
    2873                 : 
    2874              11 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2875               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2876               0 :                 return 1;
    2877                 :         } /* }}} */
    2878                 : 
    2879                 :         /* Allocate our service-context {{{ */
    2880              11 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->svc), OCI_HTYPE_SVCCTX, 0, NULL));
    2881                 : 
    2882              11 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2883               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2884               0 :                 return 1;
    2885                 :         } /* }}} */
    2886                 : 
    2887                 :         /* Set the username {{{ */
    2888              11 :         if (username) {
    2889              11 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) username_len, (ub4) OCI_ATTR_USERNAME, OCI_G(err)));
    2890                 : 
    2891              11 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2892               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2893               0 :                         return 1;
    2894                 :                 }
    2895                 :         }/* }}} */
    2896                 : 
    2897                 :         /* Set the password {{{ */
    2898              11 :         if (password) {
    2899              11 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) password_len, (ub4) OCI_ATTR_PASSWORD, OCI_G(err)));
    2900                 : 
    2901              11 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2902               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2903               0 :                         return 1;
    2904                 :                 }
    2905                 :         }/* }}} */
    2906                 : 
    2907                 :         /* Set the edition attribute on the session handle {{{ */
    2908                 : #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
    2909                 :         if (OCI_G(edition)) {
    2910                 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(edition), (ub4) (strlen(OCI_G(edition))), (ub4) OCI_ATTR_EDITION, OCI_G(err)));
    2911                 : 
    2912                 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2913                 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2914                 :                         return 1;
    2915                 :                 }
    2916                 :         }
    2917                 : #endif /* }}} */
    2918                 : 
    2919                 :         /* Set the driver name attribute on the session handle {{{ */
    2920                 : #if (OCI_MAJOR_VERSION >= 11)
    2921                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
    2922                 : 
    2923                 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2924                 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2925                 :                 return 1;
    2926                 :         }
    2927                 : #endif /* }}} */
    2928                 : 
    2929                 :         /* Set the server handle in the service handle {{{ */
    2930              11 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err)));
    2931                 : 
    2932              11 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2933               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2934               0 :                 return 1;
    2935                 :         } /* }}} */
    2936                 : 
    2937                 :         /* Set the authentication handle in the service handle {{{ */
    2938              11 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->session, 0, OCI_ATTR_SESSION, OCI_G(err)));
    2939                 : 
    2940              11 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2941               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2942               0 :                 return 1;
    2943                 :         } /* }}} */
    2944                 : 
    2945              11 :         if (new_password) {
    2946                 :                 /* Try to change password if new one was provided {{{ */
    2947               4 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPasswordChange, (connection->svc, OCI_G(err), (text *)username, username_len, (text *)password, password_len, (text *)new_password, new_password_len, OCI_AUTH));
    2948                 : 
    2949               4 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2950               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2951               0 :                         return 1;
    2952                 :                 }
    2953                 : 
    2954               4 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err)));
    2955                 : 
    2956               4 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2957               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2958               0 :                         return 1;
    2959                 :                 } /* }}} */
    2960                 :         } else {
    2961                 :                 /* start the session {{{ */
    2962               7 :                 ub4 cred_type = OCI_CRED_RDBMS;
    2963                 : 
    2964                 :                 /* Extract the overloaded session_mode parameter into valid Oracle credential and session mode values */
    2965               7 :                 if (session_mode & PHP_OCI_CRED_EXT) {
    2966               0 :                         cred_type = OCI_CRED_EXT;
    2967               0 :                         session_mode ^= PHP_OCI_CRED_EXT;
    2968                 :                 }
    2969                 : 
    2970               7 :                 session_mode |= OCI_STMT_CACHE;
    2971                 : 
    2972               7 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) cred_type, (ub4) session_mode));
    2973                 : 
    2974               7 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    2975               7 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2976                 :                         /* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
    2977                 :                          * user's password has expired, but is still usable.
    2978                 :                          */
    2979               7 :                         if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
    2980               7 :                                 return 1;
    2981                 :                         }
    2982                 :                 } /* }}} */
    2983                 :         }
    2984                 : 
    2985                 :         /* Brand new connection: Init and update the next_ping in the connection */
    2986               4 :         if (php_oci_ping_init(connection, OCI_G(err) TSRMLS_CC) != OCI_SUCCESS) {
    2987               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2988               0 :                 return 1;
    2989                 :         }
    2990                 : 
    2991               4 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &statement_cache_size, 0, (ub4) OCI_ATTR_STMTCACHESIZE, OCI_G(err)));
    2992                 : 
    2993               4 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    2994               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    2995               0 :                 return 1;
    2996                 :         }
    2997                 : 
    2998                 :         /* Successfully created session */
    2999               4 :         return 0;
    3000                 : } /* }}} */
    3001                 : 
    3002                 : /* {{{ php_oci_create_session()
    3003                 :  *
    3004                 :  * Create session using client-side session pool - new norm
    3005                 :  */
    3006                 : static int php_oci_create_session(php_oci_connection *connection, php_oci_spool *session_pool, char *dbname, int dbname_len, char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, int session_mode TSRMLS_DC)
    3007             330 : {
    3008             330 :         php_oci_spool *actual_spool = NULL;
    3009                 : #if (OCI_MAJOR_VERSION > 10)
    3010                 :         ub4 purity = -2;                                /* Illegal value to initialize */
    3011                 : #endif
    3012             330 :         time_t timestamp = time(NULL);
    3013             330 :         ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
    3014                 : 
    3015                 :         /* Persistent connections have private session pools */
    3016             330 :         if (connection->is_persistent && !connection->private_spool &&
    3017                 :                 !(connection->private_spool = php_oci_create_spool(username, username_len, password, password_len, dbname, dbname_len, NULL, 0, connection->charset TSRMLS_CC))) {
    3018               0 :                         return 1;
    3019                 :         }
    3020             330 :         actual_spool = (connection->is_persistent) ? (connection->private_spool) : (session_pool);
    3021                 : 
    3022             330 :         connection->env = actual_spool->env;
    3023                 : 
    3024                 :         /* Do this upfront so that connection close on an error would know that this is a session pool
    3025                 :          * connection. Failure to do this would result in crashes in error scenarios
    3026                 :          */
    3027             330 :         if (!connection->using_spool) {
    3028             322 :                 connection->using_spool = 1;
    3029                 :         }
    3030                 : 
    3031             330 :         if (OCI_G(debug_mode)) {
    3032               0 :                 if (session_pool) {
    3033               0 :                         php_printf ("OCI8 DEBUG L1: using shared pool: (%p) at (%s:%d) \n", session_pool, __FILE__, __LINE__);
    3034                 :                 } else {
    3035               0 :                         php_printf ("OCI8 DEBUG L1: using private pool: (%p) at (%s:%d) \n", connection->private_spool, __FILE__, __LINE__);
    3036                 :                 }
    3037                 :         }
    3038                 : 
    3039                 :         /* The passed in "connection" can be a cached stub from plist or freshly created. In the former
    3040                 :          * case, we do not have to allocate any handles
    3041                 :          */
    3042                 : 
    3043             330 :         if (!connection->err) {
    3044             322 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
    3045                 : 
    3046             322 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3047               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3048               0 :                         return 1;
    3049                 :                 }
    3050                 :         }
    3051                 : 
    3052                 :         /* {{{ Allocate and initialize the connection-private authinfo handle if not allocated yet */
    3053             330 :         if (!connection->authinfo) {
    3054             322 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->authinfo), OCI_HTYPE_AUTHINFO, 0, NULL));
    3055                 : 
    3056             322 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3057               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3058               0 :                         return 1;
    3059                 :                 }
    3060                 : 
    3061                 :                 /* Set the Connection class and purity if OCI client version >= 11g */
    3062                 : #if (OCI_MAJOR_VERSION > 10)
    3063                 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(connection_class), (ub4)(strlen(OCI_G(connection_class))), (ub4)OCI_ATTR_CONNECTION_CLASS, OCI_G(err)));
    3064                 : 
    3065                 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3066                 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3067                 :                         return 1;
    3068                 :                 }
    3069                 : 
    3070                 :                 if (connection->is_persistent)
    3071                 :                         purity = OCI_ATTR_PURITY_SELF;
    3072                 :                 else
    3073                 :                         purity = OCI_ATTR_PURITY_NEW;
    3074                 : 
    3075                 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_AUTHINFO, (dvoid *) &purity, (ub4)0, (ub4)OCI_ATTR_PURITY, OCI_G(err)));
    3076                 : 
    3077                 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3078                 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3079                 :                         return 1;
    3080                 :                 }
    3081                 : #endif
    3082                 :         } /* }}} */
    3083                 : 
    3084                 :         /* Debug statements {{{ */
    3085             330 :         if (OCI_G(debug_mode)) {
    3086               0 :                 ub4 numfree = 0, numbusy = 0, numopen = 0;
    3087               0 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numopen, (ub4 *)0, OCI_ATTR_SPOOL_OPEN_COUNT, OCI_G(err)));
    3088               0 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numbusy, (ub4 *)0, OCI_ATTR_SPOOL_BUSY_COUNT, OCI_G(err)));
    3089               0 :                 numfree = numopen - numbusy;    /* number of free connections in the pool */
    3090               0 :                 php_printf ("OCI8 DEBUG L1: (numopen=%d)(numbusy=%d) at (%s:%d) \n", numopen, numbusy, __FILE__, __LINE__);
    3091                 :         } /* }}} */
    3092                 : 
    3093                 :                 /* Ping loop: Ping and loop till we get a good connection. When a database instance goes
    3094                 :                  * down, it can leave several bad connections that need to be flushed out before getting a
    3095                 :                  * good one. In non-RAC, we always get a brand new connection at the end of the loop and in
    3096                 :                  * RAC, we can get a good connection from a different instance before flushing out all bad
    3097                 :                  * ones. We do not need to ping brand new connections.
    3098                 :                  */
    3099                 :         do {
    3100                 :                 /* Continue to use the global error handle as the connection is closed when an error occurs */
    3101             330 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode),OCISessionGet, (connection->env, OCI_G(err), &(connection->svc), (OCIAuthInfo *)connection->authinfo, (OraText *)actual_spool->poolname, (ub4)actual_spool->poolname_len, NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL));
    3102                 : 
    3103             330 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3104               1 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3105                 : 
    3106                 :                         /* Session creation returns OCI_SUCCESS_WITH_INFO when user's password has expired, but
    3107                 :                          * is still usable.
    3108                 :                          */
    3109                 : 
    3110               1 :                         if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
    3111               1 :                                 return 1;
    3112                 :                         }
    3113                 :                 }
    3114                 : 
    3115                 :                 /* {{{ Populate the session and server fields of the connection */
    3116             329 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->server), (ub4 *)0, OCI_ATTR_SERVER, OCI_G(err)));
    3117                 : 
    3118             329 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err))); /* }}} */
    3119                 : 
    3120             329 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextGetValue, (connection->session, OCI_G(err), (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), (void **)&(connection->next_pingp)));
    3121             329 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3122               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3123               0 :                         return 1;
    3124                 :                 }
    3125                 : 
    3126             329 :                 if (!(connection->next_pingp)){
    3127                 :                         /* This is a brand new connection, we need not ping, but have to initialize ping */
    3128             321 :                         if (php_oci_ping_init(connection, OCI_G(err) TSRMLS_CC) != OCI_SUCCESS) {
    3129               0 :                                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3130               0 :                                 return 1;
    3131                 :                         }
    3132               8 :                 } else if ((*(connection->next_pingp) > 0) && (timestamp >= *(connection->next_pingp))) {
    3133               0 :                         if (php_oci_connection_ping(connection TSRMLS_CC)) {
    3134                 :                                 /* Got a good connection - update next_ping and get out of ping loop */
    3135               0 :                                 *(connection->next_pingp) = timestamp + OCI_G(ping_interval);
    3136                 :                         } else {
    3137                 :                                 /* Bad connection - remove from pool */
    3138               0 :                                 PHP_OCI_CALL(OCISessionRelease, (connection->svc, connection->err, NULL,0, (ub4) OCI_SESSRLS_DROPSESS));
    3139               0 :                                 connection->svc = NULL;
    3140               0 :                                 connection->server = NULL;
    3141               0 :                                 connection->session = NULL;
    3142                 :                         }
    3143                 :                 }       /* If ping applicable */
    3144             329 :         } while (!(connection->svc));
    3145                 : 
    3146             329 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &statement_cache_size, 0, (ub4) OCI_ATTR_STMTCACHESIZE, OCI_G(err)));
    3147                 : 
    3148             329 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    3149               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    3150               0 :                 return 1;
    3151                 :         }
    3152                 : 
    3153                 :         /* Session is now taken from the session pool and attached and open */
    3154             329 :         connection->is_stub = 0;
    3155             329 :         connection->is_attached = connection->is_open = 1;
    3156                 : 
    3157             329 :         return 0;
    3158                 : } /* }}} */
    3159                 : 
    3160                 : /* {{{ php_oci_spool_list_dtor()
    3161                 :  *
    3162                 :  * Session pool destructor function
    3163                 :  */
    3164                 : static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
    3165             262 : {
    3166             262 :         php_oci_spool *session_pool = (php_oci_spool *)entry->ptr;
    3167                 : 
    3168             262 :         if (session_pool) {
    3169             262 :                 php_oci_spool_close(session_pool TSRMLS_CC);
    3170                 :         }
    3171                 : 
    3172                 :         return;
    3173                 : } /* }}} */
    3174                 : 
    3175                 : /* {{{  php_oci_spool_close()
    3176                 :  *
    3177                 :  * Destroys the OCI Session Pool
    3178                 :  */
    3179                 : static void php_oci_spool_close(php_oci_spool *session_pool TSRMLS_DC)
    3180             292 : {
    3181             292 :         if (session_pool->poolname_len) {
    3182             292 :                 PHP_OCI_CALL(OCISessionPoolDestroy, ((dvoid *) session_pool->poolh,
    3183                 :                         (dvoid *) session_pool->err, OCI_SPD_FORCE));
    3184                 :         }
    3185                 : 
    3186             292 :         if (session_pool->poolh) {
    3187             292 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->poolh, OCI_HTYPE_SPOOL));
    3188                 :         }
    3189                 : 
    3190             292 :         if (session_pool->err) {
    3191             292 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->err, OCI_HTYPE_ERROR));
    3192                 :         }
    3193                 : 
    3194             292 :         if (session_pool->env) {
    3195             292 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) session_pool->env, OCI_HTYPE_ENV));
    3196                 :         }
    3197                 : 
    3198             292 :         if (session_pool->spool_hash_key) {
    3199             262 :                 free(session_pool->spool_hash_key);
    3200                 :         }
    3201                 : 
    3202             292 :         free(session_pool);
    3203             292 : } /* }}} */
    3204                 : 
    3205                 : /* {{{ php_oci_ping_init()
    3206                 :  *
    3207                 :  * Initializes the next_ping time as a context value in the connection.  We now use
    3208                 :  * OCIContext{Get,Set}Value to store the next_ping because we need to support ping for
    3209                 :  * non-persistent DRCP connections
    3210                 :  */
    3211                 : static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TSRMLS_DC)
    3212             325 : {
    3213             325 :         time_t *next_pingp = NULL;
    3214                 : 
    3215             325 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextGetValue, (connection->session, errh, (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), (void **)&next_pingp));
    3216             325 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    3217               0 :                 return OCI_G(errcode);
    3218                 :         }
    3219                 : 
    3220                 :         /* This must be a brand-new connection. Allocate memory for the ping */
    3221             325 :         if (!next_pingp) {
    3222             325 :                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIMemoryAlloc, (connection->session, errh, (void **)&next_pingp, OCI_DURATION_SESSION, sizeof(time_t), OCI_MEMORY_CLEARED));
    3223             325 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    3224               0 :                         return OCI_G(errcode);
    3225                 :                 }
    3226                 :         }
    3227                 : 
    3228             325 :         if (OCI_G(ping_interval) >= 0) {
    3229             325 :                 time_t timestamp = time(NULL);
    3230             325 :                 *next_pingp = timestamp + OCI_G(ping_interval);
    3231                 :         } else {
    3232               0 :                 *next_pingp = 0;
    3233                 :         }
    3234                 : 
    3235                 :         /* Set the new ping value into the connection */
    3236             325 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextSetValue, (connection->session, errh, OCI_DURATION_SESSION, (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), next_pingp));
    3237             325 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    3238               0 :                 OCIMemoryFree(connection->session, errh, next_pingp);
    3239               0 :                 return OCI_G(errcode);
    3240                 :         }
    3241                 : 
    3242                 :         /* Cache the pointer so we do not have to do OCIContextGetValue repeatedly */
    3243             325 :         connection->next_pingp = next_pingp;
    3244                 : 
    3245             325 :         return OCI_SUCCESS;
    3246                 : } /* }}} */
    3247                 : 
    3248                 : #endif /* HAVE_OCI8 */
    3249                 : 
    3250                 : /*
    3251                 :  * Local variables:
    3252                 :  * tab-width: 4
    3253                 :  * c-basic-offset: 4
    3254                 :  * End:
    3255                 :  * vim600: noet sw=4 ts=4 fdm=marker
    3256                 :  * vim<600: noet sw=4 ts=4
    3257                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:04 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.