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