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