PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - oci8 - oci8_statement.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 713
Code covered: 86.1 % Executed lines: 614
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
      16                 :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17                 :    |                                                                      |
      18                 :    | Collection support by Andy Sautins <asautins@veripost.net>           |
      19                 :    | Temporary LOB support by David Benson <dbenson@mancala.com>          |
      20                 :    | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at>        |
      21                 :    |                                                                      |
      22                 :    | Redesigned by: Antony Dovgal <antony@zend.com>                       |
      23                 :    |                Andi Gutmans <andi@zend.com>                          |
      24                 :    |                Wez Furlong <wez@omniti.com>                          |
      25                 :    +----------------------------------------------------------------------+
      26                 : */
      27                 : 
      28                 : /* $Id: oci8_statement.c 272374 2008-12-31 11:17:49Z sebastian $ */
      29                 : 
      30                 : 
      31                 : #ifdef HAVE_CONFIG_H
      32                 : #include "config.h"
      33                 : #endif
      34                 : 
      35                 : #include "php.h"
      36                 : #include "ext/standard/info.h"
      37                 : #include "php_ini.h"
      38                 : 
      39                 : #if HAVE_OCI8
      40                 : 
      41                 : #include "php_oci8.h"
      42                 : #include "php_oci8_int.h"
      43                 : 
      44                 : /* {{{ php_oci_statement_create() 
      45                 :  Create statemend handle and allocate necessary resources */
      46                 : php_oci_statement *php_oci_statement_create (php_oci_connection *connection, char *query, int query_len TSRMLS_DC)
      47           33842 : {
      48                 :         php_oci_statement *statement;
      49                 :         
      50           33842 :         statement = ecalloc(1,sizeof(php_oci_statement));
      51                 : 
      52                 : #if HAVE_OCI_STMT_PREPARE2
      53           33842 :         if (!query_len) {
      54                 :                 /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */
      55            1421 :                 PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
      56                 :         }
      57                 : #else
      58                 :         PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
      59                 : #endif
      60                 :                         
      61           33842 :         PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL));
      62                 :         
      63           33842 :         if (query_len > 0) {
      64                 : #if HAVE_OCI_STMT_PREPARE2
      65           32421 :                 PHP_OCI_CALL_RETURN(connection->errcode, OCIStmtPrepare2, 
      66                 :                                 (
      67                 :                                  connection->svc,
      68                 :                                  &(statement->stmt),
      69                 :                                  connection->err,
      70                 :                                  (text *)query,
      71                 :                                  query_len,
      72                 :                                  NULL,
      73                 :                                  0,
      74                 :                                  OCI_NTV_SYNTAX,
      75                 :                                  OCI_DEFAULT
      76                 :                                 )
      77                 :                 );
      78                 : #else
      79                 :                 PHP_OCI_CALL_RETURN(connection->errcode, OCIStmtPrepare, (statement->stmt, connection->err, (text *)query, query_len, OCI_NTV_SYNTAX, OCI_DEFAULT));
      80                 : #endif          
      81           32421 :                 if (connection->errcode != OCI_SUCCESS) {
      82               3 :                         php_oci_error(connection->err, connection->errcode TSRMLS_CC);
      83                 : 
      84                 : #if HAVE_OCI_STMT_PREPARE2
      85               3 :                         PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT));
      86               3 :                         PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
      87                 : #else
      88                 :                         PHP_OCI_CALL(OCIHandleFree,(statement->stmt, OCI_HTYPE_STMT));
      89                 :                         PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
      90                 : #endif
      91                 :                         
      92               3 :                         efree(statement);
      93               3 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
      94               3 :                         return NULL;
      95                 :                 }
      96                 :         }
      97                 :         
      98           66257 :         if (query && query_len) {
      99           32418 :                 statement->last_query = estrndup(query, query_len);
     100           32418 :                 statement->last_query_len = query_len;
     101                 :         }
     102                 :         else {
     103            1421 :                 statement->last_query = NULL;
     104            1421 :                 statement->last_query_len = 0;
     105                 :         }
     106                 : 
     107           33839 :         statement->connection = connection;
     108           33839 :         statement->has_data = 0;
     109           33839 :         statement->parent_stmtid = 0;
     110           33839 :         zend_list_addref(statement->connection->rsrc_id);
     111                 : 
     112           33839 :         if (OCI_G(default_prefetch) > 0) {
     113           33839 :                 php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC);
     114                 :         }
     115                 :         
     116           33839 :         PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
     117                 : 
     118           33839 :         OCI_G(num_statements)++;
     119                 :         
     120           33839 :         return statement;
     121                 : }
     122                 : /* }}} */
     123                 : 
     124                 : /* {{{ php_oci_statement_set_prefetch()
     125                 :  Set prefetch buffer size for the statement (we're assuming that one row is ~1K sized) */
     126                 : int php_oci_statement_set_prefetch(php_oci_statement *statement, long size TSRMLS_DC)
     127           33842 : { 
     128           33842 :         ub4 prefetch = size * 1024;
     129                 : 
     130           33842 :         if (size < 1) {
     131               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows has to be greater than or equal to 1");
     132               0 :                 return 1;
     133                 :         }
     134                 :         
     135           33842 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_MEMORY, statement->err));
     136                 : 
     137           33842 :         if (statement->errcode != OCI_SUCCESS) {
     138               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     139               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     140               0 :                 return 1;
     141                 :         }
     142                 : 
     143           33842 :         prefetch = size;
     144           33842 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err));
     145                 :         
     146           33842 :         if (statement->errcode != OCI_SUCCESS) {
     147               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     148               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     149               0 :                 return 1;
     150                 :         }
     151                 : 
     152           33842 :         return 0;
     153                 : }
     154                 : /* }}} */
     155                 : 
     156                 : /* {{{ php_oci_statement_fetch() 
     157                 :  Fetch a row from the statement */
     158                 : int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
     159          131546 : {
     160                 :         int i;
     161                 :         void *handlepp;
     162                 :         ub4 typep, iterp, idxp;
     163                 :         ub1 in_outp, piecep;
     164          131546 :         zend_bool piecewisecols = 0;
     165                 : 
     166                 :         php_oci_out_column *column;
     167                 : 
     168          131546 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
     169                 : 
     170          131546 :         if ( statement->errcode == OCI_NO_DATA || nrows == 0 ) {
     171           30152 :                 if (statement->last_query == NULL) {
     172                 :                         /* reset define-list for refcursors */
     173              15 :                         if (statement->columns) {
     174              13 :                                 zend_hash_destroy(statement->columns);
     175              13 :                                 efree(statement->columns);
     176              13 :                                 statement->columns = NULL;
     177              13 :                                 statement->ncolumns = 0;
     178                 :                         }
     179              15 :                         statement->executed = 0;
     180                 :                 }
     181                 : 
     182           30152 :                 statement->errcode = 0; /* OCI_NO_DATA is NO error for us!!! */
     183           30152 :                 statement->has_data = 0;
     184                 : 
     185           30152 :                 if (nrows == 0) {
     186                 :                         /* this is exactly what we requested */
     187               7 :                         return 0;
     188                 :                 }
     189           30145 :                 return 1;
     190                 :         }
     191                 : 
     192                 :         /* reset length for all piecewise columns */
     193          293652 :         for (i = 0; i < statement->ncolumns; i++) {
     194          192258 :                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     195          192258 :                 if (column->piecewise) {
     196              12 :                         column->retlen4 = 0;
     197              12 :                         piecewisecols = 1;
     198                 :                 }
     199                 :         }
     200                 :         
     201          202800 :         while (statement->errcode == OCI_NEED_DATA) {
     202              12 :                 if (piecewisecols) {
     203              12 :                         PHP_OCI_CALL_RETURN(statement->errcode,
     204                 :                                 OCIStmtGetPieceInfo, 
     205                 :                                    (
     206                 :                                         statement->stmt,
     207                 :                                         statement->err,
     208                 :                                         &handlepp,
     209                 :                                         &typep,
     210                 :                                         &in_outp,
     211                 :                                         &iterp,
     212                 :                                         &idxp,
     213                 :                                         &piecep
     214                 :                                    )
     215                 :                         );
     216                 : 
     217                 :                         /* scan through our columns for a piecewise column with a matching handle */
     218              34 :                         for (i = 0; i < statement->ncolumns; i++) {
     219              22 :                                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     220              22 :                                 if (column->piecewise && handlepp == column->oci_define)   {
     221              12 :                                         if (!column->data) {
     222               4 :                                                 column->data = (text *) ecalloc(1, PHP_OCI_PIECE_SIZE + 1);
     223                 :                                         } else {
     224               8 :                                                 column->data = erealloc(column->data, column->retlen4 + PHP_OCI_PIECE_SIZE + 1);
     225                 :                                         }
     226              12 :                                         column->cb_retlen = PHP_OCI_PIECE_SIZE;
     227                 : 
     228                 :                                         /* and instruct fetch to fetch waiting piece into our buffer */
     229              12 :                                         PHP_OCI_CALL(OCIStmtSetPieceInfo,
     230                 :                                                    (
     231                 :                                                         (void *) column->oci_define,
     232                 :                                                         OCI_HTYPE_DEFINE,
     233                 :                                                         statement->err,
     234                 :                                                         ((char*)column->data) + column->retlen4,
     235                 :                                                         &(column->cb_retlen),
     236                 :                                                         piecep,
     237                 :                                                         &column->indicator,
     238                 :                                                         &column->retcode
     239                 :                                                    )
     240                 :                                         );
     241                 :                                 }
     242                 :                         }
     243                 :                 }
     244                 : 
     245              12 :                 PHP_OCI_CALL_RETURN(statement->errcode,  OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
     246                 : 
     247              12 :                 if (piecewisecols) {
     248              34 :                         for (i = 0; i < statement->ncolumns; i++) {
     249              22 :                                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     250              22 :                                 if (column && column->piecewise && handlepp == column->oci_define)        {
     251              12 :                                         column->retlen4 += column->cb_retlen;
     252                 :                                 }
     253                 :                         }
     254                 :                 }
     255                 :         }
     256                 : 
     257          101394 :         if (statement->errcode == OCI_SUCCESS_WITH_INFO || statement->errcode == OCI_SUCCESS) {
     258          101388 :                 statement->has_data = 1;
     259                 : 
     260                 :                 /* do the stuff needed for OCIDefineByName */
     261          293644 :                 for (i = 0; i < statement->ncolumns; i++) {
     262          192256 :                         column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     263          192256 :                         if (column == NULL) {
     264               0 :                                 continue;
     265                 :                         }
     266                 :                         
     267          192256 :                         if (!column->define) {
     268          102240 :                                 continue;
     269                 :                         }
     270                 :                         
     271           90016 :                         zval_dtor(column->define->zval);
     272           90016 :                         php_oci_column_to_zval(column, column->define->zval, 0 TSRMLS_CC);
     273                 :                 }
     274                 : 
     275          101388 :                 return 0;
     276                 :         }
     277                 : 
     278               6 :         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     279               6 :         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     280                 : 
     281               6 :         statement->has_data = 0;
     282                 : 
     283               6 :         return 1;
     284                 : }
     285                 : /* }}} */
     286                 : 
     287                 : /* {{{ php_oci_statement_get_column() 
     288                 :  Get column from the result set */
     289                 : php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, long column_index, char *column_name, int column_name_len TSRMLS_DC)
     290          577110 : {
     291          577110 :         php_oci_out_column *column = NULL;
     292                 :         int i;
     293                 : 
     294          577110 :         if (statement->columns == NULL) { /* we release the columns at the end of a fetch */
     295               0 :                 return NULL;
     296                 :         }
     297                 : 
     298          577110 :         if (column_name) {
     299             365 :                 for (i = 0; i < statement->ncolumns; i++) {
     300             358 :                         column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     301             358 :                         if (column == NULL) {
     302               0 :                                 continue;
     303             358 :                         } else if (((int) column->name_len == column_name_len) && (!strncmp(column->name, column_name, column_name_len))) {
     304              69 :                                 return column;
     305                 :                         }
     306                 :                 }
     307          577034 :         } else if (column_index != -1) {
     308          577027 :                 if (zend_hash_index_find(statement->columns, column_index, (void **)&column) == FAILURE) {
     309               7 :                         return NULL;
     310                 :                 }
     311          577020 :                 return column;
     312                 :         }
     313                 : 
     314              14 :         return NULL;
     315                 : }
     316                 : /* }}} */
     317                 : 
     318                 : /* php_oci_define_callback() {{{ */
     319                 : sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp)
     320          184896 : {
     321          184896 :         php_oci_out_column *outcol = (php_oci_out_column *)ctx;
     322                 : 
     323          184896 :         if (!outcol) {
     324                 :                 TSRMLS_FETCH();
     325                 :                 
     326               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid context pointer value");
     327               0 :                 return OCI_ERROR;
     328                 :         }
     329                 :         
     330          184896 :         switch(outcol->data_type) {
     331                 :                 case SQLT_RSET: {
     332                 :                                 php_oci_statement *nested_stmt;
     333                 :                                 TSRMLS_FETCH();
     334                 : 
     335            1413 :                                 nested_stmt = php_oci_statement_create(outcol->statement->connection, NULL, 0 TSRMLS_CC); 
     336            1413 :                                 if (!nested_stmt) {
     337               0 :                                         return OCI_ERROR;
     338                 :                                 }
     339            1413 :                                 nested_stmt->parent_stmtid = outcol->statement->id;
     340            1413 :                                 zend_list_addref(outcol->statement->id);
     341            1413 :                                 outcol->nested_statement = nested_stmt;
     342            1413 :                                 outcol->stmtid = nested_stmt->id;
     343                 : 
     344            1413 :                                 *bufpp = nested_stmt->stmt;
     345            1413 :                                 *alenpp = &(outcol->retlen4);
     346            1413 :                                 *piecep = OCI_ONE_PIECE;
     347            1413 :                                 *indpp = &(outcol->indicator);
     348            1413 :                                 *rcpp = &(outcol->retcode);
     349            1413 :                                 return OCI_CONTINUE;
     350                 :                         }
     351                 :                         break;
     352                 :                 case SQLT_RDD:
     353                 :                 case SQLT_BLOB: 
     354                 :                 case SQLT_CLOB:
     355                 :                 case SQLT_BFILE: {
     356                 :                                 php_oci_descriptor *descr;
     357                 :                                 int dtype;
     358                 :                                 TSRMLS_FETCH();
     359                 : 
     360          183483 :                                 if (outcol->data_type == SQLT_BFILE) {
     361               3 :                                         dtype = OCI_DTYPE_FILE;
     362          183480 :                                 } else if (outcol->data_type == SQLT_RDD ) {
     363               1 :                                         dtype = OCI_DTYPE_ROWID;
     364                 :                                 } else {
     365          183479 :                                         dtype = OCI_DTYPE_LOB;
     366                 :                                 }
     367                 : 
     368          183483 :                                 descr = php_oci_lob_create(outcol->statement->connection, dtype TSRMLS_CC);
     369          183483 :                                 if (!descr) {
     370               0 :                                         return OCI_ERROR;
     371                 :                                 }
     372          183483 :                                 outcol->descid = descr->id;
     373          183483 :                                 descr->charset_form = outcol->charset_form;
     374                 :                                 
     375          183483 :                                 *bufpp = descr->descriptor;
     376          183483 :                                 *alenpp = &(outcol->retlen4);
     377          183483 :                                 *piecep = OCI_ONE_PIECE;
     378          183483 :                                 *indpp = &(outcol->indicator);
     379          183483 :                                 *rcpp = &(outcol->retcode);
     380                 : 
     381          183483 :                                 return OCI_CONTINUE;
     382                 :                         }
     383                 :                         break;
     384                 :         }
     385               0 :         return OCI_ERROR;
     386                 : }
     387                 : /* }}} */
     388                 : 
     389                 : /* {{{ php_oci_statement_execute() 
     390                 :  Execute statement */
     391                 : int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
     392           34737 : {
     393                 :         php_oci_out_column *outcol;
     394                 :         php_oci_out_column column;
     395           34737 :         OCIParam *param = NULL;
     396                 :         text *colname;
     397                 :         ub4 counter;
     398                 :         ub2 define_type;
     399                 :         ub4 iters;
     400                 :         ub4 colcount;
     401                 :         ub2 dynamic;
     402                 :         dvoid *buf;
     403                 : 
     404           34737 :         switch (mode) {
     405                 :                 case OCI_COMMIT_ON_SUCCESS:
     406                 :                 case OCI_DESCRIBE_ONLY:
     407                 :                 case OCI_DEFAULT:
     408                 :                         /* only these are allowed */
     409                 :                         break;
     410                 :                 default:
     411               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid execute mode given: %d", mode);
     412               1 :                         return 1;
     413                 :                         break;
     414                 :         }
     415                 :         
     416           34736 :         if (!statement->stmttype) {
     417                 :                 /* get statement type */
     418           33811 :                 PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0,      OCI_ATTR_STMT_TYPE,     statement->err));
     419                 : 
     420           33811 :                 if (statement->errcode != OCI_SUCCESS) {
     421               0 :                         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     422               0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     423               0 :                         return 1;
     424                 :                 }
     425                 :         }
     426                 : 
     427           34736 :         if (statement->stmttype == OCI_STMT_SELECT) {
     428           32675 :                 iters = 0;
     429                 :         } else {
     430            2061 :                 iters = 1;
     431                 :         }
     432                 :         
     433           34736 :         if (statement->last_query) { 
     434                 :                 /* if we execute refcursors we don't have a query and 
     435                 :                    we don't want to execute!!! */
     436                 : 
     437           33317 :                 if (statement->binds) {
     438            1020 :                         zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_pre_exec TSRMLS_CC);
     439                 :                 }
     440                 : 
     441                 :                 /* execute statement */
     442           33317 :                 PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtExecute, (statement->connection->svc,   statement->stmt, statement->err, iters,   0, NULL, NULL, mode));
     443                 : 
     444           33317 :                 if (statement->errcode != OCI_SUCCESS) {
     445             159 :                         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     446             159 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     447             159 :                         return 1;
     448                 :                 }
     449                 :                 
     450           33158 :                 if (statement->binds) {
     451            1016 :                         zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec TSRMLS_CC);
     452                 :                 }
     453                 : 
     454           33158 :                 if (mode & OCI_COMMIT_ON_SUCCESS) {
     455           31570 :                         statement->connection->needs_commit = 0;
     456                 :                 } else {
     457            1588 :                         statement->connection->needs_commit = 1;
     458                 :                 }
     459                 :         }
     460                 : 
     461           34577 :         if (statement->stmttype == OCI_STMT_SELECT && statement->executed == 0) {
     462                 :                 /* we only need to do the define step is this very statement is executed the first time! */
     463           32645 :                 statement->executed = 1;
     464                 :                 
     465           32645 :                 ALLOC_HASHTABLE(statement->columns);
     466           32645 :                 zend_hash_init(statement->columns, 13, NULL, php_oci_column_hash_dtor, 0);
     467                 :                 
     468           32645 :                 counter = 1;
     469                 : 
     470                 :                 /* get number of columns */
     471           32645 :                 PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err));
     472                 :                 
     473           32645 :                 if (statement->errcode != OCI_SUCCESS) {
     474               0 :                         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     475               0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     476               0 :                         return 1; 
     477                 :                 }
     478                 : 
     479           32645 :                 statement->ncolumns = colcount;
     480                 :                 
     481           95827 :                 for (counter = 1; counter <= colcount; counter++) {
     482           63182 :                         memset(&column,0,sizeof(php_oci_out_column));
     483                 :                         
     484           63182 :                         if (zend_hash_index_update(statement->columns, counter, &column, sizeof(php_oci_out_column), (void**) &outcol) == FAILURE) {
     485               0 :                                 efree(statement->columns);
     486                 :                                 /* out of memory */
     487               0 :                                 return 1;
     488                 :                         } 
     489                 :                         
     490                 :                         /* get column */
     491           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)&param, counter));
     492                 :                         
     493           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     494               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     495               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     496               0 :                                 return 1;
     497                 :                         }
     498                 : 
     499                 :                         /* get column datatype */
     500           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err));
     501                 : 
     502           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     503               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     504               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     505               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     506               0 :                                 return 1;
     507                 :                         }
     508                 : 
     509                 :                         /* get character set form  */
     510           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_form, (ub4 *)0, OCI_ATTR_CHARSET_FORM, statement->err));
     511                 : 
     512           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     513               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     514               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     515               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     516               0 :                                 return 1;
     517                 :                         }
     518                 :         
     519                 :                         /* get character set id  */
     520           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_id, (ub4 *)0, OCI_ATTR_CHARSET_ID, statement->err));
     521                 : 
     522           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     523               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     524               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     525               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     526               0 :                                 return 1;
     527                 :                         }
     528                 :         
     529                 :                         /* get size of the column */
     530           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err));
     531                 :                         
     532           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     533               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     534               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     535               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     536               0 :                                 return 1; 
     537                 :                         }
     538                 : 
     539           63182 :                         outcol->storage_size4 = outcol->data_size;
     540           63182 :                         outcol->retlen = outcol->data_size;
     541                 : 
     542                 :                         /* get scale of the column */
     543           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err));
     544                 :                         
     545           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     546               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     547               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     548               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     549               0 :                                 return 1;
     550                 :                         }
     551                 : 
     552                 :                         /* get precision of the column */
     553           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err));
     554                 :                         
     555           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     556               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     557               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     558               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     559               0 :                                 return 1;
     560                 :                         }
     561                 :                         
     562                 :                         /* get name of the column */
     563           63182 :                         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err));
     564                 :                         
     565           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     566               0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     567               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     568               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     569               0 :                                 return 1;
     570                 :                         }
     571           63182 :                         PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     572                 : 
     573           63182 :                         outcol->name = estrndup((char*) colname, outcol->name_len);
     574                 : 
     575                 :                         /* find a user-setted define */
     576           63182 :                         if (statement->defines) {
     577           30020 :                                 if (zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define) == SUCCESS) {
     578           30015 :                                         if (outcol->define->type) {
     579               7 :                                                 outcol->data_type = outcol->define->type;
     580                 :                                         }
     581                 :                                 }
     582                 :                         }
     583                 : 
     584           63182 :                         buf = 0;
     585           63182 :                         switch (outcol->data_type) {
     586                 :                                 case SQLT_RSET:
     587            1407 :                                         outcol->statement = statement; /* parent handle */
     588                 : 
     589            1407 :                                         define_type = SQLT_RSET;
     590            1407 :                                         outcol->is_cursor = 1;
     591            1407 :                                         outcol->storage_size4 = -1;
     592            1407 :                                         outcol->retlen = -1;
     593            1407 :                                         dynamic = OCI_DYNAMIC_FETCH;
     594            1407 :                                         break;
     595                 : 
     596                 :                                 case SQLT_RDD:   /* ROWID */
     597                 :                                 case SQLT_BLOB:  /* binary LOB */
     598                 :                                 case SQLT_CLOB:  /* character LOB */
     599                 :                                 case SQLT_BFILE: /* binary file LOB */
     600           60156 :                                         outcol->statement = statement; /* parent handle */
     601                 : 
     602           60156 :                                         define_type = outcol->data_type;
     603           60156 :                                         outcol->is_descr = 1;
     604           60156 :                                         outcol->storage_size4 = -1;
     605           60156 :                                         dynamic = OCI_DYNAMIC_FETCH;
     606           60156 :                                         break;
     607                 : 
     608                 :                                 case SQLT_LNG:
     609                 :                                 case SQLT_LBI:
     610               4 :                                         if (outcol->data_type == SQLT_LBI) {
     611               1 :                                                 define_type = SQLT_BIN;
     612                 :                                         } else {
     613               3 :                                                 define_type = SQLT_CHR;
     614                 :                                         }
     615               4 :                                         outcol->storage_size4 = PHP_OCI_MAX_DATA_SIZE;
     616               4 :                                         outcol->piecewise = 1;
     617               4 :                                         dynamic = OCI_DYNAMIC_FETCH;
     618               4 :                                         break;
     619                 : 
     620                 :                                 case SQLT_BIN:
     621                 :                                 default:
     622            1615 :                                         define_type = SQLT_CHR;
     623            1615 :                                         if (outcol->data_type == SQLT_BIN) {
     624               4 :                                                 define_type = SQLT_BIN;
     625                 :                                         }
     626            2572 :                                         if ((outcol->data_type == SQLT_DAT) || (outcol->data_type == SQLT_NUM)
     627                 : #ifdef SQLT_TIMESTAMP
     628                 :                                                 || (outcol->data_type == SQLT_TIMESTAMP)
     629                 : #endif
     630                 : #ifdef SQLT_TIMESTAMP_TZ
     631                 :                                                 || (outcol->data_type == SQLT_TIMESTAMP_TZ)
     632                 : #endif
     633                 : #ifdef SQLT_TIMESTAMP_LTZ
     634                 :                                                 || (outcol->data_type == SQLT_TIMESTAMP_LTZ)
     635                 : #endif
     636                 : #ifdef SQLT_INTERVAL_YM
     637                 :                                                 || (outcol->data_type == SQLT_INTERVAL_YM)
     638                 : #endif
     639                 : #ifdef SQLT_INTERVAL_DS
     640                 :                                                 || (outcol->data_type == SQLT_INTERVAL_DS)
     641                 : #endif
     642                 :                                                 ) {
     643             957 :                                                 outcol->storage_size4 = 512; /* XXX this should fit "most" NLS date-formats and Numbers */
     644                 : #if defined(SQLT_IBFLOAT) && defined(SQLT_IBDOUBLE)
     645             658 :                                         } else if (outcol->data_type == SQLT_IBFLOAT || outcol->data_type == SQLT_IBDOUBLE) {
     646               0 :                                                 outcol->storage_size4 = 1024;
     647                 : #endif
     648                 :                                         } else {
     649             658 :                                                 outcol->storage_size4++; /* add one for string terminator */
     650                 :                                         }
     651                 :                                         
     652            1615 :                                         outcol->storage_size4 *= 3;
     653                 :                                         
     654            1615 :                                         dynamic = OCI_DEFAULT;
     655            1615 :                                         buf = outcol->data = (text *) safe_emalloc(1, outcol->storage_size4, 0);
     656            1615 :                                         memset(buf, 0, outcol->storage_size4);
     657                 :                                         break;
     658                 :                         }
     659                 : 
     660           63182 :                         if (dynamic == OCI_DYNAMIC_FETCH) {
     661           61567 :                                 PHP_OCI_CALL_RETURN(statement->errcode, 
     662                 :                                         OCIDefineByPos,
     663                 :                                         (
     664                 :                                                 statement->stmt,                           /* IN/OUT handle to the requested SQL query */
     665                 :                                                 (OCIDefine **)&outcol->oci_define,             /* IN/OUT pointer to a pointer to a define handle */
     666                 :                                                 statement->err,                          /* IN/OUT An error handle  */
     667                 :                                                 counter,                                    /* IN     position in the select list */
     668                 :                                                 (dvoid *)NULL,                              /* IN/OUT pointer to a buffer */
     669                 :                                                 outcol->storage_size4,                      /* IN     The size of each valuep buffer in bytes */
     670                 :                                                 define_type,                                /* IN     The data type */
     671                 :                                                 (dvoid *)&outcol->indicator,                /* IN     pointer to an indicator variable or arr */
     672                 :                                                 (ub2 *)NULL,                                /* IN/OUT Pointer to array of length of data fetched */
     673                 :                                                 (ub2 *)NULL,                                /* OUT    Pointer to array of column-level return codes */
     674                 :                                                 OCI_DYNAMIC_FETCH                               /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
     675                 :                                         )
     676                 :                                 );
     677                 : 
     678                 :                         } else {
     679            1615 :                                 PHP_OCI_CALL_RETURN(statement->errcode, 
     680                 :                                         OCIDefineByPos,
     681                 :                                         (
     682                 :                                                 statement->stmt,                           /* IN/OUT handle to the requested SQL query */ 
     683                 :                                                 (OCIDefine **)&outcol->oci_define,             /* IN/OUT pointer to a pointer to a define handle */
     684                 :                                                 statement->err,                          /* IN/OUT An error handle  */
     685                 :                                                 counter,                                    /* IN     position in the select list */
     686                 :                                                 (dvoid *)buf,                               /* IN/OUT pointer to a buffer */
     687                 :                                                 outcol->storage_size4,                      /* IN     The size of each valuep buffer in bytes */
     688                 :                                                 define_type,                                /* IN     The data type */
     689                 :                                                 (dvoid *)&outcol->indicator,                /* IN     pointer to an indicator variable or arr */
     690                 :                                                 (ub2 *)&outcol->retlen,                     /* IN/OUT Pointer to array of length of data fetched */
     691                 :                                                 (ub2 *)&outcol->retcode,                    /* OUT    Pointer to array of column-level return codes */
     692                 :                                                 OCI_DEFAULT                                     /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
     693                 :                                         )
     694                 :                                 );
     695                 : 
     696                 :                         }
     697                 :                         
     698           63182 :                         if (statement->errcode != OCI_SUCCESS) {
     699               0 :                                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
     700               0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     701               0 :                                 return 0;
     702                 :                         }
     703                 : 
     704                 :                         /* additional OCIDefineDynamic() call */
     705           63182 :                         switch (outcol->data_type) {
     706                 :                                 case SQLT_RSET:
     707                 :                                 case SQLT_RDD:
     708                 :                                 case SQLT_BLOB: 
     709                 :                                 case SQLT_CLOB:
     710                 :                                 case SQLT_BFILE:
     711           61563 :                                         PHP_OCI_CALL_RETURN(statement->errcode, 
     712                 :                                                 OCIDefineDynamic,
     713                 :                                                 (
     714                 :                                                         outcol->oci_define,
     715                 :                                                         statement->err,
     716                 :                                                         (dvoid *)outcol,
     717                 :                                                         php_oci_define_callback
     718                 :                                                 )
     719                 :                                         );
     720                 : 
     721                 :                                         break;
     722                 :                         }
     723                 :                 }
     724                 :         }
     725                 : 
     726           34577 :         return 0;
     727                 : }
     728                 : /* }}} */
     729                 : 
     730                 : /* {{{ php_oci_statement_cancel() 
     731                 :  Cancel statement */
     732                 : int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC)
     733               7 : {
     734                 :         
     735               7 :         return php_oci_statement_fetch(statement, 0 TSRMLS_CC);
     736                 :                 
     737                 : } /* }}} */
     738                 : 
     739                 : /* {{{ php_oci_statement_free() 
     740                 :  Destroy statement handle and free associated resources */
     741                 : void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC)
     742           33839 : {
     743           33839 :         if (statement->stmt) {
     744                 : #if HAVE_OCI_STMT_PREPARE2
     745           33839 :                 if (statement->last_query_len) { /* FIXME: magical */
     746           32418 :                         PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT));
     747                 :                 } else {
     748            1421 :                         PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
     749                 :                 }
     750                 : #else
     751                 :                 PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
     752                 : #endif
     753           33839 :                 statement->stmt = 0;
     754                 :         }
     755                 : 
     756           33839 :         if (statement->err) {
     757           33839 :                 PHP_OCI_CALL(OCIHandleFree, (statement->err, OCI_HTYPE_ERROR));
     758           33839 :                 statement->err = 0;
     759                 :         }
     760                 : 
     761           33839 :         if (statement->last_query) {
     762           32418 :                 efree(statement->last_query);
     763                 :         }
     764                 : 
     765           33839 :         if (statement->columns) {
     766           32632 :                 zend_hash_destroy(statement->columns);
     767           32632 :                 efree(statement->columns);
     768                 :         }
     769                 : 
     770           33839 :         if (statement->binds) {
     771             216 :                 zend_hash_destroy(statement->binds);
     772             216 :                 efree(statement->binds);
     773                 :         }
     774                 : 
     775           33839 :         if (statement->defines) {
     776           15020 :                 zend_hash_destroy(statement->defines);
     777           15020 :                 efree(statement->defines);
     778                 :         }
     779                 : 
     780           33839 :         if (statement->parent_stmtid) {
     781            1413 :                 zend_list_delete(statement->parent_stmtid);
     782                 :         }
     783                 : 
     784           33839 :         zend_list_delete(statement->connection->rsrc_id);
     785           33839 :         efree(statement);
     786                 :         
     787           33839 :         OCI_G(num_statements)--;
     788           33839 : } /* }}} */
     789                 : 
     790                 : /* {{{ php_oci_bind_pre_exec() 
     791                 :  Helper function */
     792                 : int php_oci_bind_pre_exec(void *data TSRMLS_DC)
     793            1133 : {
     794            1133 :         php_oci_bind *bind = (php_oci_bind *) data;
     795                 : 
     796                 :         /* reset all bind stuff to a normal state..-. */
     797                 : 
     798            1133 :         bind->indicator = 0; 
     799                 : 
     800            1133 :         return 0;
     801                 : }
     802                 : /* }}} */
     803                 : 
     804                 : /* {{{ php_oci_bind_post_exec() 
     805                 :  Helper function */
     806                 : int php_oci_bind_post_exec(void *data TSRMLS_DC)
     807            1129 : {
     808            1129 :         php_oci_bind *bind = (php_oci_bind *) data;
     809            1129 :         php_oci_connection *connection = bind->parent_statement->connection;
     810                 : 
     811            1129 :         if (bind->indicator == -1) { /* NULL */
     812               3 :                 zval *val = bind->zval;
     813               3 :                 if (Z_TYPE_P(val) == IS_STRING) {
     814               1 :                         *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */
     815                 :                 }
     816               3 :                 zval_dtor(val);
     817               3 :                 ZVAL_NULL(val);
     818            1845 :         } else if (Z_TYPE_P(bind->zval) == IS_STRING && Z_STRLEN_P(bind->zval) > 0) {
     819             719 :                 Z_STRVAL_P(bind->zval) = erealloc(Z_STRVAL_P(bind->zval), Z_STRLEN_P(bind->zval)+1);
     820             719 :                 Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0';
     821             407 :         } else if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
     822                 :                 int i;
     823                 :                 zval **entry;
     824              15 :                 HashTable *hash = HASH_OF(bind->zval);
     825                 :         
     826              15 :                 zend_hash_internal_pointer_reset(hash);
     827                 : 
     828              15 :                 switch (bind->array.type) {
     829                 :                         case SQLT_NUM:
     830                 :                         case SQLT_INT:
     831                 :                         case SQLT_LNG:
     832              18 :                                 for (i = 0; i < bind->array.current_length; i++) {
     833              25 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
     834              10 :                                                 zval_dtor(*entry);
     835              10 :                                                 ZVAL_LONG(*entry, ((ub4 *)(bind->array.elements))[i]);
     836              10 :                                                 zend_hash_move_forward(hash);
     837                 :                                         } else {
     838               5 :                                                 add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
     839                 :                                         }
     840                 :                                 }
     841               3 :                                 break;
     842                 :                         case SQLT_FLT:
     843              12 :                                 for (i = 0; i < bind->array.current_length; i++) {
     844              20 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
     845              10 :                                                 zval_dtor(*entry);
     846              10 :                                                 ZVAL_DOUBLE(*entry, ((double *)(bind->array.elements))[i]);
     847              10 :                                                 zend_hash_move_forward(hash);
     848                 :                                         } else {
     849               0 :                                                 add_next_index_double(bind->zval, ((double *)(bind->array.elements))[i]);
     850                 :                                         }
     851                 :                                 }
     852               2 :                                 break;
     853                 :                         case SQLT_ODT:
     854              12 :                                 for (i = 0; i < bind->array.current_length; i++) {
     855                 :                                         oratext buff[1024];
     856              10 :                                         ub4 buff_len = 1024;
     857                 : 
     858              10 :                                         memset((void*)buff,0,sizeof(buff));
     859                 :                                                         
     860              20 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
     861              10 :                                                 PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
     862              10 :                                                 zval_dtor(*entry);
     863                 : 
     864              10 :                                                 if (connection->errcode != OCI_SUCCESS) {
     865               0 :                                                         php_oci_error(connection->err, connection->errcode TSRMLS_CC);
     866               0 :                                                         ZVAL_NULL(*entry);
     867                 :                                                 } else {
     868              10 :                                                         ZVAL_STRINGL(*entry, (char *)buff, buff_len, 1);
     869                 :                                                 }
     870              10 :                                                 zend_hash_move_forward(hash);
     871                 :                                         } else {
     872               0 :                                                 PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
     873               0 :                                                 if (connection->errcode != OCI_SUCCESS) {
     874               0 :                                                         php_oci_error(connection->err, connection->errcode TSRMLS_CC);
     875               0 :                                                         add_next_index_null(bind->zval);
     876                 :                                                 } else {
     877               0 :                                                         add_next_index_stringl(bind->zval, (char *)buff, buff_len, 1);
     878                 :                                                 }
     879                 :                                         }
     880                 :                                 }
     881               2 :                                 break;
     882                 :         
     883                 :                         case SQLT_AFC:
     884                 :                         case SQLT_CHR:
     885                 :                         case SQLT_VCS:
     886                 :                         case SQLT_AVC:
     887                 :                         case SQLT_STR:
     888                 :                         case SQLT_LVC:
     889              48 :                                 for (i = 0; i < bind->array.current_length; i++) {
     890                 :                                         /* int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); */
     891              40 :                                         int curr_element_length = bind->array.element_lengths[i];
     892              75 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
     893              35 :                                                 zval_dtor(*entry);
     894              35 :                                                 ZVAL_STRINGL(*entry, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
     895              35 :                                                 zend_hash_move_forward(hash);
     896                 :                                         } else {
     897               5 :                                                 add_next_index_stringl(bind->zval, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
     898                 :                                         }
     899                 :                                 }
     900                 :                                 break;
     901                 :                 }
     902                 :         }
     903                 : 
     904            1129 :         return 0;
     905                 : }
     906                 : /* }}} */
     907                 : 
     908                 : /* {{{ php_oci_bind_by_name() 
     909                 :  Bind zval to the given placeholder */
     910                 : int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long maxlength, long type TSRMLS_DC)
     911             309 : {
     912                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS 
     913             309 :         php_oci_collection *bind_collection = NULL;
     914                 : #endif
     915             309 :         php_oci_descriptor *bind_descriptor = NULL;
     916             309 :         php_oci_statement  *bind_statement  = NULL;
     917             309 :         dvoid *oci_desc                 = NULL;
     918                 :         /* dvoid *php_oci_collection           = NULL; */
     919             309 :         OCIStmt *oci_stmt               = NULL;
     920             309 :         dvoid *bind_data                = NULL;
     921                 :         php_oci_bind bind, *old_bind, *bindp;
     922             309 :         int mode = OCI_DATA_AT_EXEC;
     923             309 :         sb4 value_sz = -1;
     924                 : 
     925             309 :         switch (type) {
     926                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
     927                 :                 case SQLT_NTY:
     928                 :                 {
     929                 :                         zval **tmp;
     930                 :                         
     931               1 :                         if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
     932               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
     933               0 :                                 return 1;
     934                 :                         }
     935                 : 
     936               1 :                         PHP_OCI_ZVAL_TO_COLLECTION_EX(*tmp, bind_collection);
     937               1 :                         value_sz = sizeof(void*);
     938               1 :                         mode = OCI_DEFAULT;
     939                 :                 
     940               1 :                         if (!bind_collection->collection) {
     941               0 :                                 return 1;
     942                 :                         }
     943                 :                 }
     944               1 :                         break;
     945                 : #endif
     946                 :                 case SQLT_BFILEE:
     947                 :                 case SQLT_CFILEE:
     948                 :                 case SQLT_CLOB:
     949                 :                 case SQLT_BLOB:
     950                 :                 case SQLT_RDD:
     951                 :                 {
     952                 :                         zval **tmp;
     953                 :                         
     954             176 :                         if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
     955               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
     956               0 :                                 return 1;
     957                 :                         }
     958                 : 
     959             176 :                         PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, bind_descriptor);
     960                 : 
     961             176 :                         value_sz = sizeof(void*);
     962                 :                         
     963             176 :                         oci_desc = bind_descriptor->descriptor;
     964                 :                         
     965             176 :                         if (!oci_desc) {
     966               0 :                                 return 1;
     967                 :                         }
     968                 :                 }
     969             176 :                         break;
     970                 :                         
     971                 :                 case SQLT_INT:
     972                 :                 case SQLT_NUM:
     973               2 :                         convert_to_long(var);
     974               2 :                         bind_data = (ub4 *)&Z_LVAL_P(var);
     975               2 :                         value_sz = sizeof(ub4);
     976               2 :                         mode = OCI_DEFAULT;
     977               2 :                         break;
     978                 :                         
     979                 :                 case SQLT_LBI:
     980                 :                 case SQLT_BIN:
     981                 :                 case SQLT_LNG:
     982                 :                 case SQLT_CHR:
     983                 :                         /* this is the default case when type was not specified */
     984             124 :                         if (Z_TYPE_P(var) != IS_NULL) {
     985             115 :                                 convert_to_string(var);
     986                 :                         }
     987             124 :                         if (maxlength == -1) {
     988             119 :                                 value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0;
     989                 :                         } else {
     990               5 :                                 value_sz = maxlength;
     991                 :                         }
     992             124 :                         break;
     993                 : 
     994                 :                 case SQLT_RSET:
     995               6 :                         PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement);
     996               6 :                         value_sz = sizeof(void*);
     997                 : 
     998               6 :                         oci_stmt = bind_statement->stmt;
     999                 : 
    1000               6 :                         if (!oci_stmt) {
    1001               0 :                                 return 1;
    1002                 :                         }
    1003               6 :                         break;
    1004                 : 
    1005                 :                 default:
    1006               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %ld", type);
    1007               0 :                         return 1;
    1008                 :                         break;
    1009                 :         }
    1010                 :         
    1011             309 :         if (value_sz == 0) { 
    1012               7 :                 value_sz = 1;
    1013                 :         }
    1014                 :         
    1015             309 :         if (!statement->binds) {
    1016             199 :                 ALLOC_HASHTABLE(statement->binds);
    1017             199 :                 zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
    1018                 :         }
    1019                 : 
    1020             309 :         memset((void*)&bind,0,sizeof(php_oci_bind));
    1021             309 :         if (zend_hash_find(statement->binds, name, name_len + 1, (void **)&old_bind) == SUCCESS) {
    1022               2 :                 bindp = old_bind;
    1023               2 :                 if (bindp->zval) {
    1024               2 :                         zval_ptr_dtor(&bindp->zval);
    1025                 :                 }
    1026                 :         } else {
    1027             307 :                 zend_hash_update(statement->binds, name, name_len + 1, &bind, sizeof(php_oci_bind), (void **)&bindp);
    1028                 :         }
    1029                 :         
    1030             309 :         bindp->descriptor = oci_desc;
    1031             309 :         bindp->statement = oci_stmt;
    1032             309 :         bindp->parent_statement = statement;
    1033             309 :         bindp->zval = var;
    1034             309 :         zval_add_ref(&var); 
    1035                 :         
    1036             309 :         PHP_OCI_CALL_RETURN(statement->errcode, 
    1037                 :                 OCIBindByName,
    1038                 :                 (
    1039                 :                         statement->stmt,                /* statement handle */
    1040                 :                         (OCIBind **)&bindp->bind,       /* bind hdl (will alloc) */
    1041                 :                         statement->err,               /* error handle */
    1042                 :                         (text*) name,                    /* placeholder name */                                   
    1043                 :                         name_len,                        /* placeholder length */
    1044                 :                         (dvoid *)bind_data,              /* in/out data */
    1045                 :                         value_sz, /* PHP_OCI_MAX_DATA_SIZE, */ /* max size of input/output data */
    1046                 :                         (ub2)type,                       /* in/out data type */
    1047                 :                         (dvoid *)&bindp->indicator,      /* indicator (ignored) */
    1048                 :                         (ub2 *)0,                        /* size array (ignored) */
    1049                 :                         (ub2 *)&bindp->retcode,          /* return code (ignored) */
    1050                 :                         (ub4)0,                          /* maxarr_len (PL/SQL only?) */
    1051                 :                         (ub4 *)0,                        /* actual array size (PL/SQL only?) */
    1052                 :                         mode                             /* mode */
    1053                 :                 )
    1054                 :         );
    1055                 : 
    1056             309 :         if (statement->errcode != OCI_SUCCESS) {
    1057               1 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1058               1 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1059               1 :                 return 1;
    1060                 :         }
    1061                 : 
    1062             308 :         if (mode == OCI_DATA_AT_EXEC) {
    1063             305 :                 PHP_OCI_CALL_RETURN(statement->errcode, OCIBindDynamic, 
    1064                 :                                 (
    1065                 :                                  bindp->bind,
    1066                 :                                  statement->err,
    1067                 :                                  (dvoid *)bindp,
    1068                 :                                  php_oci_bind_in_callback,
    1069                 :                                  (dvoid *)bindp,
    1070                 :                                  php_oci_bind_out_callback
    1071                 :                                 )
    1072                 :                 );
    1073                 : 
    1074             305 :                 if (statement->errcode != OCI_SUCCESS) {
    1075               0 :                         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1076               0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1077               0 :                         return 1;
    1078                 :                 }
    1079                 :         }
    1080                 : 
    1081                 : #ifdef PHP_OCI8_HAVE_COLLECTIONS
    1082             308 :         if (type == SQLT_NTY) {
    1083                 :                 /* Bind object */
    1084               1 :                 PHP_OCI_CALL_RETURN(statement->errcode, OCIBindObject, 
    1085                 :                                 (
    1086                 :                                  bindp->bind,
    1087                 :                                  statement->err,
    1088                 :                                  bind_collection->tdo,
    1089                 :                                  (dvoid **) &(bind_collection->collection),
    1090                 :                                  (ub4 *) 0,
    1091                 :                                  (dvoid **) 0,
    1092                 :                                  (ub4 *) 0
    1093                 :                                 )
    1094                 :                 );
    1095                 :                 
    1096               1 :                 if (statement->errcode) {
    1097               0 :                         php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1098               0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1099               0 :                         return 1;
    1100                 :                 }
    1101                 :         }
    1102                 : #endif
    1103                 :         
    1104             308 :         return 0;
    1105                 : } /* }}} */
    1106                 : 
    1107                 : /* {{{ php_oci_bind_in_callback() 
    1108                 :  Callback used when binding LOBs and VARCHARs */
    1109                 : sb4 php_oci_bind_in_callback(
    1110                 :                                         dvoid *ictxp,     /* context pointer */
    1111                 :                                         OCIBind *bindp,   /* bind handle */
    1112                 :                                         ub4 iter,         /* 0-based execute iteration value */
    1113                 :                                         ub4 index,        /* index of current array for PL/SQL or row index for SQL */
    1114                 :                                         dvoid **bufpp,    /* pointer to data */
    1115                 :                                         ub4 *alenp,       /* size after value/piece has been read */
    1116                 :                                         ub1 *piecep,      /* which piece */
    1117                 :                                         dvoid **indpp)    /* indicator value */
    1118             307 : {
    1119                 :         php_oci_bind *phpbind;
    1120                 :         zval *val;
    1121                 :         TSRMLS_FETCH();
    1122                 : 
    1123             307 :         if (!(phpbind=(php_oci_bind *)ictxp) || !(val = phpbind->zval)) {
    1124               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
    1125               0 :                 return OCI_ERROR;
    1126                 :         }
    1127                 : 
    1128             307 :         if (ZVAL_IS_NULL(val)) {
    1129                 :                 /* we're going to insert a NULL column */
    1130               6 :                 phpbind->indicator = -1;
    1131               6 :                 *bufpp = 0;
    1132               6 :                 *alenp = -1;
    1133               6 :                 *indpp = (dvoid *)&phpbind->indicator;
    1134             425 :         } else  if ((phpbind->descriptor == 0) && (phpbind->statement == 0)) {
    1135                 :                 /* "normal string bind */
    1136             124 :                 convert_to_string(val); 
    1137                 : 
    1138             124 :                 *bufpp = Z_STRVAL_P(val);
    1139             124 :                 *alenp = Z_STRLEN_P(val);
    1140             124 :                 *indpp = (dvoid *)&phpbind->indicator;
    1141             177 :         } else if (phpbind->statement != 0) {
    1142                 :                 /* RSET */
    1143               3 :                 *bufpp = phpbind->statement;
    1144               3 :                 *alenp = -1;            /* seems to be allright */
    1145               3 :                 *indpp = (dvoid *)&phpbind->indicator;
    1146                 :         } else { 
    1147                 :                 /* descriptor bind */
    1148             174 :                 *bufpp = phpbind->descriptor;
    1149             174 :                 *alenp = -1;            /* seems to be allright */
    1150             174 :                 *indpp = (dvoid *)&phpbind->indicator;
    1151                 :         }
    1152                 : 
    1153             307 :         *piecep = OCI_ONE_PIECE; /* pass all data in one go */
    1154                 : 
    1155             307 :         return OCI_CONTINUE;
    1156                 : }/* }}} */
    1157                 : 
    1158                 : /* {{{ php_oci_bind_out_callback()
    1159                 :  Callback used when binding LOBs and VARCHARs */
    1160                 : sb4 php_oci_bind_out_callback(
    1161                 :                                         dvoid *octxp,      /* context pointer */
    1162                 :                                         OCIBind *bindp,    /* bind handle */
    1163                 :                                         ub4 iter,          /* 0-based execute iteration value */
    1164                 :                                         ub4 index,         /* index of current array for PL/SQL or row index for SQL */
    1165                 :                                         dvoid **bufpp,     /* pointer to data */
    1166                 :                                         ub4 **alenpp,      /* size after value/piece has been read */
    1167                 :                                         ub1 *piecep,       /* which piece */
    1168                 :                                         dvoid **indpp,     /* indicator value */
    1169                 :                                         ub2 **rcodepp)     /* return code */
    1170             679 : {
    1171                 :         php_oci_bind *phpbind;
    1172                 :         zval *val;
    1173             679 :         sb4 retval = OCI_ERROR;
    1174                 :         TSRMLS_FETCH();
    1175                 : 
    1176             679 :         if (!(phpbind=(php_oci_bind *)octxp) || !(val = phpbind->zval)) {
    1177               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
    1178               0 :                 return retval;
    1179                 :         }
    1180                 : 
    1181             679 :         if (Z_TYPE_P(val) == IS_RESOURCE) {
    1182                 :                 /* Processing for ref-cursor out binds */
    1183               5 :                 if (phpbind->statement != NULL) {
    1184               5 :                         *bufpp = phpbind->statement;
    1185               5 :                         *alenpp = &phpbind->dummy_len;
    1186               5 :                         *piecep = OCI_ONE_PIECE;
    1187               5 :                         *rcodepp = &phpbind->retcode;
    1188               5 :                         *indpp = &phpbind->indicator;
    1189                 :                 }
    1190               5 :                 retval = OCI_CONTINUE;
    1191             674 :         } else if (Z_TYPE_P(val) == IS_OBJECT) {
    1192              74 :                 if (!phpbind->descriptor) {
    1193               0 :                         return OCI_ERROR;
    1194                 :                 }
    1195              74 :                 *alenpp = &phpbind->dummy_len;
    1196              74 :                 *bufpp = phpbind->descriptor;
    1197              74 :                 *piecep = OCI_ONE_PIECE;
    1198              74 :                 *rcodepp = &phpbind->retcode;
    1199              74 :                 *indpp = &phpbind->indicator;
    1200              74 :                 retval = OCI_CONTINUE;
    1201                 :         } else {
    1202             600 :                 convert_to_string(val);
    1203             600 :                 zval_dtor(val);
    1204                 :                 
    1205             600 :                 Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */
    1206             600 :                 Z_STRVAL_P(val) = ecalloc(1, Z_STRLEN_P(phpbind->zval) + 1);
    1207                 :                 
    1208                 :                 /* XXX we assume that zend-zval len has 4 bytes */
    1209             600 :                 *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval); 
    1210             600 :                 *bufpp = Z_STRVAL_P(phpbind->zval);
    1211             600 :                 *piecep = OCI_ONE_PIECE;
    1212             600 :                 *rcodepp = &phpbind->retcode;
    1213             600 :                 *indpp = &phpbind->indicator;
    1214             600 :                 retval = OCI_CONTINUE;
    1215                 :         }
    1216                 : 
    1217             679 :         return retval;
    1218                 : }
    1219                 : /* }}} */
    1220                 : 
    1221                 : /* {{{ php_oci_statement_get_column_helper() 
    1222                 :  Helper function to get column by name and index */
    1223                 : php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data)
    1224             279 : {
    1225                 :         zval *z_statement, *column_index;
    1226                 :         php_oci_statement *statement;
    1227                 :         php_oci_out_column *column;
    1228                 : 
    1229             279 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_statement, &column_index) == FAILURE) {
    1230               9 :                 return NULL;
    1231                 :         }
    1232                 : 
    1233             270 :         statement = (php_oci_statement *) zend_fetch_resource(&z_statement TSRMLS_CC, -1, "oci8 statement", NULL, 1, le_statement);
    1234                 : 
    1235             270 :         if (!statement) {
    1236               8 :                 return NULL;
    1237                 :         }
    1238                 : 
    1239             262 :         if (need_data && !statement->has_data) {
    1240               1 :                 return NULL;
    1241                 :         }
    1242                 :         
    1243             261 :         if (Z_TYPE_P(column_index) == IS_STRING) {
    1244              76 :                 column = php_oci_statement_get_column(statement, -1, Z_STRVAL_P(column_index), Z_STRLEN_P(column_index) TSRMLS_CC);
    1245              76 :                 if (!column) {
    1246               7 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column name \"%s\"", Z_STRVAL_P(column_index));
    1247               7 :                         return NULL;
    1248                 :                 }
    1249                 :         } else {
    1250                 :                 zval tmp;
    1251                 :                 /* NB: for PHP4 compat only, it should be using 'Z' instead */
    1252             185 :                 tmp = *column_index;
    1253             185 :                 zval_copy_ctor(&tmp);
    1254             185 :                 convert_to_long(&tmp);
    1255             185 :                 column = php_oci_statement_get_column(statement, Z_LVAL(tmp), NULL, 0 TSRMLS_CC);
    1256             185 :                 if (!column) {
    1257              14 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column index \"%ld\"", Z_LVAL(tmp));
    1258              14 :                         zval_dtor(&tmp);
    1259              14 :                         return NULL;
    1260                 :                 }
    1261             171 :                 zval_dtor(&tmp);
    1262                 :         }
    1263             240 :         return column;
    1264                 : } /* }}} */
    1265                 : 
    1266                 : /* {{{ php_oci_statement_get_type()
    1267                 :  Return type of the statement */
    1268                 : int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC)
    1269              26 : {
    1270                 :         ub2 statement_type;
    1271                 :         
    1272              26 :         *type = 0;
    1273                 :         
    1274              26 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
    1275                 : 
    1276              26 :         if (statement->errcode != OCI_SUCCESS) {
    1277               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1278               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1279               0 :                 return 1;
    1280                 :         }
    1281                 : 
    1282              26 :         *type = statement_type;
    1283                 : 
    1284              26 :         return 0;
    1285                 : } /* }}} */
    1286                 : 
    1287                 : /* {{{ php_oci_statement_get_numrows() 
    1288                 :  Get the number of rows fetched to the clientside (NOT the number of rows in the result set) */
    1289                 : int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC)
    1290              25 : {
    1291                 :         ub4 statement_numrows;
    1292                 :         
    1293              25 :         *numrows = 0;
    1294                 :         
    1295              25 :         PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err));
    1296                 : 
    1297              25 :         if (statement->errcode != OCI_SUCCESS) {
    1298               0 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1299               0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1300               0 :                 return 1;
    1301                 :         }
    1302                 : 
    1303              25 :         *numrows = statement_numrows;
    1304                 : 
    1305              25 :         return 0;
    1306                 : } /* }}} */
    1307                 : 
    1308                 : /* {{{ php_oci_bind_array_by_name() 
    1309                 :  Bind arrays to PL/SQL types */
    1310                 : int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC)
    1311              24 : {
    1312                 :         php_oci_bind *bind, *bindp;
    1313                 : 
    1314              24 :         convert_to_array(var);
    1315                 : 
    1316              24 :         if (maxlength < -1) {
    1317               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid max length value (%ld)", maxlength);
    1318               1 :                 return 1;
    1319                 :         }
    1320                 :         
    1321              23 :         switch(type) {
    1322                 :                 case SQLT_NUM:
    1323                 :                 case SQLT_INT:
    1324                 :                 case SQLT_LNG:
    1325               3 :                         bind = php_oci_bind_array_helper_number(var, max_table_length TSRMLS_CC);
    1326               3 :                         break;
    1327                 : 
    1328                 :                 case SQLT_FLT:
    1329               2 :                         bind = php_oci_bind_array_helper_double(var, max_table_length TSRMLS_CC);
    1330               2 :                         break;
    1331                 :                         
    1332                 :                 case SQLT_AFC:
    1333                 :                 case SQLT_CHR:
    1334                 :                 case SQLT_VCS:
    1335                 :                 case SQLT_AVC:
    1336                 :                 case SQLT_STR:
    1337                 :                 case SQLT_LVC:
    1338              12 :                         if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(var)) == 0) {
    1339               4 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must provide max length value for empty arrays");
    1340               4 :                                 return 1;
    1341                 :                         }
    1342               8 :                         bind = php_oci_bind_array_helper_string(var, max_table_length, maxlength TSRMLS_CC);
    1343               8 :                         break;
    1344                 :                 case SQLT_ODT:
    1345               5 :                         bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection TSRMLS_CC);
    1346               5 :                         break;
    1347                 :                 default:
    1348               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %ld", type);
    1349               1 :                         return 1;
    1350                 :                         break;
    1351                 :         }
    1352                 : 
    1353              18 :         if (bind == NULL) {
    1354                 :                 /* failed to generate bind struct */
    1355               1 :                 return 1;
    1356                 :         }
    1357                 :         
    1358              17 :         if (!statement->binds) {
    1359              17 :                 ALLOC_HASHTABLE(statement->binds);
    1360              17 :                 zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
    1361                 :         }
    1362                 : 
    1363              17 :         zend_hash_update(statement->binds, name, name_len + 1, bind, sizeof(php_oci_bind), (void **)&bindp);
    1364                 : 
    1365              17 :         bindp->descriptor = NULL;
    1366              17 :         bindp->statement = NULL;
    1367              17 :         bindp->parent_statement = statement;
    1368              17 :         bindp->bind = NULL;
    1369              17 :         bindp->zval = var;
    1370              17 :         bindp->array.type = type;
    1371              17 :         zval_add_ref(&var);
    1372                 : 
    1373              17 :         PHP_OCI_CALL_RETURN(statement->errcode, 
    1374                 :                                                         OCIBindByName, 
    1375                 :                                                         (
    1376                 :                                                                 statement->stmt,
    1377                 :                                                                 (OCIBind **)&bindp->bind,
    1378                 :                                                                 statement->err,
    1379                 :                                                                 (text *)name,
    1380                 :                                                                 name_len,
    1381                 :                                                                 (dvoid *) bindp->array.elements, 
    1382                 :                                                                 (sb4) bind->array.max_length,
    1383                 :                                                                 type,
    1384                 :                                                                 (dvoid *)bindp->array.indicators,
    1385                 :                                                                 (ub2 *)bind->array.element_lengths,
    1386                 :                                                                 (ub2 *)0, /* bindp->array.retcodes, */
    1387                 :                                                                 (ub4) max_table_length,
    1388                 :                                                                 (ub4 *) &(bindp->array.current_length),
    1389                 :                                                                 (ub4) OCI_DEFAULT
    1390                 :                                                         )
    1391                 :                                                 );
    1392                 :         
    1393                 :                 
    1394              17 :         if (statement->errcode != OCI_SUCCESS) {
    1395               1 :                 efree(bind);
    1396               1 :                 php_oci_error(statement->err, statement->errcode TSRMLS_CC);
    1397               1 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1398               1 :                 return 1;
    1399                 :         }
    1400              16 :         efree(bind);
    1401              16 :         return 0;
    1402                 : } /* }}} */
    1403                 : 
    1404                 : /* {{{ php_oci_bind_array_helper_string() 
    1405                 :  Bind arrays to PL/SQL types */
    1406                 : php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC)
    1407               8 : {
    1408                 :         php_oci_bind *bind;
    1409                 :         ub4 i;
    1410                 :         HashTable *hash;
    1411                 :         zval **entry;
    1412                 : 
    1413               8 :         hash = HASH_OF(var);
    1414                 : 
    1415               8 :         if (maxlength == -1) {
    1416               1 :                 zend_hash_internal_pointer_reset(hash);
    1417               7 :                 while (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
    1418               5 :                         convert_to_string_ex(entry);
    1419               5 :                         if (Z_STRLEN_PP(entry) > maxlength) {
    1420               2 :                                 maxlength = Z_STRLEN_PP(entry) + 1;
    1421                 :                         }
    1422               5 :                         zend_hash_move_forward(hash);
    1423                 :                 }
    1424                 :         }
    1425                 :         
    1426               8 :         bind = emalloc(sizeof(php_oci_bind));
    1427               8 :         bind->array.elements         = (text *)safe_emalloc(max_table_length * (maxlength + 1), sizeof(text), 0);
    1428               8 :         memset(bind->array.elements, 0, max_table_length * (maxlength + 1) * sizeof(text));
    1429               8 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1430               8 :         bind->array.old_length               = bind->array.current_length;
    1431               8 :         bind->array.max_length               = maxlength;
    1432               8 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1433               8 :         memset(bind->array.element_lengths, 0, max_table_length*sizeof(ub2));
    1434               8 :         bind->array.indicators               = safe_emalloc(max_table_length, sizeof(sb2), 0);
    1435               8 :         memset(bind->array.indicators, 0, max_table_length*sizeof(sb2));
    1436                 :         
    1437               8 :         zend_hash_internal_pointer_reset(hash);
    1438                 :         
    1439              43 :         for (i = 0; i < bind->array.current_length; i++) {
    1440              35 :                 if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
    1441              35 :                         convert_to_string_ex(entry);
    1442              35 :                         bind->array.element_lengths[i] = Z_STRLEN_PP(entry); 
    1443              35 :                         if (Z_STRLEN_PP(entry) == 0) {
    1444               5 :                                 bind->array.indicators[i] = -1;
    1445                 :                         }
    1446              35 :                         zend_hash_move_forward(hash);
    1447                 :                 } else {
    1448               0 :                         break;
    1449                 :                 }
    1450                 :         }
    1451                 : 
    1452               8 :         zend_hash_internal_pointer_reset(hash);
    1453              53 :         for (i = 0; i < max_table_length; i++) {
    1454              80 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1455                 :                         int element_length; 
    1456                 :                         
    1457              35 :                         convert_to_string_ex(entry);
    1458              35 :                         element_length = (maxlength > Z_STRLEN_PP(entry)) ? Z_STRLEN_PP(entry) : maxlength;
    1459                 :                         
    1460              35 :                         memcpy((text *)bind->array.elements + i*maxlength, Z_STRVAL_PP(entry), element_length);
    1461              35 :                         ((text *)bind->array.elements)[i*maxlength + element_length] = '\0';
    1462                 :                         
    1463              35 :                         zend_hash_move_forward(hash);
    1464                 :                 } else {
    1465              10 :                         ((text *)bind->array.elements)[i*maxlength] = '\0';
    1466                 :                 }
    1467                 :         }
    1468               8 :         zend_hash_internal_pointer_reset(hash);
    1469                 : 
    1470               8 :         return bind;
    1471                 : } /* }}} */
    1472                 : 
    1473                 : /* {{{ php_oci_bind_array_helper_number() 
    1474                 :  Bind arrays to PL/SQL types */
    1475                 : php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC)
    1476               3 : {
    1477                 :         php_oci_bind *bind;
    1478                 :         ub4 i;
    1479                 :         HashTable *hash;
    1480                 :         zval **entry;
    1481                 : 
    1482               3 :         hash = HASH_OF(var);
    1483                 : 
    1484               3 :         bind = emalloc(sizeof(php_oci_bind));
    1485               3 :         bind->array.elements         = (ub4 *)safe_emalloc(max_table_length, sizeof(ub4), 0);
    1486               3 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1487               3 :         bind->array.old_length               = bind->array.current_length;
    1488               3 :         bind->array.max_length               = sizeof(ub4);
    1489               3 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1490               3 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1491               3 :         bind->array.indicators               = NULL;
    1492                 :         
    1493               3 :         zend_hash_internal_pointer_reset(hash);
    1494              23 :         for (i = 0; i < max_table_length; i++) {
    1495              20 :                 if (i < bind->array.current_length) {
    1496              10 :                         bind->array.element_lengths[i] = sizeof(ub4);
    1497                 :                 }
    1498              30 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1499              10 :                         convert_to_long_ex(entry);
    1500              10 :                         ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_PP(entry);
    1501              10 :                         zend_hash_move_forward(hash);
    1502                 :                 } else {
    1503              10 :                         ((ub4 *)bind->array.elements)[i] = 0;
    1504                 :                 }
    1505                 :         }
    1506               3 :         zend_hash_internal_pointer_reset(hash);
    1507                 : 
    1508               3 :         return bind;
    1509                 : } /* }}} */
    1510                 : 
    1511                 : /* {{{ php_oci_bind_array_helper_double() 
    1512                 :  Bind arrays to PL/SQL types */
    1513                 : php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC)
    1514               2 : {
    1515                 :         php_oci_bind *bind;
    1516                 :         ub4 i;
    1517                 :         HashTable *hash;
    1518                 :         zval **entry;
    1519                 : 
    1520               2 :         hash = HASH_OF(var);
    1521                 : 
    1522               2 :         bind = emalloc(sizeof(php_oci_bind));
    1523               2 :         bind->array.elements         = (double *)safe_emalloc(max_table_length, sizeof(double), 0);
    1524               2 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1525               2 :         bind->array.old_length               = bind->array.current_length;
    1526               2 :         bind->array.max_length               = sizeof(double);
    1527               2 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1528               2 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1529               2 :         bind->array.indicators               = NULL;
    1530                 :         
    1531               2 :         zend_hash_internal_pointer_reset(hash);
    1532              17 :         for (i = 0; i < max_table_length; i++) {
    1533              15 :                 if (i < bind->array.current_length) {
    1534              10 :                         bind->array.element_lengths[i] = sizeof(double);
    1535                 :                 }
    1536              25 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1537              10 :                         convert_to_double_ex(entry);
    1538              10 :                         ((double *)bind->array.elements)[i] = (double) Z_DVAL_PP(entry);
    1539              10 :                         zend_hash_move_forward(hash);
    1540                 :                 } else {
    1541               5 :                         ((double *)bind->array.elements)[i] = 0;
    1542                 :                 }
    1543                 :         }
    1544               2 :         zend_hash_internal_pointer_reset(hash);
    1545                 : 
    1546               2 :         return bind;
    1547                 : } /* }}} */
    1548                 : 
    1549                 : /* {{{ php_oci_bind_array_helper_date() 
    1550                 :  Bind arrays to PL/SQL types */
    1551                 : php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC)
    1552               5 : {
    1553                 :         php_oci_bind *bind;
    1554                 :         ub4 i;
    1555                 :         HashTable *hash;
    1556                 :         zval **entry;
    1557                 : 
    1558               5 :         hash = HASH_OF(var);
    1559                 : 
    1560               5 :         bind = emalloc(sizeof(php_oci_bind));
    1561               5 :         bind->array.elements         = (OCIDate *)safe_emalloc(max_table_length, sizeof(OCIDate), 0);
    1562               5 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1563               5 :         bind->array.old_length               = bind->array.current_length;
    1564               5 :         bind->array.max_length               = sizeof(OCIDate);
    1565               5 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1566               5 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1567               5 :         bind->array.indicators               = NULL;
    1568                 : 
    1569               5 :         zend_hash_internal_pointer_reset(hash);
    1570              30 :         for (i = 0; i < max_table_length; i++) {
    1571                 :                 OCIDate oci_date;
    1572              26 :                 if (i < bind->array.current_length) {
    1573              15 :                         bind->array.element_lengths[i] = sizeof(OCIDate);
    1574                 :                 }
    1575              40 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1576                 :                         
    1577              15 :                         convert_to_string_ex(entry);
    1578              15 :                         PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date));
    1579                 : 
    1580              15 :                         if (connection->errcode != OCI_SUCCESS) {
    1581                 :                                 /* failed to convert string to date */
    1582               1 :                                 efree(bind->array.element_lengths);
    1583               1 :                                 efree(bind->array.elements);
    1584               1 :                                 efree(bind);
    1585               1 :                                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1586               1 :                                 return NULL;
    1587                 :                         }
    1588                 :                         
    1589              14 :                         ((OCIDate *)bind->array.elements)[i] = oci_date;
    1590              14 :                         zend_hash_move_forward(hash);
    1591                 :                 } else {
    1592              11 :                         PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)"01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date));
    1593                 : 
    1594              11 :                         if (connection->errcode != OCI_SUCCESS) {
    1595                 :                                 /* failed to convert string to date */
    1596               0 :                                 efree(bind->array.element_lengths);
    1597               0 :                                 efree(bind->array.elements);
    1598               0 :                                 efree(bind);
    1599               0 :                                 php_oci_error(connection->err, connection->errcode TSRMLS_CC);
    1600               0 :                                 return NULL;
    1601                 :                         }
    1602                 :         
    1603              11 :                         ((OCIDate *)bind->array.elements)[i] = oci_date;
    1604                 :                 }
    1605                 :         }
    1606               4 :         zend_hash_internal_pointer_reset(hash);
    1607                 : 
    1608               4 :         return bind;
    1609                 : } /* }}} */
    1610                 : 
    1611                 : #endif /* HAVE_OCI8 */
    1612                 : 
    1613                 : /*
    1614                 :  * Local variables:
    1615                 :  * tab-width: 4
    1616                 :  * c-basic-offset: 4
    1617                 :  * End:
    1618                 :  * vim600: noet sw=4 ts=4 fdm=marker
    1619                 :  * vim<600: noet sw=4 ts=4
    1620                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:13 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.