root/ext/pdo_sqlite/sqlite_driver.c

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

DEFINITIONS

This source file includes following definitions.
  1. _pdo_sqlite_error
  2. pdo_sqlite_fetch_error_func
  3. pdo_sqlite_cleanup_callbacks
  4. sqlite_handle_closer
  5. sqlite_handle_preparer
  6. sqlite_handle_doer
  7. pdo_sqlite_last_insert_id
  8. sqlite_handle_quoter
  9. sqlite_handle_begin
  10. sqlite_handle_commit
  11. sqlite_handle_rollback
  12. pdo_sqlite_get_attribute
  13. pdo_sqlite_set_attr
  14. do_callback
  15. php_sqlite3_func_callback
  16. php_sqlite3_func_step_callback
  17. php_sqlite3_func_final_callback
  18. php_sqlite3_collation_callback
  19. PHP_METHOD
  20. PHP_METHOD
  21. PHP_METHOD
  22. get_driver_methods
  23. pdo_sqlite_request_shutdown
  24. make_filename_safe
  25. authorizer
  26. pdo_sqlite_handle_factory

   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 #include "zend_exceptions.h"
  33 
  34 int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line) /* {{{ */
  35 {
  36         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
  37         pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
  38         pdo_sqlite_error_info *einfo = &H->einfo;
  39 
  40         einfo->errcode = sqlite3_errcode(H->db);
  41         einfo->file = file;
  42         einfo->line = line;
  43 
  44         if (einfo->errcode != SQLITE_OK) {
  45                 if (einfo->errmsg) {
  46                         pefree(einfo->errmsg, dbh->is_persistent);
  47                 }
  48                 einfo->errmsg = pestrdup((char*)sqlite3_errmsg(H->db), dbh->is_persistent);
  49         } else { /* no error */
  50                 strncpy(*pdo_err, PDO_ERR_NONE, sizeof(PDO_ERR_NONE));
  51                 return 0;
  52         }
  53         switch (einfo->errcode) {
  54                 case SQLITE_NOTFOUND:
  55                         strncpy(*pdo_err, "42S02", sizeof("42S02"));
  56                         break;
  57 
  58                 case SQLITE_INTERRUPT:
  59                         strncpy(*pdo_err, "01002", sizeof("01002"));
  60                         break;
  61 
  62                 case SQLITE_NOLFS:
  63                         strncpy(*pdo_err, "HYC00", sizeof("HYC00"));
  64                         break;
  65 
  66                 case SQLITE_TOOBIG:
  67                         strncpy(*pdo_err, "22001", sizeof("22001"));
  68                         break;
  69 
  70                 case SQLITE_CONSTRAINT:
  71                         strncpy(*pdo_err, "23000", sizeof("23000"));
  72                         break;
  73 
  74                 case SQLITE_ERROR:
  75                 default:
  76                         strncpy(*pdo_err, "HY000", sizeof("HY000"));
  77                         break;
  78         }
  79 
  80         if (!dbh->methods) {
  81                 zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode, "SQLSTATE[%s] [%d] %s",
  82                                 *pdo_err, einfo->errcode, einfo->errmsg);
  83         }
  84 
  85         return einfo->errcode;
  86 }
  87 /* }}} */
  88 
  89 static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
  90 {
  91         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
  92         pdo_sqlite_error_info *einfo = &H->einfo;
  93 
  94         if (einfo->errcode) {
  95                 add_next_index_long(info, einfo->errcode);
  96                 add_next_index_string(info, einfo->errmsg);
  97         }
  98 
  99         return 1;
 100 }
 101 
 102 static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
 103 {
 104         struct pdo_sqlite_func *func;
 105 
 106         while (H->funcs) {
 107                 func = H->funcs;
 108                 H->funcs = func->next;
 109 
 110                 if (H->db) {
 111                         /* delete the function from the handle */
 112                         sqlite3_create_function(H->db,
 113                                 func->funcname,
 114                                 func->argc,
 115                                 SQLITE_UTF8,
 116                                 func,
 117                                 NULL, NULL, NULL);
 118                 }
 119 
 120                 efree((char*)func->funcname);
 121                 if (!Z_ISUNDEF(func->func)) {
 122                         zval_ptr_dtor(&func->func);
 123                 }
 124                 if (!Z_ISUNDEF(func->step)) {
 125                         zval_ptr_dtor(&func->step);
 126                 }
 127                 if (!Z_ISUNDEF(func->fini)) {
 128                         zval_ptr_dtor(&func->fini);
 129                 }
 130                 efree(func);
 131         }
 132 
 133         while (H->collations) {
 134                 struct pdo_sqlite_collation *collation;
 135                 collation = H->collations;
 136                 H->collations = collation->next;
 137 
 138                 if (H->db) {
 139                         /* delete the collation from the handle */
 140                         sqlite3_create_collation(H->db,
 141                                 collation->name,
 142                                 SQLITE_UTF8,
 143                                 collation,
 144                                 NULL);
 145                 }
 146 
 147                 efree((char*)collation->name);
 148                 if (!Z_ISUNDEF(collation->callback)) {
 149                         zval_ptr_dtor(&collation->callback);
 150                 }
 151                 efree(collation);
 152         }
 153 }
 154 
 155 static int sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */
 156 {
 157         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 158 
 159         if (H) {
 160                 pdo_sqlite_error_info *einfo = &H->einfo;
 161 
 162                 pdo_sqlite_cleanup_callbacks(H);
 163                 if (H->db) {
 164                         sqlite3_close(H->db);
 165                         H->db = NULL;
 166                 }
 167                 if (einfo->errmsg) {
 168                         pefree(einfo->errmsg, dbh->is_persistent);
 169                         einfo->errmsg = NULL;
 170                 }
 171                 pefree(H, dbh->is_persistent);
 172                 dbh->driver_data = NULL;
 173         }
 174         return 0;
 175 }
 176 /* }}} */
 177 
 178 static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options)
 179 {
 180         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 181         pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
 182         int i;
 183         const char *tail;
 184 
 185         S->H = H;
 186         stmt->driver_data = S;
 187         stmt->methods = &sqlite_stmt_methods;
 188         stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL|PDO_PLACEHOLDER_NAMED;
 189 
 190         if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY)) {
 191                 H->einfo.errcode = SQLITE_ERROR;
 192                 pdo_sqlite_error(dbh);
 193                 return 0;
 194         }
 195 
 196         i = sqlite3_prepare(H->db, sql, sql_len, &S->stmt, &tail);
 197         if (i == SQLITE_OK) {
 198                 return 1;
 199         }
 200 
 201         pdo_sqlite_error(dbh);
 202 
 203         return 0;
 204 }
 205 
 206 static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
 207 {
 208         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 209         char *errmsg = NULL;
 210 
 211         if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
 212                 pdo_sqlite_error(dbh);
 213                 if (errmsg)
 214                         sqlite3_free(errmsg);
 215 
 216                 return -1;
 217         } else {
 218                 return sqlite3_changes(H->db);
 219         }
 220 }
 221 
 222 static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
 223 {
 224         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 225         char *id;
 226 
 227         id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
 228         *len = strlen(id);
 229         return id;
 230 }
 231 
 232 /* NB: doesn't handle binary strings... use prepared stmts for that */
 233 static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
 234 {
 235         *quoted = safe_emalloc(2, unquotedlen, 3);
 236         sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
 237         *quotedlen = strlen(*quoted);
 238         return 1;
 239 }
 240 
 241 static int sqlite_handle_begin(pdo_dbh_t *dbh)
 242 {
 243         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 244         char *errmsg = NULL;
 245 
 246         if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
 247                 pdo_sqlite_error(dbh);
 248                 if (errmsg)
 249                         sqlite3_free(errmsg);
 250                 return 0;
 251         }
 252         return 1;
 253 }
 254 
 255 static int sqlite_handle_commit(pdo_dbh_t *dbh)
 256 {
 257         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 258         char *errmsg = NULL;
 259 
 260         if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
 261                 pdo_sqlite_error(dbh);
 262                 if (errmsg)
 263                         sqlite3_free(errmsg);
 264                 return 0;
 265         }
 266         return 1;
 267 }
 268 
 269 static int sqlite_handle_rollback(pdo_dbh_t *dbh)
 270 {
 271         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 272         char *errmsg = NULL;
 273 
 274         if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
 275                 pdo_sqlite_error(dbh);
 276                 if (errmsg)
 277                         sqlite3_free(errmsg);
 278                 return 0;
 279         }
 280         return 1;
 281 }
 282 
 283 static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
 284 {
 285         switch (attr) {
 286                 case PDO_ATTR_CLIENT_VERSION:
 287                 case PDO_ATTR_SERVER_VERSION:
 288                         ZVAL_STRING(return_value, (char *)sqlite3_libversion());
 289                         break;
 290 
 291                 default:
 292                         return 0;
 293         }
 294 
 295         return 1;
 296 }
 297 
 298 static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
 299 {
 300         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 301 
 302         switch (attr) {
 303                 case PDO_ATTR_TIMEOUT:
 304                         sqlite3_busy_timeout(H->db, zval_get_long(val) * 1000);
 305                         return 1;
 306         }
 307         return 0;
 308 }
 309 
 310 static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
 311                 int argc, sqlite3_value **argv, sqlite3_context *context,
 312                 int is_agg)
 313 {
 314         zval *zargs = NULL;
 315         zval retval;
 316         int i;
 317         int ret;
 318         int fake_argc;
 319         zend_reference *agg_context = NULL;
 320 
 321         if (is_agg) {
 322                 is_agg = 2;
 323         }
 324 
 325         fake_argc = argc + is_agg;
 326 
 327         fc->fci.size = sizeof(fc->fci);
 328         fc->fci.function_table = EG(function_table);
 329         ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
 330         fc->fci.symbol_table = NULL;
 331         fc->fci.object = NULL;
 332         fc->fci.retval = &retval;
 333         fc->fci.param_count = fake_argc;
 334 
 335         /* build up the params */
 336 
 337         if (fake_argc) {
 338                 zargs = safe_emalloc(fake_argc, sizeof(zval), 0);
 339         }
 340 
 341         if (is_agg) {
 342                 agg_context = (zend_reference*)sqlite3_aggregate_context(context, sizeof(zend_reference));
 343                 if (!agg_context) {
 344                         ZVAL_NULL(&zargs[0]);
 345                 } else {
 346                         if (Z_ISUNDEF(agg_context->val)) {
 347                                 GC_REFCOUNT(agg_context) = 1;
 348                                 GC_TYPE_INFO(agg_context) = IS_REFERENCE;
 349                                 ZVAL_NULL(&agg_context->val);
 350                         }
 351                         ZVAL_REF(&zargs[0], agg_context);
 352                 }
 353                 ZVAL_LONG(&zargs[1], sqlite3_aggregate_count(context));
 354         }
 355 
 356         for (i = 0; i < argc; i++) {
 357                 /* get the value */
 358                 switch (sqlite3_value_type(argv[i])) {
 359                         case SQLITE_INTEGER:
 360                                 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
 361                                 break;
 362 
 363                         case SQLITE_FLOAT:
 364                                 ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
 365                                 break;
 366 
 367                         case SQLITE_NULL:
 368                                 ZVAL_NULL(&zargs[i + is_agg]);
 369                                 break;
 370 
 371                         case SQLITE_BLOB:
 372                         case SQLITE3_TEXT:
 373                         default:
 374                                 ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
 375                                 break;
 376                 }
 377         }
 378 
 379         fc->fci.params = zargs;
 380 
 381         if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
 382                 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
 383         }
 384 
 385         /* clean up the params */
 386         if (zargs) {
 387                 for (i = is_agg; i < fake_argc; i++) {
 388                         zval_ptr_dtor(&zargs[i]);
 389                 }
 390                 if (is_agg) {
 391                         zval_ptr_dtor(&zargs[1]);
 392                 }
 393                 efree(zargs);
 394         }
 395 
 396         if (!is_agg || !argv) {
 397                 /* only set the sqlite return value if we are a scalar function,
 398                  * or if we are finalizing an aggregate */
 399                 if (!Z_ISUNDEF(retval)) {
 400                         switch (Z_TYPE(retval)) {
 401                                 case IS_LONG:
 402                                         sqlite3_result_int(context, Z_LVAL(retval));
 403                                         break;
 404 
 405                                 case IS_NULL:
 406                                         sqlite3_result_null(context);
 407                                         break;
 408 
 409                                 case IS_DOUBLE:
 410                                         sqlite3_result_double(context, Z_DVAL(retval));
 411                                         break;
 412 
 413                                 default:
 414                                         convert_to_string_ex(&retval);
 415                                         sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
 416                                         break;
 417                         }
 418                 } else {
 419                         sqlite3_result_error(context, "failed to invoke callback", 0);
 420                 }
 421 
 422                 if (agg_context) {
 423                         zval_ptr_dtor(&agg_context->val);
 424                 }
 425         } else {
 426                 /* we're stepping in an aggregate; the return value goes into
 427                  * the context */
 428                 if (agg_context) {
 429                         zval_ptr_dtor(&agg_context->val);
 430                 }
 431                 if (!Z_ISUNDEF(retval)) {
 432                         ZVAL_COPY_VALUE(&agg_context->val, &retval);
 433                         ZVAL_UNDEF(&retval);
 434                 } else {
 435                         ZVAL_UNDEF(&agg_context->val);
 436                 }
 437         }
 438 
 439         if (!Z_ISUNDEF(retval)) {
 440                 zval_ptr_dtor(&retval);
 441         }
 442 
 443         return ret;
 444 }
 445 
 446 static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
 447         sqlite3_value **argv)
 448 {
 449         struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
 450 
 451         do_callback(&func->afunc, &func->func, argc, argv, context, 0);
 452 }
 453 
 454 static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
 455         sqlite3_value **argv)
 456 {
 457         struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
 458 
 459         do_callback(&func->astep, &func->step, argc, argv, context, 1);
 460 }
 461 
 462 static void php_sqlite3_func_final_callback(sqlite3_context *context)
 463 {
 464         struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
 465 
 466         do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
 467 }
 468 
 469 static int php_sqlite3_collation_callback(void *context,
 470         int string1_len, const void *string1,
 471         int string2_len, const void *string2)
 472 {
 473         int ret;
 474         zval zargs[2];
 475         zval retval;
 476         struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
 477 
 478         collation->fc.fci.size = sizeof(collation->fc.fci);
 479         collation->fc.fci.function_table = EG(function_table);
 480         ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
 481         collation->fc.fci.symbol_table = NULL;
 482         collation->fc.fci.object = NULL;
 483         collation->fc.fci.retval = &retval;
 484 
 485         // Prepare the arguments.
 486         ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
 487         ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
 488         collation->fc.fci.param_count = 2;
 489         collation->fc.fci.params = zargs;
 490 
 491         if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
 492                 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
 493         } else if (!Z_ISUNDEF(retval)) {
 494                 if (Z_TYPE(retval) != IS_LONG) {
 495                         convert_to_long_ex(&retval);
 496                 }
 497                 ret = 0;
 498                 if (Z_LVAL(retval) > 0) {
 499                         ret = 1;
 500                 } else if (Z_LVAL(retval) < 0) {
 501                         ret = -1;
 502                 }
 503                 zval_ptr_dtor(&retval);
 504         }
 505 
 506         zval_ptr_dtor(&zargs[0]);
 507         zval_ptr_dtor(&zargs[1]);
 508 
 509         return ret;
 510 }
 511 
 512 /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
 513    Registers a UDF with the sqlite db handle */
 514 static PHP_METHOD(SQLite, sqliteCreateFunction)
 515 {
 516         struct pdo_sqlite_func *func;
 517         zval *callback;
 518         char *func_name;
 519         size_t func_name_len;
 520         zend_long argc = -1;
 521         zend_string *cbname = NULL;
 522         pdo_dbh_t *dbh;
 523         pdo_sqlite_db_handle *H;
 524         int ret;
 525 
 526         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l",
 527                         &func_name, &func_name_len, &callback, &argc)) {
 528                 RETURN_FALSE;
 529         }
 530 
 531         dbh = Z_PDO_DBH_P(getThis());
 532         PDO_CONSTRUCT_CHECK;
 533 
 534         if (!zend_is_callable(callback, 0, &cbname)) {
 535                 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
 536                 zend_string_release(cbname);
 537                 RETURN_FALSE;
 538         }
 539         zend_string_release(cbname);
 540 
 541         H = (pdo_sqlite_db_handle *)dbh->driver_data;
 542 
 543         func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
 544 
 545         ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
 546                         func, php_sqlite3_func_callback, NULL, NULL);
 547         if (ret == SQLITE_OK) {
 548                 func->funcname = estrdup(func_name);
 549 
 550                 ZVAL_COPY(&func->func, callback);
 551 
 552                 func->argc = argc;
 553 
 554                 func->next = H->funcs;
 555                 H->funcs = func;
 556 
 557                 RETURN_TRUE;
 558         }
 559 
 560         efree(func);
 561         RETURN_FALSE;
 562 }
 563 /* }}} */
 564 
 565 /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
 566    Registers a UDF with the sqlite db handle */
 567 
 568 /* The step function should have the prototype:
 569    mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
 570 
 571    $context will be null for the first row; on subsequent rows it will have
 572    the value that was previously returned from the step function; you should
 573    use this to maintain state for the aggregate.
 574 
 575    The fini function should have the prototype:
 576    mixed fini(mixed $context, int $rownumber)
 577 
 578    $context will hold the return value from the very last call to the step function.
 579    rownumber will hold the number of rows over which the aggregate was performed.
 580    The return value of this function will be used as the return value for this
 581    aggregate UDF.
 582 */
 583 
 584 static PHP_METHOD(SQLite, sqliteCreateAggregate)
 585 {
 586         struct pdo_sqlite_func *func;
 587         zval *step_callback, *fini_callback;
 588         char *func_name;
 589         size_t func_name_len;
 590         zend_long argc = -1;
 591         zend_string *cbname = NULL;
 592         pdo_dbh_t *dbh;
 593         pdo_sqlite_db_handle *H;
 594         int ret;
 595 
 596         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l",
 597                         &func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
 598                 RETURN_FALSE;
 599         }
 600 
 601         dbh = Z_PDO_DBH_P(getThis());
 602         PDO_CONSTRUCT_CHECK;
 603 
 604         if (!zend_is_callable(step_callback, 0, &cbname)) {
 605                 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
 606                 zend_string_release(cbname);
 607                 RETURN_FALSE;
 608         }
 609         zend_string_release(cbname);
 610         if (!zend_is_callable(fini_callback, 0, &cbname)) {
 611                 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
 612                 zend_string_release(cbname);
 613                 RETURN_FALSE;
 614         }
 615         zend_string_release(cbname);
 616 
 617         H = (pdo_sqlite_db_handle *)dbh->driver_data;
 618 
 619         func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
 620 
 621         ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
 622                         func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
 623         if (ret == SQLITE_OK) {
 624                 func->funcname = estrdup(func_name);
 625 
 626                 ZVAL_COPY(&func->step, step_callback);
 627 
 628                 ZVAL_COPY(&func->fini, fini_callback);
 629 
 630                 func->argc = argc;
 631 
 632                 func->next = H->funcs;
 633                 H->funcs = func;
 634 
 635                 RETURN_TRUE;
 636         }
 637 
 638         efree(func);
 639         RETURN_FALSE;
 640 }
 641 /* }}} */
 642 
 643 /* {{{ bool SQLite::sqliteCreateCollation(string name, mixed callback)
 644    Registers a collation with the sqlite db handle */
 645 static PHP_METHOD(SQLite, sqliteCreateCollation)
 646 {
 647         struct pdo_sqlite_collation *collation;
 648         zval *callback;
 649         char *collation_name;
 650         size_t collation_name_len;
 651         zend_string *cbname = NULL;
 652         pdo_dbh_t *dbh;
 653         pdo_sqlite_db_handle *H;
 654         int ret;
 655 
 656         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz",
 657                 &collation_name, &collation_name_len, &callback)) {
 658                 RETURN_FALSE;
 659         }
 660 
 661         dbh = Z_PDO_DBH_P(getThis());
 662         PDO_CONSTRUCT_CHECK;
 663 
 664         if (!zend_is_callable(callback, 0, &cbname)) {
 665                 php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
 666                 zend_string_release(cbname);
 667                 RETURN_FALSE;
 668         }
 669         zend_string_release(cbname);
 670 
 671         H = (pdo_sqlite_db_handle *)dbh->driver_data;
 672 
 673         collation = (struct pdo_sqlite_collation*)ecalloc(1, sizeof(*collation));
 674 
 675         ret = sqlite3_create_collation(H->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_collation_callback);
 676         if (ret == SQLITE_OK) {
 677                 collation->name = estrdup(collation_name);
 678 
 679                 ZVAL_COPY(&collation->callback, callback);
 680 
 681                 collation->next = H->collations;
 682                 H->collations = collation;
 683 
 684                 RETURN_TRUE;
 685         }
 686 
 687         efree(collation);
 688         RETURN_FALSE;
 689 }
 690 /* }}} */
 691 
 692 static const zend_function_entry dbh_methods[] = {
 693         PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
 694         PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
 695         PHP_ME(SQLite, sqliteCreateCollation, NULL, ZEND_ACC_PUBLIC)
 696         PHP_FE_END
 697 };
 698 
 699 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind)
 700 {
 701         switch (kind) {
 702                 case PDO_DBH_DRIVER_METHOD_KIND_DBH:
 703                         return dbh_methods;
 704 
 705                 default:
 706                         return NULL;
 707         }
 708 }
 709 
 710 static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)
 711 {
 712         pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
 713         /* unregister functions, so that they don't linger for the next
 714          * request */
 715         if (H) {
 716                 pdo_sqlite_cleanup_callbacks(H);
 717         }
 718 }
 719 
 720 static struct pdo_dbh_methods sqlite_methods = {
 721         sqlite_handle_closer,
 722         sqlite_handle_preparer,
 723         sqlite_handle_doer,
 724         sqlite_handle_quoter,
 725         sqlite_handle_begin,
 726         sqlite_handle_commit,
 727         sqlite_handle_rollback,
 728         pdo_sqlite_set_attr,
 729         pdo_sqlite_last_insert_id,
 730         pdo_sqlite_fetch_error_func,
 731         pdo_sqlite_get_attribute,
 732         NULL,   /* check_liveness: not needed */
 733         get_driver_methods,
 734         pdo_sqlite_request_shutdown
 735 };
 736 
 737 static char *make_filename_safe(const char *filename)
 738 {
 739         if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) {
 740                 char *fullpath = expand_filepath(filename, NULL);
 741 
 742                 if (!fullpath) {
 743                         return NULL;
 744                 }
 745 
 746                 if (php_check_open_basedir(fullpath)) {
 747                         efree(fullpath);
 748                         return NULL;
 749                 }
 750                 return fullpath;
 751         }
 752         return estrdup(filename);
 753 }
 754 
 755 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
 756                 const char *arg5, const char *arg6)
 757 {
 758         char *filename;
 759         switch (access_type) {
 760                 case SQLITE_COPY: {
 761                                         filename = make_filename_safe(arg4);
 762                         if (!filename) {
 763                                 return SQLITE_DENY;
 764                         }
 765                         efree(filename);
 766                         return SQLITE_OK;
 767                 }
 768 
 769                 case SQLITE_ATTACH: {
 770                                         filename = make_filename_safe(arg3);
 771                         if (!filename) {
 772                                 return SQLITE_DENY;
 773                         }
 774                         efree(filename);
 775                         return SQLITE_OK;
 776                 }
 777 
 778                 default:
 779                         /* access allowed */
 780                         return SQLITE_OK;
 781         }
 782 }
 783 
 784 static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
 785 {
 786         pdo_sqlite_db_handle *H;
 787         int i, ret = 0;
 788         zend_long timeout = 60;
 789         char *filename;
 790 
 791         H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
 792 
 793         H->einfo.errcode = 0;
 794         H->einfo.errmsg = NULL;
 795         dbh->driver_data = H;
 796 
 797         filename = make_filename_safe(dbh->data_source);
 798 
 799         if (!filename) {
 800                 zend_throw_exception_ex(php_pdo_get_exception(), 0,
 801                         "open_basedir prohibits opening %s",
 802                         dbh->data_source);
 803                 goto cleanup;
 804         }
 805 
 806         i = sqlite3_open(filename, &H->db);
 807         efree(filename);
 808 
 809         if (i != SQLITE_OK) {
 810                 pdo_sqlite_error(dbh);
 811                 goto cleanup;
 812         }
 813 
 814         if (PG(open_basedir) && *PG(open_basedir)) {
 815                 sqlite3_set_authorizer(H->db, authorizer, NULL);
 816         }
 817 
 818         if (driver_options) {
 819                 timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout);
 820         }
 821         sqlite3_busy_timeout(H->db, timeout * 1000);
 822 
 823         dbh->alloc_own_columns = 1;
 824         dbh->max_escaped_char_length = 2;
 825 
 826         ret = 1;
 827 
 828 cleanup:
 829         dbh->methods = &sqlite_methods;
 830 
 831         return ret;
 832 }
 833 /* }}} */
 834 
 835 pdo_driver_t pdo_sqlite_driver = {
 836         PDO_DRIVER_HEADER(sqlite),
 837         pdo_sqlite_handle_factory
 838 };
 839 
 840 /*
 841  * Local variables:
 842  * tab-width: 4
 843  * c-basic-offset: 4
 844  * End:
 845  * vim600: noet sw=4 ts=4 fdm=marker
 846  * vim<600: noet sw=4 ts=4
 847  */

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