File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / oci8 / oci8.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:52 2014 UTC (10 years, 10 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>