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-21 Instrumented lines: 296
Code covered: 48.3 % Executed lines: 143
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

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

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