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: 188 328 57.3 %
Date: 2014-10-24 Functions: 9 12 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       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         141 : static void free_sqlda(XSQLDA const *sqlda) /* {{{ */
      37             : {
      38             :         int i;
      39             :         
      40         352 :         for (i = 0; i < sqlda->sqld; ++i) {
      41         211 :                 XSQLVAR const *var = &sqlda->sqlvar[i];
      42             :                 
      43         211 :                 if (var->sqlind) {
      44         205 :                         efree(var->sqlind);
      45             :                 }
      46             :         }
      47         141 : }
      48             : /* }}} */
      49             :         
      50             : /* called by PDO to clean up a statement handle */
      51         112 : static int firebird_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
      52             : {
      53         112 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
      54         112 :         int result = 1, i;
      55             :         
      56             :         /* release the statement */
      57         112 :         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         269 :         for (i = 0; i < S->out_sqlda.sqld; ++i) {
      64         157 :                 if (S->fetch_buf[i]) {
      65          48 :                         efree(S->fetch_buf[i]);
      66             :                 }
      67             :         }
      68         112 :         efree(S->fetch_buf);
      69             :         
      70         112 :         zend_hash_destroy(S->named_params);
      71         112 :         FREE_HASHTABLE(S->named_params);
      72             :         
      73             :         /* clean up the input descriptor */
      74         112 :         if (S->in_sqlda) {
      75          29 :                 free_sqlda(S->in_sqlda);
      76          29 :                 efree(S->in_sqlda);
      77             :         }
      78             : 
      79         112 :         free_sqlda(&S->out_sqlda);
      80         112 :         efree(S);
      81             :         
      82         112 :         return result;
      83             : }
      84             : /* }}} */
      85             : 
      86             : /* called by PDO to execute a prepared query */
      87         182 : static int firebird_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
      88             : {
      89         182 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
      90         182 :         pdo_firebird_db_handle *H = S->H;
      91         182 :         unsigned long 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         182 :                 if ((*S->name || S->cursor_open) && isc_dsql_free_statement(H->isc_status, &S->stmt, DSQL_close)) {
      98           0 :                         break;
      99             :                 }
     100         182 :                 S->cursor_open = 0;
     101             :                 /* assume all params have been bound */
     102             :         
     103         182 :                 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         182 :                 stmt->row_count = affected_rows;
     111             :                 
     112         182 :                 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          52 :                                 if (isc_dsql_sql_info(H->isc_status, &S->stmt, sizeof ( info_count),
     118             :                                         info_count, sizeof(result), result)) {
     119           0 :                                         break;
     120             :                                 }
     121          52 :                                 if (result[0] == isc_info_sql_records) {
     122          52 :                                         unsigned i = 3, result_size = isc_vax_integer(&result[1], 2);
     123         312 :                                         while (result[i] != isc_info_end && i < result_size) {
     124         208 :                                                 short len = (short) isc_vax_integer(&result[i + 1], 2);
     125         208 :                                                 if (result[i] != isc_info_req_select_count) {
     126         156 :                                                         affected_rows += isc_vax_integer(&result[i + 3], len);
     127             :                                                 }
     128         208 :                                                 i += len + 3;
     129             :                                         }
     130          52 :                                         stmt->row_count = affected_rows;
     131             :                                 }
     132             :                         default:
     133             :                                 ;
     134             :                 }
     135             : 
     136             :                 /* commit? */
     137         182 :                 if (stmt->dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
     138           0 :                         break;
     139             :                 }
     140             :         
     141         182 :                 *S->name = 0;
     142         182 :                 S->cursor_open = (S->out_sqlda.sqln > 0);      /* A cursor is opened, when more than zero columns returned */
     143         182 :                 S->exhausted = !S->cursor_open;
     144             :                 
     145         182 :                 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         339 : static int firebird_stmt_fetch(pdo_stmt_t *stmt, /* {{{ */
     156             :         enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
     157             : {
     158         339 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     159         339 :         pdo_firebird_db_handle *H = S->H;
     160             : 
     161         339 :         if (!stmt->executed) {
     162           0 :                 strcpy(stmt->error_code, "HY000");
     163           0 :                 H->last_app_error = "Cannot fetch from a closed cursor";
     164         339 :         } else if (!S->exhausted) {
     165         338 :                 if (isc_dsql_fetch(H->isc_status, &S->stmt, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
     166          81 :                         if (H->isc_status[0] && H->isc_status[1]) {
     167           0 :                                 RECORD_ERROR(stmt);
     168             :                         }
     169          81 :                         S->exhausted = 1;
     170          81 :                         return 0;
     171             :                 }
     172         257 :                 if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
     173           0 :                         S->exhausted = 1;
     174             :                 }
     175         257 :                 stmt->row_count++;
     176         257 :                 return 1;
     177             :         }
     178           1 :         return 0;
     179             : }
     180             : /* }}} */
     181             : 
     182             : /* called by PDO to retrieve information about the fields being returned */
     183         154 : static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
     184             : {
     185         154 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     186         154 :         struct pdo_column_data *col = &stmt->columns[colno];
     187         154 :         XSQLVAR *var = &S->out_sqlda.sqlvar[colno];
     188             :         int colname_len;
     189             :         char *cp;
     190             :         
     191             :         /* allocate storage for the column */
     192         154 :         var->sqlind = (void*)ecalloc(1, var->sqllen + 2*sizeof(short));
     193         154 :         var->sqldata = &((char*)var->sqlind)[sizeof(short)];
     194             : 
     195         308 :         colname_len = (S->H->fetch_table_names && var->relname_length)
     196           0 :                                         ? (var->aliasname_length + var->relname_length + 1)
     197         154 :                                         : (var->aliasname_length);
     198         154 :         col->precision = -var->sqlscale;
     199         154 :         col->maxlen = var->sqllen;
     200         154 :         col->namelen = colname_len;
     201         154 :         col->name = cp = emalloc(colname_len + 1);
     202         154 :         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         154 :         memmove(cp, var->aliasname, var->aliasname_length);
     208         154 :         *(cp+var->aliasname_length) = '\0';
     209         154 :         col->param_type = PDO_PARAM_STR;
     210             : 
     211         154 :         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             :         unsigned long *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             :                 unsigned long 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         575 : static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,  /* {{{ */
     299             :         unsigned long *len, int *caller_frees TSRMLS_DC)
     300             : {
     301         575 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     302         575 :         XSQLVAR const *var = &S->out_sqlda.sqlvar[colno];
     303             : 
     304         575 :         if (*var->sqlind == -1) {
     305             :                 /* A NULL value */
     306           7 :                 *ptr = NULL;
     307           7 :                 *len = 0;
     308             :         } else {
     309         568 :                 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           3 :                         ISC_INT64 n, f = scales[-var->sqlscale];
     328             : 
     329           3 :                         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           3 :                                         n = *(ISC_INT64*)var->sqldata;
     338             :                         }
     339             :                                 
     340           3 :                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     341             :                         
     342           3 :                         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           3 :                         } else if (n <= -f) {
     346           2 :                                 *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
     347           2 :                                         n / f, -var->sqlscale, -n % f);                              
     348             :                          } else {
     349           1 :                                 *len = slprintf(*ptr, CHAR_BUF_LEN, "-0.%0*" LL_MASK "d", -var->sqlscale, -n % f);
     350             :                         }
     351             :                 } else {
     352         565 :                         switch (var->sqltype & ~1) {
     353             :                                 struct tm t;
     354             :                                 char *fmt;                              
     355             : 
     356             :                                 case SQL_VARYING:
     357         339 :                                         *ptr = &var->sqldata[2];
     358         339 :                                         *len = *(short*)var->sqldata;
     359         339 :                                         break;
     360             :                                 case SQL_TEXT:
     361          11 :                                         *ptr = var->sqldata;
     362          11 :                                         *len = var->sqllen;
     363          11 :                                         break;
     364             :                                 case SQL_SHORT:
     365           1 :                                     *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     366           1 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%d", *(short*)var->sqldata);
     367           1 :                                         break;
     368             :                                 case SQL_LONG:
     369         213 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
     370         213 :                                         *len = slprintf(*ptr, CHAR_BUF_LEN, "%ld", *(ISC_LONG*)var->sqldata);
     371         213 :                                         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           1 :                                                 isc_decode_timestamp((ISC_TIMESTAMP*)var->sqldata, &t);
     394           1 :                                                 fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT;
     395             :                                         }
     396             :                                         /* convert the timestamp into a string */
     397           1 :                                         *len = 80;
     398           1 :                                         *ptr = FETCH_BUF(S->fetch_buf[colno], char, *len, NULL);
     399           1 :                                         *len = strftime(*ptr, *len, fmt, &t);
     400           1 :                                         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         575 :         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 :         unsigned long 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             : 
     427           0 :         convert_to_string_ex(&param);
     428             :         
     429           0 :         for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size)  {
     430             : 
     431           0 :                 chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
     432             : 
     433           0 :                 if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL_P(param)[put_cnt])) {
     434           0 :                         RECORD_ERROR(stmt);
     435           0 :                         result = 0;
     436           0 :                         break;
     437             :                 }
     438           0 :                 put_cnt += chunk_size;
     439             :         }
     440             :         
     441           0 :         zval_dtor(param);
     442             : 
     443           0 :         if (isc_close_blob(H->isc_status, &h)) {
     444           0 :                 RECORD_ERROR(stmt);
     445           0 :                 return 0;
     446             :         }
     447           0 :         return result;
     448             : }       
     449             : 
     450        1075 : static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, /* {{{ */
     451             :         enum pdo_param_event event_type TSRMLS_DC)
     452             : {
     453        1075 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     454        1075 :         XSQLDA *sqlda = param->is_param ? S->in_sqlda : &S->out_sqlda;
     455             :         XSQLVAR *var;
     456             : 
     457        1075 :         if (event_type == PDO_PARAM_EVT_FREE) { /* not used */
     458         154 :                 return 1;
     459             :         }
     460             : 
     461         921 :         if (!sqlda || param->paramno >= sqlda->sqld) {
     462           0 :                 strcpy(stmt->error_code, "HY093");
     463           0 :                 S->H->last_app_error = "Invalid parameter index";
     464           0 :                 return 0;
     465             :         }
     466         921 :         if (param->is_param && param->paramno == -1) {
     467             :                 long *index;
     468             : 
     469             :                 /* try to determine the index by looking in the named_params hash */
     470          44 :                 if (SUCCESS == zend_hash_find(S->named_params, param->name, param->namelen+1, (void*)&index)) {
     471          43 :                         param->paramno = *index;
     472             :                 } else {
     473             :                         /* ... or by looking in the input descriptor */
     474             :                         int i;
     475             : 
     476           4 :                         for (i = 0; i < sqlda->sqld; ++i) {
     477           3 :                                 XSQLVAR *var = &sqlda->sqlvar[i];
     478             : 
     479           6 :                                 if ((var->aliasname_length && !strncasecmp(param->name, var->aliasname, 
     480           0 :                                                 min(param->namelen, var->aliasname_length))) 
     481           3 :                                                 || (var->sqlname_length && !strncasecmp(param->name, var->sqlname,
     482           0 :                                                 min(param->namelen, var->sqlname_length)))) {
     483           0 :                                         param->paramno = i;
     484           0 :                                         break;
     485             :                                 }
     486             :                         }
     487           1 :                         if (i >= sqlda->sqld) {
     488           1 :                                 strcpy(stmt->error_code, "HY093");
     489           1 :                                 S->H->last_app_error = "Invalid parameter name";
     490           1 :                                 return 0;
     491             :                         }
     492             :                 }
     493             :         }
     494             : 
     495         920 :         var = &sqlda->sqlvar[param->paramno];
     496             :         
     497         920 :         switch (event_type) {
     498             :                 char *value;
     499             :                 unsigned long value_len;
     500             :                 int caller_frees;
     501             :                         
     502             :                 case PDO_PARAM_EVT_ALLOC:
     503         154 :                         if (param->is_param) {
     504             :                                 /* allocate the parameter */
     505         131 :                                 if (var->sqlind) {
     506          77 :                                         efree(var->sqlind);
     507             :                                 }
     508         131 :                                 var->sqlind = (void*)emalloc(var->sqllen + 2*sizeof(short));
     509         131 :                                 var->sqldata = &((char*)var->sqlind)[sizeof(short)];
     510             :                         }
     511         154 :                         break;
     512             :                         
     513             :                 case PDO_PARAM_EVT_EXEC_PRE:
     514         197 :                         if (!param->is_param) {
     515          36 :                                 break;
     516             :                         }
     517             : 
     518         161 :                         *var->sqlind = 0;
     519             : 
     520         161 :                         switch (var->sqltype & ~1) {
     521             :                                 case SQL_ARRAY:
     522           0 :                                         strcpy(stmt->error_code, "HY000");
     523           0 :                                         S->H->last_app_error = "Cannot bind to array field";
     524           0 :                                         return 0;
     525             :         
     526             :                                 case SQL_BLOB:
     527           0 :                                         return firebird_bind_blob(stmt, (ISC_QUAD*)var->sqldata,
     528             :                                                 param->parameter TSRMLS_CC);
     529             :                         }
     530             :                                                         
     531             :                         /* check if a NULL should be inserted */
     532         161 :                         switch (Z_TYPE_P(param->parameter)) {
     533             :                                 int force_null;
     534             :                                 
     535             :                                 case IS_LONG:
     536             :                                         /* keep the allow-NULL flag */
     537          20 :                                         var->sqltype = (sizeof(long) == 8 ? SQL_INT64 : SQL_LONG) | (var->sqltype & 1);
     538          20 :                                         var->sqldata = (void*)&Z_LVAL_P(param->parameter);
     539          20 :                                         var->sqllen = sizeof(long);
     540          20 :                                         break;
     541             :                                 case IS_DOUBLE:
     542             :                                         /* keep the allow-NULL flag */
     543           0 :                                         var->sqltype = SQL_DOUBLE | (var->sqltype & 1);
     544           0 :                                         var->sqldata = (void*)&Z_DVAL_P(param->parameter);
     545           0 :                                         var->sqllen = sizeof(double);
     546           0 :                                         break;
     547             :                                 case IS_STRING:
     548         137 :                                         force_null = 0;
     549             :         
     550             :                                         /* for these types, an empty string can be handled like a NULL value */
     551         137 :                                         switch (var->sqltype & ~1) {
     552             :                                                 case SQL_SHORT:
     553             :                                                 case SQL_LONG:
     554             :                                                 case SQL_INT64:
     555             :                                                 case SQL_FLOAT:
     556             :                                                 case SQL_DOUBLE:
     557             :                                                 case SQL_TIMESTAMP:
     558             :                                                 case SQL_TYPE_DATE:
     559             :                                                 case SQL_TYPE_TIME:
     560          15 :                                                         force_null = (Z_STRLEN_P(param->parameter) == 0);
     561             :                                         }
     562         137 :                                         if (!force_null) {
     563             :                                                 /* keep the allow-NULL flag */
     564         137 :                                                 var->sqltype = SQL_TEXT | (var->sqltype & 1);
     565         137 :                                                 var->sqldata = Z_STRVAL_P(param->parameter);
     566         137 :                                                 var->sqllen   = Z_STRLEN_P(param->parameter);
     567         137 :                                                 break;
     568             :                                         }
     569             :                                 case IS_NULL:
     570             :                                         /* complain if this field doesn't allow NULL values */
     571           3 :                                         if (~var->sqltype & 1) {
     572           0 :                                                 strcpy(stmt->error_code, "HY105");
     573           0 :                                                 S->H->last_app_error = "Parameter requires non-null value";
     574           0 :                                                 return 0;
     575             :                                         }
     576           3 :                                         *var->sqlind = -1;
     577           3 :                                         break;
     578             :                                 default:
     579           1 :                                         strcpy(stmt->error_code, "HY105");
     580           1 :                                         S->H->last_app_error = "Binding arrays/objects is not supported";
     581           1 :                                         return 0;
     582             :                         }
     583         160 :                         break;
     584             : 
     585             :                 case PDO_PARAM_EVT_FETCH_POST:
     586          98 :                         if (param->paramno == -1) {
     587           1 :                             return 0;
     588             :                         }
     589          97 :                         if (param->is_param) {
     590          37 :                                 break;
     591             :                         }
     592          60 :                         value = NULL;
     593          60 :                         value_len = 0;
     594          60 :                         caller_frees = 0;
     595             :                         
     596          60 :                         if (firebird_stmt_get_col(stmt, param->paramno, &value, &value_len, &caller_frees TSRMLS_CC)) {
     597          60 :                                 switch (PDO_PARAM_TYPE(param->param_type)) {
     598             :                                         case PDO_PARAM_STR:
     599          60 :                                                 if (value) {
     600          60 :                                                         ZVAL_STRINGL(param->parameter, value, value_len, 1);
     601          60 :                                                         break;
     602             :                                                 }
     603             :                                         case PDO_PARAM_INT:
     604           0 :                                                 if (value) {
     605           0 :                                                         ZVAL_LONG(param->parameter, *(long*)value);
     606           0 :                                                         break;
     607             :                                                 }
     608             :                                         case PDO_PARAM_EVT_NORMALIZE:
     609           0 :                                                  if (!param->is_param) {
     610           0 :                                                       char *s = param->name;
     611           0 :                                                       while (*s != '\0') {
     612           0 :                                                            *s = toupper(*s);
     613           0 :                                                             s++;
     614             :                                                       }
     615             :                                                  }
     616           0 :                                                         break;
     617             :                                         default:
     618           0 :                                                 ZVAL_NULL(param->parameter);
     619             :                                 }
     620          60 :                                 if (value && caller_frees) {
     621           0 :                                         efree(value);
     622             :                                 }
     623          60 :                                 return 1;
     624             :                         }
     625           0 :                         return 0;
     626             :                 default:
     627             :                         ;
     628             :         }               
     629         858 :         return 1;
     630             : }
     631             : /* }}} */
     632             : 
     633           1 : static int firebird_stmt_set_attribute(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) /* {{{ */
     634             : {
     635           1 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     636             :         
     637           1 :         switch (attr) {
     638             :                 default:
     639           0 :                         return 0;
     640             :                 case PDO_ATTR_CURSOR_NAME:
     641           1 :                         convert_to_string(val);
     642             :                         
     643           1 :                         if (isc_dsql_set_cursor_name(S->H->isc_status, &S->stmt, Z_STRVAL_P(val),0)) {
     644           0 :                                 RECORD_ERROR(stmt);
     645           0 :                                 return 0;
     646             :                         }
     647           1 :                         strlcpy(S->name, Z_STRVAL_P(val), sizeof(S->name));
     648             :                         break;
     649             :         }
     650           1 :         return 1;
     651             : }
     652             : /* }}} */
     653             : 
     654           0 : static int firebird_stmt_get_attribute(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) /* {{{ */
     655             : {
     656           0 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     657             :         
     658           0 :         switch (attr) {
     659             :                 default:
     660           0 :                         return 0;
     661             :                 case PDO_ATTR_CURSOR_NAME:
     662           0 :                         if (*S->name) {
     663           0 :                                 ZVAL_STRING(val,S->name,1);
     664             :                         } else {
     665           0 :                                 ZVAL_NULL(val);
     666             :                         }
     667             :                         break;
     668             :         }
     669           0 :         return 1;
     670             : }
     671             : /* }}} */
     672             : 
     673          27 : static int firebird_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
     674             : {
     675          27 :         pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
     676             :         
     677             :         /* close the statement handle */
     678          27 :         if ((*S->name || S->cursor_open) && isc_dsql_free_statement(S->H->isc_status, &S->stmt, DSQL_close)) {
     679           0 :                 RECORD_ERROR(stmt);
     680           0 :                 return 0;
     681             :         }
     682          27 :         *S->name = 0;
     683          27 :         S->cursor_open = 0;
     684          27 :         return 1;
     685             : }
     686             : /* }}} */
     687             : 
     688             : 
     689             : struct pdo_stmt_methods firebird_stmt_methods = { /* {{{ */
     690             :         firebird_stmt_dtor,
     691             :         firebird_stmt_execute,
     692             :         firebird_stmt_fetch,
     693             :         firebird_stmt_describe,
     694             :         firebird_stmt_get_col,
     695             :         firebird_stmt_param_hook,
     696             :         firebird_stmt_set_attribute,
     697             :         firebird_stmt_get_attribute,
     698             :         NULL, /* get_column_meta_func */
     699             :         NULL, /* next_rowset_func */
     700             :         firebird_stmt_cursor_closer
     701             : };
     702             : /* }}} */
     703             : 
     704             : /*
     705             :  * Local variables:
     706             :  * tab-width: 4
     707             :  * c-basic-offset: 4
     708             :  * End:
     709             :  * vim600: noet sw=4 ts=4 fdm=marker
     710             :  * vim<600: noet sw=4 ts=4
     711             :  */

Generated by: LCOV version 1.10

Generated at Fri, 24 Oct 2014 05:21:51 +0000 (6 days ago)

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