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-19 Instrumented lines: 653
Code covered: 83.0 % Executed lines: 542
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 272374 2008-12-31 11:17:49Z sebastian $ */
      30                 : /* TODO
      31                 :  *
      32                 :  * file://localhost/www/docs/oci10/ociaahan.htm#423823 - implement lob_empty() with OCI_ATTR_LOBEMPTY
      33                 :  *
      34                 :  * get OCI_ATTR_CHARSET_ID attr of column to detect UTF string and multiply buffer in 4 times
      35                 :  *
      36                 :  * */
      37                 : 
      38                 : #ifdef HAVE_CONFIG_H
      39                 : #include "config.h"
      40                 : #endif
      41                 : 
      42                 : #include "php.h"
      43                 : #include "ext/standard/info.h"
      44                 : #include "php_ini.h"
      45                 : #include "ext/standard/php_smart_str.h"
      46                 : 
      47                 : #if HAVE_OCI8
      48                 : 
      49                 : #include "php_oci8.h"
      50                 : #include "php_oci8_int.h"
      51                 : #include "zend_hash.h"
      52                 : 
      53                 : ZEND_DECLARE_MODULE_GLOBALS(oci)
      54                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
      55                 : static PHP_GINIT_FUNCTION(oci);
      56                 : #endif
      57                 : 
      58                 : /* True globals, no need for thread safety */
      59                 : int le_connection;
      60                 : int le_pconnection;
      61                 : int le_statement;
      62                 : int le_descriptor;
      63                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS 
      64                 : int le_collection;
      65                 : #endif
      66                 : 
      67                 : zend_class_entry *oci_lob_class_entry_ptr;
      68                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
      69                 : zend_class_entry *oci_coll_class_entry_ptr;
      70                 : #endif
      71                 : 
      72                 : #ifndef SQLT_BFILEE
      73                 : #define SQLT_BFILEE 114
      74                 : #endif
      75                 : #ifndef SQLT_CFILEE
      76                 : #define SQLT_CFILEE 115
      77                 : #endif
      78                 : 
      79                 : #define PHP_OCI_ERRBUF_LEN 512
      80                 : 
      81                 : #if ZEND_MODULE_API_NO > 20020429
      82                 : #define ONUPDATELONGFUNC OnUpdateLong
      83                 : #else
      84                 : #define ONUPDATELONGFUNC OnUpdateInt
      85                 : #endif
      86                 : 
      87                 : /* static protos {{{ */
      88                 : static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
      89                 : static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
      90                 : static void php_oci_statement_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
      91                 : static void php_oci_descriptor_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
      92                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS 
      93                 : static void php_oci_collection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
      94                 : #endif
      95                 : 
      96                 : static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC);
      97                 : #ifdef ZTS
      98                 : static int php_oci_list_helper(zend_rsrc_list_entry *le, void *le_type TSRMLS_DC);
      99                 : #endif
     100                 : static int php_oci_connection_ping(php_oci_connection * TSRMLS_DC);
     101                 : static int php_oci_connection_status(php_oci_connection * TSRMLS_DC);
     102                 : static int php_oci_connection_close(php_oci_connection * TSRMLS_DC);
     103                 : /* }}} */
     104                 : 
     105                 : /* {{{ dynamically loadable module stuff */
     106                 : #ifdef COMPILE_DL_OCI8
     107                 : ZEND_GET_MODULE(oci8)
     108                 : #endif /* COMPILE_DL */
     109                 : /* }}} */
     110                 : 
     111                 : #ifdef ZEND_ENGINE_2
     112                 : ZEND_BEGIN_ARG_INFO(oci_second_arg_force_ref, 0)
     113                 :         ZEND_ARG_PASS_INFO(0)
     114                 :         ZEND_ARG_PASS_INFO(1)
     115                 : ZEND_END_ARG_INFO()
     116                 : ZEND_BEGIN_ARG_INFO(oci_third_arg_force_ref, 0)
     117                 :         ZEND_ARG_PASS_INFO(0)
     118                 :         ZEND_ARG_PASS_INFO(0)
     119                 :         ZEND_ARG_PASS_INFO(1)
     120                 : ZEND_END_ARG_INFO()
     121                 : #else
     122                 : static unsigned char oci_second_arg_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };
     123                 : static unsigned char oci_third_arg_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
     124                 : #endif
     125                 : 
     126                 : /* {{{ extension function prototypes
     127                 : */
     128                 : PHP_FUNCTION(oci_bind_by_name);
     129                 : PHP_FUNCTION(oci_bind_array_by_name);
     130                 : PHP_FUNCTION(oci_define_by_name);
     131                 : PHP_FUNCTION(oci_field_is_null);
     132                 : PHP_FUNCTION(oci_field_name);
     133                 : PHP_FUNCTION(oci_field_size);
     134                 : PHP_FUNCTION(oci_field_scale);
     135                 : PHP_FUNCTION(oci_field_precision);
     136                 : PHP_FUNCTION(oci_field_type);
     137                 : PHP_FUNCTION(oci_field_type_raw);
     138                 : PHP_FUNCTION(oci_execute);
     139                 : PHP_FUNCTION(oci_fetch);
     140                 : PHP_FUNCTION(oci_cancel);
     141                 : PHP_FUNCTION(ocifetchinto);
     142                 : PHP_FUNCTION(oci_fetch_object);
     143                 : PHP_FUNCTION(oci_fetch_row);
     144                 : PHP_FUNCTION(oci_fetch_assoc);
     145                 : PHP_FUNCTION(oci_fetch_array);
     146                 : PHP_FUNCTION(ocifetchstatement);
     147                 : PHP_FUNCTION(oci_fetch_all);
     148                 : PHP_FUNCTION(oci_free_statement);
     149                 : PHP_FUNCTION(oci_internal_debug);
     150                 : PHP_FUNCTION(oci_close);
     151                 : PHP_FUNCTION(oci_connect);
     152                 : PHP_FUNCTION(oci_new_connect);
     153                 : PHP_FUNCTION(oci_pconnect);
     154                 : PHP_FUNCTION(oci_error);
     155                 : PHP_FUNCTION(oci_free_descriptor);
     156                 : PHP_FUNCTION(oci_commit);
     157                 : PHP_FUNCTION(oci_rollback);
     158                 : PHP_FUNCTION(oci_new_descriptor);
     159                 : PHP_FUNCTION(oci_num_fields);
     160                 : PHP_FUNCTION(oci_parse);
     161                 : PHP_FUNCTION(oci_new_cursor);
     162                 : PHP_FUNCTION(oci_result);
     163                 : PHP_FUNCTION(oci_server_version);
     164                 : PHP_FUNCTION(oci_statement_type);
     165                 : PHP_FUNCTION(oci_num_rows);
     166                 : PHP_FUNCTION(oci_set_prefetch);
     167                 : PHP_FUNCTION(oci_password_change);
     168                 : PHP_FUNCTION(oci_lob_save);
     169                 : PHP_FUNCTION(oci_lob_import);
     170                 : PHP_FUNCTION(oci_lob_export);
     171                 : PHP_FUNCTION(oci_lob_load);
     172                 : PHP_FUNCTION(oci_lob_tell);
     173                 : PHP_FUNCTION(oci_lob_write);
     174                 : PHP_FUNCTION(oci_lob_append);
     175                 : PHP_FUNCTION(oci_lob_copy);
     176                 : PHP_FUNCTION(oci_lob_truncate);
     177                 : PHP_FUNCTION(oci_lob_erase);
     178                 : PHP_FUNCTION(oci_lob_flush);
     179                 : PHP_FUNCTION(ocisetbufferinglob);
     180                 : PHP_FUNCTION(ocigetbufferinglob);
     181                 : PHP_FUNCTION(oci_lob_is_equal);
     182                 : PHP_FUNCTION(oci_lob_rewind);
     183                 : PHP_FUNCTION(oci_lob_read);
     184                 : PHP_FUNCTION(oci_lob_eof);
     185                 : PHP_FUNCTION(oci_lob_seek);
     186                 : PHP_FUNCTION(oci_lob_size);
     187                 : #ifdef HAVE_OCI8_TEMP_LOB
     188                 : PHP_FUNCTION(oci_lob_write_temporary);
     189                 : PHP_FUNCTION(oci_lob_close);
     190                 : #endif
     191                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     192                 : PHP_FUNCTION(oci_new_collection);
     193                 : PHP_FUNCTION(oci_free_collection);
     194                 : PHP_FUNCTION(oci_collection_append);
     195                 : PHP_FUNCTION(oci_collection_element_get);
     196                 : PHP_FUNCTION(oci_collection_element_assign);
     197                 : PHP_FUNCTION(oci_collection_assign);
     198                 : PHP_FUNCTION(oci_collection_size);
     199                 : PHP_FUNCTION(oci_collection_max);
     200                 : PHP_FUNCTION(oci_collection_trim);
     201                 : #endif
     202                 : /* }}} */
     203                 : 
     204                 : /* {{{ extension definition structures
     205                 : */
     206                 : static zend_function_entry php_oci_functions[] = {
     207                 :         PHP_FE(oci_define_by_name,          oci_third_arg_force_ref)
     208                 :         PHP_FE(oci_bind_by_name,            oci_third_arg_force_ref)
     209                 :         PHP_FE(oci_bind_array_by_name,      oci_third_arg_force_ref)
     210                 :         PHP_FE(oci_field_is_null,           NULL)
     211                 :         PHP_FE(oci_field_name,              NULL)
     212                 :         PHP_FE(oci_field_size,              NULL)
     213                 :         PHP_FE(oci_field_scale,             NULL)
     214                 :         PHP_FE(oci_field_precision,         NULL)
     215                 :         PHP_FE(oci_field_type,              NULL)
     216                 :         PHP_FE(oci_field_type_raw,          NULL)
     217                 :         PHP_FE(oci_execute,                 NULL)
     218                 :         PHP_FE(oci_cancel,                  NULL)
     219                 :         PHP_FE(oci_fetch,                   NULL)
     220                 :         PHP_FE(oci_fetch_object,            NULL)
     221                 :         PHP_FE(oci_fetch_row,               NULL)
     222                 :         PHP_FE(oci_fetch_assoc,             NULL)
     223                 :         PHP_FE(oci_fetch_array,             NULL)
     224                 :         PHP_FE(ocifetchinto,                oci_second_arg_force_ref)
     225                 :         PHP_FE(oci_fetch_all,               oci_second_arg_force_ref)
     226                 :         PHP_FE(oci_free_statement,          NULL)
     227                 :         PHP_FE(oci_internal_debug,          NULL)
     228                 :         PHP_FE(oci_num_fields,              NULL)
     229                 :         PHP_FE(oci_parse,                   NULL)
     230                 :         PHP_FE(oci_new_cursor,              NULL)
     231                 :         PHP_FE(oci_result,                  NULL)
     232                 :         PHP_FE(oci_server_version,          NULL)
     233                 :         PHP_FE(oci_statement_type,          NULL)
     234                 :         PHP_FE(oci_num_rows,                NULL)
     235                 :         PHP_FE(oci_close,                   NULL)
     236                 :         PHP_FE(oci_connect,                 NULL)
     237                 :         PHP_FE(oci_new_connect,             NULL)
     238                 :         PHP_FE(oci_pconnect,                NULL)
     239                 :         PHP_FE(oci_error,                   NULL)
     240                 :         PHP_FE(oci_free_descriptor,         NULL)
     241                 :         PHP_FE(oci_lob_save,                NULL)
     242                 :         PHP_FE(oci_lob_import,              NULL)
     243                 :         PHP_FE(oci_lob_size,                NULL)       
     244                 :         PHP_FE(oci_lob_load,                NULL)
     245                 :         PHP_FE(oci_lob_read,                NULL)
     246                 :         PHP_FE(oci_lob_eof,                 NULL)       
     247                 :         PHP_FE(oci_lob_tell,                NULL)
     248                 :         PHP_FE(oci_lob_truncate,            NULL)
     249                 :         PHP_FE(oci_lob_erase,               NULL)
     250                 :         PHP_FE(oci_lob_flush,               NULL)
     251                 :         PHP_FE(ocisetbufferinglob,          NULL)
     252                 :         PHP_FE(ocigetbufferinglob,          NULL)
     253                 :         PHP_FE(oci_lob_is_equal,                    NULL)
     254                 :         PHP_FE(oci_lob_rewind,              NULL)
     255                 :         PHP_FE(oci_lob_write,               NULL)
     256                 :         PHP_FE(oci_lob_append,              NULL)
     257                 :         PHP_FE(oci_lob_copy,                NULL)
     258                 :         PHP_FE(oci_lob_export,              NULL)
     259                 :         PHP_FE(oci_lob_seek,                NULL)
     260                 :         PHP_FE(oci_commit,                  NULL)
     261                 :         PHP_FE(oci_rollback,                NULL)
     262                 :         PHP_FE(oci_new_descriptor,          NULL)
     263                 :         PHP_FE(oci_set_prefetch,            NULL)
     264                 :         PHP_FE(oci_password_change,         NULL)
     265                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     266                 :         PHP_FE(oci_free_collection,         NULL)
     267                 :         PHP_FE(oci_collection_append,       NULL)
     268                 :         PHP_FE(oci_collection_element_get,      NULL)
     269                 :         PHP_FE(oci_collection_element_assign,   NULL)
     270                 :         PHP_FE(oci_collection_assign,       NULL)
     271                 :         PHP_FE(oci_collection_size,         NULL)
     272                 :         PHP_FE(oci_collection_max,          NULL)
     273                 :         PHP_FE(oci_collection_trim,         NULL)
     274                 :         PHP_FE(oci_new_collection,          NULL)
     275                 : #endif
     276                 :         
     277                 :         PHP_FALIAS(oci_free_cursor,     oci_free_statement,       NULL)
     278                 :         PHP_FALIAS(ocifreecursor,       oci_free_statement,       NULL)
     279                 :         PHP_FALIAS(ocibindbyname,       oci_bind_by_name,       oci_third_arg_force_ref)
     280                 :         PHP_FALIAS(ocidefinebyname,     oci_define_by_name,     oci_third_arg_force_ref)
     281                 :         PHP_FALIAS(ocicolumnisnull,     oci_field_is_null,      NULL)
     282                 :         PHP_FALIAS(ocicolumnname,       oci_field_name,         NULL)
     283                 :         PHP_FALIAS(ocicolumnsize,       oci_field_size,         NULL)
     284                 :         PHP_FALIAS(ocicolumnscale,      oci_field_scale,        NULL)
     285                 :         PHP_FALIAS(ocicolumnprecision,  oci_field_precision,    NULL)
     286                 :         PHP_FALIAS(ocicolumntype,       oci_field_type,         NULL)
     287                 :         PHP_FALIAS(ocicolumntyperaw,    oci_field_type_raw,     NULL)
     288                 :         PHP_FALIAS(ociexecute,          oci_execute,            NULL)
     289                 :         PHP_FALIAS(ocicancel,           oci_cancel,             NULL)
     290                 :         PHP_FALIAS(ocifetch,            oci_fetch,              NULL)
     291                 :         PHP_FALIAS(ocifetchstatement,   oci_fetch_all,          oci_second_arg_force_ref)
     292                 :         PHP_FALIAS(ocifreestatement,    oci_free_statement,     NULL)
     293                 :         PHP_FALIAS(ociinternaldebug,    oci_internal_debug,     NULL)
     294                 :         PHP_FALIAS(ocinumcols,          oci_num_fields,         NULL)
     295                 :         PHP_FALIAS(ociparse,            oci_parse,              NULL)
     296                 :         PHP_FALIAS(ocinewcursor,        oci_new_cursor,         NULL)
     297                 :         PHP_FALIAS(ociresult,           oci_result,             NULL)
     298                 :         PHP_FALIAS(ociserverversion,    oci_server_version,     NULL)
     299                 :         PHP_FALIAS(ocistatementtype,    oci_statement_type,     NULL)
     300                 :         PHP_FALIAS(ocirowcount,         oci_num_rows,           NULL)
     301                 :         PHP_FALIAS(ocilogoff,           oci_close,              NULL)
     302                 :         PHP_FALIAS(ocilogon,            oci_connect,            NULL)
     303                 :         PHP_FALIAS(ocinlogon,           oci_new_connect,        NULL)
     304                 :         PHP_FALIAS(ociplogon,           oci_pconnect,           NULL)
     305                 :         PHP_FALIAS(ocierror,            oci_error,              NULL)
     306                 :         PHP_FALIAS(ocifreedesc,         oci_free_descriptor,    NULL)
     307                 :         PHP_FALIAS(ocisavelob,          oci_lob_save,           NULL)
     308                 :         PHP_FALIAS(ocisavelobfile,      oci_lob_import,         NULL)
     309                 :         PHP_FALIAS(ociwritelobtofile,   oci_lob_export,         NULL)
     310                 :         PHP_FALIAS(ociloadlob,          oci_lob_load,           NULL)
     311                 :         PHP_FALIAS(ocicommit,           oci_commit,             NULL)
     312                 :         PHP_FALIAS(ocirollback,         oci_rollback,           NULL)
     313                 :         PHP_FALIAS(ocinewdescriptor,    oci_new_descriptor,     NULL)
     314                 :         PHP_FALIAS(ocisetprefetch,      oci_set_prefetch,       NULL)
     315                 :         PHP_FALIAS(ocipasswordchange,   oci_password_change,    NULL)
     316                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     317                 :         PHP_FALIAS(ocifreecollection,   oci_free_collection,    NULL)
     318                 :         PHP_FALIAS(ocinewcollection,    oci_new_collection,     NULL)
     319                 :         PHP_FALIAS(ocicollappend,       oci_collection_append,  NULL)
     320                 :         PHP_FALIAS(ocicollgetelem,      oci_collection_element_get,     NULL)
     321                 :         PHP_FALIAS(ocicollassignelem,   oci_collection_element_assign,  NULL)
     322                 :         PHP_FALIAS(ocicollsize,         oci_collection_size,    NULL)
     323                 :         PHP_FALIAS(ocicollmax,          oci_collection_max,     NULL)
     324                 :         PHP_FALIAS(ocicolltrim,         oci_collection_trim,    NULL)
     325                 : #endif
     326                 :         {NULL,NULL,NULL}
     327                 : };
     328                 : 
     329                 : static zend_function_entry php_oci_lob_class_functions[] = {
     330                 :         PHP_FALIAS(load,        oci_lob_load,           NULL)
     331                 :         PHP_FALIAS(tell,        oci_lob_tell,           NULL)
     332                 :         PHP_FALIAS(truncate,    oci_lob_truncate,       NULL)
     333                 :         PHP_FALIAS(erase,       oci_lob_erase,          NULL)
     334                 :         PHP_FALIAS(flush,       oci_lob_flush,          NULL)
     335                 :         PHP_FALIAS(setbuffering,ocisetbufferinglob,     NULL)
     336                 :         PHP_FALIAS(getbuffering,ocigetbufferinglob,     NULL)
     337                 :         PHP_FALIAS(rewind,      oci_lob_rewind,                 NULL)
     338                 :         PHP_FALIAS(read,        oci_lob_read,           NULL)
     339                 :         PHP_FALIAS(eof,         oci_lob_eof,            NULL)
     340                 :         PHP_FALIAS(seek,        oci_lob_seek,           NULL)   
     341                 :         PHP_FALIAS(write,       oci_lob_write,          NULL)
     342                 :         PHP_FALIAS(append,      oci_lob_append,         NULL)
     343                 :         PHP_FALIAS(size,        oci_lob_size,           NULL)
     344                 :         PHP_FALIAS(writetofile, oci_lob_export,         NULL)
     345                 :         PHP_FALIAS(export,      oci_lob_export,         NULL)
     346                 :         PHP_FALIAS(import,      oci_lob_import,         NULL)
     347                 : #ifdef HAVE_OCI8_TEMP_LOB
     348                 :         PHP_FALIAS(writetemporary,  oci_lob_write_temporary,    NULL)
     349                 :         PHP_FALIAS(close,           oci_lob_close,              NULL)
     350                 : #endif
     351                 :         PHP_FALIAS(save,        oci_lob_save,           NULL)
     352                 :         PHP_FALIAS(savefile,    oci_lob_import,         NULL)
     353                 :         PHP_FALIAS(free,        oci_free_descriptor,    NULL)
     354                 :         {NULL,NULL,NULL}
     355                 : };
     356                 : 
     357                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     358                 : static zend_function_entry php_oci_coll_class_functions[] = {
     359                 :         PHP_FALIAS(append,        oci_collection_append,            NULL)
     360                 :         PHP_FALIAS(getelem,       oci_collection_element_get,       NULL)
     361                 :         PHP_FALIAS(assignelem,    oci_collection_element_assign,    NULL)
     362                 :         PHP_FALIAS(assign,        oci_collection_assign,            NULL)
     363                 :         PHP_FALIAS(size,          oci_collection_size,              NULL)
     364                 :         PHP_FALIAS(max,           oci_collection_max,               NULL)
     365                 :         PHP_FALIAS(trim,          oci_collection_trim,              NULL)
     366                 :         PHP_FALIAS(free,          oci_free_collection,              NULL)
     367                 :         {NULL,NULL,NULL}
     368                 : };
     369                 : #endif
     370                 : 
     371                 : zend_module_entry oci8_module_entry = {
     372                 :         STANDARD_MODULE_HEADER,
     373                 :         "oci8",               /* extension name */
     374                 :         php_oci_functions,    /* extension function list */
     375                 :         PHP_MINIT(oci),       /* extension-wide startup function */
     376                 :         PHP_MSHUTDOWN(oci),   /* extension-wide shutdown function */
     377                 :         PHP_RINIT(oci),       /* per-request startup function */
     378                 :         PHP_RSHUTDOWN(oci),   /* per-request shutdown function */
     379                 :         PHP_MINFO(oci),       /* information function */
     380                 :         "1.2.5",
     381                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
     382                 :         PHP_MODULE_GLOBALS(oci),  /* globals descriptor */
     383                 :         PHP_GINIT(oci),           /* globals ctor */
     384                 :         NULL,                     /* globals dtor */
     385                 :         NULL,                     /* post deactivate */
     386                 :         STANDARD_MODULE_PROPERTIES_EX
     387                 : #else
     388                 :         STANDARD_MODULE_PROPERTIES
     389                 : #endif
     390                 : };
     391                 : /* }}} */
     392                 : 
     393                 : /* {{{ PHP_INI */
     394                 : PHP_INI_BEGIN()
     395                 :     STD_PHP_INI_ENTRY("oci8.max_persistent",          "-1", PHP_INI_SYSTEM,         ONUPDATELONGFUNC,               max_persistent,         zend_oci_globals,       oci_globals)
     396                 :     STD_PHP_INI_ENTRY("oci8.persistent_timeout",      "-1", PHP_INI_SYSTEM,         ONUPDATELONGFUNC,               persistent_timeout,     zend_oci_globals,       oci_globals)
     397                 :     STD_PHP_INI_ENTRY("oci8.ping_interval",           "60", PHP_INI_SYSTEM,         ONUPDATELONGFUNC,               ping_interval,          zend_oci_globals,       oci_globals)
     398                 :     STD_PHP_INI_BOOLEAN("oci8.privileged_connect",    "0",  PHP_INI_SYSTEM,         OnUpdateBool,           privileged_connect,     zend_oci_globals,       oci_globals)
     399                 :     STD_PHP_INI_ENTRY("oci8.statement_cache_size",            "20", PHP_INI_SYSTEM,         ONUPDATELONGFUNC,               statement_cache_size,           zend_oci_globals,       oci_globals)
     400                 :     STD_PHP_INI_ENTRY("oci8.default_prefetch",                "10", PHP_INI_SYSTEM,         ONUPDATELONGFUNC,               default_prefetch,               zend_oci_globals,       oci_globals)
     401                 :     STD_PHP_INI_ENTRY("oci8.old_oci_close_semantics",         "0",  PHP_INI_SYSTEM,         OnUpdateBool,           old_oci_close_semantics,                zend_oci_globals,       oci_globals)
     402                 : PHP_INI_END()
     403                 : /* }}} */
     404                 : 
     405                 : /* {{{ startup, shutdown and info functions
     406                 : */
     407                 : 
     408                 : /* {{{  php_oci_init_global_handles()
     409                 :  Initialize global handles only when they are needed 
     410                 : */
     411                 : static void php_oci_init_global_handles(TSRMLS_D)
     412             224 : {
     413                 :         sword errcode;
     414             224 :         sb4 error_code = 0;
     415                 :         text tmp_buf[PHP_OCI_ERRBUF_LEN];
     416                 : 
     417             224 :         errcode = OCIEnvInit (&OCI_G(env), OCI_DEFAULT, 0, NULL);
     418                 :         
     419             224 :         if (errcode == OCI_ERROR) {
     420               0 :                 goto oci_error;
     421                 :         }
     422                 :         
     423             224 :         errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL);
     424                 :         
     425             224 :         if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) {
     426                 :                 goto oci_error;
     427                 :         }
     428                 : 
     429             224 :         return;
     430                 :         
     431               0 : oci_error:
     432                 :         
     433               0 :         OCIErrorGet(OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR);
     434                 : 
     435               0 :         if (error_code) {
     436               0 :                 int tmp_buf_len = strlen((char *)tmp_buf);
     437                 : 
     438               0 :                 if (tmp_buf_len > 0 && tmp_buf[tmp_buf_len - 1] == '\n') {
     439               0 :                         tmp_buf[tmp_buf_len - 1] = '\0';
     440                 :                 }
     441                 :                         
     442               0 :                 if (errcode != OCI_SUCCESS_WITH_INFO) {
     443               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf);
     444                 :                         
     445               0 :                         OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV);
     446                 :                         
     447               0 :                         OCI_G(env) = NULL;
     448               0 :                         OCI_G(err) = NULL;
     449                 :                 } else {
     450               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", tmp_buf);
     451                 :                 }
     452                 :         }
     453                 : } /* }}} */
     454                 : 
     455                 : /* {{{ php_oci_cleanup_global_handles()
     456                 :  Free global handles (if they were initialized before)
     457                 : */
     458                 : static void php_oci_cleanup_global_handles(TSRMLS_D)
     459           13598 : {
     460           13598 :         if (OCI_G(err)) {
     461             224 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR));
     462             223 :                 OCI_G(err) = NULL;
     463                 :         }
     464                 :         
     465           13597 :         if (OCI_G(env)) {
     466             223 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV));
     467             223 :                 OCI_G(env) = NULL;
     468                 :         }
     469           13597 : } /* }}} */
     470                 : 
     471                 : /* {{{ PHP_GINIT_FUNCTION
     472                 :  Zerofill globals during module init
     473                 : */
     474                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
     475                 : static PHP_GINIT_FUNCTION(oci)
     476                 : #else
     477                 : static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC)
     478                 : #endif
     479           13565 : {
     480           13565 :         memset(oci_globals, 0, sizeof(zend_oci_globals));
     481           13565 : }
     482                 : /* }}} */
     483                 : 
     484                 : PHP_MINIT_FUNCTION(oci)
     485           13565 : {
     486                 :         zend_class_entry oci_lob_class_entry;
     487                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     488                 :         zend_class_entry oci_coll_class_entry;
     489                 : #endif
     490                 : 
     491                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     492                 : #define PHP_OCI_INIT_MODE_TMP OCI_DEFAULT | OCI_OBJECT
     493                 : #else
     494                 : #define PHP_OCI_INIT_MODE_TMP OCI_DEFAULT
     495                 : #endif
     496                 : 
     497                 : #ifdef ZTS
     498                 : #define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP | OCI_THREADED
     499                 : #else
     500                 : #define PHP_OCI_INIT_MODE PHP_OCI_INIT_MODE_TMP
     501                 : #endif
     502                 : 
     503                 : #if !HAVE_OCI_ENV_CREATE
     504                 :         OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL);
     505                 : #endif
     506                 : 
     507                 : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
     508                 :         /* this is handled by new globals management code */
     509                 : #else
     510                 :         ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, NULL);
     511                 : #endif
     512           13565 :         REGISTER_INI_ENTRIES();
     513                 : 
     514           13565 :         le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number);
     515           13565 :         le_connection = zend_register_list_destructors_ex(php_oci_connection_list_dtor, NULL, "oci8 connection", module_number);
     516           13565 :         le_pconnection = zend_register_list_destructors_ex(NULL, php_oci_pconnection_list_dtor, "oci8 persistent connection", module_number);
     517           13565 :         le_descriptor = zend_register_list_destructors_ex(php_oci_descriptor_list_dtor, NULL, "oci8 descriptor", module_number);
     518                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     519           13565 :         le_collection = zend_register_list_destructors_ex(php_oci_collection_list_dtor, NULL, "oci8 collection", module_number);
     520                 : #endif
     521                 : 
     522           13565 :         INIT_CLASS_ENTRY(oci_lob_class_entry, "OCI-Lob", php_oci_lob_class_functions);
     523                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     524           13565 :         INIT_CLASS_ENTRY(oci_coll_class_entry, "OCI-Collection", php_oci_coll_class_functions);
     525                 : #endif
     526                 : 
     527           13565 :         oci_lob_class_entry_ptr = zend_register_internal_class(&oci_lob_class_entry TSRMLS_CC);
     528                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     529           13565 :         oci_coll_class_entry_ptr = zend_register_internal_class(&oci_coll_class_entry TSRMLS_CC);
     530                 : #endif
     531                 : 
     532                 : /* thies@thieso.net 990203 i do not think that we will need all of them - just in here for completeness for now! */
     533           13565 :         REGISTER_LONG_CONSTANT("OCI_DEFAULT",OCI_DEFAULT, CONST_CS | CONST_PERSISTENT);
     534           13565 :         REGISTER_LONG_CONSTANT("OCI_SYSOPER",OCI_SYSOPER, CONST_CS | CONST_PERSISTENT);
     535           13565 :         REGISTER_LONG_CONSTANT("OCI_SYSDBA",OCI_SYSDBA, CONST_CS | CONST_PERSISTENT);
     536           13565 :         REGISTER_LONG_CONSTANT("OCI_DESCRIBE_ONLY",OCI_DESCRIBE_ONLY, CONST_CS | CONST_PERSISTENT);
     537           13565 :         REGISTER_LONG_CONSTANT("OCI_COMMIT_ON_SUCCESS",OCI_COMMIT_ON_SUCCESS, CONST_CS | CONST_PERSISTENT);
     538           13565 :         REGISTER_LONG_CONSTANT("OCI_EXACT_FETCH",OCI_EXACT_FETCH, CONST_CS | CONST_PERSISTENT);
     539                 : 
     540                 : /* for $LOB->seek() */
     541           13565 :         REGISTER_LONG_CONSTANT("OCI_SEEK_SET",PHP_OCI_SEEK_SET, CONST_CS | CONST_PERSISTENT);
     542           13565 :         REGISTER_LONG_CONSTANT("OCI_SEEK_CUR",PHP_OCI_SEEK_CUR, CONST_CS | CONST_PERSISTENT);
     543           13565 :         REGISTER_LONG_CONSTANT("OCI_SEEK_END",PHP_OCI_SEEK_END, CONST_CS | CONST_PERSISTENT);
     544                 : 
     545                 : /*      for $LOB->flush() */
     546           13565 :         REGISTER_LONG_CONSTANT("OCI_LOB_BUFFER_FREE",OCI_LOB_BUFFER_FREE, CONST_CS | CONST_PERSISTENT);
     547                 :         
     548                 : /* for OCIBindByName (real "oci" names + short "php" names*/
     549           13565 :         REGISTER_LONG_CONSTANT("SQLT_BFILEE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
     550           13565 :         REGISTER_LONG_CONSTANT("SQLT_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
     551           13565 :         REGISTER_LONG_CONSTANT("SQLT_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
     552           13565 :         REGISTER_LONG_CONSTANT("SQLT_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
     553           13565 :         REGISTER_LONG_CONSTANT("SQLT_RDD",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
     554           13565 :         REGISTER_LONG_CONSTANT("SQLT_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);     
     555           13565 :         REGISTER_LONG_CONSTANT("SQLT_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);     
     556           13565 :         REGISTER_LONG_CONSTANT("SQLT_RSET",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
     557           13565 :         REGISTER_LONG_CONSTANT("SQLT_AFC",SQLT_AFC, CONST_CS | CONST_PERSISTENT);
     558           13565 :         REGISTER_LONG_CONSTANT("SQLT_CHR",SQLT_CHR, CONST_CS | CONST_PERSISTENT);
     559           13565 :         REGISTER_LONG_CONSTANT("SQLT_VCS",SQLT_VCS, CONST_CS | CONST_PERSISTENT);
     560           13565 :         REGISTER_LONG_CONSTANT("SQLT_AVC",SQLT_AVC, CONST_CS | CONST_PERSISTENT);
     561           13565 :         REGISTER_LONG_CONSTANT("SQLT_STR",SQLT_STR, CONST_CS | CONST_PERSISTENT);
     562           13565 :         REGISTER_LONG_CONSTANT("SQLT_LVC",SQLT_LVC, CONST_CS | CONST_PERSISTENT);
     563           13565 :         REGISTER_LONG_CONSTANT("SQLT_FLT",SQLT_FLT, CONST_CS | CONST_PERSISTENT);
     564           13565 :         REGISTER_LONG_CONSTANT("SQLT_UIN",SQLT_UIN, CONST_CS | CONST_PERSISTENT);
     565           13565 :         REGISTER_LONG_CONSTANT("SQLT_LNG",SQLT_LNG, CONST_CS | CONST_PERSISTENT);
     566           13565 :         REGISTER_LONG_CONSTANT("SQLT_LBI",SQLT_LBI, CONST_CS | CONST_PERSISTENT);
     567           13565 :         REGISTER_LONG_CONSTANT("SQLT_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
     568           13565 :         REGISTER_LONG_CONSTANT("SQLT_ODT",SQLT_ODT, CONST_CS | CONST_PERSISTENT);
     569                 : #if defined(HAVE_OCI_INSTANT_CLIENT) || (defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION > 10)
     570                 :         REGISTER_LONG_CONSTANT("SQLT_BDOUBLE",SQLT_BDOUBLE, CONST_CS | CONST_PERSISTENT);
     571                 :         REGISTER_LONG_CONSTANT("SQLT_BFLOAT",SQLT_BFLOAT, CONST_CS | CONST_PERSISTENT);
     572                 : #endif
     573                 : 
     574                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     575           13565 :         REGISTER_LONG_CONSTANT("OCI_B_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);
     576           13565 :         REGISTER_LONG_CONSTANT("SQLT_NTY",SQLT_NTY, CONST_CS | CONST_PERSISTENT);     
     577           13565 :         REGISTER_STRING_CONSTANT("OCI_SYSDATE","SYSDATE", CONST_CS | CONST_PERSISTENT);
     578                 : #endif
     579                 : 
     580           13565 :         REGISTER_LONG_CONSTANT("OCI_B_BFILE",SQLT_BFILEE, CONST_CS | CONST_PERSISTENT);
     581           13565 :         REGISTER_LONG_CONSTANT("OCI_B_CFILEE",SQLT_CFILEE, CONST_CS | CONST_PERSISTENT);
     582           13565 :         REGISTER_LONG_CONSTANT("OCI_B_CLOB",SQLT_CLOB, CONST_CS | CONST_PERSISTENT);
     583           13565 :         REGISTER_LONG_CONSTANT("OCI_B_BLOB",SQLT_BLOB, CONST_CS | CONST_PERSISTENT);
     584           13565 :         REGISTER_LONG_CONSTANT("OCI_B_ROWID",SQLT_RDD, CONST_CS | CONST_PERSISTENT);
     585           13565 :         REGISTER_LONG_CONSTANT("OCI_B_CURSOR",SQLT_RSET, CONST_CS | CONST_PERSISTENT);
     586           13565 :         REGISTER_LONG_CONSTANT("OCI_B_BIN",SQLT_BIN, CONST_CS | CONST_PERSISTENT);
     587           13565 :         REGISTER_LONG_CONSTANT("OCI_B_INT",SQLT_INT, CONST_CS | CONST_PERSISTENT);
     588           13565 :         REGISTER_LONG_CONSTANT("OCI_B_NUM",SQLT_NUM, CONST_CS | CONST_PERSISTENT);
     589                 : 
     590                 : /* for OCIFetchStatement */
     591           13565 :         REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_COLUMN", PHP_OCI_FETCHSTATEMENT_BY_COLUMN, CONST_CS | CONST_PERSISTENT);
     592           13565 :         REGISTER_LONG_CONSTANT("OCI_FETCHSTATEMENT_BY_ROW", PHP_OCI_FETCHSTATEMENT_BY_ROW, CONST_CS | CONST_PERSISTENT);
     593                 : 
     594                 : /* for OCIFetchInto &  OCIResult */
     595           13565 :         REGISTER_LONG_CONSTANT("OCI_ASSOC",PHP_OCI_ASSOC, CONST_CS | CONST_PERSISTENT);
     596           13565 :         REGISTER_LONG_CONSTANT("OCI_NUM",PHP_OCI_NUM, CONST_CS | CONST_PERSISTENT);
     597           13565 :         REGISTER_LONG_CONSTANT("OCI_BOTH",PHP_OCI_BOTH, CONST_CS | CONST_PERSISTENT);
     598           13565 :         REGISTER_LONG_CONSTANT("OCI_RETURN_NULLS",PHP_OCI_RETURN_NULLS, CONST_CS | CONST_PERSISTENT);
     599           13565 :         REGISTER_LONG_CONSTANT("OCI_RETURN_LOBS",PHP_OCI_RETURN_LOBS, CONST_CS | CONST_PERSISTENT);
     600                 : 
     601                 : /* for OCINewDescriptor (real "oci" names + short "php" names*/
     602           13565 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
     603           13565 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
     604           13565 :         REGISTER_LONG_CONSTANT("OCI_DTYPE_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
     605                 : 
     606           13565 :         REGISTER_LONG_CONSTANT("OCI_D_FILE",OCI_DTYPE_FILE, CONST_CS | CONST_PERSISTENT);
     607           13565 :         REGISTER_LONG_CONSTANT("OCI_D_LOB",OCI_DTYPE_LOB, CONST_CS | CONST_PERSISTENT);
     608           13565 :         REGISTER_LONG_CONSTANT("OCI_D_ROWID",OCI_DTYPE_ROWID, CONST_CS | CONST_PERSISTENT);
     609                 : 
     610                 : /* for OCIWriteTemporaryLob */
     611                 : #ifdef HAVE_OCI8_TEMP_LOB
     612           13565 :         REGISTER_LONG_CONSTANT("OCI_TEMP_CLOB",OCI_TEMP_CLOB, CONST_CS | CONST_PERSISTENT);
     613           13565 :         REGISTER_LONG_CONSTANT("OCI_TEMP_BLOB",OCI_TEMP_BLOB, CONST_CS | CONST_PERSISTENT);
     614                 : #endif
     615                 : 
     616           13565 :         return SUCCESS;
     617                 : }
     618                 : 
     619                 : /* ----------------------------------------------------------------- */
     620                 : 
     621                 : PHP_RINIT_FUNCTION(oci)
     622           13551 : {
     623           13551 :         OCI_G(debug_mode) = 0; /* start "fresh" */
     624           13551 :         OCI_G(num_links) = OCI_G(num_persistent);
     625           13551 :         OCI_G(errcode) = 0;
     626                 : 
     627           13551 :         return SUCCESS;
     628                 : }
     629                 : 
     630                 : PHP_MSHUTDOWN_FUNCTION(oci)
     631           13598 : {
     632           13598 :         OCI_G(shutdown) = 1;
     633                 :         
     634           13598 :         UNREGISTER_INI_ENTRIES();
     635                 : 
     636                 : #ifndef ZTS
     637           13598 :         php_oci_cleanup_global_handles(TSRMLS_C);
     638                 : #endif
     639                 : 
     640                 : #if !HAVE_OCI_ENV_CREATE
     641                 :         OCITerminate(OCI_DEFAULT);
     642                 : #endif
     643                 : 
     644           13597 :         return SUCCESS;
     645                 : }
     646                 : 
     647                 : PHP_RSHUTDOWN_FUNCTION(oci)
     648           13584 : {
     649                 : #ifdef ZTS
     650                 :         zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_descriptor TSRMLS_CC);
     651                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS 
     652                 :         zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_collection TSRMLS_CC);
     653                 : #endif
     654                 :         while (OCI_G(num_statements)) { 
     655                 :                 zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_statement TSRMLS_CC);
     656                 :         }
     657                 : #endif
     658                 : 
     659                 :         /* check persistent connections and do the necessary actions if needed */
     660           13584 :         zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
     661                 : 
     662                 : #ifdef ZTS
     663                 :         zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_connection TSRMLS_CC);
     664                 :         php_oci_cleanup_global_handles(TSRMLS_C);
     665                 : #endif
     666                 : 
     667           13584 :         return SUCCESS;
     668                 : }
     669                 : 
     670                 : PHP_MINFO_FUNCTION(oci)
     671               6 : {
     672                 :         char buf[32];
     673                 : 
     674               6 :         php_info_print_table_start();
     675               6 :         php_info_print_table_row(2, "OCI8 Support", "enabled");
     676               6 :         php_info_print_table_row(2, "Version", "1.2.5");
     677               6 :         php_info_print_table_row(2, "Revision", "$Revision: 272374 $");
     678                 : 
     679               6 :         snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent));
     680               6 :         php_info_print_table_row(2, "Active Persistent Connections", buf);
     681               6 :         snprintf(buf, sizeof(buf), "%ld", OCI_G(num_links));
     682               6 :         php_info_print_table_row(2, "Active Connections", buf);
     683                 : 
     684                 : #if !defined(PHP_WIN32) && !defined(HAVE_OCI_INSTANT_CLIENT)
     685               6 :         php_info_print_table_row(2, "Oracle Version", PHP_OCI8_VERSION );
     686               6 :         php_info_print_table_row(2, "Compile-time ORACLE_HOME", PHP_OCI8_DIR );
     687               6 :         php_info_print_table_row(2, "Libraries Used", PHP_OCI8_SHARED_LIBADD );
     688                 : #else 
     689                 : #       if defined(HAVE_OCI_INSTANT_CLIENT) && defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION) 
     690                 :         snprintf(buf, sizeof(buf), "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION);
     691                 :         php_info_print_table_row(2, "Oracle Instant Client Version", buf);
     692                 : #       endif
     693                 : #endif
     694                 : 
     695                 : #ifdef HAVE_OCI8_TEMP_LOB
     696               6 :         php_info_print_table_row(2, "Temporary Lob support", "enabled" );
     697                 : #else
     698                 :         php_info_print_table_row(2, "Temporary Lob support", "disabled" );
     699                 : #endif
     700                 : 
     701                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     702               6 :         php_info_print_table_row(2, "Collections support", "enabled" );
     703                 : #else
     704                 :         php_info_print_table_row(2, "Collections support", "disabled" );
     705                 : #endif
     706                 : 
     707               6 :         php_info_print_table_end();
     708                 :         
     709               6 :         DISPLAY_INI_ENTRIES();
     710               6 : }
     711                 : /* }}} */
     712                 : 
     713                 : /* list destructors {{{ */
     714                 : 
     715                 : /* {{{ php_oci_connection_list_dtor()
     716                 :  Non-persistent connection destructor */
     717                 : static void php_oci_connection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
     718             252 : {
     719             252 :         php_oci_connection *connection = (php_oci_connection *)entry->ptr;
     720             252 :         php_oci_connection_close(connection TSRMLS_CC);
     721             252 :         OCI_G(num_links)--;
     722             252 : } /* }}} */
     723                 : 
     724                 : /* {{{ php_oci_pconnection_list_dtor()
     725                 :  Persistent connection destructor */
     726                 : static void php_oci_pconnection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
     727              25 : {
     728              25 :         php_oci_connection *connection = (php_oci_connection *)entry->ptr;
     729              25 :         php_oci_connection_close(connection TSRMLS_CC);
     730              25 :         OCI_G(num_persistent)--;
     731              25 : } /* }}} */
     732                 : 
     733                 : /* {{{ php_oci_statement_list_dtor()
     734                 :  Statement destructor */
     735                 : static void php_oci_statement_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
     736           33839 : {
     737           33839 :         php_oci_statement *statement = (php_oci_statement *)entry->ptr;
     738           33839 :         php_oci_statement_free(statement TSRMLS_CC);
     739           33839 : } /* }}} */
     740                 : 
     741                 : /* {{{ php_oci_descriptor_list_dtor()
     742                 :  Descriptor destructor */
     743                 : static void php_oci_descriptor_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
     744          183673 : {
     745          183673 :         php_oci_descriptor *descriptor = (php_oci_descriptor *)entry->ptr;
     746          183673 :         php_oci_lob_free(descriptor TSRMLS_CC);
     747          183673 : } /* }}} */
     748                 : 
     749                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS 
     750                 : /* {{{ php_oci_collection_list_dtor()
     751                 :  Collection destructor */
     752                 : static void php_oci_collection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC)
     753           70047 : {
     754           70047 :         php_oci_collection *collection = (php_oci_collection *)entry->ptr;
     755           70047 :         php_oci_collection_close(collection TSRMLS_CC);
     756           70047 : } /* }}} */
     757                 : #endif
     758                 : 
     759                 : /* }}} */
     760                 : 
     761                 : /* hash destructors {{{ */
     762                 : 
     763                 : /* {{{ php_oci_define_hash_dtor()
     764                 :  Define hash destructor */
     765                 : void php_oci_define_hash_dtor(void *data)
     766           30020 : {
     767           30020 :         php_oci_define *define = (php_oci_define *) data;
     768                 : 
     769           30020 :         zval_ptr_dtor(&define->zval);
     770                 : 
     771           30020 :         if (define->name) {
     772           30020 :                 efree(define->name);
     773           30020 :                 define->name = NULL;
     774                 :         }
     775           30020 : }
     776                 : /* }}} */
     777                 : 
     778                 : /* {{{ php_oci_bind_hash_dtor()
     779                 :  Bind hash destructor */
     780                 : void php_oci_bind_hash_dtor(void *data)
     781             324 : {
     782             324 :         php_oci_bind *bind = (php_oci_bind *) data;
     783                 : 
     784             324 :         if (bind->array.elements) {
     785              17 :                 efree(bind->array.elements);
     786                 :         }
     787                 : 
     788             324 :         if (bind->array.element_lengths) {
     789              17 :                 efree(bind->array.element_lengths);
     790                 :         }
     791                 : 
     792             324 :         if (bind->array.indicators) {
     793               8 :                 efree(bind->array.indicators);
     794                 :         }
     795                 : 
     796                 : /*
     797                 :         if (bind->array.retcodes) {
     798                 :                 efree(bind->array.retcodes);
     799                 :         } 
     800                 : */
     801                 : 
     802             324 :         zval_ptr_dtor(&bind->zval);
     803             324 : }
     804                 : /* }}} */
     805                 : 
     806                 : /* {{{ php_oci_column_hash_dtor()
     807                 :  Column hash destructor */
     808                 : void php_oci_column_hash_dtor(void *data)
     809           63182 : {
     810           63182 :         php_oci_out_column *column = (php_oci_out_column *) data;
     811                 :         TSRMLS_FETCH();
     812                 : 
     813           63182 :         if (column->stmtid) {
     814            1405 :                 zend_list_delete(column->stmtid);
     815                 :         }
     816                 : 
     817           63182 :         if (column->is_descr) {
     818           60156 :                 zend_list_delete(column->descid);
     819                 :         }
     820                 : 
     821           63182 :         if (column->data) {
     822            1619 :                 efree(column->data);
     823                 :         }
     824                 : 
     825           63182 :         if (column->name) {
     826           63182 :                 efree(column->name);
     827                 :         }
     828           63182 : }
     829                 : /* }}} */
     830                 : 
     831                 : /* {{{ php_oci_descriptor_flush_hash_dtor()
     832                 :  Flush descriptors on commit */
     833                 : void php_oci_descriptor_flush_hash_dtor(void *data)
     834          183669 : {
     835          183669 :         php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
     836                 :         TSRMLS_FETCH();
     837                 :         
     838          183669 :         if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
     839               1 :                 php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
     840               1 :                 descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
     841                 :         }
     842          183669 :         data = NULL;
     843          183669 : }
     844                 : /* }}} */
     845                 : 
     846                 : /* {{{ php_oci_descriptor_delete_from_hash()
     847                 :  Delete descriptor from the hash */
     848                 : int php_oci_descriptor_delete_from_hash(void *data, void *id TSRMLS_DC)
     849         2516399 : {
     850         2516399 :         php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
     851         2516399 :         int *desc_id = (int *) id;
     852                 :         
     853         2516399 :         if (descriptor && desc_id && descriptor->id == *desc_id) {
     854          183612 :                 return 1;
     855                 :         }
     856         2332787 :         return 0;
     857                 : }
     858                 : /* }}} */
     859                 : 
     860                 : /* }}} */
     861                 : 
     862                 : /* {{{ php_oci_error()
     863                 :  Fetch & print out error message if we get an error */
     864                 : sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
     865             206 : {
     866             206 :         text *errbuf = (text *)NULL;
     867             206 :         sb4 errcode = 0;
     868                 : 
     869             206 :         switch (status) {
     870                 :                 case OCI_SUCCESS:
     871               0 :                         break;
     872                 :                 case OCI_SUCCESS_WITH_INFO:
     873               1 :                         errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
     874               1 :                         if (errbuf) {
     875               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf);
     876               1 :                                 efree(errbuf);
     877                 :                         } else {
     878               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_SUCCESS_WITH_INFO: failed to fetch error message");
     879                 :                         }
     880               1 :                         break;
     881                 :                 case OCI_NEED_DATA:
     882               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NEED_DATA");
     883               0 :                         break;
     884                 :                 case OCI_NO_DATA:
     885               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA");
     886               2 :                         break;
     887                 :                 case OCI_ERROR: 
     888             200 :                         errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC);
     889             200 :                         if (errbuf) {
     890             200 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf);
     891             200 :                                 efree(errbuf);
     892                 :                         } else {
     893               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to fetch error message");
     894                 :                         }
     895             200 :                         break;
     896                 :                 case OCI_INVALID_HANDLE:
     897               3 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_INVALID_HANDLE");
     898               3 :                         break;
     899                 :                 case OCI_STILL_EXECUTING:
     900               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_STILL_EXECUTING");
     901               0 :                         break;
     902                 :                 case OCI_CONTINUE:
     903               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE");
     904               0 :                         break;
     905                 :                 default:
     906               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", status);
     907                 :                         break;
     908                 :         }
     909             206 :         return errcode;
     910                 : }
     911                 : /* }}} */
     912                 : 
     913                 : /* {{{ php_oci_fetch_errmsg()
     914                 :  Fetch error message into the buffer from the error handle provided */
     915                 : sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC)
     916             219 : {
     917             219 :         sb4 error_code = 0;
     918                 :         text tmp_buf[PHP_OCI_ERRBUF_LEN];
     919                 : 
     920             219 :         tmp_buf[0] = '\0';
     921                 :         
     922             219 :         PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR));
     923                 :         
     924             219 :         if (error_code) {
     925             219 :                 int tmp_buf_len = strlen((char *)tmp_buf);
     926                 :                 
     927             219 :                 if (tmp_buf_len && tmp_buf[tmp_buf_len - 1] == '\n') {
     928             219 :                         tmp_buf[tmp_buf_len - 1] = '\0';
     929                 :                 }
     930             219 :                 if (tmp_buf_len && error_buf) {
     931             219 :                         *error_buf = NULL;
     932             219 :                         *error_buf = (text *)estrndup((char *)tmp_buf, tmp_buf_len);
     933                 :                 }
     934                 :         }
     935             219 :         return error_code;
     936                 : } /* }}} */
     937                 : 
     938                 : #ifdef HAVE_OCI8_ATTR_STATEMENT
     939                 : /* {{{ php_oci_fetch_sqltext_offset()
     940                 :  Compute offset in the SQL statement */
     941                 : int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset TSRMLS_DC)
     942               9 : {
     943               9 :         *sqltext = NULL;
     944               9 :         *error_offset = 0;
     945                 : 
     946               9 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (text *) sqltext, (ub4 *)0, OCI_ATTR_STATEMENT, statement->err));
     947                 :         
     948               9 :         if (statement->errcode != OCI_SUCCESS) { 
     949               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     950               0 :                 return 1;
     951                 :         }
     952                 : 
     953               9 :         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));
     954                 :         
     955               9 :         if (statement->errcode != OCI_SUCCESS) { 
     956               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     957               0 :                 return 1;
     958                 :         }
     959               9 :         return 0;
     960                 : } /* }}} */
     961                 : #endif
     962                 : 
     963                 : /* {{{ php_oci_do_connect() 
     964                 :  Connect wrapper */
     965                 : void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive)
     966             319 : {
     967                 :         php_oci_connection *connection;
     968                 :         char *username, *password;
     969             319 :         char *dbname = NULL, *charset = NULL;
     970             319 :         int username_len = 0, password_len = 0;
     971             319 :         int dbname_len = 0, charset_len = 0;
     972             319 :         long session_mode = OCI_DEFAULT;
     973                 : 
     974                 :         /* if a fourth parameter is handed over, it is the charset identifier (but is only used in Oracle 9i+) */
     975             319 :         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) {
     976               5 :                 return;
     977                 :         } 
     978                 :         
     979             314 :         if (!charset_len) {
     980             306 :                 charset = NULL;
     981                 :         }
     982                 :         
     983             314 :         connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC);
     984                 : 
     985             314 :         if (!connection) {
     986              14 :                 RETURN_FALSE;
     987                 :         }
     988             300 :         RETURN_RESOURCE(connection->rsrc_id);
     989                 :         
     990                 : } /* }}} */
     991                 : 
     992                 : /* {{{ php_oci_do_connect_ex()
     993                 :  * The real connect function. Allocates all the resources needed, establishes the connection and returns the result handle (or NULL) */
     994                 : 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) 
     995             318 : {
     996                 :         zend_rsrc_list_entry *le;
     997                 :         zend_rsrc_list_entry new_le;
     998             318 :         php_oci_connection *connection = NULL;
     999             318 :         smart_str hashed_details = {0};
    1000                 :         time_t timestamp;
    1001                 : #if HAVE_OCI_ENV_NLS_CREATE
    1002             318 :         ub2 charsetid = 0;
    1003             318 :         ub2 charsetid_nls_lang = 0;
    1004                 : #endif
    1005                 :         
    1006             318 :         switch (session_mode) {
    1007                 :                 case OCI_DEFAULT:
    1008             305 :                         break;
    1009                 :                 case OCI_SYSOPER:
    1010                 :                 case OCI_SYSDBA:
    1011              11 :                         if (!OCI_G(privileged_connect)) {
    1012               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");
    1013               2 :                                 return NULL;
    1014                 :                         }
    1015                 :                         /*  Disable privileged connections in Safe Mode (N.b. safe mode has been removed in PHP 6 anyway) */
    1016               9 :                         if (PG(safe_mode)) {
    1017               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Privileged connect is disabled in Safe Mode");
    1018               1 :                                 return NULL;
    1019                 :                         }
    1020                 :                         /* Increase security by not caching privileged
    1021                 :                          * oci_pconnect() connections. The connection becomes
    1022                 :                          * equivalent to oci_connect() or oci_new_connect().
    1023                 :                          */
    1024               8 :                         persistent = 0;
    1025               8 :                         break;
    1026                 :                 default:
    1027               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid session mode specified (%ld)", session_mode);
    1028               2 :                         return NULL;
    1029                 :                         break;
    1030                 :         }
    1031                 : 
    1032             313 :         smart_str_appendl_ex(&hashed_details, "oci8___", sizeof("oci8___") - 1, 0);
    1033             313 :         smart_str_appendl_ex(&hashed_details, username, username_len, 0);
    1034             313 :         smart_str_appendl_ex(&hashed_details, "__", sizeof("__") - 1, 0);
    1035             313 :         if (password_len) {
    1036                 :                 ulong password_hash;
    1037             311 :                 password_hash = zend_inline_hash_func(password, password_len);
    1038             311 :                 smart_str_append_unsigned_ex(&hashed_details, password_hash, 0);
    1039                 :         }
    1040             313 :         smart_str_appendl_ex(&hashed_details, "__", sizeof("__") - 1, 0);
    1041                 : 
    1042             313 :         if (dbname) {
    1043             313 :                 smart_str_appendl_ex(&hashed_details, dbname, dbname_len, 0);
    1044                 :         }
    1045             313 :         smart_str_appendl_ex(&hashed_details, "__", sizeof("__") - 1, 0);
    1046                 : 
    1047                 :         /* Initialize global handles if the weren't initialized before */
    1048             313 :         if (OCI_G(env) == NULL) {
    1049             224 :                 php_oci_init_global_handles(TSRMLS_C);
    1050                 :         }
    1051                 : 
    1052                 : #if HAVE_OCI_ENV_NLS_CREATE
    1053             313 :         if (charset && *charset) {
    1054               8 :                 PHP_OCI_CALL_RETURN(charsetid, OCINlsCharSetNameToId, (OCI_G(env), (CONST oratext *)charset));
    1055               8 :                 if (!charsetid) {
    1056               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid character set name: %s", charset);
    1057                 :                 } else {
    1058               6 :                         smart_str_append_unsigned_ex(&hashed_details, charsetid, 0);
    1059                 :                 }
    1060                 :         }
    1061                 : 
    1062                 :         /* use NLS_LANG if no or invalid charset specified */
    1063             313 :         if (!charsetid) {
    1064             307 :                 size_t rsize = 0;
    1065                 :                 sword result;
    1066                 : 
    1067             307 :                 PHP_OCI_CALL_RETURN(result, OCINlsEnvironmentVariableGet, (&charsetid_nls_lang, 0, OCI_NLS_CHARSET_ID, 0, &rsize));
    1068             307 :                 if (result != OCI_SUCCESS) {
    1069               0 :                         charsetid_nls_lang = 0;
    1070                 :                 }
    1071             307 :                 smart_str_append_unsigned_ex(&hashed_details, charsetid_nls_lang, 0);
    1072                 :         }
    1073                 : #else
    1074                 :         if (charset && *charset) {
    1075                 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Your version of Oracle Client doesn't support setting the charset; bad or no charset conversions may result");
    1076                 :         }
    1077                 : #endif
    1078                 : 
    1079             313 :         timestamp = time(NULL);
    1080                 :         
    1081             313 :         smart_str_append_unsigned_ex(&hashed_details, session_mode, 0);
    1082             313 :         smart_str_0(&hashed_details);
    1083                 : 
    1084                 :         /* make it lowercase */
    1085             313 :         php_strtolower(hashed_details.c, hashed_details.len);
    1086                 :         
    1087             313 :         if (!exclusive && !new_password) {
    1088             281 :                 zend_bool found = 0;
    1089                 : 
    1090             291 :                 if (persistent && zend_hash_find(&EG(persistent_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
    1091              10 :                         found = 1;
    1092                 :                         /* found */
    1093              10 :                         if (le->type == le_pconnection) {
    1094              10 :                                 connection = (php_oci_connection *)le->ptr;  
    1095                 :                         }
    1096             271 :                 } else if (!persistent && zend_hash_find(&EG(regular_list), hashed_details.c, hashed_details.len+1, (void **) &le) == SUCCESS) {
    1097              22 :                         found = 1;
    1098              22 :                         if (le->type == le_index_ptr) {
    1099                 :                                 int type, link;
    1100                 :                                 void *ptr;
    1101                 : 
    1102              22 :                                 link = (int) le->ptr;
    1103              22 :                                 ptr = zend_list_find(link,&type);
    1104              22 :                                 if (ptr && (type == le_connection)) {
    1105              17 :                                         connection = (php_oci_connection *)ptr;
    1106                 :                                 }
    1107                 :                         }
    1108                 :                 }
    1109                 : 
    1110             281 :                 if (connection) {
    1111              27 :                         if (connection->is_open) {
    1112                 :                                 /* found an open connection. now ping it */
    1113              27 :                                 if (connection->is_persistent) {
    1114                 :                                         /* check connection liveness in the following order:
    1115                 :                                          * 1) always check OCI_ATTR_SERVER_STATUS
    1116                 :                                          * 2) see if it's time to ping it
    1117                 :                                          * 3) ping it if needed 
    1118                 :                                          * */
    1119              10 :                                         if (php_oci_connection_status(connection TSRMLS_CC)) {
    1120                 :                                                 /* only ping if: 
    1121                 :                                                  * 1) next_ping > 0, which means that ping_interval is not -1 (aka "Off")
    1122                 :                                                  * 2) current_timestamp > next_ping, which means "it's time to check if it's still alive"
    1123                 :                                                  * */
    1124              10 :                                                 if ( (connection->next_ping > 0) && (timestamp >= connection->next_ping) && !php_oci_connection_ping(connection TSRMLS_CC)) {
    1125                 :                                                         /* server died */
    1126                 :                                                 } else {
    1127                 :                                                         int rsrc_type;
    1128                 :                                                         php_oci_connection *tmp;
    1129                 : 
    1130                 :                                                         /* okay, the connection is open and the server is still alive */
    1131              10 :                                                         connection->used_this_request = 1;
    1132              10 :                                                         tmp = (php_oci_connection *)zend_list_find(connection->rsrc_id, &rsrc_type);
    1133                 : 
    1134              10 :                                                         if (tmp != NULL && rsrc_type == le_pconnection && strlen(tmp->hash_key) == hashed_details.len &&
    1135                 :                                                                 memcmp(tmp->hash_key, hashed_details.c, hashed_details.len) == 0 && zend_list_addref(connection->rsrc_id) == SUCCESS) {
    1136                 :                                                                 /* do nothing */
    1137                 :                                                         } else {
    1138               7 :                                                                 connection->rsrc_id = zend_list_insert(connection, le_pconnection);
    1139                 :                                                         }
    1140              10 :                                                         smart_str_free_ex(&hashed_details, 0);
    1141              10 :                                                         return connection;
    1142                 :                                                 }
    1143                 :                                         }
    1144                 :                                         /* server died */
    1145               0 :                                         connection->is_open = 0;
    1146               0 :                                         zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
    1147               0 :                                         connection = NULL;
    1148               0 :                                         goto open;
    1149                 :                                 } else {
    1150                 :                                         /* we do not ping non-persistent connections */
    1151              17 :                                         smart_str_free_ex(&hashed_details, 0);
    1152              17 :                                         zend_list_addref(connection->rsrc_id);
    1153              17 :                                         return connection;
    1154                 :                                 }
    1155                 :                         } else {
    1156               0 :                                 zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
    1157               0 :                                 connection = NULL;
    1158               0 :                                 goto open;
    1159                 :                         }
    1160             254 :                 } else if (found) {
    1161                 :                         /* found something, but it's not a connection, delete it */
    1162               5 :                         if (persistent) {
    1163               0 :                                 zend_hash_del(&EG(persistent_list), hashed_details.c, hashed_details.len+1);
    1164                 :                         } else {
    1165               5 :                                 zend_hash_del(&EG(regular_list), hashed_details.c, hashed_details.len+1);
    1166                 :                         }
    1167                 :                 }
    1168                 :         }
    1169             286 : open:
    1170             286 :         if (persistent) {
    1171              25 :                 zend_bool alloc_non_persistent = 0;
    1172                 :                         
    1173              25 :                 if (OCI_G(max_persistent)!=-1 && OCI_G(num_persistent)>=OCI_G(max_persistent)) {
    1174                 :                         /* try to find an idle connection and kill it */
    1175               0 :                         zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
    1176                 :                         
    1177               0 :                         if (OCI_G(max_persistent)!=-1 && OCI_G(num_persistent)>=OCI_G(max_persistent)) {
    1178                 :                                 /* all persistent connactions are in use, fallback to non-persistent connection creation */
    1179               0 :                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Too many open persistent connections (%ld)", OCI_G(num_persistent));
    1180               0 :                                 alloc_non_persistent = 1;
    1181                 :                         }
    1182                 :                 }
    1183                 :                 
    1184              25 :                 if (alloc_non_persistent) {
    1185               0 :                         connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
    1186               0 :                         connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
    1187               0 :                         connection->is_persistent = 0;
    1188                 :                 } else {
    1189              25 :                         connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection));
    1190              25 :                         connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len);
    1191              25 :                         connection->is_persistent = 1;
    1192                 :                 }
    1193                 :         } else {
    1194             261 :                 connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
    1195             261 :                 connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
    1196             261 :                 connection->is_persistent = 0;
    1197                 :         }
    1198                 : 
    1199             286 :         connection->idle_expiry = (OCI_G(persistent_timeout) > 0) ? (timestamp + OCI_G(persistent_timeout)) : 0;
    1200             286 :         if (OCI_G(ping_interval) >= 0) {
    1201             286 :                 connection->next_ping = timestamp + OCI_G(ping_interval);
    1202                 :         } else {
    1203                 :                 /* -1 means "Off" */
    1204               0 :                 connection->next_ping = 0;
    1205                 :         }
    1206                 : 
    1207                 :         /* mark password as unchanged by PHP during the duration of the database session */
    1208             286 :         connection->passwd_changed = 0;
    1209                 :         
    1210             286 :         smart_str_free_ex(&hashed_details, 0);
    1211                 : 
    1212                 :         /* allocate environment handle */
    1213                 : #if HAVE_OCI_ENV_NLS_CREATE
    1214                 : #define PHP_OCI_INIT_FUNC_NAME "OCIEnvNlsCreate"
    1215                 :         
    1216             286 :         if (charsetid) {
    1217               6 :                 connection->charset = charsetid;
    1218                 :         } else {
    1219             280 :                 connection->charset = charsetid_nls_lang;
    1220                 :         }
    1221                 : 
    1222                 :         /* create an environment using the character set id, Oracle 9i+ ONLY */
    1223             286 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIEnvNlsCreate, (&(connection->env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, connection->charset, connection->charset));
    1224                 : 
    1225                 : #elif HAVE_OCI_ENV_CREATE
    1226                 : #define PHP_OCI_INIT_FUNC_NAME "OCIEnvCreate"
    1227                 :         
    1228                 :         /* allocate env handle without NLS support */
    1229                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIEnvCreate, (&(connection->env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL));
    1230                 : #else
    1231                 : #define PHP_OCI_INIT_FUNC_NAME "OCIEnvInit"
    1232                 :         
    1233                 :         /* the simpliest way */
    1234                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIEnvInit, (&(connection->env), OCI_DEFAULT, 0, NULL));
    1235                 : #endif
    1236                 : 
    1237             286 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1238                 : #ifdef HAVE_OCI_INSTANT_CLIENT
    1239                 : # ifdef PHP_WIN32
    1240                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_OCI_INIT_FUNC_NAME "() failed. There is something wrong with your system - please check that PATH includes the directory with Oracle Instant Client libraries");
    1241                 : # else
    1242                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_OCI_INIT_FUNC_NAME "() failed. There is something wrong with your system - please check that LD_LIBRARY_PATH includes the directory with Oracle Instant Client libraries");
    1243                 : # endif
    1244                 : #else
    1245               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_OCI_INIT_FUNC_NAME "() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory");
    1246                 : #endif
    1247               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1248               0 :                 return NULL;
    1249                 :         }
    1250                 :         
    1251                 :         /* allocate our server handle {{{ */    
    1252             286 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->server), OCI_HTYPE_SERVER, 0, NULL));
    1253                 :         
    1254             286 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1255               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1256               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1257               0 :                 return NULL;
    1258                 :         } /* }}} */
    1259                 : 
    1260                 :         /* attach to the server {{{ */
    1261             286 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerAttach, (connection->server, OCI_G(err), (text*)dbname, dbname_len, (ub4) OCI_DEFAULT));
    1262                 :         
    1263             286 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1264               3 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1265               3 :                 php_oci_connection_close(connection TSRMLS_CC);
    1266               3 :                 return NULL;
    1267                 :         } /* }}} */
    1268             283 :         connection->is_attached = 1;
    1269                 : 
    1270                 :         /* allocate our session handle {{{ */
    1271             283 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->session), OCI_HTYPE_SESSION, 0, NULL));
    1272                 :         
    1273             283 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1274               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1275               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1276               0 :                 return NULL;
    1277                 :         } /* }}} */
    1278                 : 
    1279                 :         /* allocate our private error-handle {{{ */
    1280             283 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL));
    1281                 : 
    1282             283 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1283               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1284               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1285               0 :                 return NULL;
    1286                 :         } /* }}} */
    1287                 : 
    1288                 :         /* allocate our service-context {{{ */
    1289             283 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->svc), OCI_HTYPE_SVCCTX, 0, NULL));
    1290                 : 
    1291             283 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1292               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1293               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1294               0 :                 return NULL;
    1295                 :         } /* }}} */
    1296                 : 
    1297                 :         /* set the username {{{ */
    1298             283 :         if (username) {
    1299             283 :                 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)));
    1300                 :                 
    1301             283 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1302               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1303               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1304               0 :                         return NULL;
    1305                 :                 } 
    1306                 :         }/* }}} */
    1307                 : 
    1308                 :         /* set the password {{{ */
    1309             283 :         if (password) {
    1310             283 :                 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)));
    1311                 :                 
    1312             283 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1313               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1314               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1315               0 :                         return NULL;
    1316                 :                 } 
    1317                 :         }/* }}} */
    1318                 : 
    1319                 :         /* set the server handle in the service handle {{{ */ 
    1320             283 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err)));
    1321                 : 
    1322             283 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1323               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1324               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1325               0 :                 return NULL;
    1326                 :         } /* }}} */
    1327                 : 
    1328                 :         /* set the authentication handle in the service handle {{{ */
    1329             283 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->session, 0, OCI_ATTR_SESSION, OCI_G(err)));
    1330                 : 
    1331             283 :         if (OCI_G(errcode) != OCI_SUCCESS) {
    1332               0 :                 php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1333               0 :                 php_oci_connection_close(connection TSRMLS_CC);
    1334               0 :                 return NULL;
    1335                 :         } /* }}} */
    1336                 : 
    1337             283 :         if (new_password) {
    1338                 :                 /* try to change password if new one was provided {{{ */
    1339               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));
    1340                 : 
    1341               4 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1342               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1343               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1344               0 :                         return NULL;
    1345                 :                 }
    1346                 : 
    1347               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)));
    1348                 : 
    1349               4 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1350               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1351               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1352               0 :                         return NULL;
    1353                 :                 } /* }}} */
    1354                 :         } else {
    1355                 :                 /* start the session {{{ */
    1356             279 :                 switch (session_mode) {
    1357                 :                         case OCI_DEFAULT:
    1358                 : #if HAVE_OCI_STMT_PREPARE2
    1359                 :                                 /* statement caching is suported only in Oracle 9+ */
    1360             273 :                                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_RDBMS, (ub4) OCI_STMT_CACHE));
    1361                 : #else
    1362                 :                                 /* others cannot use stmt caching, so we call OCISessionBegin() with OCI_DEFAULT */
    1363                 :                                 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_RDBMS, (ub4) OCI_DEFAULT));
    1364                 : #endif
    1365             273 :                                 break;
    1366                 :                         case OCI_SYSDBA:
    1367                 :                         case OCI_SYSOPER:
    1368                 :                         default:
    1369               6 :                                 if (username_len == 1 && username[0] == '/' && password_len == 0) {
    1370               0 :                                         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_EXT, (ub4) session_mode));
    1371                 :                                 } else {
    1372               6 :                                         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionBegin, (connection->svc, OCI_G(err), connection->session, (ub4) OCI_CRED_RDBMS, (ub4) session_mode));
    1373                 :                                 }
    1374                 :                                 break;
    1375                 :                 }
    1376                 : 
    1377             279 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1378               6 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1379                 :                         /* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
    1380                 :                          * user's password has expired, but is still usable.
    1381                 :                          * */
    1382               6 :                         if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) {
    1383               6 :                                 php_oci_connection_close(connection TSRMLS_CC);
    1384               6 :                                 return NULL;
    1385                 :                         }
    1386                 :                 } /* }}} */
    1387                 :         }
    1388                 : 
    1389                 : #if HAVE_OCI_STMT_PREPARE2
    1390                 :         {
    1391             277 :                 ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0;
    1392                 : 
    1393             277 :                 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)));
    1394                 :                 
    1395             277 :                 if (OCI_G(errcode) != OCI_SUCCESS) {
    1396               0 :                         php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
    1397               0 :                         php_oci_connection_close(connection TSRMLS_CC);
    1398               0 :                         return NULL;
    1399                 :                 }       
    1400                 :         }
    1401                 : #endif
    1402                 :         
    1403                 :         /* mark it as open */
    1404             277 :         connection->is_open = 1;
    1405                 :         
    1406                 :         /* add to the appropriate hash */
    1407             277 :         if (connection->is_persistent) {
    1408              25 :                 new_le.ptr = connection;
    1409              25 :                 new_le.type = le_pconnection;
    1410              25 :                 connection->used_this_request = 1;
    1411              25 :                 connection->rsrc_id = zend_list_insert(connection, le_pconnection);
    1412              25 :                 zend_hash_update(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
    1413              25 :                 OCI_G(num_persistent)++;
    1414             252 :         } else if (!exclusive) {
    1415             226 :                 connection->rsrc_id = zend_list_insert(connection, le_connection);
    1416             226 :                 new_le.ptr = (void *)connection->rsrc_id;
    1417             226 :                 new_le.type = le_index_ptr;
    1418             226 :                 zend_hash_update(&EG(regular_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL);
    1419             226 :                 OCI_G(num_links)++;
    1420                 :         } else {
    1421              26 :                 connection->rsrc_id = zend_list_insert(connection, le_connection);   
    1422              26 :                 OCI_G(num_links)++;
    1423                 :         }
    1424             277 :         return connection;
    1425                 : }
    1426                 : /* }}} */
    1427                 : 
    1428                 : /* {{{ php_oci_connection_ping()
    1429                 :  * Ping connection. Uses OCIPing() or OCIServerVersion() depending on the Oracle Client version */
    1430                 : static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
    1431               1 : {
    1432                 :         /* OCIPing() crashes Oracle servers older than 10.2 */
    1433                 : #if 0
    1434                 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
    1435                 : #else
    1436                 :         char version[256];
    1437                 :         /* use good old OCIServerVersion() by default */
    1438               1 :         PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerVersion, (connection->server, OCI_G(err), (text*)version, sizeof(version), OCI_HTYPE_SERVER));
    1439                 : #endif
    1440                 :         
    1441               1 :         if (OCI_G(errcode) == OCI_SUCCESS) {
    1442               1 :                 return 1;
    1443                 :         }
    1444                 : 
    1445                 :         /* ignore errors here, just return failure 
    1446                 :          * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
    1447               0 :         return 0;
    1448                 : }
    1449                 : /* }}} */
    1450                 : 
    1451                 : /* {{{ php_oci_connection_status()
    1452                 :  Check connection status (pre-ping check) */
    1453                 : static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
    1454              10 : {
    1455              10 :         ub4 ss = 0;
    1456                 : 
    1457                 :         /* get OCI_ATTR_SERVER_STATUS */
    1458              10 :         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)));
    1459                 :         
    1460              10 :         if (OCI_G(errcode) == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
    1461              10 :                 return 1;
    1462                 :         }
    1463                 : 
    1464                 :         /* ignore errors here, just return failure 
    1465                 :          * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
    1466               0 :         return 0;
    1467                 : }
    1468                 : /* }}} */
    1469                 : 
    1470                 : /* {{{ php_oci_connection_rollback()
    1471                 :  Rollback connection */
    1472                 : int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
    1473              18 : {
    1474              18 :         PHP_OCI_CALL_RETURN(connection->errcode, OCITransRollback, (connection->svc, connection->err, (ub4) 0));
    1475              18 :         connection->needs_commit = 0;
    1476                 : 
    1477              18 :         if (connection->errcode != OCI_SUCCESS) {
    1478               0 :                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1479               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1480               0 :                 return 1;
    1481                 :         }
    1482              18 :         return 0;
    1483                 : } /* }}} */
    1484                 : 
    1485                 : /* {{{ php_oci_connection_commit()
    1486                 :  Commit connection */
    1487                 : int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
    1488              97 : {
    1489              97 :         PHP_OCI_CALL_RETURN(connection->errcode, OCITransCommit, (connection->svc, connection->err, (ub4) 0));
    1490              97 :         connection->needs_commit = 0;
    1491                 : 
    1492              97 :         if (connection->errcode != OCI_SUCCESS) {
    1493               0 :                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1494               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1495               0 :                 return 1;
    1496                 :         }
    1497              97 :         return 0;
    1498                 : } /* }}} */
    1499                 : 
    1500                 : /* {{{ php_oci_connection_close() 
    1501                 :  Close the connection and free all its resources */
    1502                 : static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC)
    1503             286 : {
    1504             286 :         int result = 0;
    1505             286 :         zend_bool in_call_save = OCI_G(in_call);
    1506                 : 
    1507             286 :         if (connection->descriptors) {
    1508              75 :                 zend_hash_destroy(connection->descriptors);
    1509              75 :                 efree(connection->descriptors);
    1510                 :         }
    1511                 : 
    1512             286 :         if (connection->svc) {       
    1513                 :                 /* rollback outstanding transactions */
    1514             283 :                 if (connection->needs_commit) {
    1515              12 :                         if (php_oci_connection_rollback(connection TSRMLS_CC)) {
    1516                 :                                 /* rollback failed */
    1517               0 :                                 result = 1;
    1518                 :                         }
    1519                 :                 }
    1520                 :         }
    1521                 : 
    1522             286 :         if (connection->svc && connection->session && connection->is_open) {
    1523             277 :                 PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0));
    1524                 :         }
    1525                 :         
    1526             286 :         if (connection->session) {
    1527             283 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->session, OCI_HTYPE_SESSION));
    1528                 :         }
    1529                 :         
    1530             286 :         if (connection->is_attached) {
    1531             283 :                 PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT));
    1532                 :         }
    1533                 :         
    1534             286 :         if (connection->svc) {
    1535             283 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc,      (ub4) OCI_HTYPE_SVCCTX));
    1536                 :         }
    1537                 :         
    1538             286 :         if (connection->err) {
    1539             283 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR));
    1540                 :         }
    1541                 :         
    1542             286 :         if (connection->server) {
    1543             286 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER));
    1544                 :         }
    1545                 :         
    1546             286 :         if (connection->env) {
    1547             286 :                 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV));
    1548                 :         }
    1549                 : 
    1550             286 :         if (connection->is_persistent) {
    1551              25 :                 if (connection->hash_key) {
    1552              25 :                         free(connection->hash_key);
    1553                 :                 }
    1554              25 :                 free(connection);
    1555                 :         } else {
    1556             261 :                 if (connection->hash_key) {
    1557             261 :                         efree(connection->hash_key);
    1558                 :                 }
    1559             261 :                 efree(connection);
    1560                 :         }
    1561             286 :         connection = NULL;
    1562             286 :         OCI_G(in_call) = in_call_save;
    1563             286 :         return result;
    1564                 : } /* }}} */
    1565                 : 
    1566                 : /* {{{ php_oci_password_change()
    1567                 :  Change password for the user with the username given */
    1568                 : 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)
    1569               2 : {
    1570               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));
    1571                 : 
    1572               2 :         if (connection->errcode != OCI_SUCCESS) {
    1573               0 :                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1574               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1575               0 :                 return 1;
    1576                 :         }
    1577               2 :         connection->passwd_changed = 1;
    1578               2 :         return 0;
    1579                 : } /* }}} */
    1580                 : 
    1581                 : /* {{{ php_oci_server_get_version() 
    1582                 :  Get Oracle server version */
    1583                 : int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC) 
    1584               4 : {
    1585                 :         char version_buff[256];
    1586                 : 
    1587               4 :         PHP_OCI_CALL_RETURN(connection->errcode, OCIServerVersion, (connection->svc, connection->err, (text*)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
    1588                 :         
    1589               4 :         if (connection->errcode != OCI_SUCCESS) {
    1590               0 :                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1591               0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1592               0 :                 return 1;
    1593                 :         }
    1594                 :         
    1595               4 :         *version = estrdup(version_buff);
    1596               4 :         return 0;
    1597                 : } /* }}} */
    1598                 : 
    1599                 : /* {{{ php_oci_column_to_zval() 
    1600                 :  Convert php_oci_out_column struct into zval */
    1601                 : int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSRMLS_DC)
    1602          282079 : {
    1603                 :         php_oci_descriptor *descriptor;
    1604                 :         ub4 lob_length;
    1605                 :         int column_size;
    1606                 :         char *lob_buffer;
    1607                 :         int lob_fetch_status;
    1608                 :         
    1609          282079 :         if (column->indicator == -1) { /* column is NULL */ 
    1610              90 :                 ZVAL_NULL(value); 
    1611              90 :                 return 0;
    1612                 :         }
    1613                 :         
    1614          281989 :         if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
    1615            1413 :                 ZVAL_RESOURCE(value, column->stmtid);
    1616            1413 :                 zend_list_addref(column->stmtid);
    1617          280576 :         } else if (column->is_descr) {
    1618                 :                 
    1619          273317 :                 if (column->data_type != SQLT_RDD) {
    1620                 :                         int rsrc_type;
    1621                 :                         
    1622                 :                         /* reset descriptor's length */
    1623          273316 :                         descriptor = (php_oci_descriptor *) zend_list_find(column->descid, &rsrc_type);
    1624                 : 
    1625          273316 :                         if (!descriptor || rsrc_type != le_descriptor) {
    1626               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find LOB descriptor #%d", column->descid);
    1627               0 :                                 return 1;
    1628                 :                         }
    1629                 :                                                                   
    1630          273316 :                         descriptor->lob_size = -1;
    1631          273316 :                         descriptor->lob_current_position = 0;
    1632          273316 :                         descriptor->buffering = 0;
    1633                 :                 }
    1634                 : 
    1635          273317 :                 if (column->data_type != SQLT_RDD && (mode & PHP_OCI_RETURN_LOBS)) {
    1636                 :                         /* PHP_OCI_RETURN_LOBS means that we want the content of the LOB back instead of the locator */
    1637                 :                         
    1638            1034 :                         lob_fetch_status = php_oci_lob_read(descriptor, -1, 0, &lob_buffer, &lob_length TSRMLS_CC);
    1639                 : #ifdef HAVE_OCI8_TEMP_LOB
    1640            1034 :                         php_oci_temp_lob_close(descriptor TSRMLS_CC);
    1641                 : #endif
    1642            1034 :                         if (lob_fetch_status) {
    1643               0 :                                 ZVAL_FALSE(value);
    1644               0 :                                 return 1;
    1645                 :                         } else {
    1646            1034 :                                 if (lob_length > 0) {
    1647            1027 :                                         ZVAL_STRINGL(value, lob_buffer, lob_length, 0);
    1648                 :                                 } else {
    1649               7 :                                         ZVAL_EMPTY_STRING(value);
    1650                 :                                 }
    1651            1034 :                                 return 0;
    1652                 :                         }
    1653                 :                 } else { 
    1654                 :                         /* return the locator */
    1655          272283 :                         object_init_ex(value, oci_lob_class_entry_ptr);
    1656          272283 :                         add_property_resource(value, "descriptor", column->descid);
    1657          272283 :                         zend_list_addref(column->descid);
    1658                 :                 }
    1659                 :         } else {
    1660            7259 :                 switch (column->retcode) {
    1661                 :                         case 0: 
    1662                 :                                 /* intact value */
    1663            7259 :                                 if (column->piecewise) {
    1664              12 :                                         column_size = column->retlen4;
    1665                 :                                 } else {
    1666            7247 :                                         column_size = column->retlen;
    1667                 :                                 }
    1668                 :                                 break;
    1669                 :                         
    1670                 :                         default:                                
    1671               0 :                                 ZVAL_FALSE(value); 
    1672               0 :                                 return 0;
    1673                 :                 }
    1674                 :                 
    1675            7259 :                 ZVAL_STRINGL(value, column->data, column_size, 1);
    1676                 :         }
    1677          280955 :         return 0;
    1678                 : }
    1679                 : /* }}} */
    1680                 : 
    1681                 : /* {{{ php_oci_fetch_row() 
    1682                 :  Fetch the next row from the given statement */
    1683                 : void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args)
    1684          131248 : {
    1685                 :         zval *z_statement, *array;
    1686                 :         php_oci_statement *statement;
    1687                 :         php_oci_out_column *column;
    1688          131248 :         ub4 nrows = 1;
    1689                 :         int i;
    1690          131248 :         long fetch_mode = 0;
    1691                 : 
    1692          131248 :         if (expected_args > 2) {
    1693                 :                 /* only for ocifetchinto BC */
    1694                 : 
    1695            6625 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|l", &z_statement, &array, &fetch_mode) == FAILURE) {
    1696               2 :                         return;
    1697                 :                 }
    1698                 :                 
    1699            6623 :                 if (ZEND_NUM_ARGS() == 2) {
    1700               1 :                         fetch_mode = mode;
    1701                 :                 }
    1702          124623 :         } else if (expected_args == 2) {
    1703                 :                 /* only for oci_fetch_array() */
    1704                 : 
    1705            4545 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &fetch_mode) == FAILURE) {
    1706               0 :                         return;
    1707                 :                 }
    1708                 :                 
    1709            4545 :                 if (ZEND_NUM_ARGS() == 1) {
    1710              41 :                         fetch_mode = mode;
    1711                 :                 }
    1712                 :         } else {
    1713                 :                 /* for all oci_fetch_*() */
    1714                 :                 
    1715          120078 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
    1716               0 :                         return;
    1717                 :                 }
    1718                 :         
    1719          120078 :                 fetch_mode = mode;
    1720                 :         }
    1721                 : 
    1722          131246 :         if (!(fetch_mode & PHP_OCI_NUM) && !(fetch_mode & PHP_OCI_ASSOC)) {
    1723                 :                 /* none of the modes present, use the default one */
    1724              25 :                 if (mode & PHP_OCI_ASSOC) {
    1725              20 :                         fetch_mode |= PHP_OCI_ASSOC;
    1726                 :                 } 
    1727              25 :                 if (mode & PHP_OCI_NUM) {
    1728              25 :                         fetch_mode |= PHP_OCI_NUM;
    1729                 :                 }
    1730                 :         }
    1731                 : 
    1732          131246 :         PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
    1733                 : 
    1734          131245 :         if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
    1735           30067 :                 RETURN_FALSE;
    1736                 :         }
    1737                 : 
    1738          101178 :         array_init(return_value);
    1739                 : 
    1740          292984 :         for (i = 0; i < statement->ncolumns; i++) {
    1741                 :                 
    1742          191806 :                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
    1743                 :                 
    1744          191806 :                 if (column == NULL) {
    1745               0 :                         continue;
    1746                 :                 }
    1747          191806 :                 if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) {
    1748              57 :                         continue;
    1749                 :                 }
    1750                 : 
    1751          191749 :                 if (!(column->indicator == -1)) {
    1752                 :                         zval *element;
    1753                 :                         
    1754          191670 :                         MAKE_STD_ZVAL(element);
    1755          191670 :                         php_oci_column_to_zval(column, element, fetch_mode TSRMLS_CC);
    1756                 : 
    1757          191670 :                         if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
    1758            9320 :                                 add_index_zval(return_value, i, element);
    1759                 :                         }
    1760          191670 :                         if (fetch_mode & PHP_OCI_ASSOC) {
    1761          182425 :                                 if (fetch_mode & PHP_OCI_NUM) {
    1762              75 :                                         ZVAL_ADDREF(element);
    1763                 :                                 }
    1764          182425 :                                 add_assoc_zval(return_value, column->name, element);
    1765                 :                         }
    1766                 :                 
    1767                 :                 } else {
    1768              79 :                         if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) {
    1769              55 :                                 add_index_null(return_value, i);
    1770                 :                         }
    1771              79 :                         if (fetch_mode & PHP_OCI_ASSOC) {
    1772              52 :                                 add_assoc_null(return_value, column->name);
    1773                 :                         }
    1774                 :                 }
    1775                 :         }
    1776                 : 
    1777          101178 :         if (expected_args > 2) {
    1778                 :                 /* only for ocifetchinto BC
    1779                 :                  * in all other cases we return array, not long
    1780                 :                  */
    1781            6618 :                 REPLACE_ZVAL_VALUE(&array, return_value, 1); /* copy return_value to given reference */
    1782            6618 :                 zval_dtor(return_value);
    1783            6618 :                 RETURN_LONG(statement->ncolumns);
    1784                 :         }
    1785                 : }
    1786                 : /* }}} */
    1787                 : 
    1788                 : /* {{{ php_oci_persistent_helper() 
    1789                 :  Helper function to close/rollback persistent connections at the end of request */
    1790                 : static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
    1791              40 : {
    1792                 :         time_t timestamp;
    1793                 :         php_oci_connection *connection;
    1794                 : 
    1795              40 :         timestamp = time(NULL);
    1796                 :         
    1797              40 :         if (le->type == le_pconnection) {
    1798              25 :                 connection = (php_oci_connection *)le->ptr;
    1799                 : 
    1800              25 :                 if (connection->used_this_request) {
    1801              25 :                         if ((PG(connection_status) & PHP_CONNECTION_TIMEOUT) || OCI_G(in_call)) {
    1802               0 :                                 return ZEND_HASH_APPLY_REMOVE;
    1803                 :                         }
    1804                 : 
    1805              25 :                         if (connection->descriptors) {
    1806               3 :                                 zend_hash_destroy(connection->descriptors);
    1807               3 :                                 efree(connection->descriptors);
    1808               3 :                                 connection->descriptors = NULL;
    1809                 :                         }
    1810                 :                         
    1811              25 :                         if (connection->needs_commit) {
    1812               2 :                                 php_oci_connection_rollback(connection TSRMLS_CC);
    1813                 :                         }
    1814                 :                         
    1815                 :                         /* If oci_password_change() changed the password of a
    1816                 :                          * persistent connection, close the connection and remove
    1817                 :                          * it from the persistent connection cache.  This means
    1818                 :                          * subsequent scripts will be prevented from being able to
    1819                 :                          * present the old (now invalid) password to a usable
    1820                 :                          * connection to the database; they must use the new
    1821                 :                          * password.
    1822                 :                          */
    1823              25 :                         if (connection->passwd_changed) {
    1824               1 :                                 return ZEND_HASH_APPLY_REMOVE;
    1825                 :                         }
    1826                 : 
    1827              24 :                         if (OCI_G(persistent_timeout) > 0) {
    1828               0 :                                 connection->idle_expiry = timestamp + OCI_G(persistent_timeout);
    1829                 :                         }
    1830                 :                 
    1831              24 :                         if (OCI_G(ping_interval) >= 0) {
    1832              24 :                                 connection->next_ping = timestamp + OCI_G(ping_interval);
    1833                 :                         } else {
    1834                 :                                 /* ping_interval is -1 */
    1835               0 :                                 connection->next_ping = 0;
    1836                 :                         }
    1837                 : 
    1838              24 :                         connection->used_this_request = 0;
    1839                 : 
    1840               0 :                 } else if (OCI_G(persistent_timeout) != -1) {
    1841               0 :                         if (connection->idle_expiry < timestamp) {
    1842                 :                                 /* connection has timed out */
    1843               0 :                                 return ZEND_HASH_APPLY_REMOVE;
    1844                 :                         }
    1845                 :                 }
    1846                 :         }
    1847              39 :         return ZEND_HASH_APPLY_KEEP;
    1848                 : } /* }}} */
    1849                 : 
    1850                 : #ifdef ZTS
    1851                 : /* {{{ php_oci_list_helper() 
    1852                 :  Helper function to destroy data on thread shutdown in ZTS mode */
    1853                 : static int php_oci_list_helper(zend_rsrc_list_entry *le, void *le_type TSRMLS_DC)
    1854                 : {
    1855                 :         int type = (int) le_type;
    1856                 : 
    1857                 :         if (le->type == type) {
    1858                 :                 if (le->ptr != NULL && --le->refcount<=0) {
    1859                 :                         return ZEND_HASH_APPLY_REMOVE;
    1860                 :                 }
    1861                 :         }
    1862                 :         return ZEND_HASH_APPLY_KEEP;
    1863                 : } /* }}} */
    1864                 : #endif
    1865                 : 
    1866                 : #endif /* HAVE_OCI8 */
    1867                 : 
    1868                 : /*
    1869                 :  * Local variables:
    1870                 :  * tab-width: 4
    1871                 :  * c-basic-offset: 4
    1872                 :  * End:
    1873                 :  * vim600: noet sw=4 ts=4 fdm=marker
    1874                 :  * vim<600: noet sw=4 ts=4
    1875                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:13 +0000 (5 days ago)

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