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

LCOV - code coverage report
Current view: top level - ext/pdo_firebird - firebird_statement.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 171 342 50.0 %
Date: 2014-11-10 Functions: 8 12 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 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             :   | Author: Ard Biesheuvel <abies@php.net>                               |
      16             :   +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : #include "config.h"
      21             : #endif
      22             : 
      23             : #include "php.h"
      24             : #include "php_ini.h"
      25             : #include "ext/standard/info.h"
      26             : #include "pdo/php_pdo.h"
      27             : #include "pdo/php_pdo_driver.h"
      28             : #include "php_pdo_firebird.h"
      29             : #include "php_pdo_firebird_int.h"
      30             : 
      31             : #include <time.h>
      32             :         
      33             : #define RECORD_ERROR(stmt) _firebird_error(NULL, stmt,  __FILE__, __LINE__ TSRMLS_CC)
      34             : 
      35             : /* free the allocated space for passing field values to the db and back */
      36         125 : static void free_sqlda(XSQLDA const *sqlda) /* {{{ */
      37             : {
      38             :         int i;
      39             :         
      40         322 :         for (i = 0; i < sqlda->sqld; ++i) {
      41         197 :                 XSQLVAR const *var = &sqlda->sqlvar[i];
      42             :                 
      43         197 :                 if (var->sqlind) {
      44         191 :                         efree(var->sqlind);
      45             :                 }
      46             :         }
      47         125 : }
      48             : /* }}} */
      49             :         
      50             : /* called by PDO to clean up a statement handle */
      51         102 : static int firebird_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
      52             : {
      53         102 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
      54         102 :         int result = 1, i;
      55             :         
      56             :         /* release the statement */
      57         102 :         if (isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_drop)) {
      58           0 :                 RECORD_ERROR(stmt);
      59           0 :                 result = 0;
      60             :         }
      61             : 
      62             :         /* clean up the fetch buffers if they have been used */
      63         254 :         for (i = 0; i < S->out_sqlda.sqld; ++i) {
      64         152 :                 if (S->fetch_buf[i]) {
      65          46 :                         efree(S->fetch_buf[i]);
      66             :                 }
      67             :         }
      68         102 :         efree(S->fetch_buf);
      69             :         
      70         102 :         zend_hash_destroy(S->named_params);
      71         102 :         FREE_HASHTABLE(S->named_params);
      72             :         
      73             :         /* clean up the input descriptor */
      74         102 :         if (S->in_sqlda) {
      75          23 :                 free_sqlda(S->in_sqlda);
      76          23 :                 efree(S->in_sqlda);
      77             :         }
      78             : 
      79         102 :         free_sqlda(&S->out_sqlda);
      80         102 :         efree(S);
      81             :         
      82         102 :         return result;
      83             : }
      84             : /* }}} */
      85             : 
      86             : /* called by PDO to execute a prepared query */
      87         172 : static int firebird_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
      88             : {
      89         172 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
      90         172 :         pdo_firebird_db_handle *H = S->H;
      91         172 :         zend_ulong affected_rows = 0;
      92             :         static char info_count[] = {isc_info_sql_records};
      93             :         char result[64];
      94             : 
      95             :         do {
      96             :                 /* named or open cursors should be closed first */
      97         172 :                 if ((*S->name || S->cursor_open) && isc_dsql_free_statement(H->isc_status, &S->stmt, DSQL_close)) {
      98           0 :                         break;
      99             :                 }
     100         172 :                 S->cursor_open = 0;
     101             :                 /* assume all params have been bound */
     102             :         
     103         172 :                 if (isc_dsql_execute(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION, S->in_sqlda)) {
     104           0 :                         break;
     105             :                 }
     106             :                 
     107             :                 /* Determine how many rows have changed. In this case we are
     108             :                  * only interested in rows changed, not rows retrieved. That
     109             :                  * should be handled by the client when fetching. */
     110         172 :                 stmt->row_count = affected_rows;
     111             :                 
     112         172 :                 switch (S->statement_type) {
     113             :                         case isc_info_sql_stmt_insert:
     114             :                         case isc_info_sql_stmt_update:
     115             :                         case isc_info_sql_stmt_delete:
     116             :                         case isc_info_sql_stmt_exec_procedure:
     117          45 :                                 if (isc_dsql_sql_info(H->isc_status, &S->stmt, sizeof ( info_count),
     118             :                                         info_count, sizeof(result), result)) {
     119           0 :                                         break;
     120             :                                 }
     121          45 :                                 if (result[0] == isc_info_sql_records) {
     122          45 :                                         unsigned i = 3, result_size = isc_vax_integer(&result[1], 2);
     123         270 :                                         while (result[i] != isc_info_end && i < result_size) {
     124         180 :                                                 short len = (short) isc_vax_integer(&result[i + 1], 2);
     125         180 :                                                 if (result[i] != isc_info_req_select_count) {
     126         135 :                                                         affected_rows += isc_vax_integer(&result[i + 3], len);
     127             :                                                 }
     128         180 :                                                 i += len + 3;
     129             :                                         }
     130          45 :                                         stmt->row_count = affected_rows;
     131             :                                 }
     132             :                         default:
     133             :                                 ;
     134             :                 }
     135             : 
     136             :                 /* commit? */
     137         172 :                 if (stmt->dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
     138           0 :                         break;
     139             :                 }
     140             :         
     141         172 :                 *S->name = 0;
     142         172 :                 S->cursor_open = (S->out_sqlda.sqln > 0);      /* A cursor is opened, when more than zero columns returned */
     143         172 :                 S->exhausted = !S->cursor_open;
     144             :                 
     145         172 :                 return 1;
     146             :         } while (0);
     147             : 
     148           0 :         RECORD_ERROR(stmt);     
     149             : 
     150           0 :         return 0;
     151             : }
     152             : /* }}} */
     153             : 
     154             : /* called by PDO to fetch the next row from a statement */
     155         327 : static int firebird_stmt_fetch(pdo_stmt_t *stmt, /* {{{ */
     156             :         enum pdo_fetch_orientation ori, zend_long offset TSRMLS_DC)
     157             : {
     158         327 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     159         327 :         pdo_firebird_db_handle *H = S->H;
     160             : 
     161         327 :         if (!stmt->executed) {
     162           0 :                 strcpy(stmt->error_code, "HY000");
     163           0 :                 H->last_app_error = "Cannot fetch from a closed cursor";
     164         327 :         } else if (!S->exhausted) {
     165         326 :                 if (isc_dsql_fetch(H->isc_status, &S->stmt, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
     166          76 :                         if (H->isc_status[0] && H->isc_status[1]) {
     167           0 :                                 RECORD_ERROR(stmt);
     168             :                         }
     169          76 :                         S->exhausted = 1;
     170          76 :                         return 0;
     171             :                 }
     172         250 :                 if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
     173           0 :                         S->exhausted = 1;
     174             :                 }
     175         250 :                 stmt->row_count++;
     176         250 :                 return 1;
     177             :         }
     178           1 :         return 0;
     179             : }
     180             : /* }}} */
     181             : 
     182             : /* called by PDO to retrieve information about the fields being returned */
     183         146 : static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
     184             : {
     185         146 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     186         146 :         struct pdo_column_data *col = &stmt->columns[colno];
     187         146 :         XSQLVAR *var = &S->out_sqlda.sqlvar[colno];
     188             :         int colname_len;
     189             :         char *cp;
     190             :         
     191             :         /* allocate storage for the column */
     192         146 :         var->sqlind = (void*)ecalloc(1, var->sqllen + 2*sizeof(short));
     193         146 :         var->sqldata = &((char*)var->sqlind)[sizeof(short)];
     194             : 
     195         292 :         colname_len = (S->H->fetch_table_names && var->relname_length)
     196           0 :                                         ? (var->aliasname_length + var->relname_length + 1)
     197         146 :                                         : (var->aliasname_length);
     198         146 :         col->precision = -var->sqlscale;
     199         146 :         col->maxlen = var->sqllen;
     200         146 :         col->namelen = colname_len;
     201         146 :         col->name = cp = emalloc(colname_len + 1);
     202         146 :         if (colname_len > var->aliasname_length) {
     203           0 :                 memmove(cp, var->relname, var->relname_length);
     204           0 :                 cp += var->relname_length;
     205           0 :                 *cp++ = '.';
     206             :         }
     207         146 :         memmove(cp, var->aliasname, var->aliasname_length);
     208         146 :         *(cp+var->aliasname_length) = '\0';
     209         146 :         col->param_type = PDO_PARAM_STR;
     210             : 
     211         146 :         return 1;
     212             : }
     213             : /* }}} */
     214             : 
     215             : #define FETCH_BUF(buf,type,len,lenvar) ((buf) = (buf) ? (buf) : \
     216             :         emalloc((len) ? (len * sizeof(type)) : ((*(unsigned long*)lenvar) = sizeof(type))))
     217             : 
     218             : #define CHAR_BUF_LEN 24
     219             : 
     220             : /* fetch a blob into a fetch buffer */
     221           0 : static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ */
     222             :         zend_ulong *len, ISC_QUAD *blob_id TSRMLS_DC)
     223             : {
     224           0 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     225           0 :         pdo_firebird_db_handle *H = S->H;
     226           0 :         isc_blob_handle blobh = NULL;
     227           0 :         char const bl_item = isc_info_blob_total_length;
     228             :         char bl_info[20];
     229             :         unsigned short i;
     230           0 :         int result = *len = 0;
     231             : 
     232           0 :         if (isc_open_blob(H->isc_status, &H->db, &H->tr, &blobh, blob_id)) {
     233           0 :                 RECORD_ERROR(stmt);
     234           0 :                 return 0;
     235             :         }
     236             : 
     237           0 :         if (isc_blob_info(H->isc_status, &blobh, 1, const_cast(&bl_item),
     238             :                         sizeof(bl_info), bl_info)) {
     239           0 :                 RECORD_ERROR(stmt);
     240           0 :                 goto fetch_blob_end;
     241             :         }
     242             : 
     243             :         /* find total length of blob's data */
     244           0 :         for (i = 0; i < sizeof(bl_info); ) {
     245             :                 unsigned short item_len;
     246           0 :                 char item = bl_info[i++];
     247             : 
     248           0 :                 if (item == isc_info_end || item == isc_info_truncated || item == isc_info_error
     249             :                                 || i >= sizeof(bl_info)) {
     250           0 :                         H->last_app_error = "Couldn't determine BLOB size";
     251           0 :                         goto fetch_blob_end;
     252             :                 }                                                               
     253             : 
     254           0 :                 item_len = (unsigned short) isc_vax_integer(&bl_info[i], 2);
     255             : 
     256           0 :                 if (item == isc_info_blob_total_length) {
     257           0 :                         *len = isc_vax_integer(&bl_info[i+2], item_len);
     258           0 :                         break;
     259             :                 }
     260           0 :                 i += item_len+2;
     261             :         }
     262             : 
     263             :         /* we've found the blob's length, now fetch! */
     264             :         
     265           0 :         if (*len) {
     266             :                 zend_ulong cur_len;
     267             :                 unsigned short seg_len;
     268             :                 ISC_STATUS stat;
     269             : 
     270           0 :                 *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);
     271             :         
     272           0 :                 for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
     273             :         
     274           0 :                         unsigned short chunk_size = (*len-cur_len) > USHRT_MAX ? USHRT_MAX
     275           0 :                                 : (unsigned short)(*len-cur_len);
     276             :         
     277           0 :                         stat = isc_get_segment(H->isc_status, &blobh, &seg_len, chunk_size, &(*ptr)[cur_len]);
     278             :                 }
     279             :         
     280           0 :                 (*ptr)[*len++] = '\0';
     281             :         
     282           0 :                 if (H->isc_status[0] == 1 && (stat != 0 && stat != isc_segstr_eof && stat != isc_segment)) {
     283           0 :                         H->last_app_error = "Error reading from BLOB";
     284           0 :                         goto fetch_blob_end;
     285             :                 }
     286             :         }
     287           0 :         result = 1;
     288             : 
     289             : fetch_blob_end:
     290           0 :         if (isc_close_blob(H->isc_status, &blobh)) {
     291           0 :                 RECORD_ERROR(stmt);
     292           0 :                 return 0;
     293             :         }
     294           0 :         return result;
     295             : }
     296             : /* }}} */
     297             : 
     298         558 : static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,  /* {{{ */
     299             :         zend_ulong *len, int *caller_frees TSRMLS_DC)
     300             : {
     301         558 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     302         558 :         XSQLVAR const *var = &S->out_sqlda.sqlvar[colno];
     303             : 
     304         558 :         if (*var->sqlind == -1) {
     305             :                 /* A NULL value */
     306           7 :                 *ptr = NULL;
     307           7 :                 *len = 0;
     308             :         } else {
     309         551 :                 if (var->sqlscale < 0) {
     310             :                         static ISC_INT64 const scales[] = { 1, 10, 100, 1000, 
     311             :                                 10000, 
     312             :                                 100000, 
     313             :                                 1000000, 
     314             :                                 10000000,
     315             :                                 100000000, 
     316             :                                 1000000000, 
     317             :                                 LL_LIT(10000000000), 
     318             :                                 LL_LIT(100000000000),
     319             :                                 LL_LIT(1000000000000), 
     320             :                                 LL_LIT(10000000000000), 
     321             :                                 LL_LIT(100000000000000),
     322             :                                 LL_LIT(1000000000000000),
     323             :                                 LL_LIT(10000000000000000), 
     324             :                                 LL_LIT(100000000000000000), 
     325             :                                 LL_LIT(1000000000000000000)
     326             :                         };
     327           0 :                         ISC_INT64 n, f = scales[-var->sqlscale];
     328             : 
     329           0 :                         switch (var->sqltype & ~1) {
     330             :                                 case SQL_SHORT:
     331           0 :                                         n = *(short*)var->sqldata;
     332           0 :                                         break;
     333             :                                 case SQL_LONG:
     334           0 :                                         n = *(ISC_LONG*)var->sqldata;
     335           0 :                                         break;
     336             :                                 case SQL_INT64:
     337           0 :                                         n = *(ISC_INT64*)var->sqldata;
     338             :                         }
     339             :                                 
     340           0 :                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     341             :                         
     342           0 :                         if (n >= 0) {
     343           0 :                                 *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d", 
     344             :                                         n / f, -var->sqlscale, n % f);
     345           0 :                         } else if (n <= -f) {
     346           0 :                                 *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
     347           0 :                                         n / f, -var->sqlscale, -n % f);                              
     348             :                          } else {
     349           0 :                                 *len = slprintf(*ptr, CHAR_BUF_LEN, "-0.%0*" LL_MASK "d", -var->sqlscale, -n % f);
     350             :                         }
     351             :                 } else {
     352         551 :                         switch (var->sqltype & ~1) {
     353             :                                 struct tm t;
     354             :                                 char *fmt;                              
     355             : 
     356             :                                 case SQL_VARYING:
     357         329 :                                         *ptr = &var->sqldata[2];
     358         329 :                                         *len = *(short*)var->sqldata;
     359         329 :                                         break;
     360             :                                 case SQL_TEXT:
     361          11 :                                         *ptr = var->sqldata;
     362          11 :                                         *len = var->sqllen;
     363          11 :                                         break;
     364             :                                 case SQL_SHORT:
     365           0 :                                     *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     366           0 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%d", *(short*)var->sqldata);
     367           0 :                                         break;
     368             :                                 case SQL_LONG:
     369         211 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     370         211 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%ld", *(ISC_LONG*)var->sqldata);
     371         211 :                                         break;
     372             :                                 case SQL_INT64:
     373           0 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     374           0 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d", *(ISC_INT64*)var->sqldata);
     375           0 :                                         break;
     376             :                                 case SQL_FLOAT:
     377           0 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     378           0 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%F", *(float*)var->sqldata);
     379           0 :                                         break;
     380             :                                 case SQL_DOUBLE:
     381           0 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     382           0 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%F" , *(double*)var->sqldata);
     383           0 :                                         break;
     384             :                                 case SQL_TYPE_DATE:
     385           0 :                                         isc_decode_sql_date((ISC_DATE*)var->sqldata, &t);
     386           0 :                                         fmt = S->H->date_format ? S->H->date_format : PDO_FB_DEF_DATE_FMT;
     387           0 :                                         if (0) {
     388             :                                 case SQL_TYPE_TIME:
     389           0 :                                                 isc_decode_sql_time((ISC_TIME*)var->sqldata, &t);
     390           0 :                                                 fmt = S->H->time_format ? S->H->time_format : PDO_FB_DEF_TIME_FMT;
     391           0 :                                         } else if (0) {
     392             :                                 case SQL_TIMESTAMP:
     393           0 :                                                 isc_decode_timestamp((ISC_TIMESTAMP*)var->sqldata, &t);
     394           0 :                                                 fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT;
     395             :                                         }
     396             :                                         /* convert the timestamp into a string */
     397           0 :                                         *len = 80;
     398           0 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, *len, NULL);
     399           0 :                                         *len = strftime(*ptr, *len, fmt, &t);
     400           0 :                                         break;
     401             :                                 case SQL_BLOB:
     402           0 :                                         return firebird_fetch_blob(stmt,colno,ptr,len,
     403             :                                                 (ISC_QUAD*)var->sqldata TSRMLS_CC);
     404             :                         }
     405             :                 }
     406             :         }
     407         558 :         return 1;
     408             : }
     409             : /* }}} */
     410             : 
     411           0 : static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param TSRMLS_DC)
     412             : {
     413           0 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     414           0 :         pdo_firebird_db_handle *H = S->H;
     415           0 :         isc_blob_handle h = NULL;
     416           0 :         zend_ulong put_cnt = 0, rem_cnt;
     417             :         unsigned short chunk_size;
     418           0 :         int result = 1;
     419             :         
     420           0 :         if (isc_create_blob(H->isc_status, &H->db, &H->tr, &h, blob_id)) {
     421           0 :                 RECORD_ERROR(stmt);
     422           0 :                 return 0;
     423             :         }
     424             : 
     425           0 :         SEPARATE_ZVAL(param);
     426           0 :         convert_to_string_ex(param);
     427             :         
     428           0 :         for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size)  {
     429             : 
     430           0 :                 chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
     431             : 
     432           0 :                 if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL_P(param)[put_cnt])) {
     433           0 :                         RECORD_ERROR(stmt);
     434           0 :                         result = 0;
     435           0 :                         break;
     436             :                 }
     437           0 :                 put_cnt += chunk_size;
     438             :         }
     439             :         
     440             :         zval_dtor(param);
     441             : 
     442           0 :         if (isc_close_blob(H->isc_status, &h)) {
     443           0 :                 RECORD_ERROR(stmt);
     444           0 :                 return 0;
     445             :         }
     446           0 :         return result;
     447             : }       
     448             : 
     449         980 : static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, /* {{{ */
     450             :         enum pdo_param_event event_type TSRMLS_DC)
     451             : {
     452         980 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     453         980 :         XSQLDA *sqlda = param->is_param ? S->in_sqlda : &S->out_sqlda;
     454             :         XSQLVAR *var;
     455             : 
     456         980 :         if (event_type == PDO_PARAM_EVT_FREE) { /* not used */
     457         140 :                 return 1;
     458             :         }
     459             : 
     460         840 :         if (!sqlda || param->paramno >= sqlda->sqld) {
     461           0 :                 strcpy(stmt->error_code, "HY093");
     462           0 :                 S->H->last_app_error = "Invalid parameter index";
     463           0 :                 return 0;
     464             :         }
     465         840 :         if (param->is_param && param->paramno == -1) {
     466             :                 zval *index;
     467             : 
     468             :                 /* try to determine the index by looking in the named_params hash */
     469          44 :                 if ((index = zend_hash_find(S->named_params, param->name)) != NULL) {
     470          43 :                         param->paramno = Z_LVAL_P(index);
     471             :                 } else {
     472             :                         /* ... or by looking in the input descriptor */
     473             :                         int i;
     474             : 
     475           4 :                         for (i = 0; i < sqlda->sqld; ++i) {
     476           3 :                                 XSQLVAR *var = &sqlda->sqlvar[i];
     477             : 
     478           6 :                                 if ((var->aliasname_length && !strncasecmp(param->name->val, var->aliasname, 
     479           0 :                                                 min(param->name->len, var->aliasname_length))) 
     480           3 :                                                 || (var->sqlname_length && !strncasecmp(param->name->val, var->sqlname,
     481           0 :                                                 min(param->name->len, var->sqlname_length)))) {
     482           0 :                                         param->paramno = i;
     483           0 :                                         break;
     484             :                                 }
     485             :                         }
     486           1 :                         if (i >= sqlda->sqld) {
     487           1 :                                 strcpy(stmt->error_code, "HY093");
     488           1 :                                 S->H->last_app_error = "Invalid parameter name";
     489           1 :                                 return 0;
     490             :                         }
     491             :                 }
     492             :         }
     493             : 
     494         839 :         var = &sqlda->sqlvar[param->paramno];
     495             :         
     496         839 :         switch (event_type) {
     497             :                 char *value;
     498             :                 zend_ulong value_len;
     499             :                 int caller_frees;
     500             :                 zval *parameter;
     501             :                         
     502             :                 case PDO_PARAM_EVT_ALLOC:
     503         140 :                         if (param->is_param) {
     504             :                                 /* allocate the parameter */
     505         120 :                                 if (var->sqlind) {
     506          75 :                                         efree(var->sqlind);
     507             :                                 }
     508         120 :                                 var->sqlind = (void*)emalloc(var->sqllen + 2*sizeof(short));
     509         120 :                                 var->sqldata = &((char*)var->sqlind)[sizeof(short)];
     510             :                         }
     511         140 :                         break;
     512             :                         
     513             :                 case PDO_PARAM_EVT_EXEC_PRE:
     514         184 :                         if (!param->is_param) {
     515          33 :                                 break;
     516             :                         }
     517             : 
     518         151 :                         *var->sqlind = 0;
     519         302 :                         if (Z_ISREF(param->parameter)) {
     520          41 :                                 parameter = Z_REFVAL(param->parameter);
     521             :                         } else {
     522         110 :                                 parameter = &param->parameter;
     523             :                         }
     524             :                         
     525         151 :                         if (Z_TYPE_P(parameter) == IS_RESOURCE) {
     526             :                                 php_stream *stm;
     527             : 
     528           1 :                                 php_stream_from_zval_no_verify(stm, parameter);
     529           1 :                                 if (stm) {
     530           1 :                                         zval_ptr_dtor(parameter);
     531           1 :                                         ZVAL_STR(parameter, php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0));
     532             :                                 } else {
     533           0 :                                         pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
     534           0 :                                         return 0;
     535             :                                 }
     536             :                         }
     537             : 
     538         151 :                         switch (var->sqltype & ~1) {
     539             :                                 case SQL_ARRAY:
     540           0 :                                         strcpy(stmt->error_code, "HY000");
     541           0 :                                         S->H->last_app_error = "Cannot bind to array field";
     542           0 :                                         return 0;
     543             :         
     544             :                                 case SQL_BLOB:
     545           0 :                                         return firebird_bind_blob(stmt, (ISC_QUAD*)var->sqldata, parameter TSRMLS_CC);
     546             :                         }
     547             :                                                         
     548             :                         /* check if a NULL should be inserted */
     549         151 :                         switch (Z_TYPE_P(parameter)) {
     550             :                                 int force_null;
     551             :                                 
     552             :                                 case IS_LONG:
     553             :                                         /* keep the allow-NULL flag */
     554          21 :                                         var->sqltype = (sizeof(zend_long) == 8 ? SQL_INT64 : SQL_LONG) | (var->sqltype & 1);
     555          21 :                                         var->sqldata = (void*)&Z_LVAL_P(parameter);
     556          21 :                                         var->sqllen = sizeof(zend_long);
     557          21 :                                         break;
     558             :                                 case IS_DOUBLE:
     559             :                                         /* keep the allow-NULL flag */
     560           0 :                                         var->sqltype = SQL_DOUBLE | (var->sqltype & 1);
     561           0 :                                         var->sqldata = (void*)&Z_DVAL_P(parameter);
     562           0 :                                         var->sqllen = sizeof(double);
     563           0 :                                         break;
     564             :                                 case IS_STRING:
     565         128 :                                         force_null = 0;
     566             :         
     567             :                                         /* for these types, an empty string can be handled like a NULL value */
     568         128 :                                         switch (var->sqltype & ~1) {
     569             :                                                 case SQL_SHORT:
     570             :                                                 case SQL_LONG:
     571             :                                                 case SQL_INT64:
     572             :                                                 case SQL_FLOAT:
     573             :                                                 case SQL_DOUBLE:
     574             :                                                 case SQL_TIMESTAMP:
     575             :                                                 case SQL_TYPE_DATE:
     576             :                                                 case SQL_TYPE_TIME:
     577          13 :                                                         force_null = (Z_STRLEN_P(parameter) == 0);
     578             :                                         }
     579         128 :                                         if (!force_null) {
     580             :                                                 /* keep the allow-NULL flag */
     581         128 :                                                 var->sqltype = SQL_TEXT | (var->sqltype & 1);
     582         128 :                                                 var->sqldata = Z_STRVAL_P(parameter);
     583         128 :                                                 var->sqllen   = Z_STRLEN_P(parameter);
     584         128 :                                                 break;
     585             :                                         }
     586             :                                 case IS_NULL:
     587             :                                         /* complain if this field doesn't allow NULL values */
     588           2 :                                         if (~var->sqltype & 1) {
     589           0 :                                                 strcpy(stmt->error_code, "HY105");
     590           0 :                                                 S->H->last_app_error = "Parameter requires non-null value";
     591           0 :                                                 return 0;
     592             :                                         }
     593           2 :                                         *var->sqlind = -1;
     594           2 :                                         break;
     595             :                                 default:
     596           0 :                                         strcpy(stmt->error_code, "HY105");
     597           0 :                                         S->H->last_app_error = "Binding arrays/objects is not supported";
     598           0 :                                         return 0;
     599             :                         }
     600         151 :                         break;
     601             : 
     602             :                 case PDO_PARAM_EVT_FETCH_POST:
     603          89 :                         if (param->paramno == -1) {
     604           0 :                             return 0;
     605             :                         }
     606          89 :                         if (param->is_param) {
     607          30 :                                 break;
     608             :                         }
     609          59 :                         value = NULL;
     610          59 :                         value_len = 0;
     611          59 :                         caller_frees = 0;
     612         118 :                         if (Z_ISREF(param->parameter)) {
     613          59 :                                 parameter = Z_REFVAL(param->parameter);
     614             :                         } else {
     615           0 :                                 parameter = &param->parameter;
     616             :                         }
     617          59 :                         zval_ptr_dtor(parameter);
     618          59 :                         ZVAL_NULL(parameter);
     619             :                         
     620          59 :                         if (firebird_stmt_get_col(stmt, param->paramno, &value, &value_len, &caller_frees TSRMLS_CC)) {
     621          59 :                                 switch (PDO_PARAM_TYPE(param->param_type)) {
     622             :                                         case PDO_PARAM_STR:
     623          59 :                                                 if (value) {
     624         118 :                                                         ZVAL_STRINGL(parameter, value, value_len);
     625          59 :                                                         break;
     626             :                                                 }
     627             :                                         case PDO_PARAM_INT:
     628           0 :                                                 if (value) {
     629           0 :                                                         ZVAL_LONG(parameter, *(zend_long*)value);
     630           0 :                                                         break;
     631             :                                                 }
     632             :                                         case PDO_PARAM_EVT_NORMALIZE:
     633           0 :                                                          if (!param->is_param) {
     634           0 :                                                                   char *s = param->name->val;
     635           0 :                                                                   while (*s != '\0') {
     636           0 :                                                                            *s = toupper(*s);
     637           0 :                                                                                 s++;
     638             :                                                                   }
     639             :                                                          }
     640           0 :                                                 break;
     641             :                                         default:
     642           0 :                                                 ZVAL_NULL(parameter);
     643             :                                 }
     644          59 :                                 if (value && caller_frees) {
     645           0 :                                         efree(value);
     646             :                                 }
     647          59 :                                 return 1;
     648             :                         }
     649           0 :                         return 0;
     650             :                 default:
     651             :                         ;
     652             :         }               
     653         780 :         return 1;
     654             : }
     655             : /* }}} */
     656             : 
     657           0 : static int firebird_stmt_set_attribute(pdo_stmt_t *stmt, zend_long attr, zval *val TSRMLS_DC) /* {{{ */
     658             : {
     659           0 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     660             :         
     661           0 :         switch (attr) {
     662             :                 default:
     663           0 :                         return 0;
     664             :                 case PDO_ATTR_CURSOR_NAME:
     665           0 :                         convert_to_string(val);
     666             :                         
     667           0 :                         if (isc_dsql_set_cursor_name(S->H->isc_status, &S->stmt, Z_STRVAL_P(val),0)) {
     668           0 :                                 RECORD_ERROR(stmt);
     669           0 :                                 return 0;
     670             :                         }
     671           0 :                         strlcpy(S->name, Z_STRVAL_P(val), sizeof(S->name));
     672             :                         break;
     673             :         }
     674           0 :         return 1;
     675             : }
     676             : /* }}} */
     677             : 
     678           0 : static int firebird_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval *val TSRMLS_DC) /* {{{ */
     679             : {
     680           0 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     681             :         
     682           0 :         switch (attr) {
     683             :                 default:
     684           0 :                         return 0;
     685             :                 case PDO_ATTR_CURSOR_NAME:
     686           0 :                         if (*S->name) {
     687           0 :                                 ZVAL_STRING(val, S->name);
     688             :                         } else {
     689           0 :                                 ZVAL_NULL(val);
     690             :                         }
     691             :                         break;
     692             :         }
     693           0 :         return 1;
     694             : }
     695             : /* }}} */
     696             : 
     697          27 : static int firebird_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
     698             : {
     699          27 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     700             :         
     701             :         /* close the statement handle */
     702          27 :         if ((*S->name || S->cursor_open) && isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_close)) {
     703           0 :                 RECORD_ERROR(stmt);
     704           0 :                 return 0;
     705             :         }
     706          27 :         *S->name = 0;
     707          27 :         S->cursor_open = 0;
     708          27 :         return 1;
     709             : }
     710             : /* }}} */
     711             : 
     712             : 
     713             : struct pdo_stmt_methods firebird_stmt_methods = { /* {{{ */
     714             :         firebird_stmt_dtor,
     715             :         firebird_stmt_execute,
     716             :         firebird_stmt_fetch,
     717             :         firebird_stmt_describe,
     718             :         firebird_stmt_get_col,
     719             :         firebird_stmt_param_hook,
     720             :         firebird_stmt_set_attribute,
     721             :         firebird_stmt_get_attribute,
     722             :         NULL, /* get_column_meta_func */
     723             :         NULL, /* next_rowset_func */
     724             :         firebird_stmt_cursor_closer
     725             : };
     726             : /* }}} */
     727             : 
     728             : /*
     729             :  * Local variables:
     730             :  * tab-width: 4
     731             :  * c-basic-offset: 4
     732             :  * End:
     733             :  * vim600: noet sw=4 ts=4 fdm=marker
     734             :  * vim<600: noet sw=4 ts=4
     735             :  */

Generated by: LCOV version 1.10

Generated at Mon, 10 Nov 2014 22:46:44 +0000 (11 days ago)

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