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

LTP GCOV extension - code coverage report
Current view: directory - pdo_firebird - firebird_statement.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 278
Code covered: 42.4 % Executed lines: 118
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:34 +0000 (33 hours ago)

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