root/ext/oci8/oci8_interface.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_FUNCTION
  2. PHP_FUNCTION
  3. PHP_FUNCTION
  4. PHP_FUNCTION
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION
  10. PHP_FUNCTION
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. PHP_FUNCTION
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. PHP_FUNCTION
  25. PHP_FUNCTION
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. PHP_FUNCTION
  34. PHP_FUNCTION
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. PHP_FUNCTION
  41. PHP_FUNCTION
  42. PHP_FUNCTION
  43. PHP_FUNCTION
  44. PHP_FUNCTION
  45. PHP_FUNCTION
  46. PHP_FUNCTION
  47. PHP_FUNCTION
  48. PHP_FUNCTION
  49. PHP_FUNCTION
  50. PHP_FUNCTION
  51. PHP_FUNCTION
  52. PHP_FUNCTION
  53. PHP_FUNCTION
  54. PHP_FUNCTION
  55. PHP_FUNCTION
  56. PHP_FUNCTION
  57. PHP_FUNCTION
  58. PHP_FUNCTION
  59. PHP_FUNCTION
  60. PHP_FUNCTION
  61. PHP_FUNCTION
  62. PHP_FUNCTION
  63. PHP_FUNCTION
  64. PHP_FUNCTION
  65. PHP_FUNCTION
  66. PHP_FUNCTION
  67. PHP_FUNCTION
  68. PHP_FUNCTION
  69. PHP_FUNCTION
  70. PHP_FUNCTION
  71. PHP_FUNCTION
  72. PHP_FUNCTION
  73. PHP_FUNCTION
  74. PHP_FUNCTION
  75. PHP_FUNCTION
  76. PHP_FUNCTION
  77. PHP_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */