Back to index

php5  5.3.10
oci8_interface.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
00016    |          Thies C. Arntzen <thies@thieso.net>                         |
00017    |                                                                      |
00018    | Collection support by Andy Sautins <asautins@veripost.net>           |
00019    | Temporary LOB support by David Benson <dbenson@mancala.com>          |
00020    | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at>        |
00021    |                                                                      |
00022    | Redesigned by: Antony Dovgal <antony@zend.com>                       |
00023    |                Andi Gutmans <andi@zend.com>                          |
00024    |                Wez Furlong <wez@omniti.com>                          |
00025    +----------------------------------------------------------------------+
00026 */
00027 
00028 /* $Id: oci8_interface.c 321634 2012-01-01 13:15:04Z felipe $ */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include "php.h"
00035 #include "ext/standard/info.h"
00036 #include "php_ini.h"
00037 
00038 #if HAVE_OCI8
00039 
00040 #include "php_oci8.h"
00041 #include "php_oci8_int.h"
00042 
00043 #ifndef OCI_STMT_CALL
00044 #define OCI_STMT_CALL 10
00045 #endif
00046 
00047 /* {{{ proto bool oci_define_by_name(resource stmt, string name, mixed &var [, int type])
00048    Define a PHP variable to an Oracle column by name */
00049 /* if you want to define a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE defining!!! */
00050 PHP_FUNCTION(oci_define_by_name)
00051 {
00052        zval *stmt, *var;
00053        char *name;
00054        int name_len;
00055        long type = 0;
00056        php_oci_statement *statement;
00057        php_oci_define *define, *tmp_define;
00058 
00059        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/|l", &stmt, &name, &name_len, &var, &type) == FAILURE) {
00060               return;
00061        }
00062 
00063        if (!name_len) {
00064               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Column name cannot be empty");
00065               RETURN_FALSE;
00066        }
00067 
00068        PHP_OCI_ZVAL_TO_STATEMENT(stmt, statement);
00069 
00070        if (statement->defines == NULL) {
00071               ALLOC_HASHTABLE(statement->defines);
00072               zend_hash_init(statement->defines, 13, NULL, php_oci_define_hash_dtor, 0);
00073        }
00074 
00075        define = ecalloc(1,sizeof(php_oci_define));
00076 
00077        if (zend_hash_add(statement->defines, name, name_len, define, sizeof(php_oci_define), (void **)&tmp_define) == SUCCESS) {
00078               efree(define);
00079               define = tmp_define;
00080        } else {
00081               efree(define);
00082               RETURN_FALSE;
00083        }
00084 
00085        define->name = (text*) estrndup(name, name_len);
00086        define->name_len = name_len;
00087        define->type = type;
00088        define->zval = var;
00089        zval_add_ref(&var);
00090 
00091        RETURN_TRUE;
00092 }
00093 /* }}} */
00094 
00095 /* {{{ proto bool oci_bind_by_name(resource stmt, string name, mixed &var, [, int maxlength [, int type]])
00096    Bind a PHP variable to an Oracle placeholder by name */
00097 /* if you want to bind a LOB/CLOB etc make sure you allocate it via OCINewDescriptor BEFORE binding!!! */
00098 PHP_FUNCTION(oci_bind_by_name)
00099 {
00100        ub2    bind_type = SQLT_CHR; /* unterminated string */
00101        int name_len;
00102        long maxlen = -1, type = 0;
00103        char *name;
00104        zval *z_statement;
00105        zval *bind_var = NULL;
00106        php_oci_statement *statement;
00107        
00108        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz/|ll", &z_statement, &name, &name_len, &bind_var, &maxlen, &type) == FAILURE) {
00109               return;
00110        }
00111 
00112        if (type) {
00113               bind_type = (ub2) type;
00114        }
00115        
00116        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
00117 
00118        if (php_oci_bind_by_name(statement, name, name_len, bind_var, maxlen, bind_type TSRMLS_CC)) {
00119               RETURN_FALSE;
00120        }
00121        RETURN_TRUE;
00122 }
00123 /* }}} */
00124 
00125 /* {{{ proto bool oci_bind_array_by_name(resource stmt, string name, array &var, int max_table_length [, int max_item_length [, int type ]])
00126    Bind a PHP array to an Oracle PL/SQL type by name */
00127 PHP_FUNCTION(oci_bind_array_by_name)
00128 {
00129        int name_len;
00130        long max_item_len = -1;
00131        long max_array_len = 0;
00132        long type = SQLT_AFC;
00133        char *name;
00134        zval *z_statement;
00135        zval *bind_var = NULL;
00136        php_oci_statement *statement;
00137        
00138        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) {
00139               return;
00140        }
00141 
00142        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
00143 
00144        if (ZEND_NUM_ARGS() == 5 && max_item_len <= 0) {
00145               max_item_len = -1;
00146        }
00147        
00148        if (max_array_len <= 0) {
00149               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum array length must be greater than zero");
00150               RETURN_FALSE;
00151        }
00152        
00153        if (php_oci_bind_array_by_name(statement, name, name_len, bind_var, max_array_len, max_item_len, type TSRMLS_CC)) {
00154               RETURN_FALSE;
00155        }
00156        RETURN_TRUE;
00157 }
00158 /* }}} */
00159 
00160 /* {{{ proto bool oci_free_descriptor()
00161    Deletes large object description */
00162 PHP_FUNCTION(oci_free_descriptor)
00163 {
00164        zval **tmp, *z_descriptor = getThis();
00165        php_oci_descriptor *descriptor;
00166 
00167        if (!getThis()) {
00168               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00169                      return;
00170               }
00171        }
00172        
00173        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00174               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00175               RETURN_FALSE;
00176        }
00177 
00178        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00179 
00180        zend_list_delete(descriptor->id);
00181        RETURN_TRUE;
00182 }
00183 /* }}} */
00184 
00185 /* {{{ proto bool oci_lob_save( string data [, int offset ])
00186    Saves a large object */
00187 PHP_FUNCTION(oci_lob_save)
00188 {
00189        zval **tmp, *z_descriptor = getThis();
00190        php_oci_descriptor *descriptor;
00191        char *data;
00192        int data_len;
00193        long offset = 0;
00194        ub4 bytes_written;
00195 
00196        if (getThis()) {
00197               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &offset) == FAILURE) {
00198                      return;
00199               }
00200        }
00201        else {
00202               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &offset) == FAILURE) {
00203                      return;
00204               }
00205        }
00206        
00207        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00208               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00209               RETURN_FALSE;
00210        }
00211 
00212        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00213 
00214        if (offset < 0) {
00215               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset parameter must be greater than or equal to 0");
00216               RETURN_FALSE;
00217        }
00218        
00219        if (php_oci_lob_write(descriptor, offset, data, data_len, &bytes_written TSRMLS_CC)) {
00220               RETURN_FALSE;
00221        }
00222        RETURN_TRUE;
00223 }
00224 /* }}} */
00225 
00226 /* {{{ proto bool oci_lob_import( string filename )
00227    Loads file into a LOB */
00228 PHP_FUNCTION(oci_lob_import)
00229 {
00230        zval **tmp, *z_descriptor = getThis();
00231        php_oci_descriptor *descriptor;
00232        char *filename;
00233        int filename_len;
00234 
00235        if (getThis()) {
00236 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
00237               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
00238 #else
00239               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
00240 #endif
00241                      return;
00242               }
00243        }
00244        else {
00245 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
00246               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Op", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) {
00247 #else
00248               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) {
00249 #endif
00250                      return;
00251               }      
00252        }
00253 
00254 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || (PHP_MAJOR_VERSION < 5)
00255        /* The "p" parsing parameter handles this case in PHP 5.4+ */
00256        if (strlen(filename) != filename_len) {
00257               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename cannot contain null bytes");
00258               RETURN_FALSE;  
00259        }
00260 #endif
00261 
00262        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00263               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00264               RETURN_FALSE;
00265        }
00266 
00267        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00268 
00269        if (php_oci_lob_import(descriptor, filename TSRMLS_CC)) {
00270               RETURN_FALSE;
00271        }
00272        RETURN_TRUE;
00273 }
00274 /* }}} */
00275 
00276 /* {{{ proto string oci_lob_load()
00277    Loads a large object */
00278 PHP_FUNCTION(oci_lob_load)
00279 {
00280        zval **tmp, *z_descriptor = getThis();
00281        php_oci_descriptor *descriptor;
00282        char *buffer = NULL;
00283        ub4 buffer_len;
00284 
00285        if (!getThis()) {
00286               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00287                      return;
00288               }      
00289        }
00290        
00291        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00292               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00293               RETURN_FALSE;
00294        }
00295        
00296        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00297 
00298        if (php_oci_lob_read(descriptor, -1, 0, &buffer, &buffer_len TSRMLS_CC)) {
00299               RETURN_FALSE;
00300        }
00301        if (buffer_len > 0) {
00302               RETURN_STRINGL(buffer, buffer_len, 0);
00303        }
00304        else {
00305               RETURN_EMPTY_STRING();
00306        }
00307 }
00308 /* }}} */
00309 
00310 /* {{{ proto string oci_lob_read( int length )
00311    Reads particular part of a large object */
00312 PHP_FUNCTION(oci_lob_read)
00313 {
00314        zval **tmp, *z_descriptor = getThis();
00315        php_oci_descriptor *descriptor;
00316        long length;
00317        char *buffer;
00318        ub4 buffer_len;
00319 
00320        if (getThis()) {
00321               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
00322                      return;
00323               }
00324        }
00325        else {
00326               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_descriptor, oci_lob_class_entry_ptr, &length) == FAILURE) {
00327                      return;
00328               }      
00329        }
00330 
00331        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00332               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00333               RETURN_FALSE;
00334        }
00335        
00336        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00337 
00338        if (length <= 0) {
00339               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
00340               RETURN_FALSE;
00341        }
00342        
00343        if (php_oci_lob_read(descriptor, length, descriptor->lob_current_position, &buffer, &buffer_len TSRMLS_CC)) {
00344               RETURN_FALSE;
00345        }      
00346        if (buffer_len > 0) {
00347               RETURN_STRINGL(buffer, buffer_len, 0);
00348        }
00349        else {
00350               RETURN_EMPTY_STRING();
00351        }
00352 }
00353 /* }}} */
00354 
00355 /* {{{ proto bool oci_lob_eof()
00356    Checks if EOF is reached */
00357 PHP_FUNCTION(oci_lob_eof)
00358 {
00359        zval **tmp, *z_descriptor = getThis();
00360        php_oci_descriptor *descriptor;
00361        ub4 lob_length;
00362        
00363        if (!getThis()) {
00364               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00365                      return;
00366               }      
00367        }
00368        
00369        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00370               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00371               RETURN_FALSE;
00372        }
00373        
00374        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00375        
00376        if (!php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC) && lob_length >= 0) {
00377               if (lob_length == descriptor->lob_current_position) {
00378                      RETURN_TRUE;
00379               }
00380        }
00381        RETURN_FALSE;
00382 }
00383 /* }}} */
00384 
00385 /* {{{ proto int oci_lob_tell()
00386    Tells LOB pointer position */
00387 PHP_FUNCTION(oci_lob_tell)
00388 {
00389        zval **tmp, *z_descriptor = getThis();
00390        php_oci_descriptor *descriptor;
00391        
00392        if (!getThis()) {
00393               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00394                      return;
00395               }      
00396        }
00397        
00398        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00399               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00400               RETURN_FALSE;
00401        }
00402        
00403        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00404        
00405        RETURN_LONG(descriptor->lob_current_position);   
00406 }
00407 /* }}} */
00408 
00409 /* {{{ proto bool oci_lob_rewind()
00410    Rewind pointer of a LOB */
00411 PHP_FUNCTION(oci_lob_rewind)
00412 {
00413        zval **tmp, *z_descriptor = getThis();
00414        php_oci_descriptor *descriptor;
00415        
00416        if (!getThis()) {
00417               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00418                      return;
00419               }      
00420        }
00421        
00422        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00423               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00424               RETURN_FALSE;
00425        }
00426        
00427        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00428        
00429        descriptor->lob_current_position = 0;
00430 
00431        RETURN_TRUE;
00432 }
00433 /* }}} */
00434 
00435 /* {{{ proto bool oci_lob_seek( int offset [, int whence ])
00436    Moves the pointer of a LOB */
00437 PHP_FUNCTION(oci_lob_seek)
00438 {
00439        zval **tmp, *z_descriptor = getThis();
00440        php_oci_descriptor *descriptor;
00441        long offset, whence = PHP_OCI_SEEK_SET;
00442        ub4 lob_length;
00443        
00444        if (getThis()) {
00445               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &offset, &whence) == FAILURE) {
00446                      return;
00447               }
00448        }
00449        else {
00450               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|l", &z_descriptor, oci_lob_class_entry_ptr, &offset, &whence) == FAILURE) {
00451                      return;
00452               }      
00453        }
00454        
00455        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00456               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00457               RETURN_FALSE;
00458        }
00459        
00460        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00461 
00462        if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
00463               RETURN_FALSE;
00464        }
00465 
00466        switch(whence) {
00467               case PHP_OCI_SEEK_CUR:
00468                      descriptor->lob_current_position += offset;
00469                      break;
00470               case PHP_OCI_SEEK_END:
00471                      if ((descriptor->lob_size + offset) >= 0) {
00472                             descriptor->lob_current_position = descriptor->lob_size + offset;
00473                      }
00474                      else {
00475                             descriptor->lob_current_position = 0;
00476                      }
00477                      break;
00478               case PHP_OCI_SEEK_SET:
00479               default:
00480                             descriptor->lob_current_position = (offset > 0) ? offset : 0;
00481                      break;
00482        }      
00483        RETURN_TRUE;
00484 }
00485 /* }}} */
00486 
00487 /* {{{ proto int oci_lob_size()
00488    Returns size of a large object */
00489 PHP_FUNCTION(oci_lob_size)
00490 {
00491        zval **tmp, *z_descriptor = getThis();
00492        php_oci_descriptor *descriptor;
00493        ub4 lob_length;
00494        
00495        if (!getThis()) {
00496               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00497                      return;
00498               }      
00499        }
00500        
00501        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00502               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00503               RETURN_FALSE;
00504        }
00505        
00506        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00507        
00508        if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
00509               RETURN_FALSE;
00510        }
00511        RETURN_LONG(lob_length);
00512 }
00513 /* }}} */
00514 
00515 /* {{{ proto int oci_lob_write( string string [, int length ])
00516    Writes data to current position of a LOB */
00517 PHP_FUNCTION(oci_lob_write)
00518 {
00519        zval **tmp, *z_descriptor = getThis();
00520        php_oci_descriptor *descriptor;
00521        int data_len;
00522        long write_len = 0;
00523        ub4 bytes_written;
00524        char *data;
00525        
00526        if (getThis()) {
00527               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &write_len) == FAILURE) {
00528                      return;
00529               }
00530               
00531               if (ZEND_NUM_ARGS() == 2) {
00532                      data_len = MIN(data_len, write_len);
00533               }
00534        }
00535        else {
00536               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &write_len) == FAILURE) {
00537                      return;
00538               }
00539 
00540               if (ZEND_NUM_ARGS() == 3) {
00541                      data_len = MIN(data_len, write_len);
00542               }
00543        }
00544        
00545        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00546               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00547               RETURN_FALSE;
00548        }
00549        
00550        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00551        
00552        if (data_len <= 0) {
00553               RETURN_LONG(0);
00554        }
00555        
00556        if (php_oci_lob_write(descriptor, descriptor->lob_current_position, data, data_len, &bytes_written TSRMLS_CC)) {
00557               RETURN_FALSE;
00558        }
00559        RETURN_LONG(bytes_written);
00560 }
00561 /* }}} */
00562 
00563 /* {{{ proto bool oci_lob_append( object lob )
00564    Appends data from a LOB to another LOB */
00565 PHP_FUNCTION(oci_lob_append)
00566 {
00567        zval **tmp_dest, **tmp_from, *z_descriptor_dest = getThis(), *z_descriptor_from;
00568        php_oci_descriptor *descriptor_dest, *descriptor_from;
00569        
00570        if (getThis()) {
00571               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor_from, oci_lob_class_entry_ptr) == FAILURE) {
00572                      return;
00573               }
00574        }
00575        else {
00576               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) {
00577                      return;
00578               }      
00579        }
00580        
00581        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor"), (void **)&tmp_dest) == FAILURE) {
00582               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
00583               RETURN_FALSE;
00584        }
00585        
00586        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor"), (void **)&tmp_from) == FAILURE) {
00587               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
00588               RETURN_FALSE;
00589        }
00590        
00591        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_dest, descriptor_dest);
00592        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_from, descriptor_from);
00593        
00594        if (php_oci_lob_append(descriptor_dest, descriptor_from TSRMLS_CC)) {
00595               RETURN_FALSE;
00596        }
00597        /* XXX should we increase lob_size here ? */
00598        RETURN_TRUE;
00599 }
00600 /* }}} */
00601 
00602 /* {{{ proto bool oci_lob_truncate( [ int length ])
00603    Truncates a LOB */
00604 PHP_FUNCTION(oci_lob_truncate)
00605 {
00606        zval **tmp, *z_descriptor = getThis();
00607        php_oci_descriptor *descriptor;
00608        long trim_length = 0;
00609        ub4 ub_trim_length;
00610        
00611        if (getThis()) {
00612               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &trim_length) == FAILURE) {
00613                      return;
00614               }
00615        }
00616        else {
00617               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &z_descriptor, oci_lob_class_entry_ptr, &trim_length) == FAILURE) {
00618                      return;
00619               }      
00620        }
00621        
00622        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00623               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00624               RETURN_FALSE;
00625        }
00626 
00627        if (trim_length < 0) {
00628               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to zero");
00629               RETURN_FALSE;
00630        }
00631 
00632        ub_trim_length = (ub4) trim_length;
00633        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00634        
00635        if (php_oci_lob_truncate(descriptor, ub_trim_length TSRMLS_CC)) {
00636               RETURN_FALSE;
00637        }
00638        RETURN_TRUE;
00639 }
00640 /* }}} */
00641 
00642 /* {{{ proto int oci_lob_erase( [ int offset [, int length ] ] )
00643    Erases a specified portion of the internal LOB, starting at a specified offset */
00644 PHP_FUNCTION(oci_lob_erase)
00645 {
00646        zval **tmp, *z_descriptor = getThis();
00647        php_oci_descriptor *descriptor;
00648        ub4 bytes_erased;
00649        long offset = -1, length = -1;
00650        
00651        if (getThis()) {
00652               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &offset, &length) == FAILURE) {
00653                      return;
00654               }
00655 
00656               if (ZEND_NUM_ARGS() > 0 && offset < 0) {
00657                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be greater than or equal to 0");
00658                      RETURN_FALSE;
00659               }
00660 
00661               if (ZEND_NUM_ARGS() > 1 && length < 0) {
00662                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to 0");
00663                      RETURN_FALSE;
00664               }
00665        }
00666        else {
00667               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &z_descriptor, oci_lob_class_entry_ptr, &offset, &length) == FAILURE) {
00668                      return;
00669               }
00670 
00671               if (ZEND_NUM_ARGS() > 1 && offset < 0) {
00672                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be greater than or equal to 0");
00673                      RETURN_FALSE;
00674               }
00675               
00676               if (ZEND_NUM_ARGS() > 2 && length < 0) {
00677                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to 0");
00678                      RETURN_FALSE;
00679               }
00680        }
00681 
00682        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00683               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00684               RETURN_FALSE;
00685        }
00686 
00687        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00688 
00689        if (php_oci_lob_erase(descriptor, offset, length, &bytes_erased TSRMLS_CC)) {
00690               RETURN_FALSE;
00691        }
00692        RETURN_LONG(bytes_erased);
00693 }
00694 /* }}} */
00695 
00696 /* {{{ proto bool oci_lob_flush( [ int flag ] )
00697    Flushes the LOB buffer */
00698 PHP_FUNCTION(oci_lob_flush)
00699 {
00700        zval **tmp, *z_descriptor = getThis();
00701        php_oci_descriptor *descriptor;
00702        long flush_flag = 0;
00703        
00704        if (getThis()) {
00705               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flush_flag) == FAILURE) {
00706                      return;
00707               }
00708        }
00709        else {
00710               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &z_descriptor, oci_lob_class_entry_ptr, &flush_flag) == FAILURE) {
00711                      return;
00712               }
00713        }
00714        
00715        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00716               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00717               RETURN_FALSE;
00718        }
00719        
00720        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00721        
00722        if (descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
00723               /* buffering wasn't enabled, there is nothing to flush */
00724               RETURN_FALSE;
00725        }
00726 
00727        if (php_oci_lob_flush(descriptor, flush_flag TSRMLS_CC)) {
00728               RETURN_FALSE;
00729        }
00730        RETURN_TRUE;
00731 }
00732 /* }}} */
00733 
00734 /* {{{ proto bool ocisetbufferinglob( boolean flag )
00735    Enables/disables buffering for a LOB */
00736 PHP_FUNCTION(ocisetbufferinglob)
00737 {
00738        zval **tmp, *z_descriptor = getThis();
00739        php_oci_descriptor *descriptor;
00740        zend_bool flag;
00741        
00742        if (getThis()) {
00743               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &flag) == FAILURE) {
00744                      return;
00745               }
00746        }
00747        else {
00748               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ob", &z_descriptor, oci_lob_class_entry_ptr, &flag) == FAILURE) {
00749                      return;
00750               }      
00751        }
00752        
00753        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00754               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00755               RETURN_FALSE;
00756        }
00757        
00758        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00759        
00760        if (php_oci_lob_set_buffering(descriptor, flag TSRMLS_CC)) {
00761               RETURN_FALSE;
00762        }
00763        RETURN_TRUE;
00764 }
00765 /* }}} */
00766 
00767 /* {{{ proto bool ocigetbufferinglob()
00768    Returns current state of buffering for a LOB */
00769 PHP_FUNCTION(ocigetbufferinglob)
00770 {
00771        zval **tmp, *z_descriptor = getThis();
00772        php_oci_descriptor *descriptor;
00773        
00774        if (!getThis()) {
00775               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
00776                      return;
00777               }      
00778        }
00779 
00780        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00781               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00782               RETURN_FALSE;
00783        }
00784        
00785        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00786        
00787        if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
00788               RETURN_TRUE;
00789        }
00790        RETURN_FALSE;
00791 }
00792 /* }}} */
00793 
00794 /* {{{ proto bool oci_lob_copy( object lob_to, object lob_from [, int length ] )
00795    Copies data from a LOB to another LOB */
00796 PHP_FUNCTION(oci_lob_copy)
00797 {
00798        zval **tmp_dest, **tmp_from, *z_descriptor_dest, *z_descriptor_from;
00799        php_oci_descriptor *descriptor_dest, *descriptor_from;
00800        long length = 0;
00801        
00802        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) {
00803               return;
00804        }
00805        
00806        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor"), (void **)&tmp_dest) == FAILURE) {
00807               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
00808               RETURN_FALSE;
00809        }
00810        
00811        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_from), "descriptor", sizeof("descriptor"), (void **)&tmp_from) == FAILURE) {
00812               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
00813               RETURN_FALSE;
00814        }
00815        
00816        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_dest, descriptor_dest);
00817        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_from, descriptor_from);
00818        
00819        if (ZEND_NUM_ARGS() == 3 && length < 0) {
00820               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
00821               RETURN_FALSE;
00822        }
00823        
00824        if (ZEND_NUM_ARGS() == 2) {
00825               /* indicate that we want to copy from the current position to the end of the LOB */
00826               length = -1;
00827        }
00828 
00829        if (php_oci_lob_copy(descriptor_dest, descriptor_from, length TSRMLS_CC)) {
00830               RETURN_FALSE;
00831        }
00832        RETURN_TRUE;
00833 }
00834 /* }}} */
00835 
00836 /* {{{ proto bool oci_lob_is_equal( object lob1, object lob2 )
00837    Tests to see if two LOB/FILE locators are equal */
00838 PHP_FUNCTION(oci_lob_is_equal)
00839 {
00840        zval **tmp_first, **tmp_second, *z_descriptor_first, *z_descriptor_second;
00841        php_oci_descriptor *descriptor_first, *descriptor_second;
00842        boolean is_equal;
00843               
00844        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) {
00845               return;
00846        }
00847        
00848        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_first), "descriptor", sizeof("descriptor"), (void **)&tmp_first) == FAILURE) {
00849               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object");
00850               RETURN_FALSE;
00851        }
00852        
00853        if (zend_hash_find(Z_OBJPROP_P(z_descriptor_second), "descriptor", sizeof("descriptor"), (void **)&tmp_second) == FAILURE) {
00854               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property. The second argument should be valid descriptor object");
00855               RETURN_FALSE;
00856        }
00857        
00858        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_first, descriptor_first);
00859        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp_second, descriptor_second);
00860 
00861        if (php_oci_lob_is_equal(descriptor_first, descriptor_second, &is_equal TSRMLS_CC)) {
00862               RETURN_FALSE;
00863        }
00864        
00865        if (is_equal == TRUE) {
00866               RETURN_TRUE;
00867        }
00868        RETURN_FALSE;
00869 }
00870 /* }}} */
00871 
00872 /* {{{ proto bool oci_lob_export([string filename [, int start [, int length]]])
00873    Writes a large object into a file */
00874 PHP_FUNCTION(oci_lob_export)
00875 {      
00876        zval **tmp, *z_descriptor = getThis();
00877        php_oci_descriptor *descriptor;
00878        char *filename;
00879        char *buffer;
00880        int filename_len;
00881        long start = -1, length = -1, block_length;
00882        php_stream *stream;
00883        ub4 lob_length;
00884 
00885        if (getThis()) {
00886 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
00887               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &start, &length) == FAILURE) {
00888 #else
00889               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &start, &length) == FAILURE) {
00890 #endif
00891                      return;
00892               }
00893        
00894               if (ZEND_NUM_ARGS() > 1 && start < 0) {
00895                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start parameter must be greater than or equal to 0");
00896                      RETURN_FALSE;
00897               }
00898               if (ZEND_NUM_ARGS() > 2 && length < 0) {
00899                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than or equal to 0");
00900                      RETURN_FALSE;
00901               }
00902        }
00903        else {
00904 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
00905               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Op|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) {
00906 #else
00907               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) {
00908 #endif
00909                      return;
00910               }
00911                      
00912               if (ZEND_NUM_ARGS() > 2 && start < 0) {
00913                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start parameter must be greater than or equal to 0");
00914                      RETURN_FALSE;
00915               }
00916               if (ZEND_NUM_ARGS() > 3 && length < 0) {
00917                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than or equal to 0");
00918                      RETURN_FALSE;
00919               }
00920        }
00921 
00922 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || (PHP_MAJOR_VERSION < 5)
00923        /* The "p" parsing parameter handles this case in PHP 5.4+ */
00924        if (strlen(filename) != filename_len) {
00925               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename cannot contain null bytes");
00926               RETURN_FALSE;  
00927        }
00928 #endif
00929 
00930        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
00931               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
00932               RETURN_FALSE;
00933        }
00934        
00935        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
00936        
00937        if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
00938               RETURN_FALSE;
00939        }             
00940        
00941        if (start == -1) {
00942               start = 0;
00943        }
00944 
00945        if (length == -1) {
00946               length = lob_length - descriptor->lob_current_position;
00947        }
00948        
00949        if (length == 0) {
00950               /* nothing to write, fail silently */
00951               RETURN_FALSE;
00952        }
00953 
00954 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || (PHP_MAJOR_VERSION < 5)
00955        /* Safe mode has been removed in PHP 5.4 */
00956        if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
00957               RETURN_FALSE;
00958        }
00959 #endif
00960 
00961        if (php_check_open_basedir(filename TSRMLS_CC)) {
00962               RETURN_FALSE;
00963        }
00964 
00965 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
00966        stream = php_stream_open_wrapper_ex(filename, "w", REPORT_ERRORS, NULL, NULL);
00967 #else
00968        stream = php_stream_open_wrapper_ex(filename, "w", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL);
00969 #endif
00970 
00971        block_length = PHP_OCI_LOB_BUFFER_SIZE;
00972        if (block_length > length) {
00973               block_length = length;
00974        }
00975 
00976        while(length > 0) {
00977               ub4 tmp_bytes_read = 0;
00978               if (php_oci_lob_read(descriptor, block_length, start, &buffer, &tmp_bytes_read TSRMLS_CC)) {
00979                      php_stream_close(stream);
00980                      RETURN_FALSE;
00981               }
00982               if (tmp_bytes_read && !php_stream_write(stream, buffer, tmp_bytes_read)) {
00983                      php_stream_close(stream);
00984                      efree(buffer);
00985                      RETURN_FALSE;
00986               }
00987               if (buffer) {
00988                      efree(buffer);
00989               }
00990               
00991               length -= tmp_bytes_read;
00992               descriptor->lob_current_position += tmp_bytes_read;
00993               start += tmp_bytes_read;
00994 
00995               if (block_length > length) {
00996                      block_length = length;
00997               }
00998        }
00999 
01000        php_stream_close(stream);
01001        RETURN_TRUE;
01002 }
01003 /* }}} */
01004 
01005 /* {{{ proto bool oci_lob_write_temporary(string var [, int lob_type])
01006    Writes temporary blob */
01007 PHP_FUNCTION(oci_lob_write_temporary)
01008 {
01009        zval **tmp, *z_descriptor = getThis();
01010        php_oci_descriptor *descriptor;
01011        char *data;
01012        int data_len;
01013        long type = OCI_TEMP_CLOB;
01014 
01015        if (getThis()) {
01016               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &type) == FAILURE) {
01017                      return;
01018               }
01019        }
01020        else {
01021               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &type) == FAILURE) {
01022                      return;
01023               }      
01024        }
01025        
01026        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
01027               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
01028               RETURN_FALSE;
01029        }
01030        
01031        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
01032 
01033        if (php_oci_lob_write_tmp(descriptor, type, data, data_len TSRMLS_CC)) {
01034               RETURN_FALSE;
01035        }
01036        RETURN_TRUE;
01037 }
01038 /* }}} */
01039 
01040 /* {{{ proto bool oci_lob_close()
01041    Closes lob descriptor */
01042 PHP_FUNCTION(oci_lob_close)
01043 {
01044        zval **tmp, *z_descriptor = getThis();
01045        php_oci_descriptor *descriptor;
01046        
01047        if (!getThis()) {
01048               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_descriptor, oci_lob_class_entry_ptr) == FAILURE) {
01049                      return;
01050               }      
01051        }
01052        
01053        if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
01054               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
01055               RETURN_FALSE;
01056        }
01057        
01058        PHP_OCI_ZVAL_TO_DESCRIPTOR(*tmp, descriptor);
01059 
01060        if (php_oci_lob_close(descriptor TSRMLS_CC)) {
01061               RETURN_FALSE;
01062        }
01063        RETURN_TRUE;
01064 }
01065 /* }}} */
01066 
01067 /* {{{ proto object oci_new_descriptor(resource connection [, int type])
01068    Initialize a new empty descriptor LOB/FILE (LOB is default) */
01069 PHP_FUNCTION(oci_new_descriptor)
01070 {
01071        zval *z_connection;
01072        php_oci_connection *connection;
01073        php_oci_descriptor *descriptor;
01074        long type = OCI_DTYPE_LOB;
01075 
01076        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_connection, &type) == FAILURE) {
01077               return;
01078        }
01079 
01080        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01081 
01082        /* php_oci_lob_create() checks type */
01083        descriptor = php_oci_lob_create(connection, type TSRMLS_CC);   
01084        
01085        if (!descriptor) {
01086               RETURN_NULL();
01087        }
01088 
01089        object_init_ex(return_value, oci_lob_class_entry_ptr);
01090        add_property_resource(return_value, "descriptor", descriptor->id);
01091 }
01092 /* }}} */
01093 
01094 /* {{{ proto bool oci_rollback(resource connection)
01095    Rollback the current context */
01096 PHP_FUNCTION(oci_rollback)
01097 {
01098        zval *z_connection;
01099        php_oci_connection *connection;
01100 
01101        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
01102               return;
01103        }
01104 
01105        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01106 
01107        if (connection->descriptors) {
01108               php_oci_connection_descriptors_free(connection TSRMLS_CC);
01109        }
01110 
01111        if (php_oci_connection_rollback(connection TSRMLS_CC)) {
01112               RETURN_FALSE;
01113        }
01114        RETURN_TRUE;
01115 }
01116 /* }}} */
01117 
01118 /* {{{ proto bool oci_commit(resource connection)
01119    Commit the current context */
01120 PHP_FUNCTION(oci_commit)
01121 {
01122        zval *z_connection;
01123        php_oci_connection *connection;
01124 
01125        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
01126               return;
01127        }
01128 
01129        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01130 
01131        if (connection->descriptors) {
01132               php_oci_connection_descriptors_free(connection TSRMLS_CC);
01133        }
01134        
01135        if (php_oci_connection_commit(connection TSRMLS_CC)) {
01136               RETURN_FALSE;
01137        }
01138        RETURN_TRUE;
01139 }
01140 /* }}} */
01141 
01142 /* {{{ proto string oci_field_name(resource stmt, int col)
01143    Tell the name of a column */
01144 PHP_FUNCTION(oci_field_name)
01145 {
01146        php_oci_out_column *column;
01147 
01148        if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
01149               RETURN_STRINGL(column->name, column->name_len, 1);
01150        }
01151        RETURN_FALSE;
01152 }
01153 /* }}} */
01154 
01155 /* {{{ proto int oci_field_size(resource stmt, int col)
01156    Tell the maximum data size of a column */
01157 PHP_FUNCTION(oci_field_size)
01158 {
01159        php_oci_out_column *column;
01160 
01161        if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
01162               /* Handle data type of LONG */
01163               if (column->data_type == SQLT_LNG){
01164                      RETURN_LONG(column->storage_size4);
01165               }
01166               RETURN_LONG(column->data_size);
01167        }
01168        RETURN_FALSE;
01169 }
01170 /* }}} */
01171 
01172 /* {{{ proto int oci_field_scale(resource stmt, int col)
01173    Tell the scale of a column */
01174 PHP_FUNCTION(oci_field_scale)
01175 {
01176        php_oci_out_column *column;
01177 
01178        if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
01179               RETURN_LONG(column->scale);
01180        }
01181        RETURN_FALSE;
01182 }
01183 /* }}} */
01184 
01185 /* {{{ proto int oci_field_precision(resource stmt, int col)
01186    Tell the precision of a column */
01187 PHP_FUNCTION(oci_field_precision)
01188 {
01189        php_oci_out_column *column;
01190 
01191        if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
01192               RETURN_LONG(column->precision);
01193        }
01194        RETURN_FALSE;
01195 }
01196 /* }}} */
01197 
01198 /* {{{ proto mixed oci_field_type(resource stmt, int col)
01199    Tell the data type of a column */
01200 PHP_FUNCTION(oci_field_type)
01201 {
01202        php_oci_out_column *column;
01203 
01204        column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
01205 
01206        if (!column) {
01207               RETURN_FALSE;
01208        }
01209        
01210        switch (column->data_type) {
01211 #ifdef SQLT_TIMESTAMP
01212               case SQLT_TIMESTAMP:
01213                      RETVAL_STRING("TIMESTAMP",1);
01214                      break;
01215 #endif
01216 #ifdef SQLT_TIMESTAMP_TZ
01217               case SQLT_TIMESTAMP_TZ:
01218                      RETVAL_STRING("TIMESTAMP WITH TIMEZONE",1);
01219                      break;
01220 #endif
01221 #ifdef SQLT_TIMESTAMP_LTZ
01222               case SQLT_TIMESTAMP_LTZ:
01223                      RETVAL_STRING("TIMESTAMP WITH LOCAL TIMEZONE",1);
01224                      break;
01225 #endif
01226 #ifdef SQLT_INTERVAL_YM
01227               case SQLT_INTERVAL_YM:
01228                      RETVAL_STRING("INTERVAL YEAR TO MONTH",1);
01229                      break;
01230 #endif
01231 #ifdef SQLT_INTERVAL_DS
01232               case SQLT_INTERVAL_DS:
01233                      RETVAL_STRING("INTERVAL DAY TO SECOND",1);
01234                      break;
01235 #endif
01236               case SQLT_DAT:
01237                      RETVAL_STRING("DATE",1);
01238                      break;
01239               case SQLT_NUM:
01240                      RETVAL_STRING("NUMBER",1);
01241                      break;
01242               case SQLT_LNG:
01243                      RETVAL_STRING("LONG",1);
01244                      break;
01245               case SQLT_BIN:
01246                      RETVAL_STRING("RAW",1);
01247                      break;
01248               case SQLT_LBI:
01249                      RETVAL_STRING("LONG RAW",1);
01250                      break;
01251               case SQLT_CHR:
01252                      RETVAL_STRING("VARCHAR2",1);
01253                      break;
01254               case SQLT_RSET:
01255                      RETVAL_STRING("REFCURSOR",1);
01256                      break;
01257               case SQLT_AFC:
01258                      RETVAL_STRING("CHAR",1);
01259                      break;
01260               case SQLT_BLOB:
01261                      RETVAL_STRING("BLOB",1);
01262                      break;
01263               case SQLT_CLOB:
01264                      RETVAL_STRING("CLOB",1);
01265                      break;
01266               case SQLT_BFILE:
01267                      RETVAL_STRING("BFILE",1);
01268                      break;
01269               case SQLT_RDD:
01270                      RETVAL_STRING("ROWID",1);
01271                      break;
01272               default:
01273                      RETVAL_LONG(column->data_type);
01274        }
01275 }
01276 /* }}} */
01277 
01278 /* {{{ proto int oci_field_type_raw(resource stmt, int col)
01279    Tell the raw oracle data type of a column */
01280 PHP_FUNCTION(oci_field_type_raw)
01281 {
01282        php_oci_out_column *column;
01283 
01284        column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
01285        if (column) {
01286               RETURN_LONG(column->data_type);
01287        }
01288        RETURN_FALSE;
01289 }
01290 /* }}} */
01291 
01292 /* {{{ proto bool oci_field_is_null(resource stmt, int col)
01293    Tell whether a column is NULL */
01294 PHP_FUNCTION(oci_field_is_null)
01295 {
01296        php_oci_out_column *column;
01297 
01298        if ( ( column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0) ) ) {
01299               if (column->indicator == -1) {
01300                      RETURN_TRUE;
01301               }
01302        }
01303        RETURN_FALSE;
01304 }
01305 /* }}} */
01306 
01307 /* {{{ proto void oci_internal_debug(int onoff)
01308    Toggle internal debugging output for the OCI extension */
01309 PHP_FUNCTION(oci_internal_debug)
01310 {
01311        zend_bool on_off;
01312 
01313        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &on_off) == FAILURE) {
01314               return;
01315        }
01316        OCI_G(debug_mode) = on_off;
01317 }
01318 /* }}} */
01319 
01320 /* {{{ proto bool oci_execute(resource stmt [, int mode])
01321    Execute a parsed statement */
01322 PHP_FUNCTION(oci_execute)
01323 {
01324        zval *z_statement;
01325        php_oci_statement *statement;
01326        long mode = OCI_COMMIT_ON_SUCCESS;
01327 
01328        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &z_statement, &mode) == FAILURE) {
01329               return;
01330        }
01331 
01332        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01333 
01334        if (php_oci_statement_execute(statement, mode TSRMLS_CC)) {
01335               RETURN_FALSE;
01336        }
01337        RETURN_TRUE;
01338 }
01339 /* }}} */
01340 
01341 /* {{{ proto bool oci_cancel(resource stmt)
01342    Cancel reading from a cursor */
01343 PHP_FUNCTION(oci_cancel)
01344 {
01345        zval *z_statement;
01346        php_oci_statement *statement;
01347 
01348        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
01349               return;
01350        }
01351 
01352        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01353 
01354        if (php_oci_statement_cancel(statement TSRMLS_CC)) {
01355               RETURN_FALSE;
01356        }
01357        RETURN_TRUE;
01358 }
01359 /* }}} */
01360 
01361 /* {{{ proto bool oci_fetch(resource stmt)
01362    Prepare a new row of data for reading */
01363 PHP_FUNCTION(oci_fetch)
01364 {
01365        zval *z_statement;
01366        php_oci_statement *statement;
01367        ub4 nrows = 1; /* only one row at a time is supported for now */
01368 
01369        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
01370               return;
01371        }
01372 
01373        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01374 
01375        if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
01376               RETURN_FALSE;
01377        }
01378        RETURN_TRUE;
01379 }
01380 /* }}} */
01381 
01382 /* {{{ proto int ocifetchinto(resource stmt, array &output [, int mode])
01383    Fetch a row of result data into an array */
01384 PHP_FUNCTION(ocifetchinto)
01385 {
01386        php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM, 3);
01387 }
01388 /* }}} */
01389 
01390 /* {{{ proto int oci_fetch_all(resource stmt, array &output[, int skip[, int maxrows[, int flags]]])
01391    Fetch all rows of result data into an array */
01392 PHP_FUNCTION(oci_fetch_all)
01393 {
01394        zval *z_statement, *array, *element, *tmp;
01395        php_oci_statement *statement;
01396        php_oci_out_column **columns;
01397        zval ***outarrs;
01398        ub4 nrows = 1;
01399        int i;
01400        long rows = 0, flags = 0, skip = 0, maxrows = -1;
01401 
01402        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|lll", &z_statement, &array, &skip, &maxrows, &flags) == FAILURE) {
01403               return;
01404        }
01405 
01406        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01407 
01408        zval_dtor(array);
01409        array_init(array);
01410 
01411        while (skip--) {
01412               if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
01413                      RETURN_LONG(0);
01414               }
01415        }
01416 
01417        if (flags & PHP_OCI_FETCHSTATEMENT_BY_ROW) {
01418               columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
01419 
01420               for (i = 0; i < statement->ncolumns; i++) {
01421                      columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
01422               }
01423 
01424               while (!php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
01425                      zval *row;
01426                      
01427                      MAKE_STD_ZVAL(row);
01428                      array_init(row);
01429 
01430                      for (i = 0; i < statement->ncolumns; i++) {
01431                             MAKE_STD_ZVAL(element);
01432                             php_oci_column_to_zval(columns[ i ], element, PHP_OCI_RETURN_LOBS TSRMLS_CC);
01433 
01434                             if (flags & PHP_OCI_NUM) {
01435                                    zend_hash_next_index_insert(Z_ARRVAL_P(row), &element, sizeof(zval*), NULL);
01436                             } else { /* default to ASSOC */
01437 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
01438                                    /* zend_symtable_update is only available in 5.2+ */
01439                                    zend_symtable_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL);
01440 #else
01441                                    /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */
01442                                    zend_hash_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL);
01443 #endif
01444                             }
01445                      }
01446 
01447                      zend_hash_next_index_insert(Z_ARRVAL_P(array), &row, sizeof(zval*), NULL);
01448                      rows++;
01449 
01450                      if (maxrows != -1 && rows == maxrows) {
01451                             php_oci_statement_cancel(statement TSRMLS_CC);
01452                             break;
01453                      }
01454               }
01455               efree(columns);
01456 
01457        } else { /* default to BY_COLUMN */
01458               columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0);
01459               outarrs = safe_emalloc(statement->ncolumns, sizeof(zval*), 0);
01460               
01461               if (flags & PHP_OCI_NUM) {
01462                      for (i = 0; i < statement->ncolumns; i++) {
01463                             columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
01464                             
01465                             MAKE_STD_ZVAL(tmp);
01466                             array_init(tmp);
01467                             zend_hash_next_index_insert(Z_ARRVAL_P(array), &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
01468                      }
01469               } else { /* default to ASSOC */
01470                      for (i = 0; i < statement->ncolumns; i++) {
01471                             columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
01472                             
01473                             MAKE_STD_ZVAL(tmp);
01474                             array_init(tmp);
01475 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
01476                             /* zend_symtable_update is only available in 5.2+ */
01477                             zend_symtable_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
01478 #else
01479                             /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */
01480                             zend_hash_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ]));
01481 #endif
01482                      }
01483               }
01484 
01485               while (!php_oci_statement_fetch(statement, nrows TSRMLS_CC)) {
01486                      for (i = 0; i < statement->ncolumns; i++) {
01487                             MAKE_STD_ZVAL(element);
01488                             php_oci_column_to_zval(columns[ i ], element, PHP_OCI_RETURN_LOBS TSRMLS_CC);
01489                             zend_hash_index_update((*(outarrs[ i ]))->value.ht, rows, (void *)&element, sizeof(zval*), NULL);
01490                      }
01491 
01492                      rows++;
01493 
01494                      if (maxrows != -1 && rows == maxrows) {
01495                             php_oci_statement_cancel(statement TSRMLS_CC);
01496                             break;
01497                      }
01498               }
01499               
01500               efree(columns);
01501               efree(outarrs);
01502        }
01503 
01504        RETURN_LONG(rows);
01505 }
01506 /* }}} */
01507 
01508 /* {{{ proto object oci_fetch_object( resource stmt )
01509    Fetch a result row as an object */
01510 PHP_FUNCTION(oci_fetch_object)
01511 {
01512        php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC | PHP_OCI_RETURN_NULLS, 2);
01513 
01514        if (Z_TYPE_P(return_value) == IS_ARRAY) {
01515               object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
01516        }
01517 }
01518 /* }}} */
01519 
01520 /* {{{ proto array oci_fetch_row( resource stmt )
01521    Fetch a result row as an enumerated array */
01522 PHP_FUNCTION(oci_fetch_row)
01523 {
01524        php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_NUM | PHP_OCI_RETURN_NULLS, 1);
01525 }
01526 /* }}} */
01527 
01528 /* {{{ proto array oci_fetch_assoc( resource stmt )
01529    Fetch a result row as an associative array */
01530 PHP_FUNCTION(oci_fetch_assoc)
01531 {
01532        php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_ASSOC | PHP_OCI_RETURN_NULLS, 1);
01533 }
01534 /* }}} */
01535 
01536 /* {{{ proto array oci_fetch_array( resource stmt [, int mode ])
01537    Fetch a result row as an array */
01538 PHP_FUNCTION(oci_fetch_array)
01539 {
01540        php_oci_fetch_row(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_OCI_BOTH | PHP_OCI_RETURN_NULLS, 2);
01541 }
01542 /* }}} */
01543 
01544 /* {{{ proto bool oci_free_statement(resource stmt)
01545    Free all resources associated with a statement */
01546 PHP_FUNCTION(oci_free_statement)
01547 {
01548        zval *z_statement;
01549        php_oci_statement *statement;
01550 
01551        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
01552               return;
01553        }
01554 
01555        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01556 
01557        zend_list_delete(statement->id);
01558        RETURN_TRUE;
01559 }
01560 /* }}} */
01561 
01562 /* {{{ proto bool oci_close(resource connection)
01563    Disconnect from database */
01564 PHP_FUNCTION(oci_close)
01565 {
01566        /* oci_close for pconnect (if old_oci_close_semantics not set) would
01567         * release the connection back to the client-side session pool (and to the
01568         * server-side pool if Database Resident Connection Pool is being used).
01569         * Subsequent pconnects in the same script are not guaranteed to get the
01570         * same database session.
01571         */
01572 
01573        zval *z_connection;
01574        php_oci_connection *connection;
01575 
01576        if (OCI_G(old_oci_close_semantics)) {
01577               /* do nothing to keep BC */
01578               return;
01579        }
01580        
01581        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
01582               return;
01583        }
01584 
01585        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01586        zend_list_delete(connection->rsrc_id);
01587 
01588        ZVAL_NULL(z_connection);
01589        
01590        RETURN_TRUE;
01591 }
01592 /* }}} */
01593 
01594 /* {{{ proto resource oci_new_connect(string user, string pass [, string db])
01595    Connect to an Oracle database and log on. Returns a new session. */
01596 PHP_FUNCTION(oci_new_connect)
01597 {
01598        php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
01599 }
01600 /* }}} */
01601 
01602 /* {{{ proto resource oci_connect(string user, string pass [, string db [, string charset [, int session_mode ]])
01603    Connect to an Oracle database and log on. Returns a new session. */
01604 PHP_FUNCTION(oci_connect)
01605 {
01606        php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
01607 }
01608 /* }}} */
01609 
01610 /* {{{ proto resource oci_pconnect(string user, string pass [, string db [, string charset ]])
01611    Connect to an Oracle database using a persistent connection and log on. Returns a new session. */
01612 PHP_FUNCTION(oci_pconnect)
01613 {
01614        php_oci_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
01615 }
01616 /* }}} */
01617 
01618 /* {{{ proto array oci_error([resource stmt|connection|global])
01619    Return the last error of stmt|connection|global. If no error happened returns false. */
01620 PHP_FUNCTION(oci_error)
01621 {
01622        zval *arg = NULL;
01623        php_oci_statement *statement;
01624        php_oci_connection *connection;
01625        text *errbuf;
01626        sb4 errcode = 0;
01627        sword error = OCI_SUCCESS;
01628        dvoid *errh = NULL;
01629        ub2 error_offset = 0;
01630        text *sqltext = NULL;
01631 
01632        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
01633               return;
01634        }
01635 
01636        if (ZEND_NUM_ARGS() > 0) {
01637               statement = (php_oci_statement *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_statement);
01638        
01639               if (statement) {
01640                      errh = statement->err;
01641                      error = statement->errcode;
01642 
01643                      if (php_oci_fetch_sqltext_offset(statement, &sqltext, &error_offset TSRMLS_CC)) {
01644                             RETURN_FALSE;
01645                      }
01646                      goto go_out;
01647               }
01648 
01649               connection = (php_oci_connection *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_connection);
01650               if (connection) {
01651                      errh = connection->err;
01652                      error = connection->errcode;
01653                      goto go_out;
01654               }
01655 
01656               connection = (php_oci_connection *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_pconnection);
01657               if (connection) {
01658                      errh = connection->err;
01659                      error = connection->errcode;
01660                      goto go_out;
01661               }
01662        } else {
01663               errh = OCI_G(err);
01664               error = OCI_G(errcode);
01665        }
01666 
01667 go_out:
01668        if (error == OCI_SUCCESS) { /* no error set in the handle */
01669               RETURN_FALSE;
01670        }
01671 
01672        if (!errh) {
01673               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Oci_error: unable to find error handle");
01674               RETURN_FALSE;
01675        }
01676 
01677        errcode = php_oci_fetch_errmsg(errh, &errbuf TSRMLS_CC);
01678 
01679        if (errcode) {
01680               array_init(return_value);
01681               add_assoc_long(return_value, "code", errcode);
01682               add_assoc_string(return_value, "message", (char*) errbuf, 0);
01683               add_assoc_long(return_value, "offset", error_offset);
01684               add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : "", 1);
01685        } else {
01686               RETURN_FALSE;
01687        }
01688 }
01689 /* }}} */
01690 
01691 /* {{{ proto int oci_num_fields(resource stmt)
01692    Return the number of result columns in a statement */
01693 PHP_FUNCTION(oci_num_fields)
01694 {
01695        zval *z_statement;
01696        php_oci_statement *statement;
01697 
01698        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
01699               return;
01700        }
01701 
01702        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01703 
01704        RETURN_LONG(statement->ncolumns);
01705 }
01706 /* }}} */
01707 
01708 /* {{{ proto resource oci_parse(resource connection, string statement)
01709    Parse a SQL or PL/SQL statement and return a statement resource */
01710 PHP_FUNCTION(oci_parse)
01711 {
01712        zval *z_connection;
01713        php_oci_connection *connection;
01714        php_oci_statement *statement;
01715        char *query;
01716        int query_len;
01717 
01718        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &query, &query_len) == FAILURE) {
01719               return;
01720        }
01721 
01722        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01723 
01724        statement = php_oci_statement_create(connection, query, query_len TSRMLS_CC);
01725 
01726        if (statement) {
01727               RETURN_RESOURCE(statement->id);
01728        }
01729        RETURN_FALSE;
01730 }
01731 /* }}} */
01732 
01733 /* {{{ proto bool oci_set_prefetch(resource stmt, int prefetch_rows)
01734   Sets the number of rows to be prefetched on execute to prefetch_rows for stmt */
01735 PHP_FUNCTION(oci_set_prefetch)
01736 {
01737        zval *z_statement;
01738        php_oci_statement *statement;
01739        long size;
01740 
01741        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &z_statement, &size) == FAILURE) {
01742               return;
01743        }
01744 
01745        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
01746 
01747        if (php_oci_statement_set_prefetch(statement, size TSRMLS_CC)) {
01748               RETURN_FALSE;
01749        }
01750        RETURN_TRUE;
01751 }
01752 /* }}} */
01753 
01754 /* {{{ proto bool oci_set_client_identifier(resource connection, string value)
01755   Sets the client identifier attribute on the connection */
01756 PHP_FUNCTION(oci_set_client_identifier)
01757 {
01758        zval *z_connection;
01759        php_oci_connection *connection;
01760        char *client_id;
01761        int client_id_len;
01762 
01763        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &client_id, &client_id_len) == FAILURE) {
01764               return;
01765        }
01766 
01767        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01768 
01769        PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_id, (ub4) client_id_len, (ub4) OCI_ATTR_CLIENT_IDENTIFIER, OCI_G(err)));
01770 
01771        if (OCI_G(errcode) != OCI_SUCCESS) {
01772               php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
01773               RETURN_FALSE;
01774        }
01775 
01776        RETURN_TRUE;
01777 }
01778 /* }}} */
01779 
01780 /* {{{ proto bool oci_set_edition(string value)
01781   Sets the edition attribute for all subsequent connections created */
01782 PHP_FUNCTION(oci_set_edition)
01783 {
01784 #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
01785        char *edition;
01786        int edition_len;
01787 
01788        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &edition, &edition_len) == FAILURE) {
01789               return;
01790        }
01791 
01792        if (OCI_G(edition)) {
01793               efree(OCI_G(edition));
01794               OCI_G(edition) = NULL;
01795        }
01796 
01797        if (edition) {
01798               OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(text), 0);
01799               memcpy(OCI_G(edition), edition, edition_len);
01800               OCI_G(edition)[edition_len] = '\0';
01801        }
01802 
01803        RETURN_TRUE;
01804 #else
01805        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type");
01806        RETURN_FALSE;
01807 #endif
01808 }
01809 /* }}} */
01810 
01811 /* {{{ proto bool oci_set_module_name(resource connection, string value)
01812   Sets the module attribute on the connection */
01813 PHP_FUNCTION(oci_set_module_name)
01814 {
01815 #if (OCI_MAJOR_VERSION >= 10)
01816        zval *z_connection;
01817        php_oci_connection *connection;
01818        char *module;
01819        int module_len;
01820 
01821        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &module, &module_len) == FAILURE) {
01822               return;
01823        }
01824 
01825        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01826 
01827        PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) module, (ub4) module_len, (ub4) OCI_ATTR_MODULE, OCI_G(err)));
01828 
01829        if (OCI_G(errcode) != OCI_SUCCESS) {
01830               php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
01831               RETURN_FALSE;
01832        }
01833 
01834        RETURN_TRUE;
01835 #else
01836        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type");
01837        RETURN_FALSE;
01838 #endif
01839 }
01840 /* }}} */
01841 
01842 /* {{{ proto bool oci_set_action(resource connection, string value)
01843   Sets the action attribute on the connection */
01844 PHP_FUNCTION(oci_set_action)
01845 {
01846 #if (OCI_MAJOR_VERSION >= 10)
01847        zval *z_connection;
01848        php_oci_connection *connection;
01849        char *action;
01850        int action_len;
01851 
01852        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &action, &action_len) == FAILURE) {
01853               return;
01854        }
01855 
01856        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01857 
01858        PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) action, (ub4) action_len, (ub4) OCI_ATTR_ACTION, OCI_G(err)));
01859 
01860        if (OCI_G(errcode) != OCI_SUCCESS) {
01861               php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
01862               RETURN_FALSE;
01863        }
01864 
01865        RETURN_TRUE;
01866 #else
01867        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type");
01868        RETURN_FALSE;
01869 #endif
01870 }
01871 /* }}} */
01872 
01873 /* {{{ proto bool oci_set_client_info(resource connection, string value)
01874   Sets the client info attribute on the connection */
01875 PHP_FUNCTION(oci_set_client_info)
01876 {
01877 #if (OCI_MAJOR_VERSION >= 10)
01878        zval *z_connection;
01879        php_oci_connection *connection;
01880        char *client_info;
01881        int client_info_len;
01882 
01883        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &client_info, &client_info_len) == FAILURE) {
01884               return;
01885        }
01886 
01887        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01888 
01889        PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_info, (ub4) client_info_len, (ub4) OCI_ATTR_CLIENT_INFO, OCI_G(err)));
01890 
01891        if (OCI_G(errcode) != OCI_SUCCESS) {
01892               php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
01893               RETURN_FALSE;
01894        }
01895 
01896        RETURN_TRUE;
01897 #else
01898        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type");
01899        RETURN_FALSE;
01900 #endif
01901 }
01902 /* }}} */
01903 
01904 /* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password)
01905   Changes the password of an account */
01906 PHP_FUNCTION(oci_password_change)
01907 {
01908        zval *z_connection;
01909        char *user, *pass_old, *pass_new, *dbname;
01910        int user_len, pass_old_len, pass_new_len, dbname_len;
01911        php_oci_connection *connection;
01912 
01913 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || (PHP_MAJOR_VERSION < 5)
01914        /* Safe mode has been removed in PHP 5.4 */
01915        if (PG(safe_mode)) {
01916               php_error_docref(NULL TSRMLS_CC, E_WARNING, "is disabled in Safe Mode");
01917               RETURN_FALSE;
01918        }
01919 #endif
01920 
01921        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) {
01922               PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01923 
01924               if (!user_len) {
01925                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "username cannot be empty");
01926                      RETURN_FALSE;
01927               }
01928               if (!pass_old_len) {
01929                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "old password cannot be empty");
01930                      RETURN_FALSE;
01931               }
01932               if (!pass_new_len) {
01933                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "new password cannot be empty");
01934                      RETURN_FALSE;
01935               }
01936 
01937               if (php_oci_password_change(connection, user, user_len, pass_old, pass_old_len, pass_new, pass_new_len TSRMLS_CC)) {
01938                      RETURN_FALSE;
01939               }
01940               RETURN_TRUE;
01941        } 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) {
01942 
01943               if (!user_len) {
01944                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "username cannot be empty");
01945                      RETURN_FALSE;
01946               }
01947               if (!pass_old_len) {
01948                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "old password cannot be empty");
01949                      RETURN_FALSE;
01950               }
01951               if (!pass_new_len) {
01952                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "new password cannot be empty");
01953                      RETURN_FALSE;
01954               }
01955 
01956               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);
01957               if (!connection) {
01958                      RETURN_FALSE;
01959               }
01960               RETURN_RESOURCE(connection->rsrc_id);
01961        }
01962        WRONG_PARAM_COUNT;
01963 }
01964 /* }}} */
01965 
01966 /* {{{ proto resource oci_new_cursor(resource connection)
01967    Return a new cursor (Statement-Handle) - use this to bind ref-cursors! */
01968 PHP_FUNCTION(oci_new_cursor)
01969 {
01970        zval *z_connection;
01971        php_oci_connection *connection;
01972        php_oci_statement *statement;
01973 
01974        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
01975               return;
01976        }
01977 
01978        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
01979 
01980        statement = php_oci_statement_create(connection, NULL, 0 TSRMLS_CC);
01981        
01982        if (statement) {
01983               RETURN_RESOURCE(statement->id);
01984        }
01985        RETURN_FALSE;
01986 }
01987 /* }}} */
01988 
01989 /* {{{ proto string oci_result(resource stmt, mixed column)
01990    Return a single column of result data */
01991 PHP_FUNCTION(oci_result)
01992 {
01993        php_oci_out_column *column;
01994        
01995        column = php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
01996        if(column) {
01997               php_oci_column_to_zval(column, return_value, 0 TSRMLS_CC);
01998        }
01999        else {
02000               RETURN_FALSE;
02001        }
02002 }
02003 /* }}} */
02004 
02005 /* {{{ proto string oci_client_version()
02006    Return a string containing runtime client library version information */
02007 PHP_FUNCTION(oci_client_version)
02008 {
02009        char *version = NULL;
02010 
02011        php_oci_client_get_version(&version TSRMLS_CC);
02012        RETURN_STRING(version, 0);
02013 }
02014 /* }}} */
02015 
02016 /* {{{ proto string oci_server_version(resource connection)
02017    Return a string containing server version information */
02018 PHP_FUNCTION(oci_server_version)
02019 {
02020        zval *z_connection;
02021        php_oci_connection *connection;
02022        char *version = NULL;
02023 
02024        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_connection) == FAILURE) {
02025               return;
02026        }
02027 
02028        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
02029 
02030        if (php_oci_server_get_version(connection, &version TSRMLS_CC)) {
02031               RETURN_FALSE;
02032        }
02033        
02034        RETURN_STRING(version, 0);
02035 }
02036 /* }}} */
02037 
02038 /* {{{ proto string oci_statement_type(resource stmt)
02039    Return the query type of an OCI statement */
02040 PHP_FUNCTION(oci_statement_type)
02041 {
02042        zval *z_statement;
02043        php_oci_statement *statement;
02044        ub2 type;
02045 
02046        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
02047               return;
02048        }
02049 
02050        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
02051 
02052        if (php_oci_statement_get_type(statement, &type TSRMLS_CC)) {
02053               RETURN_FALSE;
02054        }
02055 
02056        switch (type) {
02057               case OCI_STMT_SELECT:
02058                      RETVAL_STRING("SELECT",1);
02059                      break;
02060               case OCI_STMT_UPDATE:
02061                      RETVAL_STRING("UPDATE",1);
02062                      break;
02063               case OCI_STMT_DELETE:
02064                      RETVAL_STRING("DELETE",1);
02065                      break;
02066               case OCI_STMT_INSERT:
02067                      RETVAL_STRING("INSERT",1);
02068                      break;
02069               case OCI_STMT_CREATE:
02070                      RETVAL_STRING("CREATE",1);
02071                      break;
02072               case OCI_STMT_DROP:
02073                      RETVAL_STRING("DROP",1);
02074                      break;
02075               case OCI_STMT_ALTER:
02076                      RETVAL_STRING("ALTER",1);
02077                      break;
02078               case OCI_STMT_BEGIN:
02079                      RETVAL_STRING("BEGIN",1);
02080                      break;
02081               case OCI_STMT_DECLARE:
02082                      RETVAL_STRING("DECLARE",1);
02083                      break;
02084               case OCI_STMT_CALL:
02085                      RETVAL_STRING("CALL",1);
02086                      break;
02087               default:
02088                      RETVAL_STRING("UNKNOWN",1);
02089        }
02090 }
02091 /* }}} */
02092 
02093 /* {{{ proto int oci_num_rows(resource stmt)
02094    Return the row count of an OCI statement */
02095 PHP_FUNCTION(oci_num_rows)
02096 {
02097        zval *z_statement;
02098        php_oci_statement *statement;
02099        ub4 rowcount;
02100 
02101        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) {
02102               return;
02103        }
02104 
02105        PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
02106 
02107        if (php_oci_statement_get_numrows(statement, &rowcount TSRMLS_CC)) {
02108               RETURN_FALSE;
02109        }
02110        RETURN_LONG(rowcount);
02111 }
02112 /* }}} */
02113 
02114 /* {{{ proto bool oci_free_collection()
02115    Deletes collection object*/
02116 PHP_FUNCTION(oci_free_collection)
02117 {
02118        zval **tmp, *z_collection = getThis();
02119        php_oci_collection *collection;
02120 
02121        if (!getThis()) {
02122               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
02123                      return;
02124               }      
02125        }
02126        
02127        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02128               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02129               RETURN_FALSE;
02130        }
02131        
02132        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02133 
02134        zend_list_delete(collection->id);
02135        RETURN_TRUE;
02136 }
02137 /* }}} */
02138 
02139 /* {{{ proto bool oci_collection_append(string value)
02140    Append an object to the collection */
02141 PHP_FUNCTION(oci_collection_append)
02142 {
02143        zval **tmp, *z_collection = getThis();
02144        php_oci_collection *collection;
02145        char *value;
02146        int value_len;
02147 
02148        if (getThis()) {
02149               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
02150                      return;
02151               }
02152        }
02153        else {
02154               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &z_collection, oci_coll_class_entry_ptr, &value, &value_len) == FAILURE) {
02155                      return;
02156               }      
02157        }
02158        
02159        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02160               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02161               RETURN_FALSE;
02162        }
02163        
02164        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02165 
02166        if (php_oci_collection_append(collection, value, value_len TSRMLS_CC)) {
02167               RETURN_FALSE;
02168        }
02169        RETURN_TRUE;
02170 }
02171 /* }}} */
02172 
02173 /* {{{ proto string oci_collection_element_get(int ndx)
02174    Retrieve the value at collection index ndx */
02175 PHP_FUNCTION(oci_collection_element_get)
02176 {
02177        zval **tmp, *z_collection = getThis();
02178        php_oci_collection *collection;
02179        long element_index;
02180        zval *value;
02181 
02182        if (getThis()) {
02183               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &element_index) == FAILURE) {
02184                      return;
02185               }
02186        }
02187        else {
02188               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_collection, oci_coll_class_entry_ptr, &element_index) == FAILURE) {
02189                      return;
02190               }      
02191        }
02192        
02193        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02194               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02195               RETURN_FALSE;
02196        }
02197        
02198        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02199 
02200        if (php_oci_collection_element_get(collection, element_index, &value TSRMLS_CC)) {
02201               RETURN_FALSE;
02202        }
02203        
02204        *return_value = *value;
02205        zval_copy_ctor(return_value);
02206        zval_ptr_dtor(&value);
02207 }
02208 /* }}} */
02209 
02210 /* {{{ proto bool oci_collection_assign(object from)
02211    Assign a collection from another existing collection */
02212 PHP_FUNCTION(oci_collection_assign)
02213 {
02214        zval **tmp_dest, **tmp_from, *z_collection_dest = getThis(), *z_collection_from;
02215        php_oci_collection *collection_dest, *collection_from;
02216 
02217        if (getThis()) {
02218               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection_from, oci_coll_class_entry_ptr) == FAILURE) {
02219                      return;
02220               }
02221        }
02222        else {
02223               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) {
02224                      return;
02225               }      
02226        }
02227        
02228        if (zend_hash_find(Z_OBJPROP_P(z_collection_dest), "collection", sizeof("collection"), (void **)&tmp_dest) == FAILURE) {
02229               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property. The first argument should be valid collection object");
02230               RETURN_FALSE;
02231        }
02232 
02233        if (zend_hash_find(Z_OBJPROP_P(z_collection_from), "collection", sizeof("collection"), (void **)&tmp_from) == FAILURE) {
02234               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property. The second argument should be valid collection object");
02235               RETURN_FALSE;
02236        }
02237 
02238        PHP_OCI_ZVAL_TO_COLLECTION(*tmp_dest, collection_dest);
02239        PHP_OCI_ZVAL_TO_COLLECTION(*tmp_from, collection_from);
02240 
02241        if (php_oci_collection_assign(collection_dest, collection_from TSRMLS_CC)) {
02242               RETURN_FALSE;
02243        }
02244        RETURN_TRUE;
02245 }
02246 /* }}} */
02247 
02248 /* {{{ proto bool oci_collection_element_assign(int index, string val)
02249    Assign element val to collection at index ndx */
02250 PHP_FUNCTION(oci_collection_element_assign)
02251 {
02252        zval **tmp, *z_collection = getThis();
02253        php_oci_collection *collection;
02254        int value_len;
02255        long element_index;
02256        char *value;
02257 
02258        if (getThis()) {
02259               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element_index, &value, &value_len) == FAILURE) {
02260                      return;
02261               }
02262        }
02263        else {
02264               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ols", &z_collection, oci_coll_class_entry_ptr, &element_index, &value, &value_len) == FAILURE) {
02265                      return;
02266               }      
02267        }
02268        
02269        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02270               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02271               RETURN_FALSE;
02272        }
02273        
02274        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02275 
02276        if (php_oci_collection_element_set(collection, element_index, value, value_len TSRMLS_CC)) {
02277               RETURN_FALSE;
02278        }
02279        RETURN_TRUE;
02280 }
02281 /* }}} */
02282 
02283 /* {{{ proto int oci_collection_size()
02284    Return the size of a collection */
02285 PHP_FUNCTION(oci_collection_size)
02286 {
02287        zval **tmp, *z_collection = getThis();
02288        php_oci_collection *collection;
02289        sb4 size = 0;
02290        
02291        if (!getThis()) {
02292               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
02293                      return;
02294               }      
02295        }
02296        
02297        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02298               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02299               RETURN_FALSE;
02300        }
02301        
02302        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02303 
02304        if (php_oci_collection_size(collection, &size TSRMLS_CC)) {
02305               RETURN_FALSE;
02306        }
02307        RETURN_LONG(size);
02308 }
02309 /* }}} */
02310 
02311 /* {{{ proto int oci_collection_max()
02312    Return the max value of a collection. For a varray this is the maximum length of the array */
02313 PHP_FUNCTION(oci_collection_max)
02314 {
02315        zval **tmp, *z_collection = getThis();
02316        php_oci_collection *collection;
02317        long max;
02318        
02319        if (!getThis()) {
02320               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &z_collection, oci_coll_class_entry_ptr) == FAILURE) {
02321                      return;
02322               }      
02323        }
02324        
02325        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02326               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02327               RETURN_FALSE;
02328        }
02329        
02330        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02331 
02332        if (php_oci_collection_max(collection, &max TSRMLS_CC)) {
02333               RETURN_FALSE;
02334        }
02335        RETURN_LONG(max);
02336 }
02337 /* }}} */
02338 
02339 /* {{{ proto bool oci_collection_trim(int num)
02340    Trim num elements from the end of a collection */
02341 PHP_FUNCTION(oci_collection_trim)
02342 {
02343        zval **tmp, *z_collection = getThis();
02344        php_oci_collection *collection;
02345        long trim_size;
02346 
02347        if (getThis()) {
02348               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &trim_size) == FAILURE) {
02349                      return;
02350               }
02351        }
02352        else {
02353               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &z_collection, oci_coll_class_entry_ptr, &trim_size) == FAILURE) {
02354                      return;
02355               }      
02356        }
02357        
02358        if (zend_hash_find(Z_OBJPROP_P(z_collection), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
02359               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
02360               RETURN_FALSE;
02361        }
02362        
02363        PHP_OCI_ZVAL_TO_COLLECTION(*tmp, collection);
02364 
02365        if (php_oci_collection_trim(collection, trim_size TSRMLS_CC)) {
02366               RETURN_FALSE;
02367        }
02368        RETURN_TRUE;  
02369 }
02370 /* }}} */
02371 
02372 /* {{{ proto object oci_new_collection(resource connection, string tdo [, string schema])
02373    Initialize a new collection */
02374 PHP_FUNCTION(oci_new_collection)
02375 {
02376        zval *z_connection;
02377        php_oci_connection *connection;
02378        php_oci_collection *collection;
02379        char *tdo, *schema = NULL;
02380        int tdo_len, schema_len = 0;
02381        
02382        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &z_connection, &tdo, &tdo_len, &schema, &schema_len) == FAILURE) {
02383               return;
02384        }
02385        
02386        PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection);
02387        
02388        if ( (collection = php_oci_collection_create(connection, tdo, tdo_len, schema, schema_len TSRMLS_CC)) ) {
02389               object_init_ex(return_value, oci_coll_class_entry_ptr);
02390               add_property_resource(return_value, "collection", collection->id);
02391        }
02392        else {
02393               RETURN_FALSE;
02394        }
02395 }
02396 /* }}} */
02397 
02398 #endif /* HAVE_OCI8 */
02399 
02400 /*
02401  * Local variables:
02402  * tab-width: 4
02403  * c-basic-offset: 4
02404  * End:
02405  * vim600: noet sw=4 ts=4 fdm=marker
02406  * vim<600: noet sw=4 ts=4
02407  */