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

LCOV - code coverage report
Current view: top level - ext/pdo_sqlite - sqlite_driver.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 307 385 79.7 %
Date: 2016-05-28 Functions: 25 26 96.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 29 May 2016 00:48:29 +0000 (2 days ago)

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