1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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 | |
18 | Collection support by Andy Sautins <asautins@veripost.net> |
19 | Temporary LOB support by David Benson <dbenson@mancala.com> |
20 | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
21 | |
22 | Redesigned by: Antony Dovgal <antony@zend.com> |
23 | Andi Gutmans <andi@php.net> |
24 | Wez Furlong <wez@omniti.com> |
25 +----------------------------------------------------------------------+
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "php.h"
33 #include "ext/standard/info.h"
34 #include "php_ini.h"
35
36 #if HAVE_OCI8
37
38 #include "php_oci8.h"
39 #include "php_oci8_int.h"
40
41 #ifndef OCI_STMT_CALL
42 #define OCI_STMT_CALL 10
43 #endif
44
45 /* {{{ proto bool oci_register_taf_callback( resource connection [, mixed callback] )
46 Register a callback function for Oracle Transparent Application Failover (TAF) */
PHP_FUNCTION(oci_register_taf_callback)47 PHP_FUNCTION(oci_register_taf_callback)
48 {
49 zval *z_connection;
50 php_oci_connection *connection;
51 zval *callback;
52 zend_string *callback_name;
53
54 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!", &z_connection, &callback) == FAILURE) {
55 return;
56 }
57
58 if (callback) {
59 #if PHP_MAJOR_VERSION > 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION >= 2)
60 if (!zend_is_callable(callback, 0, 0)) {
61 callback_name = zend_get_callable_name(callback);
62 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(callback_name));
63 #if PHP_VERSION_ID < 70300
64 zend_string_release(callback_name);
65 #else
66 zend_string_release_ex(callback_name, 0);
67 #endif
68 RETURN_FALSE;
69 }
70 #else
71 if (!zend_is_callable(callback, 0, &callback_name)) {
72 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(callback_name));
73 #if PHP_VERSION_ID < 70300
74 zend_string_release(callback_name);
75 #else
76 zend_string_release_ex(callback_name, 0);
77 #endif
78 RETURN_FALSE;
79 }
80 #if PHP_VERSION_ID < 70300
81 zend_string_release(callback_name);
82 #else
83 zend_string_release_ex(callback_name, 0);
84 #endif
85 #endif
86 }
87
88 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
89
90 if (php_oci_register_taf_callback(connection, callback) == 0) {
91 RETURN_TRUE;
92 } else {
93 RETURN_FALSE;
94 }
95 }
96 /* }}} */
97
98 /* {{{ proto bool oci_unregister_taf_callback( resource connection )
99 * Unregister a callback function for Oracle Transparent Application Failover (TAF) */
PHP_FUNCTION(oci_unregister_taf_callback)100 PHP_FUNCTION(oci_unregister_taf_callback)
101 {
102 zval *z_connection;
103 php_oci_connection *connection;
104
105 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_connection) == FAILURE) {
106 return;
107 }
108
109 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
110
111 if (php_oci_unregister_taf_callback(connection) == 0) {
112 RETURN_TRUE;
113 } else {
114 RETURN_FALSE;
115 }
116 }
117 /* }}} */
118
119 /* {{{ proto bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])
120 Define a PHP variable to an Oracle column by name */
121 /* if you want to define a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE defining!!! */
PHP_FUNCTION(oci_define_by_name)122 PHP_FUNCTION(oci_define_by_name)
123 {
124 zval *stmt, *var;
125 char *name;
126 size_t name_len;
127 zend_long type = 0;
128 php_oci_statement *statement;
129 php_oci_define *define;
130 zend_string *zvtmp;
131
132 ZEND_PARSE_PARAMETERS_START(3, 4)
133 Z_PARAM_RESOURCE(stmt)
134 Z_PARAM_STRING(name, name_len)
135 Z_PARAM_ZVAL(var)
136 Z_PARAM_OPTIONAL
137 Z_PARAM_LONG(type)
138 ZEND_PARSE_PARAMETERS_END();
139
140 if (!name_len) {
141 php_error_docref(NULL, E_WARNING, "Column name cannot be empty");
142 RETURN_FALSE;
143 }
144
145 PHP_OCI_ZVAL_TO_STATEMENT(stmt, statement);
146
147 if (statement->defines == NULL) {
148 ALLOC_HASHTABLE(statement->defines);
149 zend_hash_init(statement->defines, 13, NULL, php_oci_define_hash_dtor, 0);
150 }
151 else if (zend_hash_str_exists(statement->defines, (const char *)name, name_len)) {
152 RETURN_FALSE;
153 }
154
155 define = ecalloc(1,sizeof(php_oci_define));
156
157 /* if (zend_hash_add(statement->defines, name, name_len, define, sizeof(php_oci_define), (void **)&tmp_define) == SUCCESS) { */
158 zvtmp = zend_string_init(name, name_len, 0);
159 if ((define = zend_hash_add_new_ptr(statement->defines, zvtmp, define)) != NULL) {
160 #if PHP_VERSION_ID < 70300
161 zend_string_release(zvtmp);
162 #else
163 zend_string_release_ex(zvtmp, 0);
164 #endif
165 } else {
166 efree(define);
167 #if PHP_VERSION_ID < 70300
168 zend_string_release(zvtmp);
169 #else
170 zend_string_release_ex(zvtmp, 0);
171 #endif
172 RETURN_FALSE;
173 }
174
175 define->name = (text*) ecalloc(1, name_len+1);
176 memcpy(define->name, name, name_len);
177 define->name[name_len] = '\0';
178 define->name_len = (ub4) name_len;
179 define->type = (ub4) type;
180 ZEND_ASSERT(Z_ISREF_P(var));
181 ZVAL_COPY(&define->val, var);
182
183 RETURN_TRUE;
184 }
185 /* }}} */
186
187 /* {{{ proto bool oci_bind_by_name(resource stmt, string name, mixed &var [, int maxlength [, int type]])
188 Bind a PHP variable to an Oracle placeholder by name */
189 /* if you want to bind a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE binding!!! */
PHP_FUNCTION(oci_bind_by_name)190 PHP_FUNCTION(oci_bind_by_name)
191 {
192 ub2 bind_type = SQLT_CHR; /* unterminated string */
193 size_t name_len;
194 zend_long maxlen = -1, type = 0;
195 char *name;
196 zval *z_statement;
197 zval *bind_var = NULL;
198 php_oci_statement *statement;
199
200 ZEND_PARSE_PARAMETERS_START(3, 5)
201 Z_PARAM_RESOURCE(z_statement)
202 Z_PARAM_STRING(name, name_len)
203 Z_PARAM_ZVAL(bind_var)
204 Z_PARAM_OPTIONAL
205 Z_PARAM_LONG(maxlen)
206 Z_PARAM_LONG(type)
207 ZEND_PARSE_PARAMETERS_END();
208
209 if (type) {
210 bind_type = (ub2) type;
211 }
212
213 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
214
215 if (php_oci_bind_by_name(statement, name, name_len, bind_var, maxlen, bind_type)) {
216 RETURN_FALSE;
217 }
218 RETURN_TRUE;
219 }
220 /* }}} */
221
222 /* {{{ proto bool oci_bind_array_by_name(resource stmt, string name, array &var, int max_table_length [, int max_item_length [, int type ]])
223 Bind a PHP array to an Oracle PL/SQL type by name */
PHP_FUNCTION(oci_bind_array_by_name)224 PHP_FUNCTION(oci_bind_array_by_name)
225 {
226 size_t name_len;
227 zend_long max_item_len = -1;
228 zend_long max_array_len = 0;
229 zend_long type = SQLT_AFC;
230 char *name;
231 zval *z_statement;
232 zval *bind_var = NULL;
233 php_oci_statement *statement;
234
235 ZEND_PARSE_PARAMETERS_START(4, 6)
236 Z_PARAM_RESOURCE(z_statement)
237 Z_PARAM_STRING(name, name_len)
238 Z_PARAM_ZVAL(bind_var)
239 Z_PARAM_LONG(max_array_len)
240 Z_PARAM_OPTIONAL
241 Z_PARAM_LONG(max_item_len)
242 Z_PARAM_LONG(type)
243 ZEND_PARSE_PARAMETERS_END();
244
245 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
246
247 if (ZEND_NUM_ARGS() == 5 && max_item_len <= 0) {
248 max_item_len = -1;
249 }
250
251 if (max_array_len <= 0) {
252 php_error_docref(NULL, E_WARNING, "Maximum array length must be greater than zero");
253 RETURN_FALSE;
254 }
255
256 if (php_oci_bind_array_by_name(statement, name, (sb4) name_len, bind_var, max_array_len, max_item_len, type)) {
257 RETURN_FALSE;
258 }
259 RETURN_TRUE;
260 }
261 /* }}} */
262
263 /* {{{ proto bool oci_free_descriptor()
264 Deletes large object description */
PHP_FUNCTION(oci_free_descriptor)265 PHP_FUNCTION(oci_free_descriptor)
266 {
267 zval *tmp, *z_descriptor = getThis();
268 php_oci_descriptor *descriptor;
269
270 if (!getThis()) {
271 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
272 return;
273 }
274 }
275
276 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
277 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
278 RETURN_FALSE;
279 }
280
281 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
282
283 zend_list_close(descriptor->id);
284 RETURN_TRUE;
285 }
286 /* }}} */
287
288 /* {{{ proto bool oci_lob_save( string data [, int offset ])
289 Saves a large object */
PHP_FUNCTION(oci_lob_save)290 PHP_FUNCTION(oci_lob_save)
291 {
292 zval *tmp, *z_descriptor = getThis();
293 php_oci_descriptor *descriptor;
294 char *data;
295 size_t data_len;
296 zend_long offset = 0;
297 ub4 bytes_written;
298
299 if (getThis()) {
300 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &data, &data_len, &offset) == FAILURE) {
301 return;
302 }
303 }
304 else {
305 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &offset) == FAILURE) {
306 return;
307 }
308 }
309
310 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
311 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
312 RETURN_FALSE;
313 }
314
315 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
316
317 if (offset < 0) {
318 php_error_docref(NULL, E_WARNING, "Offset parameter must be greater than or equal to 0");
319 RETURN_FALSE;
320 }
321
322 if (php_oci_lob_write(descriptor, (ub4) offset, data, (ub4) data_len, &bytes_written)) {
323 RETURN_FALSE;
324 }
325 RETURN_TRUE;
326 }
327 /* }}} */
328
329 /* {{{ proto bool oci_lob_import( string filename )
330 Loads file into a LOB */
PHP_FUNCTION(oci_lob_import)331 PHP_FUNCTION(oci_lob_import)
332 {
333 zval *tmp, *z_descriptor = getThis();
334 php_oci_descriptor *descriptor;
335 char *filename;
336 size_t filename_len;
337
338 if (getThis()) {
339 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &filename, &filename_len) == FAILURE) {
340 return;
341 }
342 }
343 else {
344 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Op", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) {
345 return;
346 }
347 }
348
349 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
350 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
351 RETURN_FALSE;
352 }
353
354 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
355
356 if (php_oci_lob_import(descriptor, filename)) {
357 RETURN_FALSE;
358 }
359 RETURN_TRUE;
360 }
361 /* }}} */
362
363 /* {{{ proto string oci_lob_load()
364 Loads a large object */
PHP_FUNCTION(oci_lob_load)365 PHP_FUNCTION(oci_lob_load)
366 {
367 zval *tmp, *z_descriptor = getThis();
368 php_oci_descriptor *descriptor;
369 char *buffer = NULL;
370 ub4 buffer_len;
371
372 if (!getThis()) {
373 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
374 return;
375 }
376 }
377
378 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
379 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
380 RETURN_FALSE;
381 }
382
383 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
384
385 if (php_oci_lob_read(descriptor, -1, 0, &buffer, &buffer_len)) {
386 RETURN_FALSE;
387 }
388 if (buffer_len > 0) {
389 zend_string *ret = zend_string_init(buffer, buffer_len, 0);
390 if (buffer)
391 efree(buffer);
392 RETURN_STR(ret);
393 }
394 else {
395 RETURN_EMPTY_STRING();
396 }
397 }
398 /* }}} */
399
400 /* {{{ proto string oci_lob_read( int length )
401 Reads particular part of a large object */
PHP_FUNCTION(oci_lob_read)402 PHP_FUNCTION(oci_lob_read)
403 {
404 zval *tmp, *z_descriptor = getThis();
405 php_oci_descriptor *descriptor;
406 zend_long length;
407 char *buffer;
408 ub4 buffer_len;
409
410 if (getThis()) {
411 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &length) == FAILURE) {
412 return;
413 }
414 }
415 else {
416 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &z_descriptor, oci_lob_class_entry_ptr, &length) == FAILURE) {
417 return;
418 }
419 }
420
421 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
422 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
423 RETURN_FALSE;
424 }
425
426 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
427
428 if (length <= 0) {
429 php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0");
430 RETURN_FALSE;
431 }
432
433 if (php_oci_lob_read(descriptor, length, descriptor->lob_current_position, &buffer, &buffer_len)) {
434 RETURN_FALSE;
435 }
436 if (buffer_len > 0) {
437 zend_string *ret = zend_string_init(buffer, buffer_len, 0);
438 efree(buffer);
439 RETURN_STR(ret);
440 }
441 else {
442 RETURN_EMPTY_STRING();
443 }
444 }
445 /* }}} */
446
447 /* {{{ proto bool oci_lob_eof()
448 Checks if EOF is reached */
PHP_FUNCTION(oci_lob_eof)449 PHP_FUNCTION(oci_lob_eof)
450 {
451 zval *tmp, *z_descriptor = getThis();
452 php_oci_descriptor *descriptor;
453 ub4 lob_length;
454
455 if (!getThis()) {
456 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
457 return;
458 }
459 }
460
461 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
462 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
463 RETURN_FALSE;
464 }
465
466 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
467
468 if (!php_oci_lob_get_length(descriptor, &lob_length)) {
469 if (lob_length == descriptor->lob_current_position) {
470 RETURN_TRUE;
471 }
472 }
473 RETURN_FALSE;
474 }
475 /* }}} */
476
477 /* {{{ proto int oci_lob_tell()
478 Tells LOB pointer position */
PHP_FUNCTION(oci_lob_tell)479 PHP_FUNCTION(oci_lob_tell)
480 {
481 zval *tmp, *z_descriptor = getThis();
482 php_oci_descriptor *descriptor;
483
484 if (!getThis()) {
485 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
486 return;
487 }
488 }
489
490 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
491 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
492 RETURN_FALSE;
493 }
494
495 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
496
497 RETURN_LONG(descriptor->lob_current_position);
498 }
499 /* }}} */
500
501 /* {{{ proto bool oci_lob_rewind()
502 Rewind pointer of a LOB */
PHP_FUNCTION(oci_lob_rewind)503 PHP_FUNCTION(oci_lob_rewind)
504 {
505 zval *tmp, *z_descriptor = getThis();
506 php_oci_descriptor *descriptor;
507
508 if (!getThis()) {
509 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
510 return;
511 }
512 }
513
514 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
515 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
516 RETURN_FALSE;
517 }
518
519 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
520
521 descriptor->lob_current_position = 0;
522
523 RETURN_TRUE;
524 }
525 /* }}} */
526
527 /* {{{ proto bool oci_lob_seek( int offset [, int whence ])
528 Moves the pointer of a LOB */
PHP_FUNCTION(oci_lob_seek)529 PHP_FUNCTION(oci_lob_seek)
530 {
531 zval *tmp, *z_descriptor = getThis();
532 php_oci_descriptor *descriptor;
533 zend_long offset, whence = PHP_OCI_SEEK_SET;
534 ub4 lob_length;
535
536 if (getThis()) {
537 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &offset, &whence) == FAILURE) {
538 return;
539 }
540 }
541 else {
542 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|l", &z_descriptor, oci_lob_class_entry_ptr, &offset, &whence) == FAILURE) {
543 return;
544 }
545 }
546
547 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
548 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
549 RETURN_FALSE;
550 }
551
552 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
553
554 if (php_oci_lob_get_length(descriptor, &lob_length)) {
555 RETURN_FALSE;
556 }
557
558 switch(whence) {
559 case PHP_OCI_SEEK_CUR:
560 descriptor->lob_current_position += (ub4) offset;
561 break;
562 case PHP_OCI_SEEK_END:
563 if ((descriptor->lob_size + offset) >= 0) {
564 descriptor->lob_current_position = descriptor->lob_size + (ub4) offset;
565 }
566 else {
567 descriptor->lob_current_position = 0;
568 }
569 break;
570 case PHP_OCI_SEEK_SET:
571 default:
572 descriptor->lob_current_position = (offset > 0) ? (ub4) offset : 0;
573 break;
574 }
575 if (descriptor->lob_current_position > UB4MAXVAL) {
576 php_error_docref(NULL, E_WARNING, "Invalid offset or LOB position");
577 RETURN_FALSE;
578 }
579 RETURN_TRUE;
580 }
581 /* }}} */
582
583 /* {{{ proto int oci_lob_size()
584 Returns size of a large object */
PHP_FUNCTION(oci_lob_size)585 PHP_FUNCTION(oci_lob_size)
586 {
587 zval *tmp, *z_descriptor = getThis();
588 php_oci_descriptor *descriptor;
589 ub4 lob_length;
590
591 if (!getThis()) {
592 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
593 return;
594 }
595 }
596
597 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
598 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
599 RETURN_FALSE;
600 }
601
602 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
603
604 if (php_oci_lob_get_length(descriptor, &lob_length)) {
605 RETURN_FALSE;
606 }
607 RETURN_LONG(lob_length);
608 }
609 /* }}} */
610
611 /* {{{ proto int oci_lob_write( string string [, int length ])
612 Writes data to current position of a LOB */
PHP_FUNCTION(oci_lob_write)613 PHP_FUNCTION(oci_lob_write)
614 {
615 zval *tmp, *z_descriptor = getThis();
616 php_oci_descriptor *descriptor;
617 size_t data_len;
618 zend_long write_len = 0;
619 ub4 bytes_written;
620 char *data;
621
622 if (getThis()) {
623 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &data, &data_len, &write_len) == FAILURE) {
624 return;
625 }
626
627 if (ZEND_NUM_ARGS() == 2) {
628 data_len = MIN((zend_long) data_len, write_len);
629 }
630 }
631 else {
632 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &write_len) == FAILURE) {
633 return;
634 }
635
636 if (ZEND_NUM_ARGS() == 3) {
637 data_len = MIN((zend_long) data_len, write_len);
638 }
639 }
640
641 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
642 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
643 RETURN_FALSE;
644 }
645
646 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
647
648 if (data_len <= 0) {
649 RETURN_LONG(0);
650 }
651
652 if (php_oci_lob_write(descriptor, descriptor->lob_current_position, data, (ub4) data_len, &bytes_written)) {
653 RETURN_FALSE;
654 }
655 RETURN_LONG(bytes_written);
656 }
657 /* }}} */
658
659 /* {{{ proto bool oci_lob_append( object lob )
660 Appends data from a LOB to another LOB */
PHP_FUNCTION(oci_lob_append)661 PHP_FUNCTION(oci_lob_append)
662 {
663 zval *tmp_dest, *tmp_from, *z_descriptor_dest = getThis(), *z_descriptor_from;
664 php_oci_descriptor *descriptor_dest, *descriptor_from;
665
666 if (getThis()) {
667 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor_from, oci_lob_class_entry_ptr) == FAILURE) {
668 return;
669 }
670 }
671 else {
672 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr) == FAILURE) {
673 return;
674 }
675 }
676
677 if ((tmp_dest = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor")-1)) == NULL) {
678 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
679 RETURN_FALSE;
680 }
681
682 if ((tmp_from = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor")-1)) == NULL) {
683 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
684 RETURN_FALSE;
685 }
686
687 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_dest, descriptor_dest);
688 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_from, descriptor_from);
689
690 if (php_oci_lob_append(descriptor_dest, descriptor_from)) {
691 RETURN_FALSE;
692 }
693 /* XXX should we increase lob_size here ? */
694 RETURN_TRUE;
695 }
696 /* }}} */
697
698 /* {{{ proto bool oci_lob_truncate( [ int length ])
699 Truncates a LOB */
PHP_FUNCTION(oci_lob_truncate)700 PHP_FUNCTION(oci_lob_truncate)
701 {
702 zval *tmp, *z_descriptor = getThis();
703 php_oci_descriptor *descriptor;
704 zend_long trim_length = 0;
705 ub4 ub_trim_length;
706
707 if (getThis()) {
708 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &trim_length) == FAILURE) {
709 return;
710 }
711 }
712 else {
713 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &z_descriptor, oci_lob_class_entry_ptr, &trim_length) == FAILURE) {
714 return;
715 }
716 }
717
718 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
719 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
720 RETURN_FALSE;
721 }
722
723 if (trim_length < 0) {
724 php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to zero");
725 RETURN_FALSE;
726 }
727
728 ub_trim_length = (ub4) trim_length;
729 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
730
731 if (php_oci_lob_truncate(descriptor, ub_trim_length)) {
732 RETURN_FALSE;
733 }
734 RETURN_TRUE;
735 }
736 /* }}} */
737
738 /* {{{ proto int oci_lob_erase( [ int offset [, int length ] ] )
739 Erases a specified portion of the internal LOB, starting at a specified offset */
PHP_FUNCTION(oci_lob_erase)740 PHP_FUNCTION(oci_lob_erase)
741 {
742 zval *tmp, *z_descriptor = getThis();
743 php_oci_descriptor *descriptor;
744 ub4 bytes_erased;
745 zend_long offset = -1, length = -1;
746
747 if (getThis()) {
748 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &offset, &length) == FAILURE) {
749 return;
750 }
751
752 if (ZEND_NUM_ARGS() > 0 && offset < 0) {
753 php_error_docref(NULL, E_WARNING, "Offset must be greater than or equal to 0");
754 RETURN_FALSE;
755 }
756
757 if (ZEND_NUM_ARGS() > 1 && length < 0) {
758 php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to 0");
759 RETURN_FALSE;
760 }
761 }
762 else {
763 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|ll", &z_descriptor, oci_lob_class_entry_ptr, &offset, &length) == FAILURE) {
764 return;
765 }
766
767 if (ZEND_NUM_ARGS() > 1 && offset < 0) {
768 php_error_docref(NULL, E_WARNING, "Offset must be greater than or equal to 0");
769 RETURN_FALSE;
770 }
771
772 if (ZEND_NUM_ARGS() > 2 && length < 0) {
773 php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to 0");
774 RETURN_FALSE;
775 }
776 }
777
778 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
779 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
780 RETURN_FALSE;
781 }
782
783 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
784
785 if (php_oci_lob_erase(descriptor, offset, (ub4) length, &bytes_erased)) {
786 RETURN_FALSE;
787 }
788 RETURN_LONG(bytes_erased);
789 }
790 /* }}} */
791
792 /* {{{ proto bool oci_lob_flush( [ int flag ] )
793 Flushes the LOB buffer */
PHP_FUNCTION(oci_lob_flush)794 PHP_FUNCTION(oci_lob_flush)
795 {
796 zval *tmp, *z_descriptor = getThis();
797 php_oci_descriptor *descriptor;
798 zend_long flush_flag = 0;
799
800 if (getThis()) {
801 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flush_flag) == FAILURE) {
802 return;
803 }
804 }
805 else {
806 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &z_descriptor, oci_lob_class_entry_ptr, &flush_flag) == FAILURE) {
807 return;
808 }
809 }
810
811 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
812 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
813 RETURN_FALSE;
814 }
815
816 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
817
818 if (descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
819 /* buffering wasn't enabled, there is nothing to flush */
820 RETURN_FALSE;
821 }
822
823 if (php_oci_lob_flush(descriptor, flush_flag)) {
824 RETURN_FALSE;
825 }
826 RETURN_TRUE;
827 }
828 /* }}} */
829
830 /* {{{ proto bool ocisetbufferinglob( boolean flag )
831 Enables/disables buffering for a LOB */
PHP_FUNCTION(ocisetbufferinglob)832 PHP_FUNCTION(ocisetbufferinglob)
833 {
834 zval *tmp, *z_descriptor = getThis();
835 php_oci_descriptor *descriptor;
836 zend_bool flag;
837
838 if (getThis()) {
839 if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &flag) == FAILURE) {
840 return;
841 }
842 }
843 else {
844 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &z_descriptor, oci_lob_class_entry_ptr, &flag) == FAILURE) {
845 return;
846 }
847 }
848
849 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
850 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
851 RETURN_FALSE;
852 }
853
854 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
855
856 if (php_oci_lob_set_buffering(descriptor, flag)) {
857 RETURN_FALSE;
858 }
859 RETURN_TRUE;
860 }
861 /* }}} */
862
863 /* {{{ proto bool ocigetbufferinglob()
864 Returns current state of buffering for a LOB */
PHP_FUNCTION(ocigetbufferinglob)865 PHP_FUNCTION(ocigetbufferinglob)
866 {
867 zval *tmp, *z_descriptor = getThis();
868 php_oci_descriptor *descriptor;
869
870 if (!getThis()) {
871 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
872 return;
873 }
874 }
875
876 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
877 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
878 RETURN_FALSE;
879 }
880
881 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
882
883 if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
884 RETURN_TRUE;
885 }
886 RETURN_FALSE;
887 }
888 /* }}} */
889
890 /* {{{ proto bool oci_lob_copy( object lob_to, object lob_from [, int length ] )
891 Copies data from a LOB to another LOB */
PHP_FUNCTION(oci_lob_copy)892 PHP_FUNCTION(oci_lob_copy)
893 {
894 zval *tmp_dest, *tmp_from, *z_descriptor_dest, *z_descriptor_from;
895 php_oci_descriptor *descriptor_dest, *descriptor_from;
896 zend_long length = 0;
897
898 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO|l", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr, &length) == FAILURE) {
899 return;
900 }
901
902 if ((tmp_dest = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor")-1)) == NULL) {
903 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
904 RETURN_FALSE;
905 }
906
907 if ((tmp_from = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor")-1)) == NULL) {
908 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
909 RETURN_FALSE;
910 }
911
912 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_dest, descriptor_dest);
913 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_from, descriptor_from);
914
915 if (ZEND_NUM_ARGS() == 3 && length < 0) {
916 php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0");
917 RETURN_FALSE;
918 }
919
920 if (ZEND_NUM_ARGS() == 2) {
921 /* indicate that we want to copy from the current position to the end of the LOB */
922 length = -1;
923 }
924
925 if (php_oci_lob_copy(descriptor_dest, descriptor_from, length)) {
926 RETURN_FALSE;
927 }
928 RETURN_TRUE;
929 }
930 /* }}} */
931
932 /* {{{ proto bool oci_lob_is_equal( object lob1, object lob2 )
933 Tests to see if two LOB/FILE locators are equal */
PHP_FUNCTION(oci_lob_is_equal)934 PHP_FUNCTION(oci_lob_is_equal)
935 {
936 zval *tmp_first, *tmp_second, *z_descriptor_first, *z_descriptor_second;
937 php_oci_descriptor *descriptor_first, *descriptor_second;
938 boolean is_equal;
939
940 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &z_descriptor_first, oci_lob_class_entry_ptr, &z_descriptor_second, oci_lob_class_entry_ptr) == FAILURE) {
941 return;
942 }
943
944 if ((tmp_first = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_first), "descriptor", sizeof("descriptor")-1)) == NULL) {
945 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
946 RETURN_FALSE;
947 }
948
949 if ((tmp_second = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_second), "descriptor", sizeof("descriptor")-1)) == NULL) {
950 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
951 RETURN_FALSE;
952 }
953
954 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_first, descriptor_first);
955 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_second, descriptor_second);
956
957 if (php_oci_lob_is_equal(descriptor_first, descriptor_second, &is_equal)) {
958 RETURN_FALSE;
959 }
960
961 if (is_equal == TRUE) {
962 RETURN_TRUE;
963 }
964 RETURN_FALSE;
965 }
966 /* }}} */
967
968 /* {{{ proto bool oci_lob_export([string filename [, int start [, int length]]])
969 Writes a large object into a file */
PHP_FUNCTION(oci_lob_export)970 PHP_FUNCTION(oci_lob_export)
971 {
972 zval *tmp, *z_descriptor = getThis();
973 php_oci_descriptor *descriptor;
974 char *filename;
975 char *buffer;
976 size_t filename_len;
977 zend_long start = -1, length = -1, block_length;
978 php_stream *stream;
979 ub4 lob_length;
980
981 if (getThis()) {
982 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ll", &filename, &filename_len, &start, &length) == FAILURE) {
983 return;
984 }
985
986 if (ZEND_NUM_ARGS() > 1 && start < 0) {
987 php_error_docref(NULL, E_WARNING, "Start parameter must be greater than or equal to 0");
988 RETURN_FALSE;
989 }
990 if (ZEND_NUM_ARGS() > 2 && length < 0) {
991 php_error_docref(NULL, E_WARNING, "Length parameter must be greater than or equal to 0");
992 RETURN_FALSE;
993 }
994 }
995 else {
996 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Op|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) {
997 return;
998 }
999
1000 if (ZEND_NUM_ARGS() > 2 && start < 0) {
1001 php_error_docref(NULL, E_WARNING, "Start parameter must be greater than or equal to 0");
1002 RETURN_FALSE;
1003 }
1004 if (ZEND_NUM_ARGS() > 3 && length < 0) {
1005 php_error_docref(NULL, E_WARNING, "Length parameter must be greater than or equal to 0");
1006 RETURN_FALSE;
1007 }
1008 }
1009
1010 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
1011 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
1012 RETURN_FALSE;
1013 }
1014
1015 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
1016
1017 if (php_oci_lob_get_length(descriptor, &lob_length)) {
1018 RETURN_FALSE;
1019 }
1020
1021 if (start == -1) {
1022 start = 0;
1023 }
1024
1025 if (length == -1) {
1026 length = lob_length - descriptor->lob_current_position;
1027 }
1028
1029 if (lob_length == 0) {
1030 length = 0;
1031 }
1032
1033 if (length == 0) {
1034 /* nothing to write, fail silently */
1035 RETURN_FALSE;
1036 }
1037
1038 if (php_check_open_basedir(filename)) {
1039 RETURN_FALSE;
1040 }
1041
1042 stream = php_stream_open_wrapper_ex(filename, "w", REPORT_ERRORS, NULL, NULL);
1043
1044 block_length = PHP_OCI_LOB_BUFFER_SIZE;
1045 if (block_length > length) {
1046 block_length = length;
1047 }
1048
1049 while(length > 0) {
1050 ub4 tmp_bytes_read = 0;
1051 if (php_oci_lob_read(descriptor, block_length, start, &buffer, &tmp_bytes_read)) {
1052 php_stream_close(stream);
1053 RETURN_FALSE;
1054 }
1055 if (tmp_bytes_read && !php_stream_write(stream, buffer, tmp_bytes_read)) {
1056 php_stream_close(stream);
1057 if (buffer)
1058 efree(buffer);
1059 RETURN_FALSE;
1060 }
1061 if (buffer) {
1062 efree(buffer);
1063 }
1064
1065 length -= tmp_bytes_read;
1066 descriptor->lob_current_position += tmp_bytes_read;
1067 start += tmp_bytes_read;
1068
1069 if (block_length > length) {
1070 block_length = length;
1071 }
1072 }
1073
1074 php_stream_close(stream);
1075 RETURN_TRUE;
1076 }
1077 /* }}} */
1078
1079 /* {{{ proto bool oci_lob_write_temporary(string var [, int lob_type])
1080 Writes temporary blob */
PHP_FUNCTION(oci_lob_write_temporary)1081 PHP_FUNCTION(oci_lob_write_temporary)
1082 {
1083 zval *tmp, *z_descriptor = getThis();
1084 php_oci_descriptor *descriptor;
1085 char *data;
1086 size_t data_len;
1087 zend_long type = OCI_TEMP_CLOB;
1088
1089 if (getThis()) {
1090 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &data, &data_len, &type) == FAILURE) {
1091 return;
1092 }
1093 }
1094 else {
1095 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &type) == FAILURE) {
1096 return;
1097 }
1098 }
1099
1100 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
1101 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
1102 RETURN_FALSE;
1103 }
1104
1105 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
1106
1107 if (php_oci_lob_write_tmp(descriptor, type, data, (int) data_len)) {
1108 RETURN_FALSE;
1109 }
1110 RETURN_TRUE;
1111 }
1112 /* }}} */
1113
1114 /* {{{ proto bool oci_lob_close()
1115 Closes lob descriptor */
PHP_FUNCTION(oci_lob_close)1116 PHP_FUNCTION(oci_lob_close)
1117 {
1118 zval *tmp, *z_descriptor = getThis();
1119 php_oci_descriptor *descriptor;
1120
1121 if (!getThis()) {
1122 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
1123 return;
1124 }
1125 }
1126
1127 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) {
1128 php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
1129 RETURN_FALSE;
1130 }
1131
1132 PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor);
1133
1134 if (php_oci_lob_close(descriptor)) {
1135 RETURN_FALSE;
1136 }
1137 RETURN_TRUE;
1138 }
1139 /* }}} */
1140
1141 /* {{{ proto object oci_new_descriptor(resource connection [, int type])
1142 Initialize a new empty descriptor LOB/FILE (LOB is default) */
PHP_FUNCTION(oci_new_descriptor)1143 PHP_FUNCTION(oci_new_descriptor)
1144 {
1145 zval *z_connection;
1146 php_oci_connection *connection;
1147 php_oci_descriptor *descriptor;
1148 zend_long type = OCI_DTYPE_LOB;
1149
1150 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &z_connection, &type) == FAILURE) {
1151 return;
1152 }
1153
1154 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1155
1156 /* php_oci_lob_create() checks type */
1157 descriptor = php_oci_lob_create(connection, type);
1158
1159 if (!descriptor) {
1160 RETURN_NULL();
1161 }
1162
1163 object_init_ex(return_value, oci_lob_class_entry_ptr);
1164 add_property_resource(return_value, "descriptor", descriptor->id);
1165 }
1166 /* }}} */
1167
1168 /* {{{ proto bool oci_rollback(resource connection)
1169 Rollback the current context */
PHP_FUNCTION(oci_rollback)1170 PHP_FUNCTION(oci_rollback)
1171 {
1172 zval *z_connection;
1173 php_oci_connection *connection;
1174
1175 ZEND_PARSE_PARAMETERS_START(1, 1)
1176 Z_PARAM_RESOURCE(z_connection)
1177 ZEND_PARSE_PARAMETERS_END();
1178
1179 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1180
1181 if (connection->descriptors) {
1182 php_oci_connection_descriptors_free(connection);
1183 }
1184
1185 if (php_oci_connection_rollback(connection)) {
1186 RETURN_FALSE;
1187 }
1188 RETURN_TRUE;
1189 }
1190 /* }}} */
1191
1192 /* {{{ proto bool oci_commit(resource connection)
1193 Commit the current context */
PHP_FUNCTION(oci_commit)1194 PHP_FUNCTION(oci_commit)
1195 {
1196 zval *z_connection;
1197 php_oci_connection *connection;
1198
1199 ZEND_PARSE_PARAMETERS_START(1, 1)
1200 Z_PARAM_RESOURCE(z_connection)
1201 ZEND_PARSE_PARAMETERS_END();
1202
1203 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1204
1205 if (connection->descriptors) {
1206 php_oci_connection_descriptors_free(connection);
1207 }
1208
1209 if (php_oci_connection_commit(connection)) {
1210 RETURN_FALSE;
1211 }
1212 RETURN_TRUE;
1213 }
1214 /* }}} */
1215
1216 /* {{{ proto string oci_field_name(resource stmt, mixed col)
1217 Tell the name of a column */
PHP_FUNCTION(oci_field_name)1218 PHP_FUNCTION(oci_field_name)
1219 {
1220 php_oci_out_column *column;
1221
1222 if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
1223 RETURN_STRINGL(column->name, column->name_len);
1224 }
1225 RETURN_FALSE;
1226 }
1227 /* }}} */
1228
1229 /* {{{ proto int oci_field_size(resource stmt, mixed col)
1230 Tell the maximum data size of a column */
PHP_FUNCTION(oci_field_size)1231 PHP_FUNCTION(oci_field_size)
1232 {
1233 php_oci_out_column *column;
1234
1235 if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
1236 /* Handle data type of LONG */
1237 if (column->data_type == SQLT_LNG){
1238 RETURN_LONG(column->storage_size4);
1239 }
1240 RETURN_LONG(column->data_size);
1241 }
1242 RETURN_FALSE;
1243 }
1244 /* }}} */
1245
1246 /* {{{ proto int oci_field_scale(resource stmt, mixed col)
1247 Tell the scale of a column */
PHP_FUNCTION(oci_field_scale)1248 PHP_FUNCTION(oci_field_scale)
1249 {
1250 php_oci_out_column *column;
1251
1252 if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
1253 RETURN_LONG(column->scale);
1254 }
1255 RETURN_FALSE;
1256 }
1257 /* }}} */
1258
1259 /* {{{ proto int oci_field_precision(resource stmt, mixed col)
1260 Tell the precision of a column */
PHP_FUNCTION(oci_field_precision)1261 PHP_FUNCTION(oci_field_precision)
1262 {
1263 php_oci_out_column *column;
1264
1265 if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
1266 RETURN_LONG(column->precision);
1267 }
1268 RETURN_FALSE;
1269 }
1270 /* }}} */
1271
1272 /* {{{ proto mixed oci_field_type(resource stmt, mixed col)
1273 Tell the data type of a column */
PHP_FUNCTION(oci_field_type)1274 PHP_FUNCTION(oci_field_type)
1275 {
1276 php_oci_out_column *column;
1277
1278 column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1279
1280 if (!column) {
1281 RETURN_FALSE;
1282 }
1283
1284 switch (column->data_type) {
1285 #ifdef SQLT_TIMESTAMP
1286 case SQLT_TIMESTAMP:
1287 RETVAL_STRING("TIMESTAMP");
1288 break;
1289 #endif
1290 #ifdef SQLT_TIMESTAMP_TZ
1291 case SQLT_TIMESTAMP_TZ:
1292 RETVAL_STRING("TIMESTAMP WITH TIMEZONE");
1293 break;
1294 #endif
1295 #ifdef SQLT_TIMESTAMP_LTZ
1296 case SQLT_TIMESTAMP_LTZ:
1297 RETVAL_STRING("TIMESTAMP WITH LOCAL TIMEZONE");
1298 break;
1299 #endif
1300 #ifdef SQLT_INTERVAL_YM
1301 case SQLT_INTERVAL_YM:
1302 RETVAL_STRING("INTERVAL YEAR TO MONTH");
1303 break;
1304 #endif
1305 #ifdef SQLT_INTERVAL_DS
1306 case SQLT_INTERVAL_DS:
1307 RETVAL_STRING("INTERVAL DAY TO SECOND");
1308 break;
1309 #endif
1310 case SQLT_DAT:
1311 RETVAL_STRING("DATE");
1312 break;
1313 case SQLT_NUM:
1314 RETVAL_STRING("NUMBER");
1315 break;
1316 case SQLT_LNG:
1317 RETVAL_STRING("LONG");
1318 break;
1319 case SQLT_BIN:
1320 RETVAL_STRING("RAW");
1321 break;
1322 case SQLT_LBI:
1323 RETVAL_STRING("LONG RAW");
1324 break;
1325 case SQLT_CHR:
1326 RETVAL_STRING("VARCHAR2");
1327 break;
1328 case SQLT_RSET:
1329 RETVAL_STRING("REFCURSOR");
1330 break;
1331 case SQLT_AFC:
1332 RETVAL_STRING("CHAR");
1333 break;
1334 case SQLT_BLOB:
1335 RETVAL_STRING("BLOB");
1336 break;
1337 case SQLT_CLOB:
1338 RETVAL_STRING("CLOB");
1339 break;
1340 case SQLT_BFILE:
1341 RETVAL_STRING("BFILE");
1342 break;
1343 case SQLT_RDD:
1344 RETVAL_STRING("ROWID");
1345 break;
1346 default:
1347 RETVAL_LONG(column->data_type);
1348 }
1349 }
1350 /* }}} */
1351
1352 /* {{{ proto int oci_field_type_raw(resource stmt, mixed col)
1353 Tell the raw oracle data type of a column */
PHP_FUNCTION(oci_field_type_raw)1354 PHP_FUNCTION(oci_field_type_raw)
1355 {
1356 php_oci_out_column *column;
1357
1358 column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1359 if (column) {
1360 RETURN_LONG(column->data_type);
1361 }
1362 RETURN_FALSE;
1363 }
1364 /* }}} */
1365
1366 /* {{{ proto bool oci_field_is_null(resource stmt, mixed col)
1367 Tell whether a field in the current row is NULL */
PHP_FUNCTION(oci_field_is_null)1368 PHP_FUNCTION(oci_field_is_null)
1369 {
1370 php_oci_out_column *column;
1371
1372 if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
1373 if (column->indicator == -1) {
1374 RETURN_TRUE;
1375 }
1376 }
1377 RETURN_FALSE;
1378 }
1379 /* }}} */
1380
1381 /* {{{ proto void oci_internal_debug(int onoff)
1382 Toggle internal debugging output for the OCI extension */
PHP_FUNCTION(oci_internal_debug)1383 PHP_FUNCTION(oci_internal_debug)
1384 {
1385 /* NOP in OCI8 2.0. Obsoleted by DTrace probes */
1386 }
1387 /* }}} */
1388
1389 /* {{{ proto bool oci_execute(resource stmt [, int mode])
1390 Execute a parsed statement */
PHP_FUNCTION(oci_execute)1391 PHP_FUNCTION(oci_execute)
1392 {
1393 zval *z_statement;
1394 php_oci_statement *statement;
1395 zend_long mode = OCI_COMMIT_ON_SUCCESS;
1396
1397 ZEND_PARSE_PARAMETERS_START(1, 2)
1398 Z_PARAM_RESOURCE(z_statement)
1399 Z_PARAM_OPTIONAL
1400 Z_PARAM_LONG(mode)
1401 ZEND_PARSE_PARAMETERS_END();
1402
1403 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1404
1405 if (php_oci_statement_execute(statement, (ub4) mode)) {
1406 RETURN_FALSE;
1407 }
1408 RETURN_TRUE;
1409 }
1410 /* }}} */
1411
1412 /* {{{ proto bool oci_cancel(resource stmt)
1413 Cancel reading from a cursor */
PHP_FUNCTION(oci_cancel)1414 PHP_FUNCTION(oci_cancel)
1415 {
1416 zval *z_statement;
1417 php_oci_statement *statement;
1418
1419 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_statement) == FAILURE) {
1420 return;
1421 }
1422
1423 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1424
1425 if (php_oci_statement_cancel(statement)) {
1426 RETURN_FALSE;
1427 }
1428 RETURN_TRUE;
1429 }
1430 /* }}} */
1431
1432 /* {{{ proto bool oci_fetch(resource stmt)
1433 Prepare a new row of data for reading */
PHP_FUNCTION(oci_fetch)1434 PHP_FUNCTION(oci_fetch)
1435 {
1436 zval *z_statement;
1437 php_oci_statement *statement;
1438 ub4 nrows = 1; /* only one row at a time is supported for now */
1439
1440 ZEND_PARSE_PARAMETERS_START(1, 1)
1441 Z_PARAM_RESOURCE(z_statement)
1442 ZEND_PARSE_PARAMETERS_END();
1443
1444 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1445
1446 if (php_oci_statement_fetch(statement, nrows)) {
1447 RETURN_FALSE;
1448 }
1449 RETURN_TRUE;
1450 }
1451 /* }}} */
1452
1453 /* {{{ proto int ocifetchinto(resource stmt, array &output [, int mode])
1454 Fetch a row of result data into an array */
PHP_FUNCTION(ocifetchinto)1455 PHP_FUNCTION(ocifetchinto)
1456 {
1457 php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM, 3);
1458 }
1459 /* }}} */
1460
1461 /* {{{ proto int oci_fetch_all(resource stmt, array &output[, int skip[, int maxrows[, int flags]]])
1462 Fetch all rows of result data into an array */
PHP_FUNCTION(oci_fetch_all)1463 PHP_FUNCTION(oci_fetch_all)
1464 {
1465 zval *z_statement, *array;
1466 zval element, tmp;
1467 php_oci_statement *statement;
1468 php_oci_out_column **columns;
1469 zval **outarrs;
1470 ub4 nrows = 1;
1471 int i;
1472 zend_long rows = 0, flags = 0, skip = 0, maxrows = -1;
1473
1474 ZEND_PARSE_PARAMETERS_START(2, 5)
1475 Z_PARAM_RESOURCE(z_statement)
1476 Z_PARAM_ZVAL(array)
1477 Z_PARAM_OPTIONAL
1478 Z_PARAM_LONG(skip)
1479 Z_PARAM_LONG(maxrows)
1480 Z_PARAM_LONG(flags)
1481 ZEND_PARSE_PARAMETERS_END();
1482
1483 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1484
1485 while (skip--) {
1486 if (php_oci_statement_fetch(statement, nrows)) {
1487 zend_try_array_init(array);
1488 RETURN_LONG(0);
1489 }
1490 }
1491
1492 if (flags & PHP_OCI_FETCHSTATEMENT_BY_ROW) {
1493 /* Fetch by Row: array will contain one sub-array per query row */
1494 array = zend_try_array_init(array);
1495 if (!array) {
1496 return;
1497 }
1498
1499 columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
1500 for (i = 0; i < statement->ncolumns; i++) {
1501 columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0);
1502 }
1503
1504 while (!php_oci_statement_fetch(statement, nrows)) {
1505 zval row;
1506
1507 array_init_size(&row, statement->ncolumns);
1508
1509 for (i = 0; i < statement->ncolumns; i++) {
1510 php_oci_column_to_zval(columns[ i ], &element, PHP_OCI_RETURN_LOBS);
1511
1512 if (flags & PHP_OCI_NUM) {
1513 zend_hash_next_index_insert(Z_ARRVAL(row), &element);
1514 } else { /* default to ASSOC */
1515 zend_string *zvtmp;
1516 zvtmp = zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0);
1517 zend_symtable_update(Z_ARRVAL(row), zvtmp, &element);
1518 #if PHP_VERSION_ID < 70300
1519 zend_string_release(zvtmp);
1520 #else
1521 zend_string_release_ex(zvtmp, 0);
1522 #endif
1523 }
1524 }
1525
1526 zend_hash_next_index_insert(Z_ARRVAL_P(array), &row);
1527 rows++;
1528
1529 if (maxrows != -1 && rows == maxrows) {
1530 php_oci_statement_cancel(statement);
1531 break;
1532 }
1533 }
1534 efree(columns);
1535
1536 } else { /* default to BY_COLUMN */
1537 /* Fetch by columns: array will contain one sub-array per query column */
1538 array = zend_try_array_init_size(array, statement->ncolumns);
1539 if (!array) {
1540 return;
1541 }
1542
1543 columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
1544 outarrs = safe_emalloc(statement->ncolumns, sizeof(zval*), 0);
1545
1546 if (flags & PHP_OCI_NUM) {
1547 for (i = 0; i < statement->ncolumns; i++) {
1548 columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0);
1549
1550 array_init(&tmp);
1551 outarrs[ i ] = zend_hash_next_index_insert(Z_ARRVAL_P(array), &tmp);
1552 }
1553 } else { /* default to ASSOC */
1554 for (i = 0; i < statement->ncolumns; i++) {
1555 zend_string *zvtmp;
1556 columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0);
1557
1558 array_init(&tmp);
1559 zvtmp = zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0);
1560 outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zvtmp, &tmp);
1561 #if PHP_VERSION_ID < 70300
1562 zend_string_release(zvtmp);
1563 #else
1564 zend_string_release_ex(zvtmp, 0);
1565 #endif
1566 }
1567 }
1568
1569 while (!php_oci_statement_fetch(statement, nrows)) {
1570 for (i = 0; i < statement->ncolumns; i++) {
1571 php_oci_column_to_zval(columns[ i ], &element, PHP_OCI_RETURN_LOBS);
1572 zend_hash_index_update(Z_ARRVAL_P(outarrs[ i ]), rows, &element);
1573 }
1574
1575 rows++;
1576
1577 if (maxrows != -1 && rows == maxrows) {
1578 php_oci_statement_cancel(statement);
1579 break;
1580 }
1581 }
1582
1583 efree(columns);
1584 efree(outarrs);
1585 }
1586
1587 RETURN_LONG(rows);
1588 }
1589 /* }}} */
1590
1591 /* {{{ proto object oci_fetch_object( resource stmt )
1592 Fetch a result row as an object */
PHP_FUNCTION(oci_fetch_object)1593 PHP_FUNCTION(oci_fetch_object)
1594 {
1595 php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC | PHP_OCI_RETURN_NULLS, 2);
1596
1597 if (Z_TYPE_P(return_value) == IS_ARRAY) {
1598 object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
1599 }
1600 }
1601 /* }}} */
1602
1603 /* {{{ proto array oci_fetch_row( resource stmt )
1604 Fetch a result row as an enumerated array */
PHP_FUNCTION(oci_fetch_row)1605 PHP_FUNCTION(oci_fetch_row)
1606 {
1607 php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM | PHP_OCI_RETURN_NULLS, 1);
1608 }
1609 /* }}} */
1610
1611 /* {{{ proto array oci_fetch_assoc( resource stmt )
1612 Fetch a result row as an associative array */
PHP_FUNCTION(oci_fetch_assoc)1613 PHP_FUNCTION(oci_fetch_assoc)
1614 {
1615 php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC | PHP_OCI_RETURN_NULLS, 1);
1616 }
1617 /* }}} */
1618
1619 /* {{{ proto array oci_fetch_array( resource stmt [, int mode ])
1620 Fetch a result row as an array */
PHP_FUNCTION(oci_fetch_array)1621 PHP_FUNCTION(oci_fetch_array)
1622 {
1623 php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_BOTH | PHP_OCI_RETURN_NULLS, 2);
1624 }
1625 /* }}} */
1626
1627 /* {{{ proto bool oci_free_statement(resource stmt)
1628 Free all resources associated with a statement */
PHP_FUNCTION(oci_free_statement)1629 PHP_FUNCTION(oci_free_statement)
1630 {
1631 zval *z_statement;
1632 php_oci_statement *statement;
1633
1634 ZEND_PARSE_PARAMETERS_START(1, 1)
1635 Z_PARAM_RESOURCE(z_statement)
1636 ZEND_PARSE_PARAMETERS_END();
1637
1638 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1639
1640 zend_list_close(statement->id);
1641 RETURN_TRUE;
1642 }
1643 /* }}} */
1644
1645 /* {{{ proto bool oci_close(resource connection)
1646 Disconnect from database */
PHP_FUNCTION(oci_close)1647 PHP_FUNCTION(oci_close)
1648 {
1649 /* oci_close for pconnect (if old_oci_close_semantics not set) would
1650 * release the connection back to the client-side session pool (and to the
1651 * server-side pool if Database Resident Connection Pool is being used).
1652 * Subsequent pconnects in the same script are not guaranteed to get the
1653 * same database session.
1654 */
1655
1656 zval *z_connection;
1657 php_oci_connection *connection;
1658
1659 if (OCI_G(old_oci_close_semantics)) {
1660 /* do nothing to keep BC */
1661 return;
1662 }
1663
1664 ZEND_PARSE_PARAMETERS_START(1, 1)
1665 Z_PARAM_RESOURCE(z_connection)
1666 ZEND_PARSE_PARAMETERS_END();
1667
1668 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1669 if (GC_REFCOUNT(connection->id) == 2) { /* CHANGED VERSION::PHP7
1670 Changed the refCount to 2 since
1671 internally Zend engine increments
1672 RefCount value by 1 */
1673 /* Unregister Oracle TAF */
1674 php_oci_unregister_taf_callback(connection);
1675
1676 zend_list_close(connection->id);
1677 }
1678
1679 /* ZVAL_NULL(z_connection); */
1680
1681 RETURN_TRUE;
1682 }
1683 /* }}} */
1684
1685 /* {{{ proto resource oci_new_connect(string user, string pass [, string db, string charset [, int session_mode ]])
1686 Connect to an Oracle database and log on. Returns a new session. */
PHP_FUNCTION(oci_new_connect)1687 PHP_FUNCTION(oci_new_connect)
1688 {
1689 php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
1690 }
1691 /* }}} */
1692
1693 /* {{{ proto resource oci_connect(string user, string pass [, string db [, string charset [, int session_mode ]])
1694 Connect to an Oracle database and log on. Returns a new session. */
PHP_FUNCTION(oci_connect)1695 PHP_FUNCTION(oci_connect)
1696 {
1697 php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
1698 }
1699 /* }}} */
1700
1701 /* {{{ proto resource oci_pconnect(string user, string pass [, string db [, string charset [, int session_mode ]])
1702 Connect to an Oracle database using a persistent connection and log on. Returns a new session. */
PHP_FUNCTION(oci_pconnect)1703 PHP_FUNCTION(oci_pconnect)
1704 {
1705 php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
1706 }
1707 /* }}} */
1708
1709 /* {{{ proto array oci_error([resource stmt|connection|global])
1710 Return the last error of stmt|connection|global. If no error happened returns false. */
PHP_FUNCTION(oci_error)1711 PHP_FUNCTION(oci_error)
1712 {
1713 zval *arg = NULL;
1714 php_oci_statement *statement;
1715 php_oci_connection *connection;
1716 text errbuf[PHP_OCI_ERRBUF_LEN];
1717 sb4 errcode = 0;
1718 dvoid *errh = NULL;
1719 ub2 error_offset = 0;
1720 text *sqltext = NULL;
1721
1722 ZEND_PARSE_PARAMETERS_START(0, 1)
1723 Z_PARAM_OPTIONAL
1724 Z_PARAM_RESOURCE(arg)
1725 ZEND_PARSE_PARAMETERS_END();
1726
1727 if (ZEND_NUM_ARGS() > 0) {
1728 statement = (php_oci_statement *) zend_fetch_resource_ex(arg, NULL, le_statement);
1729 if (statement) {
1730 errh = statement->err;
1731 errcode = statement->errcode;
1732
1733 if (php_oci_fetch_sqltext_offset(statement, &sqltext, &error_offset)) {
1734 RETURN_FALSE;
1735 }
1736 goto go_out;
1737 }
1738
1739 connection = (php_oci_connection *) zend_fetch_resource_ex(arg, NULL, le_connection);
1740 if (connection) {
1741 errh = connection->err;
1742 errcode = connection->errcode;
1743 goto go_out;
1744 }
1745
1746 connection = (php_oci_connection *) zend_fetch_resource_ex(arg, NULL, le_pconnection);
1747 if (connection) {
1748 errh = connection->err;
1749 errcode = connection->errcode;
1750 goto go_out;
1751 }
1752 } else {
1753 errh = OCI_G(err);
1754 errcode = OCI_G(errcode);
1755 }
1756
1757 go_out:
1758 if (errcode == 0) { /* no error set in the handle */
1759 RETURN_FALSE;
1760 }
1761
1762 if (!errh) {
1763 php_error_docref(NULL, E_WARNING, "Oci_error: unable to find error handle");
1764 RETURN_FALSE;
1765 }
1766
1767 errcode = php_oci_fetch_errmsg(errh, errbuf, sizeof(errbuf));
1768
1769 if (errcode) {
1770 array_init(return_value);
1771 add_assoc_long(return_value, "code", errcode);
1772 /* TODO: avoid reallocation ??? */
1773 add_assoc_string(return_value, "message", (char*) errbuf);
1774 add_assoc_long(return_value, "offset", error_offset);
1775 add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : "");
1776 } else {
1777 RETURN_FALSE;
1778 }
1779 }
1780 /* }}} */
1781
1782 /* {{{ proto int oci_num_fields(resource stmt)
1783 Return the number of result columns in a statement */
PHP_FUNCTION(oci_num_fields)1784 PHP_FUNCTION(oci_num_fields)
1785 {
1786 zval *z_statement;
1787 php_oci_statement *statement;
1788
1789 ZEND_PARSE_PARAMETERS_START(1, 1)
1790 Z_PARAM_RESOURCE(z_statement)
1791 ZEND_PARSE_PARAMETERS_END();
1792
1793 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1794
1795 RETURN_LONG(statement->ncolumns);
1796 }
1797 /* }}} */
1798
1799 /* {{{ proto resource oci_parse(resource connection, string statement)
1800 Parse a SQL or PL/SQL statement and return a statement resource */
PHP_FUNCTION(oci_parse)1801 PHP_FUNCTION(oci_parse)
1802 {
1803 zval *z_connection;
1804 php_oci_connection *connection;
1805 php_oci_statement *statement;
1806 char *query;
1807 size_t query_len;
1808
1809 ZEND_PARSE_PARAMETERS_START(2, 2)
1810 Z_PARAM_RESOURCE(z_connection)
1811 Z_PARAM_STRING(query, query_len)
1812 ZEND_PARSE_PARAMETERS_END();
1813
1814 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1815
1816 statement = php_oci_statement_create(connection, query, (int) query_len);
1817
1818 if (statement) {
1819 RETURN_RES(statement->id);
1820 }
1821 RETURN_FALSE;
1822 }
1823 /* }}} */
1824
1825 /* {{{ proto bool oci_set_prefetch(resource stmt, int prefetch_rows)
1826 Sets the number of rows to be prefetched on execute to prefetch_rows for stmt */
PHP_FUNCTION(oci_set_prefetch)1827 PHP_FUNCTION(oci_set_prefetch)
1828 {
1829 zval *z_statement;
1830 php_oci_statement *statement;
1831 zend_long size;
1832
1833 ZEND_PARSE_PARAMETERS_START(2, 2)
1834 Z_PARAM_RESOURCE(z_statement)
1835 Z_PARAM_LONG(size)
1836 ZEND_PARSE_PARAMETERS_END();
1837
1838 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
1839
1840 if (size < 0) {
1841 php_error_docref(NULL, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0");
1842 return;
1843 }
1844
1845 if (php_oci_statement_set_prefetch(statement, (ub4)size)) {
1846 RETURN_FALSE;
1847 }
1848 RETURN_TRUE;
1849 }
1850 /* }}} */
1851
1852 /* {{{ proto bool oci_set_client_identifier(resource connection, string value)
1853 Sets the client identifier attribute on the connection */
PHP_FUNCTION(oci_set_client_identifier)1854 PHP_FUNCTION(oci_set_client_identifier)
1855 {
1856 zval *z_connection;
1857 php_oci_connection *connection;
1858 char *client_id;
1859 size_t client_id_len;
1860 sword errstatus;
1861
1862 ZEND_PARSE_PARAMETERS_START(2, 2)
1863 Z_PARAM_RESOURCE(z_connection)
1864 Z_PARAM_STRING(client_id, client_id_len)
1865 ZEND_PARSE_PARAMETERS_END();
1866
1867 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1868
1869 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_id, (ub4) client_id_len, (ub4) OCI_ATTR_CLIENT_IDENTIFIER, connection->err));
1870
1871 if (errstatus != OCI_SUCCESS) {
1872 connection->errcode = php_oci_error(connection->err, errstatus);
1873 RETURN_FALSE;
1874 }
1875
1876 #ifdef HAVE_OCI8_DTRACE
1877 /* The alternatives to storing client_id like done below are
1878 i) display it in a probe here in oci_set_client_identifier and
1879 let the user D script correlate the connection address probe
1880 argument and the client_id. This would likely require user D
1881 script variables, which would use kernel memory.
1882 ii) call OCIAttrGet for each probe definition that uses
1883 client_id. This would be slower than storing it.
1884 */
1885
1886 if (connection->client_id) {
1887 pefree(connection->client_id, connection->is_persistent);
1888 }
1889
1890 if (client_id) {
1891 /* this long winded copy allows compatibility with older PHP versions */
1892 connection->client_id = (char *)pemalloc(client_id_len+1, connection->is_persistent);
1893 memcpy(connection->client_id, client_id, client_id_len);
1894 connection->client_id[client_id_len] = '\0';
1895 } else {
1896 connection->client_id = NULL;
1897 }
1898 #endif /* HAVE_OCI8_DTRACE */
1899
1900 RETURN_TRUE;
1901 }
1902 /* }}} */
1903
1904 /* {{{ proto bool oci_set_edition(string value)
1905 Sets the edition attribute for all subsequent connections created */
PHP_FUNCTION(oci_set_edition)1906 PHP_FUNCTION(oci_set_edition)
1907 {
1908 #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
1909 char *edition;
1910 size_t edition_len;
1911
1912 ZEND_PARSE_PARAMETERS_START(1, 1)
1913 Z_PARAM_STRING(edition, edition_len)
1914 ZEND_PARSE_PARAMETERS_END();
1915
1916 if (OCI_G(edition)) {
1917 efree(OCI_G(edition));
1918 }
1919
1920 if (edition) {
1921 OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(char), 0);
1922 memcpy(OCI_G(edition), edition, edition_len);
1923 OCI_G(edition)[edition_len] = '\0';
1924 } else {
1925 OCI_G(edition) = NULL;
1926 }
1927
1928 RETURN_TRUE;
1929 #else
1930 php_error_docref(NULL, E_NOTICE, "Unsupported attribute type");
1931 RETURN_FALSE;
1932 #endif
1933 }
1934 /* }}} */
1935
1936 /* {{{ proto bool oci_set_module_name(resource connection, string value)
1937 Sets the module attribute on the connection for end-to-end tracing */
PHP_FUNCTION(oci_set_module_name)1938 PHP_FUNCTION(oci_set_module_name)
1939 {
1940 #if (OCI_MAJOR_VERSION >= 10)
1941 zval *z_connection;
1942 php_oci_connection *connection;
1943 char *module;
1944 size_t module_len;
1945 sword errstatus;
1946
1947 ZEND_PARSE_PARAMETERS_START(2, 2)
1948 Z_PARAM_RESOURCE(z_connection)
1949 Z_PARAM_STRING(module, module_len)
1950 ZEND_PARSE_PARAMETERS_END();
1951
1952 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1953
1954 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) module, (ub4) module_len, (ub4) OCI_ATTR_MODULE, connection->err));
1955
1956 if (errstatus != OCI_SUCCESS) {
1957 connection->errcode = php_oci_error(connection->err, errstatus);
1958 RETURN_FALSE;
1959 }
1960
1961 RETURN_TRUE;
1962 #else
1963 php_error_docref(NULL, E_NOTICE, "Unsupported attribute type");
1964 RETURN_FALSE;
1965 #endif
1966 }
1967 /* }}} */
1968
1969 /* {{{ proto bool oci_set_action(resource connection, string value)
1970 Sets the action attribute on the connection for end-to-end tracing */
PHP_FUNCTION(oci_set_action)1971 PHP_FUNCTION(oci_set_action)
1972 {
1973 #if (OCI_MAJOR_VERSION >= 10)
1974 zval *z_connection;
1975 php_oci_connection *connection;
1976 char *action;
1977 size_t action_len;
1978 sword errstatus;
1979
1980 ZEND_PARSE_PARAMETERS_START(2, 2)
1981 Z_PARAM_RESOURCE(z_connection)
1982 Z_PARAM_STRING(action, action_len)
1983 ZEND_PARSE_PARAMETERS_END();
1984
1985 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
1986
1987 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) action, (ub4) action_len, (ub4) OCI_ATTR_ACTION, connection->err));
1988
1989 if (errstatus != OCI_SUCCESS) {
1990 connection->errcode = php_oci_error(connection->err, errstatus);
1991 RETURN_FALSE;
1992 }
1993
1994 RETURN_TRUE;
1995 #else
1996 php_error_docref(NULL, E_NOTICE, "Unsupported attribute type");
1997 RETURN_FALSE;
1998 #endif
1999 }
2000 /* }}} */
2001
2002 /* {{{ proto bool oci_set_client_info(resource connection, string value)
2003 Sets the client info attribute on the connection for end-to-end tracing */
PHP_FUNCTION(oci_set_client_info)2004 PHP_FUNCTION(oci_set_client_info)
2005 {
2006 #if (OCI_MAJOR_VERSION >= 10)
2007 zval *z_connection;
2008 php_oci_connection *connection;
2009 char *client_info;
2010 size_t client_info_len;
2011 sword errstatus;
2012
2013 ZEND_PARSE_PARAMETERS_START(2, 2)
2014 Z_PARAM_RESOURCE(z_connection)
2015 Z_PARAM_STRING(client_info, client_info_len)
2016 ZEND_PARSE_PARAMETERS_END();
2017
2018 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2019
2020 PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_info, (ub4) client_info_len, (ub4) OCI_ATTR_CLIENT_INFO, connection->err));
2021
2022 if (errstatus != OCI_SUCCESS) {
2023 connection->errcode = php_oci_error(connection->err, errstatus);
2024 RETURN_FALSE;
2025 }
2026
2027 RETURN_TRUE;
2028 #else
2029 php_error_docref(NULL, E_NOTICE, "Unsupported attribute type");
2030 RETURN_FALSE;
2031 #endif
2032 }
2033 /* }}} */
2034
2035 /* {{{ proto bool oci_set_db_operation(resource connection, string value)
2036 Sets the "DB operation" on the connection for Oracle end-to-end tracing.
2037 For history, see Oracle bug 16695981 */
PHP_FUNCTION(oci_set_db_operation)2038 PHP_FUNCTION(oci_set_db_operation)
2039 {
2040 #if (OCI_MAJOR_VERSION > 11)
2041 zval *z_connection;
2042 php_oci_connection *connection;
2043 char *dbop_name;
2044 size_t dbop_name_len;
2045
2046 ZEND_PARSE_PARAMETERS_START(2, 2)
2047 Z_PARAM_RESOURCE(z_connection)
2048 Z_PARAM_STRING(dbop_name, dbop_name_len)
2049 ZEND_PARSE_PARAMETERS_END();
2050
2051 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2052
2053 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) dbop_name, (ub4) dbop_name_len, (ub4) OCI_ATTR_DBOP, OCI_G(err)));
2054
2055 if (OCI_G(errcode) != OCI_SUCCESS) {
2056 php_oci_error(OCI_G(err), OCI_G(errcode));
2057 RETURN_FALSE;
2058 }
2059 RETURN_TRUE;
2060 #else
2061 php_error_docref(NULL, E_NOTICE, "Unsupported attribute type");
2062 RETURN_FALSE;
2063 #endif
2064 }
2065 /* }}} */
2066
2067 /* {{{ proto bool oci_set_call_timeout(resource connection, int call_timeout)
2068 */
PHP_FUNCTION(oci_set_call_timeout)2069 PHP_FUNCTION(oci_set_call_timeout)
2070 {
2071 #if (OCI_MAJOR_VERSION >= 18)
2072 zval *z_connection;
2073 php_oci_connection *connection;
2074 zend_long call_timeout; // milliseconds
2075
2076 ZEND_PARSE_PARAMETERS_START(2, 2)
2077 Z_PARAM_RESOURCE(z_connection)
2078 Z_PARAM_LONG(call_timeout)
2079 ZEND_PARSE_PARAMETERS_END();
2080
2081 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2082
2083 PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX, (ub4 *) &call_timeout, 0, OCI_ATTR_CALL_TIMEOUT, OCI_G(err)));
2084
2085 if (OCI_G(errcode) != OCI_SUCCESS) {
2086 php_oci_error(OCI_G(err), OCI_G(errcode));
2087 RETURN_FALSE;
2088 }
2089 RETURN_TRUE;
2090 #else
2091 php_error_docref(NULL, E_NOTICE, "Unsupported with this version of Oracle Client");
2092 RETURN_FALSE;
2093 #endif
2094 }
2095 /* }}} */
2096
2097 /* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password)
2098 Changes the password of an account */
PHP_FUNCTION(oci_password_change)2099 PHP_FUNCTION(oci_password_change)
2100 {
2101 zval *z_connection;
2102 char *user, *pass_old, *pass_new, *dbname;
2103 size_t user_len, pass_old_len, pass_new_len, dbname_len;
2104 php_oci_connection *connection;
2105
2106 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rsss", &z_connection, &user, &user_len, &pass_old, &pass_old_len, &pass_new, &pass_new_len) == SUCCESS) {
2107 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2108
2109 if (!user_len) {
2110 php_error_docref(NULL, E_WARNING, "username cannot be empty");
2111 RETURN_FALSE;
2112 }
2113 if (!pass_old_len) {
2114 php_error_docref(NULL, E_WARNING, "old password cannot be empty");
2115 RETURN_FALSE;
2116 }
2117 if (!pass_new_len) {
2118 php_error_docref(NULL, E_WARNING, "new password cannot be empty");
2119 RETURN_FALSE;
2120 }
2121
2122 if (php_oci_password_change(connection, user, (int) user_len, pass_old, (int) pass_old_len, pass_new, (int) pass_new_len)) {
2123 RETURN_FALSE;
2124 }
2125 RETURN_TRUE;
2126 } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "ssss", &dbname, &dbname_len, &user, &user_len, &pass_old, &pass_old_len, &pass_new, &pass_new_len) == SUCCESS) {
2127
2128 if (!user_len) {
2129 php_error_docref(NULL, E_WARNING, "username cannot be empty");
2130 RETURN_FALSE;
2131 }
2132 if (!pass_old_len) {
2133 php_error_docref(NULL, E_WARNING, "old password cannot be empty");
2134 RETURN_FALSE;
2135 }
2136 if (!pass_new_len) {
2137 php_error_docref(NULL, E_WARNING, "new password cannot be empty");
2138 RETURN_FALSE;
2139 }
2140
2141 connection = php_oci_do_connect_ex(user, (int) user_len, pass_old, (int) pass_old_len, pass_new, (int) pass_new_len, dbname, (int) dbname_len, NULL, OCI_DEFAULT, 0, 0);
2142 if (!connection) {
2143 RETURN_FALSE;
2144 }
2145 RETURN_RES(connection->id);
2146 }
2147 WRONG_PARAM_COUNT;
2148 }
2149 /* }}} */
2150
2151 /* {{{ proto resource oci_new_cursor(resource connection)
2152 Return a new cursor (Statement-Handle) - use this to bind ref-cursors! */
PHP_FUNCTION(oci_new_cursor)2153 PHP_FUNCTION(oci_new_cursor)
2154 {
2155 zval *z_connection;
2156 php_oci_connection *connection;
2157 php_oci_statement *statement;
2158
2159 ZEND_PARSE_PARAMETERS_START(1, 1)
2160 Z_PARAM_RESOURCE(z_connection)
2161 ZEND_PARSE_PARAMETERS_END();
2162
2163 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2164
2165 statement = php_oci_statement_create(connection, NULL, 0);
2166
2167 if (statement) {
2168 RETURN_RES(statement->id);
2169 }
2170 RETURN_FALSE;
2171 }
2172 /* }}} */
2173
2174 /* {{{ proto string oci_result(resource stmt, mixed column)
2175 Return a single column of result data */
PHP_FUNCTION(oci_result)2176 PHP_FUNCTION(oci_result)
2177 {
2178 php_oci_out_column *column;
2179
2180 column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2181 if(column) {
2182 php_oci_column_to_zval(column, return_value, 0);
2183 }
2184 else {
2185 RETURN_FALSE;
2186 }
2187 }
2188 /* }}} */
2189
2190 /* {{{ proto string oci_client_version()
2191 Return a string containing runtime client library version information */
PHP_FUNCTION(oci_client_version)2192 PHP_FUNCTION(oci_client_version)
2193 {
2194 char version[256];
2195
2196 php_oci_client_get_version(version, sizeof(version));
2197 RETURN_STRING(version);
2198 }
2199 /* }}} */
2200
2201 /* {{{ proto string oci_server_version(resource connection)
2202 Return a string containing server version information */
PHP_FUNCTION(oci_server_version)2203 PHP_FUNCTION(oci_server_version)
2204 {
2205 zval *z_connection;
2206 php_oci_connection *connection;
2207 char version[256];
2208 zend_string *ret;
2209
2210 ZEND_PARSE_PARAMETERS_START(1, 1)
2211 Z_PARAM_RESOURCE(z_connection)
2212 ZEND_PARSE_PARAMETERS_END();
2213
2214 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2215
2216 if (php_oci_server_get_version(connection, version, sizeof(version))) {
2217 RETURN_FALSE;
2218 }
2219
2220 ret = zend_string_init(version, strlen(version), 0);
2221 RETURN_STR(ret);
2222 }
2223 /* }}} */
2224
2225 /* {{{ proto string oci_statement_type(resource stmt)
2226 Return the query type of an OCI statement */
PHP_FUNCTION(oci_statement_type)2227 PHP_FUNCTION(oci_statement_type)
2228 {
2229 zval *z_statement;
2230 php_oci_statement *statement;
2231 ub2 type;
2232
2233 ZEND_PARSE_PARAMETERS_START(1, 1)
2234 Z_PARAM_RESOURCE(z_statement)
2235 ZEND_PARSE_PARAMETERS_END();
2236
2237 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
2238
2239 if (php_oci_statement_get_type(statement, &type)) {
2240 RETURN_FALSE;
2241 }
2242
2243 switch (type) {
2244 case OCI_STMT_SELECT:
2245 RETVAL_STRING("SELECT");
2246 break;
2247 case OCI_STMT_UPDATE:
2248 RETVAL_STRING("UPDATE");
2249 break;
2250 case OCI_STMT_DELETE:
2251 RETVAL_STRING("DELETE");
2252 break;
2253 case OCI_STMT_INSERT:
2254 RETVAL_STRING("INSERT");
2255 break;
2256 case OCI_STMT_CREATE:
2257 RETVAL_STRING("CREATE");
2258 break;
2259 case OCI_STMT_DROP:
2260 RETVAL_STRING("DROP");
2261 break;
2262 case OCI_STMT_ALTER:
2263 RETVAL_STRING("ALTER");
2264 break;
2265 case OCI_STMT_BEGIN:
2266 RETVAL_STRING("BEGIN");
2267 break;
2268 case OCI_STMT_DECLARE:
2269 RETVAL_STRING("DECLARE");
2270 break;
2271 case OCI_STMT_CALL:
2272 RETVAL_STRING("CALL");
2273 break;
2274 default:
2275 RETVAL_STRING("UNKNOWN");
2276 }
2277 }
2278 /* }}} */
2279
2280 /* {{{ proto int oci_num_rows(resource stmt)
2281 Return the row count of an OCI statement */
PHP_FUNCTION(oci_num_rows)2282 PHP_FUNCTION(oci_num_rows)
2283 {
2284 zval *z_statement;
2285 php_oci_statement *statement;
2286 ub4 rowcount;
2287
2288 ZEND_PARSE_PARAMETERS_START(1, 1)
2289 Z_PARAM_RESOURCE(z_statement)
2290 ZEND_PARSE_PARAMETERS_END();
2291
2292 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
2293
2294 if (php_oci_statement_get_numrows(statement, &rowcount)) {
2295 RETURN_FALSE;
2296 }
2297 RETURN_LONG(rowcount);
2298 }
2299 /* }}} */
2300
2301 /* {{{ proto bool oci_free_collection()
2302 Deletes collection object*/
PHP_FUNCTION(oci_free_collection)2303 PHP_FUNCTION(oci_free_collection)
2304 {
2305 zval *tmp, *z_collection = getThis();
2306 php_oci_collection *collection;
2307
2308 if (!getThis()) {
2309 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
2310 return;
2311 }
2312 }
2313
2314 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2315 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2316 RETURN_FALSE;
2317 }
2318
2319 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2320
2321 zend_list_close(collection->id);
2322 RETURN_TRUE;
2323 }
2324 /* }}} */
2325
2326 /* {{{ proto bool oci_collection_append(string value)
2327 Append an object to the collection */
PHP_FUNCTION(oci_collection_append)2328 PHP_FUNCTION(oci_collection_append)
2329 {
2330 zval *tmp, *z_collection = getThis();
2331 php_oci_collection *collection;
2332 char *value;
2333 size_t value_len;
2334
2335 if (getThis()) {
2336 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &value, &value_len) == FAILURE) {
2337 return;
2338 }
2339 }
2340 else {
2341 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &z_collection, oci_coll_class_entry_ptr, &value, &value_len) == FAILURE) {
2342 return;
2343 }
2344 }
2345
2346 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2347 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2348 RETURN_FALSE;
2349 }
2350
2351 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2352
2353 if (php_oci_collection_append(collection, value, (int) value_len)) {
2354 RETURN_FALSE;
2355 }
2356 RETURN_TRUE;
2357 }
2358 /* }}} */
2359
2360 /* {{{ proto string oci_collection_element_get(int ndx)
2361 Retrieve the value at collection index ndx */
PHP_FUNCTION(oci_collection_element_get)2362 PHP_FUNCTION(oci_collection_element_get)
2363 {
2364 zval *tmp, *z_collection = getThis();
2365 php_oci_collection *collection;
2366 zend_long element_index;
2367 zval value;
2368
2369 if (getThis()) {
2370 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &element_index) == FAILURE) {
2371 return;
2372 }
2373 }
2374 else {
2375 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &z_collection, oci_coll_class_entry_ptr, &element_index) == FAILURE) {
2376 return;
2377 }
2378 }
2379
2380 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2381 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2382 RETURN_FALSE;
2383 }
2384
2385 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2386
2387 if (php_oci_collection_element_get(collection, element_index, &value)) {
2388 RETURN_FALSE;
2389 }
2390
2391 RETURN_ZVAL(&value, 1, 1);
2392 }
2393 /* }}} */
2394
2395 /* {{{ proto bool oci_collection_assign(object from)
2396 Assign a collection from another existing collection */
PHP_FUNCTION(oci_collection_assign)2397 PHP_FUNCTION(oci_collection_assign)
2398 {
2399 zval *tmp_dest, *tmp_from, *z_collection_dest = getThis(), *z_collection_from;
2400 php_oci_collection *collection_dest, *collection_from;
2401
2402 if (getThis()) {
2403 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_collection_from, oci_coll_class_entry_ptr) == FAILURE) {
2404 return;
2405 }
2406 }
2407 else {
2408 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &z_collection_dest, oci_coll_class_entry_ptr, &z_collection_from, oci_coll_class_entry_ptr) == FAILURE) {
2409 return;
2410 }
2411 }
2412
2413 if ((tmp_dest = zend_hash_str_find(Z_OBJPROP_P(z_collection_dest), "collection", sizeof("collection")-1)) == NULL) {
2414 php_error_docref(NULL, E_WARNING, "Unable to find collection property. The first argument should be valid collection object");
2415 RETURN_FALSE;
2416 }
2417
2418 if ((tmp_from = zend_hash_str_find(Z_OBJPROP_P(z_collection_from), "collection", sizeof("collection")-1)) == NULL) {
2419 php_error_docref(NULL, E_WARNING, "Unable to find collection property. The second argument should be valid collection object");
2420 RETURN_FALSE;
2421 }
2422
2423 PHP_OCI_ZVAL_TO_COLLECTION(tmp_dest, collection_dest);
2424 PHP_OCI_ZVAL_TO_COLLECTION(tmp_from, collection_from);
2425
2426 if (php_oci_collection_assign(collection_dest, collection_from)) {
2427 RETURN_FALSE;
2428 }
2429 RETURN_TRUE;
2430 }
2431 /* }}} */
2432
2433 /* {{{ proto bool oci_collection_element_assign(int index, string val)
2434 Assign element val to collection at index ndx */
PHP_FUNCTION(oci_collection_element_assign)2435 PHP_FUNCTION(oci_collection_element_assign)
2436 {
2437 zval *tmp, *z_collection = getThis();
2438 php_oci_collection *collection;
2439 size_t value_len;
2440 zend_long element_index;
2441 char *value;
2442
2443 if (getThis()) {
2444 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &element_index, &value, &value_len) == FAILURE) {
2445 return;
2446 }
2447 }
2448 else {
2449 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ols", &z_collection, oci_coll_class_entry_ptr, &element_index, &value, &value_len) == FAILURE) {
2450 return;
2451 }
2452 }
2453
2454 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2455 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2456 RETURN_FALSE;
2457 }
2458
2459 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2460
2461 if (php_oci_collection_element_set(collection, element_index, value, (int) value_len)) {
2462 RETURN_FALSE;
2463 }
2464 RETURN_TRUE;
2465 }
2466 /* }}} */
2467
2468 /* {{{ proto int oci_collection_size()
2469 Return the size of a collection */
PHP_FUNCTION(oci_collection_size)2470 PHP_FUNCTION(oci_collection_size)
2471 {
2472 zval *tmp, *z_collection = getThis();
2473 php_oci_collection *collection;
2474 sb4 size = 0;
2475
2476 if (!getThis()) {
2477 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
2478 return;
2479 }
2480 }
2481
2482 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2483 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2484 RETURN_FALSE;
2485 }
2486
2487 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2488
2489 if (php_oci_collection_size(collection, &size)) {
2490 RETURN_FALSE;
2491 }
2492 RETURN_LONG(size);
2493 }
2494 /* }}} */
2495
2496 /* {{{ proto int oci_collection_max()
2497 Return the max value of a collection. For a varray this is the maximum length of the array */
PHP_FUNCTION(oci_collection_max)2498 PHP_FUNCTION(oci_collection_max)
2499 {
2500 zval *tmp, *z_collection = getThis();
2501 php_oci_collection *collection;
2502 zend_long max;
2503
2504 if (!getThis()) {
2505 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
2506 return;
2507 }
2508 }
2509
2510 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2511 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2512 RETURN_FALSE;
2513 }
2514
2515 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2516
2517 if (php_oci_collection_max(collection, &max)) {
2518 RETURN_FALSE;
2519 }
2520 RETURN_LONG(max);
2521 }
2522 /* }}} */
2523
2524 /* {{{ proto bool oci_collection_trim(int num)
2525 Trim num elements from the end of a collection */
PHP_FUNCTION(oci_collection_trim)2526 PHP_FUNCTION(oci_collection_trim)
2527 {
2528 zval *tmp, *z_collection = getThis();
2529 php_oci_collection *collection;
2530 zend_long trim_size;
2531
2532 if (getThis()) {
2533 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &trim_size) == FAILURE) {
2534 return;
2535 }
2536 }
2537 else {
2538 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &z_collection, oci_coll_class_entry_ptr, &trim_size) == FAILURE) {
2539 return;
2540 }
2541 }
2542
2543 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection")-1)) == NULL) {
2544 php_error_docref(NULL, E_WARNING, "Unable to find collection property");
2545 RETURN_FALSE;
2546 }
2547
2548 PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection);
2549
2550 if (php_oci_collection_trim(collection, trim_size)) {
2551 RETURN_FALSE;
2552 }
2553 RETURN_TRUE;
2554 }
2555 /* }}} */
2556
2557 /* {{{ proto object oci_new_collection(resource connection, string tdo [, string schema])
2558 Initialize a new collection */
PHP_FUNCTION(oci_new_collection)2559 PHP_FUNCTION(oci_new_collection)
2560 {
2561 zval *z_connection;
2562 php_oci_connection *connection;
2563 php_oci_collection *collection;
2564 char *tdo, *schema = NULL;
2565 size_t tdo_len, schema_len = 0;
2566
2567 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|s", &z_connection, &tdo, &tdo_len, &schema, &schema_len) == FAILURE) {
2568 return;
2569 }
2570
2571 PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
2572
2573 if ( (collection = php_oci_collection_create(connection, tdo, (int) tdo_len, schema, (int) schema_len)) ) {
2574 object_init_ex(return_value, oci_coll_class_entry_ptr);
2575 add_property_resource(return_value, "collection", collection->id);
2576 }
2577 else {
2578 RETURN_FALSE;
2579 }
2580 }
2581 /* }}} */
2582
2583 /* {{{ proto bool oci_get_implicit(resource stmt)
2584 Get the next statement resource from an Oracle 12c PL/SQL Implicit Result Set */
PHP_FUNCTION(oci_get_implicit_resultset)2585 PHP_FUNCTION(oci_get_implicit_resultset)
2586 {
2587 zval *z_statement;
2588 php_oci_statement *statement;
2589 php_oci_statement *imp_statement;
2590
2591 ZEND_PARSE_PARAMETERS_START(1, 1)
2592 Z_PARAM_RESOURCE(z_statement)
2593 ZEND_PARSE_PARAMETERS_END();
2594
2595 PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
2596
2597 imp_statement = php_oci_get_implicit_resultset(statement);
2598
2599 if (imp_statement) {
2600 if (php_oci_statement_execute(imp_statement, (ub4)OCI_DEFAULT))
2601 RETURN_FALSE;
2602 RETURN_RES(imp_statement->id);
2603 }
2604 RETURN_FALSE;
2605 }
2606
2607 /* }}} */
2608
2609 #endif /* HAVE_OCI8 */
2610