root/ext/pdo_sqlite/sqlite_statement.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pdo_sqlite_stmt_dtor
  2. pdo_sqlite_stmt_execute
  3. pdo_sqlite_stmt_param_hook
  4. pdo_sqlite_stmt_fetch
  5. pdo_sqlite_stmt_describe
  6. pdo_sqlite_stmt_get_col
  7. pdo_sqlite_stmt_col_meta
  8. pdo_sqlite_stmt_cursor_closer

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 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: Wez Furlong <wez@php.net>                                    |
  16   +----------------------------------------------------------------------+
  17 */
  18 
  19 /* $Id$ */
  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_sqlite.h"
  31 #include "php_pdo_sqlite_int.h"
  32 
  33 
  34 static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt)
  35 {
  36         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
  37 
  38         if (S->stmt) {
  39                 sqlite3_finalize(S->stmt);
  40                 S->stmt = NULL;
  41         }
  42         efree(S);
  43         return 1;
  44 }
  45 
  46 static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt)
  47 {
  48         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
  49 
  50         if (stmt->executed && !S->done) {
  51                 sqlite3_reset(S->stmt);
  52         }
  53 
  54         S->done = 0;
  55         switch (sqlite3_step(S->stmt)) {
  56                 case SQLITE_ROW:
  57                         S->pre_fetched = 1;
  58                         stmt->column_count = sqlite3_data_count(S->stmt);
  59                         return 1;
  60 
  61                 case SQLITE_DONE:
  62                         stmt->column_count = sqlite3_column_count(S->stmt);
  63                         stmt->row_count = sqlite3_changes(S->H->db);
  64                         sqlite3_reset(S->stmt);
  65                         S->done = 1;
  66                         return 1;
  67 
  68                 case SQLITE_ERROR:
  69                         sqlite3_reset(S->stmt);
  70                 case SQLITE_MISUSE:
  71                 case SQLITE_BUSY:
  72                 default:
  73                         pdo_sqlite_error_stmt(stmt);
  74                         return 0;
  75         }
  76 }
  77 
  78 static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
  79                 enum pdo_param_event event_type)
  80 {
  81         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
  82         zval *parameter;
  83 
  84         switch (event_type) {
  85                 case PDO_PARAM_EVT_EXEC_PRE:
  86                         if (stmt->executed && !S->done) {
  87                                 sqlite3_reset(S->stmt);
  88                                 S->done = 1;
  89                         }
  90 
  91                         if (param->is_param) {
  92 
  93                                 if (param->paramno == -1) {
  94                                         param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
  95                                 }
  96 
  97                                 switch (PDO_PARAM_TYPE(param->param_type)) {
  98                                         case PDO_PARAM_STMT:
  99                                                 return 0;
 100 
 101                                         case PDO_PARAM_NULL:
 102                                                 if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
 103                                                         return 1;
 104                                                 }
 105                                                 pdo_sqlite_error_stmt(stmt);
 106                                                 return 0;
 107 
 108                                         case PDO_PARAM_INT:
 109                                         case PDO_PARAM_BOOL:
 110                                                 if (Z_ISREF(param->parameter)) {
 111                                                         parameter = Z_REFVAL(param->parameter);
 112                                                 } else {
 113                                                         parameter = &param->parameter;
 114                                                 }
 115                                                 if (Z_TYPE_P(parameter) == IS_NULL) {
 116                                                         if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
 117                                                                 return 1;
 118                                                         }
 119                                                 } else {
 120                                                         convert_to_long(parameter);
 121 #if ZEND_LONG_MAX > 2147483647
 122                                                         if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
 123                                                                 return 1;
 124                                                         }
 125 #else
 126                                                         if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
 127                                                                 return 1;
 128                                                         }
 129 #endif
 130                                                 }
 131                                                 pdo_sqlite_error_stmt(stmt);
 132                                                 return 0;
 133 
 134                                         case PDO_PARAM_LOB:
 135                                                 if (Z_ISREF(param->parameter)) {
 136                                                         parameter = Z_REFVAL(param->parameter);
 137                                                 } else {
 138                                                         parameter = &param->parameter;
 139                                                 }
 140                                                 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
 141                                                         php_stream *stm = NULL;
 142                                                         php_stream_from_zval_no_verify(stm, parameter);
 143                                                         if (stm) {
 144                                                                 zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
 145                                                                 zval_ptr_dtor(parameter);
 146                                                                 ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
 147                                                         } else {
 148                                                                 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
 149                                                                 return 0;
 150                                                         }
 151                                                 } else if (Z_TYPE_P(parameter) == IS_NULL) {
 152                                                         if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
 153                                                                 return 1;
 154                                                         }
 155                                                         pdo_sqlite_error_stmt(stmt);
 156                                                         return 0;
 157                                                 } else {
 158                                                         convert_to_string(parameter);
 159                                                 }
 160 
 161                                                 if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
 162                                                                 Z_STRVAL_P(parameter),
 163                                                                 Z_STRLEN_P(parameter),
 164                                                                 SQLITE_STATIC)) {
 165                                                         return 1;
 166                                                 }
 167                                                 return 0;
 168 
 169                                         case PDO_PARAM_STR:
 170                                         default:
 171                                                 if (Z_ISREF(param->parameter)) {
 172                                                         parameter = Z_REFVAL(param->parameter);
 173                                                 } else {
 174                                                         parameter = &param->parameter;
 175                                                 }
 176                                                 if (Z_TYPE_P(parameter) == IS_NULL) {
 177                                                         if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
 178                                                                 return 1;
 179                                                         }
 180                                                 } else {
 181                                                         convert_to_string(parameter);
 182                                                         if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
 183                                                                         Z_STRVAL_P(parameter),
 184                                                                         Z_STRLEN_P(parameter),
 185                                                                         SQLITE_STATIC)) {
 186                                                                 return 1;
 187                                                         }
 188                                                 }
 189                                                 pdo_sqlite_error_stmt(stmt);
 190                                                 return 0;
 191                                 }
 192                         }
 193                         break;
 194 
 195                 default:
 196                         ;
 197         }
 198         return 1;
 199 }
 200 
 201 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
 202         enum pdo_fetch_orientation ori, zend_long offset)
 203 {
 204         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 205         int i;
 206         if (!S->stmt) {
 207                 return 0;
 208         }
 209         if (S->pre_fetched) {
 210                 S->pre_fetched = 0;
 211                 return 1;
 212         }
 213         if (S->done) {
 214                 return 0;
 215         }
 216         i = sqlite3_step(S->stmt);
 217         switch (i) {
 218                 case SQLITE_ROW:
 219                         return 1;
 220 
 221                 case SQLITE_DONE:
 222                         S->done = 1;
 223                         sqlite3_reset(S->stmt);
 224                         return 0;
 225 
 226                 case SQLITE_ERROR:
 227                         sqlite3_reset(S->stmt);
 228                 default:
 229                         pdo_sqlite_error_stmt(stmt);
 230                         return 0;
 231         }
 232 }
 233 
 234 static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
 235 {
 236         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 237         const char *str;
 238 
 239         if(colno >= sqlite3_column_count(S->stmt)) {
 240                 /* error invalid column */
 241                 pdo_sqlite_error_stmt(stmt);
 242                 return 0;
 243         }
 244 
 245         str = sqlite3_column_name(S->stmt, colno);
 246         stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
 247         stmt->columns[colno].maxlen = 0xffffffff;
 248         stmt->columns[colno].precision = 0;
 249 
 250         switch (sqlite3_column_type(S->stmt, colno)) {
 251                 case SQLITE_INTEGER:
 252                 case SQLITE_FLOAT:
 253                 case SQLITE3_TEXT:
 254                 case SQLITE_BLOB:
 255                 case SQLITE_NULL:
 256                 default:
 257                         stmt->columns[colno].param_type = PDO_PARAM_STR;
 258                         break;
 259         }
 260 
 261         return 1;
 262 }
 263 
 264 static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees)
 265 {
 266         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 267         if (!S->stmt) {
 268                 return 0;
 269         }
 270         if(colno >= sqlite3_data_count(S->stmt)) {
 271                 /* error invalid column */
 272                 pdo_sqlite_error_stmt(stmt);
 273                 return 0;
 274         }
 275         switch (sqlite3_column_type(S->stmt, colno)) {
 276                 case SQLITE_NULL:
 277                         *ptr = NULL;
 278                         *len = 0;
 279                         return 1;
 280 
 281                 case SQLITE_BLOB:
 282                         *ptr = (char*)sqlite3_column_blob(S->stmt, colno);
 283                         *len = sqlite3_column_bytes(S->stmt, colno);
 284                         return 1;
 285 
 286                 default:
 287                         *ptr = (char*)sqlite3_column_text(S->stmt, colno);
 288                         *len = sqlite3_column_bytes(S->stmt, colno);
 289                         return 1;
 290         }
 291 }
 292 
 293 static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
 294 {
 295         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 296         const char *str;
 297         zval flags;
 298 
 299         if (!S->stmt) {
 300                 return FAILURE;
 301         }
 302         if(colno >= sqlite3_data_count(S->stmt)) {
 303                 /* error invalid column */
 304                 pdo_sqlite_error_stmt(stmt);
 305                 return FAILURE;
 306         }
 307 
 308         array_init(return_value);
 309         array_init(&flags);
 310 
 311         switch (sqlite3_column_type(S->stmt, colno)) {
 312                 case SQLITE_NULL:
 313                         add_assoc_string(return_value, "native_type", "null");
 314                         break;
 315 
 316                 case SQLITE_FLOAT:
 317                         add_assoc_string(return_value, "native_type", "double");
 318                         break;
 319 
 320                 case SQLITE_BLOB:
 321                         add_next_index_string(&flags, "blob");
 322                 case SQLITE_TEXT:
 323                         add_assoc_string(return_value, "native_type", "string");
 324                         break;
 325 
 326                 case SQLITE_INTEGER:
 327                         add_assoc_string(return_value, "native_type", "integer");
 328                         break;
 329         }
 330 
 331         str = sqlite3_column_decltype(S->stmt, colno);
 332         if (str) {
 333                 add_assoc_string(return_value, "sqlite:decl_type", (char *)str);
 334         }
 335 
 336 #ifdef SQLITE_ENABLE_COLUMN_METADATA
 337         str = sqlite3_column_table_name(S->stmt, colno);
 338         if (str) {
 339                 add_assoc_string(return_value, "table", (char *)str);
 340         }
 341 #endif
 342 
 343         add_assoc_zval(return_value, "flags", &flags);
 344 
 345         return SUCCESS;
 346 }
 347 
 348 static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt)
 349 {
 350         pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 351         sqlite3_reset(S->stmt);
 352         return 1;
 353 }
 354 
 355 struct pdo_stmt_methods sqlite_stmt_methods = {
 356         pdo_sqlite_stmt_dtor,
 357         pdo_sqlite_stmt_execute,
 358         pdo_sqlite_stmt_fetch,
 359         pdo_sqlite_stmt_describe,
 360         pdo_sqlite_stmt_get_col,
 361         pdo_sqlite_stmt_param_hook,
 362         NULL, /* set_attr */
 363         NULL, /* get_attr */
 364         pdo_sqlite_stmt_col_meta,
 365         NULL, /* next_rowset */
 366         pdo_sqlite_stmt_cursor_closer
 367 };
 368 
 369 /*
 370  * Local variables:
 371  * tab-width: 4
 372  * c-basic-offset: 4
 373  * End:
 374  * vim600: noet sw=4 ts=4 fdm=marker
 375  * vim<600: noet sw=4 ts=4
 376  */

/* [<][>][^][v][top][bottom][index][help] */