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