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

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