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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:04 +0000 (3 days ago)

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