Annotation of embedaddon/php/ext/oci8/oci8.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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 321634 2012-01-01 13:15:04Z felipe $ */
! 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", "$Revision: 321634 $");
! 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) at (%s:%d) \n", numopen, numbusy, __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>