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/sqlite3 - sqlite3.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 774 963 80.4 %
Date: 2016-09-18 Functions: 57 65 87.7 %
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             :    | Authors: Scott MacVicar <scottmac@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 "php_sqlite3.h"
      29             : #include "php_sqlite3_structs.h"
      30             : #include "main/SAPI.h"
      31             : 
      32             : #include <sqlite3.h>
      33             : 
      34             : #include "zend_exceptions.h"
      35             : #include "zend_interfaces.h"
      36             : #include "SAPI.h"
      37             : 
      38             : ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
      39             : 
      40             : static PHP_GINIT_FUNCTION(sqlite3);
      41             : static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6);
      42             : static void sqlite3_param_dtor(zval *data);
      43             : static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
      44             : 
      45             : /* {{{ Error Handler
      46             : */
      47          13 : static void php_sqlite3_error(php_sqlite3_db_object *db_obj, char *format, ...)
      48             : {
      49             :         va_list arg;
      50             :         char    *message;
      51             : 
      52          13 :         va_start(arg, format);
      53          13 :         vspprintf(&message, 0, format, arg);
      54          13 :         va_end(arg);
      55             : 
      56          14 :         if (db_obj && db_obj->exception) {
      57           1 :                 zend_throw_exception(zend_ce_exception, message, 0);
      58             :         } else {
      59          12 :                 php_error_docref(NULL, E_WARNING, "%s", message);
      60             :         }
      61             : 
      62          13 :         if (message) {
      63          13 :                 efree(message);
      64             :         }
      65          13 : }
      66             : /* }}} */
      67             : 
      68             : #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
      69             :         if (!(db_obj) || !(member)) { \
      70             :                 php_sqlite3_error(db_obj, "The " #class_name " object has not been correctly initialised"); \
      71             :                 RETURN_FALSE; \
      72             :         }
      73             : 
      74             : #define SQLITE3_CHECK_INITIALIZED_STMT(member, class_name) \
      75             :         if (!(member)) { \
      76             :                 php_error_docref(NULL, E_WARNING, "The " #class_name " object has not been correctly initialised"); \
      77             :                 RETURN_FALSE; \
      78             :         }
      79             : 
      80             : /* {{{ PHP_INI
      81             : */
      82             : PHP_INI_BEGIN()
      83             :         STD_PHP_INI_ENTRY("sqlite3.extension_dir",  NULL, PHP_INI_SYSTEM, OnUpdateString, extension_dir, zend_sqlite3_globals, sqlite3_globals)
      84             : PHP_INI_END()
      85             : /* }}} */
      86             : 
      87             : /* Handlers */
      88             : static zend_object_handlers sqlite3_object_handlers;
      89             : static zend_object_handlers sqlite3_stmt_object_handlers;
      90             : static zend_object_handlers sqlite3_result_object_handlers;
      91             : 
      92             : /* Class entries */
      93             : zend_class_entry *php_sqlite3_sc_entry;
      94             : zend_class_entry *php_sqlite3_stmt_entry;
      95             : zend_class_entry *php_sqlite3_result_entry;
      96             : 
      97             : /* {{{ proto void SQLite3::open(String filename [, int Flags [, string Encryption Key]])
      98             :    Opens a SQLite 3 Database, if the build includes encryption then it will attempt to use the key. */
      99          79 : PHP_METHOD(sqlite3, open)
     100             : {
     101             :         php_sqlite3_db_object *db_obj;
     102         158 :         zval *object = getThis();
     103             :         char *filename, *encryption_key, *fullpath;
     104          79 :         size_t filename_len, encryption_key_len = 0;
     105          79 :         zend_long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
     106             : 
     107          79 :         db_obj = Z_SQLITE3_DB_P(object);
     108             : 
     109          79 :         if (FAILURE == zend_parse_parameters_throw(ZEND_NUM_ARGS(), "p|ls", &filename, &filename_len, &flags, &encryption_key, &encryption_key_len)) {
     110           1 :                 return;
     111             :         }
     112             : 
     113          78 :         if (db_obj->initialised) {
     114           1 :                 zend_throw_exception(zend_ce_exception, "Already initialised DB Object", 0);
     115           1 :                 return;
     116             :         }
     117             : 
     118         152 :         if (filename_len != 0 && (filename_len != sizeof(":memory:")-1 ||
     119          71 :                         memcmp(filename, ":memory:", sizeof(":memory:")-1) != 0)) {
     120           5 :                 if (!(fullpath = expand_filepath(filename, NULL))) {
     121           0 :                         zend_throw_exception(zend_ce_exception, "Unable to expand filepath", 0);
     122           0 :                         return;
     123             :                 }
     124             : 
     125           5 :                 if (php_check_open_basedir(fullpath)) {
     126           1 :                         zend_throw_exception_ex(zend_ce_exception, 0, "open_basedir prohibits opening %s", fullpath);
     127           1 :                         efree(fullpath);
     128           1 :                         return;
     129             :                 }
     130             :         } else {
     131             :                 /* filename equals "" or ":memory:" */
     132          72 :                 fullpath = filename;
     133             :         }
     134             : 
     135             : #if SQLITE_VERSION_NUMBER >= 3005000
     136          76 :         if (sqlite3_open_v2(fullpath, &(db_obj->db), flags, NULL) != SQLITE_OK) {
     137             : #else
     138             :         if (sqlite3_open(fullpath, &(db_obj->db)) != SQLITE_OK) {
     139             : #endif
     140           1 :                 zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s", sqlite3_errmsg(db_obj->db));
     141           1 :                 if (fullpath != filename) {
     142           1 :                         efree(fullpath);
     143             :                 }
     144           1 :                 return;
     145             :         }
     146             : 
     147             : #if SQLITE_HAS_CODEC
     148             :         if (encryption_key_len > 0) {
     149             :                 if (sqlite3_key(db_obj->db, encryption_key, encryption_key_len) != SQLITE_OK) {
     150             :                         zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s", sqlite3_errmsg(db_obj->db));
     151             :                         return;
     152             :                 }
     153             :         }
     154             : #endif
     155             : 
     156          75 :         db_obj->initialised = 1;
     157             : 
     158          75 :         if (PG(open_basedir) && *PG(open_basedir)) {
     159           2 :                 sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, NULL);
     160             :         }
     161             : 
     162          75 :         if (fullpath != filename) {
     163           3 :                 efree(fullpath);
     164             :         }
     165             : }
     166             : /* }}} */
     167             : 
     168             : /* {{{ proto bool SQLite3::close()
     169             :    Close a SQLite 3 Database. */
     170          46 : PHP_METHOD(sqlite3, close)
     171             : {
     172             :         php_sqlite3_db_object *db_obj;
     173          92 :         zval *object = getThis();
     174             :         int errcode;
     175          46 :         db_obj = Z_SQLITE3_DB_P(object);
     176             : 
     177          46 :         if (zend_parse_parameters_none() == FAILURE) {
     178           2 :                 return;
     179             :         }
     180             : 
     181          44 :         if (db_obj->initialised) {
     182          44 :         zend_llist_clean(&(db_obj->free_list));
     183          44 :                 if(db_obj->db) {
     184          44 :             errcode = sqlite3_close(db_obj->db);
     185          44 :             if (errcode != SQLITE_OK) {
     186           0 :                             php_sqlite3_error(db_obj, "Unable to close database: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
     187           0 :                 RETURN_FALSE;
     188             :                     }
     189             :         }
     190          44 :                 db_obj->initialised = 0;
     191             :         }
     192             : 
     193          44 :         RETURN_TRUE;
     194             : }
     195             : /* }}} */
     196             : 
     197             : /* {{{ proto bool SQLite3::exec(String Query)
     198             :    Executes a result-less query against a given database. */
     199         117 : PHP_METHOD(sqlite3, exec)
     200             : {
     201             :         php_sqlite3_db_object *db_obj;
     202         234 :         zval *object = getThis();
     203             :         zend_string *sql;
     204         117 :         char *errtext = NULL;
     205         117 :         db_obj = Z_SQLITE3_DB_P(object);
     206             : 
     207         117 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     208             : 
     209         117 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
     210           1 :                 return;
     211             :         }
     212             : 
     213         116 :         if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
     214           1 :                 php_sqlite3_error(db_obj, "%s", errtext);
     215           1 :                 sqlite3_free(errtext);
     216           1 :                 RETURN_FALSE;
     217             :         }
     218             : 
     219         115 :         RETURN_TRUE;
     220             : }
     221             : /* }}} */
     222             : 
     223             : /* {{{ proto Array SQLite3::version()
     224             :    Returns the SQLite3 Library version as a string constant and as a number. */
     225           3 : PHP_METHOD(sqlite3, version)
     226             : {
     227           3 :         if (zend_parse_parameters_none() == FAILURE) {
     228           1 :                 return;
     229             :         }
     230             : 
     231           2 :         array_init(return_value);
     232             : 
     233           2 :         add_assoc_string(return_value, "versionString", (char*)sqlite3_libversion());
     234           2 :         add_assoc_long(return_value, "versionNumber", sqlite3_libversion_number());
     235             : 
     236           2 :         return;
     237             : }
     238             : /* }}} */
     239             : 
     240             : /* {{{ proto int SQLite3::lastInsertRowID()
     241             :    Returns the rowid of the most recent INSERT into the database from the database connection. */
     242           3 : PHP_METHOD(sqlite3, lastInsertRowID)
     243             : {
     244             :         php_sqlite3_db_object *db_obj;
     245           6 :         zval *object = getThis();
     246           3 :         db_obj = Z_SQLITE3_DB_P(object);
     247             : 
     248           3 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     249             : 
     250           3 :         if (zend_parse_parameters_none() == FAILURE) {
     251           1 :                 return;
     252             :         }
     253             : 
     254           2 :         RETURN_LONG(sqlite3_last_insert_rowid(db_obj->db));
     255             : }
     256             : /* }}} */
     257             : 
     258             : /* {{{ proto int SQLite3::lastErrorCode()
     259             :    Returns the numeric result code of the most recent failed sqlite API call for the database connection. */
     260           3 : PHP_METHOD(sqlite3, lastErrorCode)
     261             : {
     262             :         php_sqlite3_db_object *db_obj;
     263           6 :         zval *object = getThis();
     264           3 :         db_obj = Z_SQLITE3_DB_P(object);
     265             : 
     266           3 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
     267             : 
     268           3 :         if (zend_parse_parameters_none() == FAILURE) {
     269           1 :                 return;
     270             :         }
     271             : 
     272           2 :         if (db_obj->initialised) {
     273           1 :                 RETURN_LONG(sqlite3_errcode(db_obj->db));
     274             :         } else {
     275           1 :                 RETURN_LONG(0);
     276             :         }
     277             : }
     278             : /* }}} */
     279             : 
     280             : /* {{{ proto string SQLite3::lastErrorMsg()
     281             :    Returns english text describing the most recent failed sqlite API call for the database connection. */
     282           3 : PHP_METHOD(sqlite3, lastErrorMsg)
     283             : {
     284             :         php_sqlite3_db_object *db_obj;
     285           6 :         zval *object = getThis();
     286           3 :         db_obj = Z_SQLITE3_DB_P(object);
     287             : 
     288           3 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
     289             : 
     290           3 :         if (zend_parse_parameters_none() == FAILURE) {
     291           1 :                 return;
     292             :         }
     293             : 
     294           2 :         if (db_obj->initialised) {
     295           2 :                 RETURN_STRING((char *)sqlite3_errmsg(db_obj->db));
     296             :         } else {
     297           1 :                 RETURN_EMPTY_STRING();
     298             :         }
     299             : }
     300             : /* }}} */
     301             : 
     302             : /* {{{ proto bool SQLite3::busyTimeout(int msecs)
     303             :    Sets a busy handler that will sleep until database is not locked or timeout is reached. Passing a value less than or equal to zero turns off all busy handlers. */
     304           0 : PHP_METHOD(sqlite3, busyTimeout)
     305             : {
     306             :         php_sqlite3_db_object *db_obj;
     307           0 :         zval *object = getThis();
     308             :         zend_long ms;
     309             :         int return_code;
     310           0 :         db_obj = Z_SQLITE3_DB_P(object);
     311             : 
     312           0 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     313             : 
     314           0 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &ms)) {
     315           0 :                 return;
     316             :         }
     317             : 
     318           0 :         return_code = sqlite3_busy_timeout(db_obj->db, ms);
     319           0 :         if (return_code != SQLITE_OK) {
     320           0 :                 php_sqlite3_error(db_obj, "Unable to set busy timeout: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
     321           0 :                 RETURN_FALSE;
     322             :         }
     323             : 
     324           0 :         RETURN_TRUE;
     325             : }
     326             : /* }}} */
     327             : 
     328             : 
     329             : #ifndef SQLITE_OMIT_LOAD_EXTENSION
     330             : /* {{{ proto bool SQLite3::loadExtension(String Shared Library)
     331             :    Attempts to load an SQLite extension library. */
     332           4 : PHP_METHOD(sqlite3, loadExtension)
     333             : {
     334             :         php_sqlite3_db_object *db_obj;
     335           8 :         zval *object = getThis();
     336           4 :         char *extension, *lib_path, *extension_dir, *errtext = NULL;
     337             :         char fullpath[MAXPATHLEN];
     338             :         size_t extension_len, extension_dir_len;
     339           4 :         db_obj = Z_SQLITE3_DB_P(object);
     340             : 
     341           4 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     342             : 
     343           4 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &extension, &extension_len)) {
     344           1 :                 return;
     345             :         }
     346             : 
     347             : #ifdef ZTS
     348             :         if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
     349             :                 (strcmp(sapi_module.name, "cli") != 0) &&
     350             :                 (strncmp(sapi_module.name, "embed", 5) != 0)
     351             :         ) {             php_sqlite3_error(db_obj, "Not supported in multithreaded Web servers");
     352             :                 RETURN_FALSE;
     353             :         }
     354             : #endif
     355             : 
     356           3 :         if (!SQLITE3G(extension_dir)) {
     357           1 :                 php_sqlite3_error(db_obj, "SQLite Extension are disabled");
     358           1 :                 RETURN_FALSE;
     359             :         }
     360             : 
     361           2 :         if (extension_len == 0) {
     362           1 :                 php_sqlite3_error(db_obj, "Empty string as an extension");
     363           1 :                 RETURN_FALSE;
     364             :         }
     365             : 
     366           1 :         extension_dir = SQLITE3G(extension_dir);
     367           1 :         extension_dir_len = strlen(SQLITE3G(extension_dir));
     368             : 
     369           1 :         if (IS_SLASH(extension_dir[extension_dir_len-1])) {
     370           0 :                 spprintf(&lib_path, 0, "%s%s", extension_dir, extension);
     371             :         } else {
     372           1 :                 spprintf(&lib_path, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, extension);
     373             :         }
     374             : 
     375           1 :         if (!VCWD_REALPATH(lib_path, fullpath)) {
     376           1 :                 php_sqlite3_error(db_obj, "Unable to load extension at '%s'", lib_path);
     377           1 :                 efree(lib_path);
     378           1 :                 RETURN_FALSE;
     379             :         }
     380             : 
     381           0 :         efree(lib_path);
     382             : 
     383           0 :         if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) {
     384           0 :                 php_sqlite3_error(db_obj, "Unable to open extensions outside the defined directory");
     385           0 :                 RETURN_FALSE;
     386             :         }
     387             : 
     388             :         /* Extension loading should only be enabled for when we attempt to load */
     389           0 :         sqlite3_enable_load_extension(db_obj->db, 1);
     390           0 :         if (sqlite3_load_extension(db_obj->db, fullpath, 0, &errtext) != SQLITE_OK) {
     391           0 :                 php_sqlite3_error(db_obj, "%s", errtext);
     392           0 :                 sqlite3_free(errtext);
     393           0 :                 sqlite3_enable_load_extension(db_obj->db, 0);
     394           0 :                 RETURN_FALSE;
     395             :         }
     396           0 :         sqlite3_enable_load_extension(db_obj->db, 0);
     397             : 
     398           0 :         RETURN_TRUE;
     399             : }
     400             : /* }}} */
     401             : #endif
     402             : 
     403             : /* {{{ proto int SQLite3::changes()
     404             :   Returns the number of database rows that were changed (or inserted or deleted) by the most recent SQL statement. */
     405           3 : PHP_METHOD(sqlite3, changes)
     406             : {
     407             :         php_sqlite3_db_object *db_obj;
     408           6 :         zval *object = getThis();
     409           3 :         db_obj = Z_SQLITE3_DB_P(object);
     410             : 
     411           3 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     412             : 
     413           3 :         if (zend_parse_parameters_none() == FAILURE) {
     414           1 :                 return;
     415             :         }
     416             : 
     417           2 :         RETURN_LONG(sqlite3_changes(db_obj->db));
     418             : }
     419             : /* }}} */
     420             : 
     421             : /* {{{ proto String SQLite3::escapeString(String value)
     422             :    Returns a string that has been properly escaped. */
     423           1 : PHP_METHOD(sqlite3, escapeString)
     424             : {
     425             :         zend_string *sql;
     426             :         char *ret;
     427             : 
     428           1 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
     429           0 :                 return;
     430             :         }
     431             : 
     432           1 :         if (ZSTR_LEN(sql)) {
     433           1 :                 ret = sqlite3_mprintf("%q", ZSTR_VAL(sql));
     434           1 :                 if (ret) {
     435           2 :                         RETVAL_STRING(ret);
     436           1 :                         sqlite3_free(ret);
     437             :                 }
     438             :         } else {
     439           0 :                 RETURN_EMPTY_STRING();
     440             :         }
     441             : }
     442             : /* }}} */
     443             : 
     444             : /* {{{ proto SQLite3Stmt SQLite3::prepare(String Query)
     445             :    Returns a prepared SQL statement for execution. */
     446          38 : PHP_METHOD(sqlite3, prepare)
     447             : {
     448             :         php_sqlite3_db_object *db_obj;
     449             :         php_sqlite3_stmt *stmt_obj;
     450          76 :         zval *object = getThis();
     451             :         zend_string *sql;
     452             :         int errcode;
     453             :         php_sqlite3_free_list *free_item;
     454             : 
     455          38 :         db_obj = Z_SQLITE3_DB_P(object);
     456             : 
     457          38 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     458             : 
     459          38 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
     460           1 :                 return;
     461             :         }
     462             : 
     463          37 :         if (!ZSTR_LEN(sql)) {
     464           1 :                 RETURN_FALSE;
     465             :         }
     466             : 
     467          36 :         object_init_ex(return_value, php_sqlite3_stmt_entry);
     468          36 :         stmt_obj = Z_SQLITE3_STMT_P(return_value);
     469          36 :         stmt_obj->db_obj = db_obj;
     470          36 :         ZVAL_COPY(&stmt_obj->db_obj_zval, object);
     471             : 
     472          36 :         errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
     473          36 :         if (errcode != SQLITE_OK) {
     474           1 :                 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
     475             :                 zval_dtor(return_value);
     476           1 :                 RETURN_FALSE;
     477             :         }
     478             : 
     479          35 :         stmt_obj->initialised = 1;
     480             : 
     481          35 :         free_item = emalloc(sizeof(php_sqlite3_free_list));
     482          35 :         free_item->stmt_obj = stmt_obj;
     483          35 :         ZVAL_COPY_VALUE(&free_item->stmt_obj_zval, return_value);
     484             : 
     485          35 :         zend_llist_add_element(&(db_obj->free_list), &free_item);
     486             : }
     487             : /* }}} */
     488             : 
     489             : /* {{{ proto SQLite3Result SQLite3::query(String Query)
     490             :    Returns true or false, for queries that return data it will return a SQLite3Result object. */
     491          32 : PHP_METHOD(sqlite3, query)
     492             : {
     493             :         php_sqlite3_db_object *db_obj;
     494             :         php_sqlite3_result *result;
     495             :         php_sqlite3_stmt *stmt_obj;
     496          64 :         zval *object = getThis();
     497             :         zval stmt;
     498             :         zend_string *sql;
     499          32 :         char *errtext = NULL;
     500             :         int return_code;
     501          32 :         db_obj = Z_SQLITE3_DB_P(object);
     502             : 
     503          32 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     504             : 
     505          32 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
     506           2 :                 return;
     507             :         }
     508             : 
     509          30 :         if (!ZSTR_LEN(sql)) {
     510           1 :                 RETURN_FALSE;
     511             :         }
     512             : 
     513             :         /* If there was no return value then just execute the query */
     514          29 :         if (!USED_RET()) {
     515           3 :                 if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
     516           2 :                         php_sqlite3_error(db_obj, "%s", errtext);
     517           2 :                         sqlite3_free(errtext);
     518             :                 }
     519           3 :                 return;
     520             :         }
     521             : 
     522          26 :         object_init_ex(&stmt, php_sqlite3_stmt_entry);
     523          26 :         stmt_obj = Z_SQLITE3_STMT_P(&stmt);
     524          26 :         stmt_obj->db_obj = db_obj;
     525          26 :         ZVAL_COPY(&stmt_obj->db_obj_zval, object);
     526             : 
     527          26 :         return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
     528          26 :         if (return_code != SQLITE_OK) {
     529           2 :                 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
     530           2 :                 zval_ptr_dtor(&stmt);
     531           2 :                 RETURN_FALSE;
     532             :         }
     533             : 
     534          24 :         stmt_obj->initialised = 1;
     535             : 
     536          24 :         object_init_ex(return_value, php_sqlite3_result_entry);
     537          24 :         result = Z_SQLITE3_RESULT_P(return_value);
     538          24 :         result->db_obj = db_obj;
     539          24 :         result->stmt_obj = stmt_obj;
     540          24 :         ZVAL_COPY_VALUE(&result->stmt_obj_zval, &stmt);
     541             : 
     542          24 :         return_code = sqlite3_step(result->stmt_obj->stmt);
     543             : 
     544          24 :         switch (return_code) {
     545             :                 case SQLITE_ROW: /* Valid Row */
     546             :                 case SQLITE_DONE: /* Valid but no results */
     547             :                 {
     548             :                         php_sqlite3_free_list *free_item;
     549          23 :                         free_item = emalloc(sizeof(php_sqlite3_free_list));
     550          23 :                         free_item->stmt_obj = stmt_obj;
     551          23 :                         free_item->stmt_obj_zval = stmt;
     552          23 :                         zend_llist_add_element(&(db_obj->free_list), &free_item);
     553          23 :                         sqlite3_reset(result->stmt_obj->stmt);
     554          23 :                         break;
     555             :                 }
     556             :                 default:
     557           1 :                         if (!EG(exception)) {
     558           0 :                                 php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
     559             :                         }
     560           1 :                         sqlite3_finalize(stmt_obj->stmt);
     561           1 :                         stmt_obj->initialised = 0;
     562             :                         zval_dtor(return_value);
     563           1 :                         RETURN_FALSE;
     564             :         }
     565             : }
     566             : /* }}} */
     567             : 
     568          92 : static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* {{{ */
     569             : {
     570          92 :         switch (sqlite3_column_type(stmt, column)) {
     571             :                 case SQLITE_INTEGER:
     572          39 :                         if ((sqlite3_column_int64(stmt, column)) >= INT_MAX || sqlite3_column_int64(stmt, column) <= INT_MIN) {
     573           2 :                                 ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column));
     574             :                         } else {
     575          37 :                                 ZVAL_LONG(data, sqlite3_column_int64(stmt, column));
     576             :                         }
     577          38 :                         break;
     578             : 
     579             :                 case SQLITE_FLOAT:
     580           4 :                         ZVAL_DOUBLE(data, sqlite3_column_double(stmt, column));
     581           4 :                         break;
     582             : 
     583             :                 case SQLITE_NULL:
     584           1 :                         ZVAL_NULL(data);
     585           1 :                         break;
     586             : 
     587             :                 case SQLITE3_TEXT:
     588          98 :                         ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column));
     589          49 :                         break;
     590             : 
     591             :                 case SQLITE_BLOB:
     592             :                 default:
     593           0 :                         ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column));
     594             :         }
     595          92 : }
     596             : /* }}} */
     597             : 
     598             : /* {{{ proto SQLite3Result SQLite3::querySingle(String Query [, bool entire_row = false])
     599             :    Returns a string of the first column, or an array of the entire row. */
     600          10 : PHP_METHOD(sqlite3, querySingle)
     601             : {
     602             :         php_sqlite3_db_object *db_obj;
     603          20 :         zval *object = getThis();
     604             :         zend_string *sql;
     605          10 :         char *errtext = NULL;
     606             :         int return_code;
     607          10 :         zend_bool entire_row = 0;
     608             :         sqlite3_stmt *stmt;
     609          10 :         db_obj = Z_SQLITE3_DB_P(object);
     610             : 
     611          10 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     612             : 
     613          10 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &sql, &entire_row)) {
     614           2 :                 return;
     615             :         }
     616             : 
     617           8 :         if (!ZSTR_LEN(sql)) {
     618           1 :                 RETURN_FALSE;
     619             :         }
     620             : 
     621             :         /* If there was no return value then just execute the query */
     622           7 :         if (!USED_RET()) {
     623           0 :                 if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
     624           0 :                         php_sqlite3_error(db_obj, "%s", errtext);
     625           0 :                         sqlite3_free(errtext);
     626             :                 }
     627           0 :                 return;
     628             :         }
     629             : 
     630           7 :         return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &stmt, NULL);
     631           7 :         if (return_code != SQLITE_OK) {
     632           0 :                 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
     633           0 :                 RETURN_FALSE;
     634             :         }
     635             : 
     636           7 :         return_code = sqlite3_step(stmt);
     637             : 
     638           7 :         switch (return_code) {
     639             :                 case SQLITE_ROW: /* Valid Row */
     640             :                 {
     641           6 :                         if (!entire_row) {
     642           4 :                                 sqlite_value_to_zval(stmt, 0, return_value);
     643             :                         } else {
     644           2 :                                 int i = 0;
     645           2 :                                 array_init(return_value);
     646           6 :                                 for (i = 0; i < sqlite3_data_count(stmt); i++) {
     647             :                                         zval data;
     648           4 :                                         sqlite_value_to_zval(stmt, i, &data);
     649           4 :                                         add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), &data);
     650             :                                 }
     651             :                         }
     652           6 :                         break;
     653             :                 }
     654             :                 case SQLITE_DONE: /* Valid but no results */
     655             :                 {
     656           0 :                         if (!entire_row) {
     657           0 :                                 RETVAL_NULL();
     658             :                         } else {
     659           0 :                                 array_init(return_value);
     660             :                         }
     661           0 :                         break;
     662             :                 }
     663             :                 default:
     664           1 :                 if (!EG(exception)) {
     665           0 :                         php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
     666             :                 }
     667           1 :                 RETVAL_FALSE;
     668             :         }
     669           7 :         sqlite3_finalize(stmt);
     670             : }
     671             : /* }}} */
     672             : 
     673          22 : static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg) /* {{{ */
     674             : {
     675          22 :         zval *zargs = NULL;
     676             :         zval retval;
     677             :         int i;
     678             :         int ret;
     679             :         int fake_argc;
     680          22 :         php_sqlite3_agg_context *agg_context = NULL;
     681             : 
     682          22 :         if (is_agg) {
     683          12 :                 is_agg = 2;
     684             :         }
     685             : 
     686          22 :         fake_argc = argc + is_agg;
     687             : 
     688          22 :         fc->fci.size = sizeof(fc->fci);
     689          22 :         ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
     690          22 :         fc->fci.object = NULL;
     691          22 :         fc->fci.retval = &retval;
     692          22 :         fc->fci.param_count = fake_argc;
     693             : 
     694             :         /* build up the params */
     695             : 
     696          22 :         if (fake_argc) {
     697          22 :                 zargs = (zval *)safe_emalloc(fake_argc, sizeof(zval), 0);
     698             :         }
     699             : 
     700          22 :         if (is_agg) {
     701             :                 /* summon the aggregation context */
     702          12 :                 agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
     703             : 
     704          24 :                 if (Z_ISUNDEF(agg_context->zval_context)) {
     705           2 :                         ZVAL_NULL(&agg_context->zval_context);
     706             :                 }
     707          12 :                 ZVAL_DUP(&zargs[0], &agg_context->zval_context);
     708          12 :                 ZVAL_LONG(&zargs[1], agg_context->row_count);
     709             :         }
     710             : 
     711          42 :         for (i = 0; i < argc; i++) {
     712          20 :                 switch (sqlite3_value_type(argv[i])) {
     713             :                         case SQLITE_INTEGER:
     714             : #if ZEND_LONG_MAX > 2147483647
     715          10 :                                 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
     716             : #else
     717             :                                 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
     718             : #endif
     719          10 :                                 break;
     720             : 
     721             :                         case SQLITE_FLOAT:
     722           0 :                                 ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
     723           0 :                                 break;
     724             : 
     725             :                         case SQLITE_NULL:
     726           0 :                                 ZVAL_NULL(&zargs[i + is_agg]);
     727           0 :                                 break;
     728             : 
     729             :                         case SQLITE_BLOB:
     730             :                         case SQLITE3_TEXT:
     731             :                         default:
     732          20 :                                 ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
     733             :                                 break;
     734             :                 }
     735             :         }
     736             : 
     737          22 :         fc->fci.params = zargs;
     738             : 
     739          22 :         if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
     740           0 :                 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
     741             :         }
     742             : 
     743          22 :         if (is_agg) {
     744          12 :                 zval_ptr_dtor(&zargs[0]);
     745             :         }
     746             : 
     747             :         /* clean up the params */
     748          22 :         if (fake_argc) {
     749          42 :                 for (i = is_agg; i < argc + is_agg; i++) {
     750          20 :                         zval_ptr_dtor(&zargs[i]);
     751             :                 }
     752          22 :                 if (is_agg) {
     753          12 :                         zval_ptr_dtor(&zargs[1]);
     754             :                 }
     755          22 :                 efree(zargs);
     756             :         }
     757             : 
     758          34 :         if (!is_agg || !argv) {
     759             :                 /* only set the sqlite return value if we are a scalar function,
     760             :                  * or if we are finalizing an aggregate */
     761          12 :                 if (!Z_ISUNDEF(retval)) {
     762           9 :                         switch (Z_TYPE(retval)) {
     763             :                                 case IS_LONG:
     764             : #if ZEND_LONG_MAX > 2147483647
     765           0 :                                         sqlite3_result_int64(context, Z_LVAL(retval));
     766             : #else
     767             :                                         sqlite3_result_int(context, Z_LVAL(retval));
     768             : #endif
     769           0 :                                         break;
     770             : 
     771             :                                 case IS_NULL:
     772           0 :                                         sqlite3_result_null(context);
     773           0 :                                         break;
     774             : 
     775             :                                 case IS_DOUBLE:
     776           0 :                                         sqlite3_result_double(context, Z_DVAL(retval));
     777           0 :                                         break;
     778             : 
     779             :                                 default:
     780           9 :                                         convert_to_string_ex(&retval);
     781           9 :                                         sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
     782             :                                         break;
     783             :                         }
     784             :                 } else {
     785           3 :                         sqlite3_result_error(context, "failed to invoke callback", 0);
     786             :                 }
     787             : 
     788          14 :                 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
     789           2 :                         zval_ptr_dtor(&agg_context->zval_context);
     790             :                 }
     791             :         } else {
     792             :                 /* we're stepping in an aggregate; the return value goes into
     793             :                  * the context */
     794          20 :                 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
     795          10 :                         zval_ptr_dtor(&agg_context->zval_context);
     796             :                 }
     797          10 :                 ZVAL_COPY_VALUE(&agg_context->zval_context, &retval);
     798          10 :                 ZVAL_UNDEF(&retval);
     799             :         }
     800             : 
     801          22 :         if (!Z_ISUNDEF(retval)) {
     802           9 :                 zval_ptr_dtor(&retval);
     803             :         }
     804          22 :         return ret;
     805             : }
     806             : /* }}}*/
     807             : 
     808          10 : static void php_sqlite3_callback_func(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
     809             : {
     810          10 :         php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
     811             : 
     812          10 :         sqlite3_do_callback(&func->afunc, &func->func, argc, argv, context, 0);
     813          10 : }
     814             : /* }}}*/
     815             : 
     816          10 : static void php_sqlite3_callback_step(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
     817             : {
     818          10 :         php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
     819          10 :         php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
     820             : 
     821          10 :         agg_context->row_count++;
     822             : 
     823          10 :         sqlite3_do_callback(&func->astep, &func->step, argc, argv, context, 1);
     824          10 : }
     825             : /* }}} */
     826             : 
     827           2 : static void php_sqlite3_callback_final(sqlite3_context *context) /* {{{ */
     828             : {
     829           2 :         php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
     830           2 :         php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
     831             : 
     832           2 :         agg_context->row_count = 0;
     833             : 
     834           2 :         sqlite3_do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
     835           2 : }
     836             : /* }}} */
     837             : 
     838           6 : static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, int b_len, const void* b) /* {{{ */
     839             : {
     840           6 :         php_sqlite3_collation *collation = (php_sqlite3_collation*)coll;
     841           6 :         zval *zargs = NULL;
     842             :         zval retval;
     843             :         int ret;
     844             : 
     845           6 :         collation->fci.fci.size = (sizeof(collation->fci.fci));
     846           6 :         ZVAL_COPY_VALUE(&collation->fci.fci.function_name, &collation->cmp_func);
     847           6 :         collation->fci.fci.object = NULL;
     848           6 :         collation->fci.fci.retval = &retval;
     849           6 :         collation->fci.fci.param_count = 2;
     850             : 
     851           6 :         zargs = safe_emalloc(2, sizeof(zval), 0);
     852          12 :         ZVAL_STRINGL(&zargs[0], a, a_len);
     853          12 :         ZVAL_STRINGL(&zargs[1], b, b_len);
     854             : 
     855           6 :         collation->fci.fci.params = zargs;
     856             : 
     857           6 :         if (!EG(exception)) {
     858             :                 //Exception occurred on previous callback. Don't attempt to call function
     859           5 :                 if ((ret = zend_call_function(&collation->fci.fci, &collation->fci.fcc)) == FAILURE) {
     860           0 :                         php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback");
     861             :                 }
     862             :         } else {
     863           1 :                 ZVAL_UNDEF(&retval);
     864             :         }
     865             : 
     866           6 :         zval_ptr_dtor(&zargs[0]);
     867           6 :         zval_ptr_dtor(&zargs[1]);
     868           6 :         efree(zargs);
     869             : 
     870           6 :         if (EG(exception)) {
     871           2 :                 ret = 0;
     872           4 :         } else if (Z_TYPE(retval) != IS_LONG){
     873             :                 //retval ought to contain a ZVAL_LONG by now
     874             :                 // (the result of a comparison, i.e. most likely -1, 0, or 1)
     875             :                 //I suppose we could accept any scalar return type, though.
     876           0 :                 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback (invalid return type).  Collation behaviour is undefined.");
     877             :         } else {
     878           4 :                 ret = Z_LVAL(retval);
     879             :         }
     880             : 
     881           6 :         zval_ptr_dtor(&retval);
     882             : 
     883           6 :         return ret;
     884             : }
     885             : /* }}} */
     886             : 
     887             : /* {{{ proto bool SQLite3::createFunction(string name, mixed callback [, int argcount])
     888             :    Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements. */
     889           5 : PHP_METHOD(sqlite3, createFunction)
     890             : {
     891             :         php_sqlite3_db_object *db_obj;
     892          10 :         zval *object = getThis();
     893             :         php_sqlite3_func *func;
     894             :         char *sql_func;
     895             :         size_t sql_func_len;
     896             :         zval *callback_func;
     897             :         zend_string *callback_name;
     898           5 :         zend_long sql_func_num_args = -1;
     899           5 :         db_obj = Z_SQLITE3_DB_P(object);
     900             : 
     901           5 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     902             : 
     903           5 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l", &sql_func, &sql_func_len, &callback_func, &sql_func_num_args) == FAILURE) {
     904           0 :                 return;
     905             :         }
     906             : 
     907           5 :         if (!sql_func_len) {
     908           0 :                 RETURN_FALSE;
     909             :         }
     910             : 
     911           5 :         if (!zend_is_callable(callback_func, 0, &callback_name)) {
     912           0 :                 php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name));
     913           0 :                 zend_string_release(callback_name);
     914           0 :                 RETURN_FALSE;
     915             :         }
     916           5 :         zend_string_release(callback_name);
     917             : 
     918           5 :         func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
     919             : 
     920           5 :         if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
     921           5 :                 func->func_name = estrdup(sql_func);
     922             : 
     923           5 :                 ZVAL_COPY(&func->func, callback_func);
     924             : 
     925           5 :                 func->argc = sql_func_num_args;
     926           5 :                 func->next = db_obj->funcs;
     927           5 :                 db_obj->funcs = func;
     928             : 
     929           5 :                 RETURN_TRUE;
     930             :         }
     931           0 :         efree(func);
     932             : 
     933           0 :         RETURN_FALSE;
     934             : }
     935             : /* }}} */
     936             : 
     937             : /* {{{ proto bool SQLite3::createAggregate(string name, mixed step, mixed final [, int argcount])
     938             :    Allows registration of a PHP function for use as an aggregate. */
     939           5 : PHP_METHOD(sqlite3, createAggregate)
     940             : {
     941             :         php_sqlite3_db_object *db_obj;
     942          10 :         zval *object = getThis();
     943             :         php_sqlite3_func *func;
     944             :         char *sql_func;
     945             :         zend_string *callback_name;
     946             :         size_t sql_func_len;
     947             :         zval *step_callback, *fini_callback;
     948           5 :         zend_long sql_func_num_args = -1;
     949           5 :         db_obj = Z_SQLITE3_DB_P(object);
     950             : 
     951           5 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
     952             : 
     953           5 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &sql_func, &sql_func_len, &step_callback, &fini_callback, &sql_func_num_args) == FAILURE) {
     954           1 :                 return;
     955             :         }
     956             : 
     957           4 :         if (!sql_func_len) {
     958           0 :                 RETURN_FALSE;
     959             :         }
     960             : 
     961           4 :         if (!zend_is_callable(step_callback, 0, &callback_name)) {
     962           1 :                 php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name));
     963           1 :                 zend_string_release(callback_name);
     964           1 :                 RETURN_FALSE;
     965             :         }
     966           3 :         zend_string_release(callback_name);
     967             : 
     968           3 :         if (!zend_is_callable(fini_callback, 0, &callback_name)) {
     969           1 :                 php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name));
     970           1 :                 zend_string_release(callback_name);
     971           1 :                 RETURN_FALSE;
     972             :         }
     973           2 :         zend_string_release(callback_name);
     974             : 
     975           2 :         func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
     976             : 
     977           2 :         if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
     978           2 :                 func->func_name = estrdup(sql_func);
     979             : 
     980           2 :                 ZVAL_COPY(&func->step, step_callback);
     981           2 :                 ZVAL_COPY(&func->fini, fini_callback);
     982             : 
     983           2 :                 func->argc = sql_func_num_args;
     984           2 :                 func->next = db_obj->funcs;
     985           2 :                 db_obj->funcs = func;
     986             : 
     987           2 :                 RETURN_TRUE;
     988             :         }
     989           0 :         efree(func);
     990             : 
     991           0 :         RETURN_FALSE;
     992             : }
     993             : /* }}} */
     994             : 
     995             : /* {{{ proto bool SQLite3::createCollation(string name, mixed callback)
     996             :    Registers a PHP function as a comparator that can be used with the SQL COLLATE operator. Callback must accept two strings and return an integer (as strcmp()). */
     997           2 : PHP_METHOD(sqlite3, createCollation)
     998             : {
     999             :         php_sqlite3_db_object *db_obj;
    1000           4 :         zval *object = getThis();
    1001             :         php_sqlite3_collation *collation;
    1002             :         char *collation_name;
    1003             :         zend_string *callback_name;
    1004             :         size_t collation_name_len;
    1005             :         zval *callback_func;
    1006           2 :         db_obj = Z_SQLITE3_DB_P(object);
    1007             : 
    1008           2 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
    1009             : 
    1010           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &collation_name, &collation_name_len, &callback_func) == FAILURE) {
    1011           0 :                 RETURN_FALSE;
    1012             :         }
    1013             : 
    1014           2 :         if (!collation_name_len) {
    1015           0 :                 RETURN_FALSE;
    1016             :         }
    1017             : 
    1018           2 :         if (!zend_is_callable(callback_func, 0, &callback_name)) {
    1019           0 :                 php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name));
    1020           0 :                 zend_string_release(callback_name);
    1021           0 :                 RETURN_FALSE;
    1022             :         }
    1023           2 :         zend_string_release(callback_name);
    1024             : 
    1025           2 :         collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation));
    1026           2 :         if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
    1027           2 :                 collation->collation_name = estrdup(collation_name);
    1028             : 
    1029           2 :                 ZVAL_COPY(&collation->cmp_func, callback_func);
    1030             : 
    1031           2 :                 collation->next = db_obj->collations;
    1032           2 :                 db_obj->collations = collation;
    1033             : 
    1034           2 :                 RETURN_TRUE;
    1035             :         }
    1036           0 :         efree(collation);
    1037             : 
    1038           0 :         RETURN_FALSE;
    1039             : }
    1040             : /* }}} */
    1041             : 
    1042             : typedef struct {
    1043             :         sqlite3_blob *blob;
    1044             :         size_t           position;
    1045             :         size_t       size;
    1046             : } php_stream_sqlite3_data;
    1047             : 
    1048           0 : static size_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
    1049             : {
    1050             : /*      php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; */
    1051             : 
    1052           0 :         return 0;
    1053             : }
    1054             : 
    1055           2 : static size_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count)
    1056             : {
    1057           2 :         php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
    1058             : 
    1059           2 :         if (sqlite3_stream->position + count >= sqlite3_stream->size) {
    1060           2 :                 count = sqlite3_stream->size - sqlite3_stream->position;
    1061           2 :                 stream->eof = 1;
    1062             :         }
    1063           2 :         if (count) {
    1064           1 :                 if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
    1065           0 :                         return 0;
    1066             :                 }
    1067           1 :                 sqlite3_stream->position += count;
    1068             :         }
    1069           2 :         return count;
    1070             : }
    1071             : 
    1072           1 : static int php_sqlite3_stream_close(php_stream *stream, int close_handle)
    1073             : {
    1074           1 :         php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
    1075             : 
    1076           1 :         if (sqlite3_blob_close(sqlite3_stream->blob) != SQLITE_OK) {
    1077             :                 /* Error occurred, but it still closed */
    1078             :         }
    1079             : 
    1080           1 :         efree(sqlite3_stream);
    1081             : 
    1082           1 :         return 0;
    1083             : }
    1084             : 
    1085           0 : static int php_sqlite3_stream_flush(php_stream *stream)
    1086             : {
    1087             :         /* do nothing */
    1088           0 :         return 0;
    1089             : }
    1090             : 
    1091             : /* {{{ */
    1092           0 : static int php_sqlite3_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs)
    1093             : {
    1094           0 :         php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
    1095             : 
    1096           0 :         switch(whence) {
    1097             :                 case SEEK_CUR:
    1098           0 :                         if (offset < 0) {
    1099           0 :                                 if (sqlite3_stream->position < (size_t)(-offset)) {
    1100           0 :                                         sqlite3_stream->position = 0;
    1101           0 :                                         *newoffs = -1;
    1102           0 :                                         return -1;
    1103             :                                 } else {
    1104           0 :                                         sqlite3_stream->position = sqlite3_stream->position + offset;
    1105           0 :                                         *newoffs = sqlite3_stream->position;
    1106           0 :                                         stream->eof = 0;
    1107           0 :                                         return 0;
    1108             :                                 }
    1109             :                         } else {
    1110           0 :                                 if (sqlite3_stream->position + (size_t)(offset) > sqlite3_stream->size) {
    1111           0 :                                         sqlite3_stream->position = sqlite3_stream->size;
    1112           0 :                                         *newoffs = -1;
    1113           0 :                                         return -1;
    1114             :                                 } else {
    1115           0 :                                         sqlite3_stream->position = sqlite3_stream->position + offset;
    1116           0 :                                         *newoffs = sqlite3_stream->position;
    1117           0 :                                         stream->eof = 0;
    1118           0 :                                         return 0;
    1119             :                                 }
    1120             :                         }
    1121             :                 case SEEK_SET:
    1122           0 :                         if (sqlite3_stream->size < (size_t)(offset)) {
    1123           0 :                                 sqlite3_stream->position = sqlite3_stream->size;
    1124           0 :                                 *newoffs = -1;
    1125           0 :                                 return -1;
    1126             :                         } else {
    1127           0 :                                 sqlite3_stream->position = offset;
    1128           0 :                                 *newoffs = sqlite3_stream->position;
    1129           0 :                                 stream->eof = 0;
    1130           0 :                                 return 0;
    1131             :                         }
    1132             :                 case SEEK_END:
    1133           0 :                         if (offset > 0) {
    1134           0 :                                 sqlite3_stream->position = sqlite3_stream->size;
    1135           0 :                                 *newoffs = -1;
    1136           0 :                                 return -1;
    1137           0 :                         } else if (sqlite3_stream->size < (size_t)(-offset)) {
    1138           0 :                                 sqlite3_stream->position = 0;
    1139           0 :                                 *newoffs = -1;
    1140           0 :                                 return -1;
    1141             :                         } else {
    1142           0 :                                 sqlite3_stream->position = sqlite3_stream->size + offset;
    1143           0 :                                 *newoffs = sqlite3_stream->position;
    1144           0 :                                 stream->eof = 0;
    1145           0 :                                 return 0;
    1146             :                         }
    1147             :                 default:
    1148           0 :                         *newoffs = sqlite3_stream->position;
    1149           0 :                         return -1;
    1150             :         }
    1151             : }
    1152             : /* }}} */
    1153             : 
    1154             : 
    1155           0 : static int php_sqlite3_stream_cast(php_stream *stream, int castas, void **ret)
    1156             : {
    1157           0 :         return FAILURE;
    1158             : }
    1159             : 
    1160           1 : static int php_sqlite3_stream_stat(php_stream *stream, php_stream_statbuf *ssb)
    1161             : {
    1162           1 :         php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
    1163           1 :         ssb->sb.st_size = sqlite3_stream->size;
    1164           1 :         return 0;
    1165             : }
    1166             : 
    1167             : static php_stream_ops php_stream_sqlite3_ops = {
    1168             :         php_sqlite3_stream_write,
    1169             :         php_sqlite3_stream_read,
    1170             :         php_sqlite3_stream_close,
    1171             :         php_sqlite3_stream_flush,
    1172             :         "SQLite3",
    1173             :         php_sqlite3_stream_seek,
    1174             :         php_sqlite3_stream_cast,
    1175             :         php_sqlite3_stream_stat,
    1176             :         NULL
    1177             : };
    1178             : 
    1179             : /* {{{ proto resource SQLite3::openBlob(string table, string column, int rowid [, string dbname])
    1180             :    Open a blob as a stream which we can read / write to. */
    1181           2 : PHP_METHOD(sqlite3, openBlob)
    1182             : {
    1183             :         php_sqlite3_db_object *db_obj;
    1184           4 :         zval *object = getThis();
    1185           2 :         char *table, *column, *dbname = "main";
    1186             :         size_t table_len, column_len, dbname_len;
    1187           2 :         zend_long rowid, flags = 0;
    1188           2 :         sqlite3_blob *blob = NULL;
    1189             :         php_stream_sqlite3_data *sqlite3_stream;
    1190             :         php_stream *stream;
    1191             : 
    1192           2 :         db_obj = Z_SQLITE3_DB_P(object);
    1193             : 
    1194           2 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
    1195             : 
    1196           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl|s", &table, &table_len, &column, &column_len, &rowid, &dbname, &dbname_len) == FAILURE) {
    1197           1 :                 return;
    1198             :         }
    1199             : 
    1200           1 :         if (sqlite3_blob_open(db_obj->db, dbname, table, column, rowid, flags, &blob) != SQLITE_OK) {
    1201           0 :                 php_sqlite3_error(db_obj, "Unable to open blob: %s", sqlite3_errmsg(db_obj->db));
    1202           0 :                 RETURN_FALSE;
    1203             :         }
    1204             : 
    1205           1 :         sqlite3_stream = emalloc(sizeof(php_stream_sqlite3_data));
    1206           1 :         sqlite3_stream->blob = blob;
    1207           1 :         sqlite3_stream->position = 0;
    1208           1 :         sqlite3_stream->size = sqlite3_blob_bytes(blob);
    1209             : 
    1210           1 :         stream = php_stream_alloc(&php_stream_sqlite3_ops, sqlite3_stream, 0, "rb");
    1211             : 
    1212           1 :         if (stream) {
    1213           1 :                 php_stream_to_zval(stream, return_value);
    1214             :         } else {
    1215           0 :                 RETURN_FALSE;
    1216             :         }
    1217             : }
    1218             : /* }}} */
    1219             : 
    1220             : /* {{{ proto bool SQLite3::enableExceptions([bool enableExceptions = false])
    1221             :    Enables an exception error mode. */
    1222           3 : PHP_METHOD(sqlite3, enableExceptions)
    1223             : {
    1224             :         php_sqlite3_db_object *db_obj;
    1225           6 :         zval *object = getThis();
    1226           3 :         zend_bool enableExceptions = 0;
    1227             : 
    1228           3 :         db_obj = Z_SQLITE3_DB_P(object);
    1229             : 
    1230           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enableExceptions) == FAILURE) {
    1231           1 :                 return;
    1232             :         }
    1233             : 
    1234           2 :         RETVAL_BOOL(db_obj->exception);
    1235             : 
    1236           2 :         db_obj->exception = enableExceptions;
    1237             : }
    1238             : /* }}} */
    1239             : 
    1240             : /* {{{ proto int SQLite3Stmt::paramCount()
    1241             :    Returns the number of parameters within the prepared statement. */
    1242           5 : PHP_METHOD(sqlite3stmt, paramCount)
    1243             : {
    1244             :         php_sqlite3_stmt *stmt_obj;
    1245          10 :         zval *object = getThis();
    1246           5 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1247             : 
    1248           5 :         if (zend_parse_parameters_none() == FAILURE) {
    1249           1 :                 return;
    1250             :         }
    1251             : 
    1252           4 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1253           4 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1254             : 
    1255           4 :         RETURN_LONG(sqlite3_bind_parameter_count(stmt_obj->stmt));
    1256             : }
    1257             : /* }}} */
    1258             : 
    1259             : /* {{{ proto bool SQLite3Stmt::close()
    1260             :    Closes the prepared statement. */
    1261           6 : PHP_METHOD(sqlite3stmt, close)
    1262             : {
    1263             :         php_sqlite3_stmt *stmt_obj;
    1264          12 :         zval *object = getThis();
    1265           6 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1266             : 
    1267           6 :         if (zend_parse_parameters_none() == FAILURE) {
    1268           0 :                 return;
    1269             :         }
    1270             : 
    1271           6 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1272             : 
    1273           6 :         if(stmt_obj->db_obj) {
    1274           6 :                 zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
    1275             :         }
    1276             : 
    1277           6 :         RETURN_TRUE;
    1278             : }
    1279             : /* }}} */
    1280             : 
    1281             : /* {{{ proto bool SQLite3Stmt::reset()
    1282             :    Reset the prepared statement to the state before it was executed, bindings still remain. */
    1283           7 : PHP_METHOD(sqlite3stmt, reset)
    1284             : {
    1285             :         php_sqlite3_stmt *stmt_obj;
    1286          14 :         zval *object = getThis();
    1287           7 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1288             : 
    1289           7 :         if (zend_parse_parameters_none() == FAILURE) {
    1290           2 :                 return;
    1291             :         }
    1292             : 
    1293           5 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1294           4 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1295             : 
    1296           4 :         if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) {
    1297           0 :                 php_sqlite3_error(stmt_obj->db_obj, "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
    1298           0 :                 RETURN_FALSE;
    1299             :         }
    1300           4 :         RETURN_TRUE;
    1301             : }
    1302             : /* }}} */
    1303             : 
    1304             : /* {{{ proto bool SQLite3Stmt::clear()
    1305             :    Clear all current bound parameters. */
    1306           3 : PHP_METHOD(sqlite3stmt, clear)
    1307             : {
    1308             :         php_sqlite3_stmt *stmt_obj;
    1309           6 :         zval *object = getThis();
    1310           3 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1311             : 
    1312           3 :         if (zend_parse_parameters_none() == FAILURE) {
    1313           1 :                 return;
    1314             :         }
    1315             : 
    1316           2 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1317           2 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1318             : 
    1319           2 :         if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) {
    1320           0 :                 php_sqlite3_error(stmt_obj->db_obj, "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
    1321           0 :                 RETURN_FALSE;
    1322             :         }
    1323             : 
    1324           2 :         if (stmt_obj->bound_params) {
    1325           2 :                 zend_hash_destroy(stmt_obj->bound_params);
    1326           2 :                 FREE_HASHTABLE(stmt_obj->bound_params);
    1327           2 :                 stmt_obj->bound_params = NULL;
    1328             :         }
    1329             : 
    1330           2 :         RETURN_TRUE;
    1331             : }
    1332             : /* }}} */
    1333             : 
    1334             : /* {{{ proto bool SQLite3Stmt::readOnly()
    1335             :    Returns true if a statement is definitely read only */
    1336           3 : PHP_METHOD(sqlite3stmt, readOnly)
    1337             : {
    1338             :         php_sqlite3_stmt *stmt_obj;
    1339           6 :         zval *object = getThis();
    1340           3 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1341             : 
    1342           3 :         if (zend_parse_parameters_none() == FAILURE) {
    1343           0 :                 return;
    1344             :         }
    1345             : 
    1346           3 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1347           3 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1348             : 
    1349             : #if SQLITE_VERSION_NUMBER >= 3007004
    1350           3 :         if (sqlite3_stmt_readonly(stmt_obj->stmt)) {
    1351           1 :                 RETURN_TRUE;
    1352             :         }
    1353             : #endif
    1354           2 :         RETURN_FALSE;
    1355             : }
    1356             : /* }}} */
    1357             : 
    1358          33 : static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
    1359             : {
    1360             :         HashTable *hash;
    1361          33 :         hash = stmt->bound_params;
    1362             : 
    1363          33 :         if (!hash) {
    1364          23 :                 ALLOC_HASHTABLE(hash);
    1365          23 :                 zend_hash_init(hash, 13, NULL, sqlite3_param_dtor, 0);
    1366          23 :                 stmt->bound_params = hash;
    1367             :         }
    1368             : 
    1369             :         /* We need a : prefix to resolve a name to a parameter number */
    1370          33 :         if (param->name) {
    1371          10 :                 if (ZSTR_VAL(param->name)[0] != ':') {
    1372             :                         /* pre-increment for character + 1 for null */
    1373           2 :                         zend_string *temp = zend_string_alloc(ZSTR_LEN(param->name) + 1, 0);
    1374           1 :                         ZSTR_VAL(temp)[0] = ':';
    1375           1 :                         memmove(ZSTR_VAL(temp) + 1, ZSTR_VAL(param->name), ZSTR_LEN(param->name) + 1);
    1376           1 :                         param->name = temp;
    1377             :                 } else {
    1378          18 :                         param->name = zend_string_init(ZSTR_VAL(param->name), ZSTR_LEN(param->name), 0);
    1379             :                 }
    1380             :                 /* do lookup*/
    1381          10 :                 param->param_number = sqlite3_bind_parameter_index(stmt->stmt, ZSTR_VAL(param->name));
    1382             :         }
    1383             : 
    1384          33 :         if (param->param_number < 1) {
    1385           1 :                 if (param->name) {
    1386           0 :                         zend_string_release(param->name);
    1387             :                 }
    1388           1 :                 return 0;
    1389             :         }
    1390             : 
    1391          32 :         if (param->param_number >= 1) {
    1392          32 :                 zend_hash_index_del(hash, param->param_number);
    1393             :         }
    1394             : 
    1395          32 :         if (param->name) {
    1396          10 :                 zend_hash_update_mem(hash, param->name, param, sizeof(struct php_sqlite3_bound_param));
    1397             :         } else {
    1398          22 :                 zend_hash_index_update_mem(hash, param->param_number, param, sizeof(struct php_sqlite3_bound_param));
    1399             :         }
    1400             : 
    1401          32 :         return 1;
    1402             : }
    1403             : /* }}} */
    1404             : 
    1405             : /* {{{ Best try to map between PHP and SQLite. Default is still text. */
    1406             : #define PHP_SQLITE3_SET_TYPE(z, p) \
    1407             :         switch (Z_TYPE_P(z)) { \
    1408             :                 default: \
    1409             :                         (p).type = SQLITE_TEXT; \
    1410             :                         break; \
    1411             :                 case IS_LONG: \
    1412             :                 case IS_TRUE: \
    1413             :                 case IS_FALSE: \
    1414             :                         (p).type = SQLITE_INTEGER; \
    1415             :                         break; \
    1416             :                 case IS_DOUBLE: \
    1417             :                         (p).type = SQLITE_FLOAT; \
    1418             :                         break; \
    1419             :                 case IS_NULL: \
    1420             :                         (p).type = SQLITE_NULL; \
    1421             :                         break; \
    1422             :         }
    1423             : /* }}} */
    1424             : 
    1425             : /* {{{ proto bool SQLite3Stmt::bindParam(int parameter_number, mixed parameter [, int type])
    1426             :    Bind Parameter to a stmt variable. */
    1427          12 : PHP_METHOD(sqlite3stmt, bindParam)
    1428             : {
    1429             :         php_sqlite3_stmt *stmt_obj;
    1430          24 :         zval *object = getThis();
    1431          12 :         struct php_sqlite3_bound_param param = {0};
    1432             :         zval *parameter;
    1433          12 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1434             : 
    1435          12 :         param.param_number = -1;
    1436          12 :         param.type = SQLITE3_TEXT;
    1437             : 
    1438          12 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "lz|l", &param.param_number, &parameter, &param.type) == FAILURE) {
    1439           0 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz|l", &param.name, &parameter, &param.type) == FAILURE) {
    1440           0 :                         return;
    1441             :                 }
    1442             :         }
    1443             : 
    1444          12 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1445          12 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1446             : 
    1447          12 :         ZVAL_COPY(&param.parameter, parameter);
    1448             : 
    1449          12 :         if (ZEND_NUM_ARGS() < 3) {
    1450           8 :                 PHP_SQLITE3_SET_TYPE(parameter, param);
    1451             :         }
    1452             : 
    1453          12 :         if (!register_bound_parameter_to_sqlite(&param, stmt_obj)) {
    1454           1 :                 if (!Z_ISUNDEF(param.parameter)) {
    1455           1 :                         zval_ptr_dtor(&(param.parameter));
    1456           1 :                         ZVAL_UNDEF(&param.parameter);
    1457             :                 }
    1458           1 :                 RETURN_FALSE;
    1459             :         }
    1460          11 :         RETURN_TRUE;
    1461             : }
    1462             : /* }}} */
    1463             : 
    1464             : /* {{{ proto bool SQLite3Stmt::bindValue(int parameter_number, mixed parameter [, int type])
    1465             :    Bind Value of a parameter to a stmt variable. */
    1466          21 : PHP_METHOD(sqlite3stmt, bindValue)
    1467             : {
    1468             :         php_sqlite3_stmt *stmt_obj;
    1469          42 :         zval *object = getThis();
    1470          21 :         struct php_sqlite3_bound_param param = {0};
    1471             :         zval *parameter;
    1472          21 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1473             : 
    1474          21 :         param.param_number = -1;
    1475          21 :         param.type = SQLITE3_TEXT;
    1476             : 
    1477          21 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "lz/|l", &param.param_number, &parameter, &param.type) == FAILURE) {
    1478          10 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz/|l", &param.name, &parameter, &param.type) == FAILURE) {
    1479           0 :                         return;
    1480             :                 }
    1481             :         }
    1482             : 
    1483          21 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1484          21 :         SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
    1485             : 
    1486          21 :         ZVAL_COPY(&param.parameter, parameter);
    1487             : 
    1488          21 :         if (ZEND_NUM_ARGS() < 3) {
    1489           8 :                 PHP_SQLITE3_SET_TYPE(parameter, param);
    1490             :         }
    1491             : 
    1492          21 :         if (!register_bound_parameter_to_sqlite(&param, stmt_obj)) {
    1493           0 :                 if (!Z_ISUNDEF(param.parameter)) {
    1494           0 :                         zval_ptr_dtor(&(param.parameter));
    1495           0 :                         ZVAL_UNDEF(&param.parameter);
    1496             :                 }
    1497           0 :                 RETURN_FALSE;
    1498             :         }
    1499          21 :         RETURN_TRUE;
    1500             : }
    1501             : /* }}} */
    1502             : 
    1503             : #undef PHP_SQLITE3_SET_TYPE
    1504             : 
    1505             : /* {{{ proto SQLite3Result SQLite3Stmt::execute()
    1506             :    Executes a prepared statement and returns a result set object. */
    1507          30 : PHP_METHOD(sqlite3stmt, execute)
    1508             : {
    1509             :         php_sqlite3_stmt *stmt_obj;
    1510             :         php_sqlite3_result *result;
    1511          60 :         zval *object = getThis();
    1512          30 :         int return_code = 0;
    1513             :         struct php_sqlite3_bound_param *param;
    1514             : 
    1515          30 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1516             : 
    1517          30 :         if (zend_parse_parameters_none() == FAILURE) {
    1518           0 :                 return;
    1519             :         }
    1520             : 
    1521          30 :         SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
    1522             : 
    1523          30 :         if (stmt_obj->bound_params) {
    1524         122 :                 ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
    1525             :                         zval *parameter;
    1526             :                         /* parameter must be a reference? */
    1527          60 :                         if (Z_ISREF(param->parameter)) {
    1528          11 :                                 parameter = Z_REFVAL(param->parameter);
    1529             :                         } else {
    1530          19 :                                 parameter = &param->parameter;
    1531             :                         }
    1532             : 
    1533             :                         /* If the ZVAL is null then it should be bound as that */
    1534          30 :                         if (Z_TYPE_P(parameter) == IS_NULL) {
    1535           1 :                                 sqlite3_bind_null(stmt_obj->stmt, param->param_number);
    1536           1 :                                 continue;
    1537             :                         }
    1538             : 
    1539          29 :                         switch (param->type) {
    1540             :                                 case SQLITE_INTEGER:
    1541           7 :                                         convert_to_long(parameter);
    1542             : #if ZEND_LONG_MAX > 2147483647
    1543           7 :                                         sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
    1544             : #else
    1545             :                                         sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
    1546             : #endif
    1547           7 :                                         break;
    1548             : 
    1549             :                                 case SQLITE_FLOAT:
    1550             :                                         /* convert_to_double(parameter);*/
    1551           1 :                                         sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter));
    1552           1 :                                         break;
    1553             : 
    1554             :                                 case SQLITE_BLOB:
    1555             :                                 {
    1556           5 :                                         php_stream *stream = NULL;
    1557           5 :                                         zend_string *buffer = NULL;
    1558           5 :                                         if (Z_TYPE_P(parameter) == IS_RESOURCE) {
    1559           2 :                                                 php_stream_from_zval_no_verify(stream, parameter);
    1560           2 :                                                 if (stream == NULL) {
    1561           0 :                                                         php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number);
    1562           0 :                                                         RETURN_FALSE;
    1563             :                                                 }
    1564           2 :                                                 buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
    1565             :                                         } else {
    1566           3 :                                                 buffer = zval_get_string(parameter);
    1567             :                                         }
    1568             : 
    1569           5 :                                         if (buffer) {
    1570           4 :                                                 sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT);
    1571             :                                                 zend_string_release(buffer);
    1572             :                                         } else {
    1573           1 :                                                 sqlite3_bind_null(stmt_obj->stmt, param->param_number);
    1574             :                                         }
    1575           5 :                                         break;
    1576             :                                 }
    1577             : 
    1578             :                                 case SQLITE3_TEXT:
    1579          16 :                                         convert_to_string(parameter);
    1580          16 :                                         sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), SQLITE_STATIC);
    1581          16 :                                         break;
    1582             : 
    1583             :                                 case SQLITE_NULL:
    1584           0 :                                         sqlite3_bind_null(stmt_obj->stmt, param->param_number);
    1585           0 :                                         break;
    1586             : 
    1587             :                                 default:
    1588           0 :                                         php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
    1589           0 :                                         RETURN_FALSE;
    1590             :                         }
    1591             :                 } ZEND_HASH_FOREACH_END();
    1592             :         }
    1593             : 
    1594          30 :         return_code = sqlite3_step(stmt_obj->stmt);
    1595             : 
    1596          30 :         switch (return_code) {
    1597             :                 case SQLITE_ROW: /* Valid Row */
    1598             :                 case SQLITE_DONE: /* Valid but no results */
    1599             :                 {
    1600          29 :                         sqlite3_reset(stmt_obj->stmt);
    1601          29 :                         object_init_ex(return_value, php_sqlite3_result_entry);
    1602          29 :                         result = Z_SQLITE3_RESULT_P(return_value);
    1603             : 
    1604          29 :                         result->is_prepared_statement = 1;
    1605          29 :                         result->db_obj = stmt_obj->db_obj;
    1606          29 :                         result->stmt_obj = stmt_obj;
    1607          29 :                         ZVAL_COPY(&result->stmt_obj_zval, object);
    1608             : 
    1609          29 :                         break;
    1610             :                 }
    1611             :                 case SQLITE_ERROR:
    1612           1 :                         sqlite3_reset(stmt_obj->stmt);
    1613             : 
    1614             :                 default:
    1615           1 :                         if (!EG(exception)) {
    1616           0 :                                 php_sqlite3_error(stmt_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
    1617             :                         }
    1618             :                         zval_dtor(return_value);
    1619           1 :                         RETURN_FALSE;
    1620             :         }
    1621             : 
    1622          29 :         return;
    1623             : }
    1624             : /* }}} */
    1625             : 
    1626             : /* {{{ proto int SQLite3Stmt::__construct(SQLite3 dbobject, String Statement)
    1627             :    __constructor for SQLite3Stmt. */
    1628           0 : PHP_METHOD(sqlite3stmt, __construct)
    1629             : {
    1630             :         php_sqlite3_stmt *stmt_obj;
    1631             :         php_sqlite3_db_object *db_obj;
    1632           0 :         zval *object = getThis();
    1633             :         zval *db_zval;
    1634             :         zend_string *sql;
    1635             :         int errcode;
    1636             :         zend_error_handling error_handling;
    1637             :         php_sqlite3_free_list *free_item;
    1638             : 
    1639           0 :         stmt_obj = Z_SQLITE3_STMT_P(object);
    1640             : 
    1641           0 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "OS", &db_zval, php_sqlite3_sc_entry, &sql) == FAILURE) {
    1642           0 :                 return;
    1643             :         }
    1644             : 
    1645           0 :         db_obj = Z_SQLITE3_DB_P(db_zval);
    1646             : 
    1647           0 :         zend_replace_error_handling(EH_THROW, NULL, &error_handling);
    1648           0 :         SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
    1649           0 :         zend_restore_error_handling(&error_handling);
    1650             : 
    1651           0 :         if (!ZSTR_LEN(sql)) {
    1652           0 :                 RETURN_FALSE;
    1653             :         }
    1654             : 
    1655           0 :         stmt_obj->db_obj = db_obj;
    1656           0 :         ZVAL_COPY(&stmt_obj->db_obj_zval, db_zval);
    1657             : 
    1658           0 :         errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
    1659           0 :         if (errcode != SQLITE_OK) {
    1660           0 :                 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
    1661             :                 zval_dtor(return_value);
    1662           0 :                 RETURN_FALSE;
    1663             :         }
    1664           0 :         stmt_obj->initialised = 1;
    1665             : 
    1666           0 :         free_item = emalloc(sizeof(php_sqlite3_free_list));
    1667           0 :         free_item->stmt_obj = stmt_obj;
    1668             :         //??  free_item->stmt_obj_zval = getThis();
    1669           0 :         ZVAL_COPY_VALUE(&free_item->stmt_obj_zval, object);
    1670             : 
    1671           0 :         zend_llist_add_element(&(db_obj->free_list), &free_item);
    1672             : }
    1673             : /* }}} */
    1674             : 
    1675             : /* {{{ proto int SQLite3Result::numColumns()
    1676             :    Number of columns in the result set. */
    1677           4 : PHP_METHOD(sqlite3result, numColumns)
    1678             : {
    1679             :         php_sqlite3_result *result_obj;
    1680           8 :         zval *object = getThis();
    1681           4 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1682             : 
    1683           4 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1684             : 
    1685           3 :         if (zend_parse_parameters_none() == FAILURE) {
    1686           1 :                 return;
    1687             :         }
    1688             : 
    1689           2 :         RETURN_LONG(sqlite3_column_count(result_obj->stmt_obj->stmt));
    1690             : }
    1691             : /* }}} */
    1692             : 
    1693             : /* {{{ proto string SQLite3Result::columnName(int column)
    1694             :    Returns the name of the nth column. */
    1695           6 : PHP_METHOD(sqlite3result, columnName)
    1696             : {
    1697             :         php_sqlite3_result *result_obj;
    1698          12 :         zval *object = getThis();
    1699           6 :         zend_long column = 0;
    1700             :         char *column_name;
    1701           6 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1702             : 
    1703           6 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1704             : 
    1705           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &column) == FAILURE) {
    1706           0 :                 return;
    1707             :         }
    1708           6 :         column_name = (char*) sqlite3_column_name(result_obj->stmt_obj->stmt, column);
    1709             : 
    1710           6 :         if (column_name == NULL) {
    1711           1 :                 RETURN_FALSE;
    1712             :         }
    1713             : 
    1714          10 :         RETVAL_STRING(column_name);
    1715             : }
    1716             : /* }}} */
    1717             : 
    1718             : /* {{{ proto int SQLite3Result::columnType(int column)
    1719             :    Returns the type of the nth column. */
    1720           4 : PHP_METHOD(sqlite3result, columnType)
    1721             : {
    1722             :         php_sqlite3_result *result_obj;
    1723           8 :         zval *object = getThis();
    1724           4 :         zend_long column = 0;
    1725           4 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1726             : 
    1727           4 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1728             : 
    1729           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &column) == FAILURE) {
    1730           0 :                 return;
    1731             :         }
    1732             : 
    1733           4 :         if (result_obj->complete) {
    1734           0 :                 RETURN_FALSE;
    1735             :         }
    1736             : 
    1737           4 :         RETURN_LONG(sqlite3_column_type(result_obj->stmt_obj->stmt, column));
    1738             : }
    1739             : /* }}} */
    1740             : 
    1741             : /* {{{ proto array SQLite3Result::fetchArray([int mode])
    1742             :    Fetch a result row as both an associative or numerically indexed array or both. */
    1743          70 : PHP_METHOD(sqlite3result, fetchArray)
    1744             : {
    1745             :         php_sqlite3_result *result_obj;
    1746         140 :         zval *object = getThis();
    1747             :         int i, ret;
    1748          70 :         zend_long mode = PHP_SQLITE3_BOTH;
    1749          70 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1750             : 
    1751          70 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1752             : 
    1753          70 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &mode) == FAILURE) {
    1754           1 :                 return;
    1755             :         }
    1756             : 
    1757          69 :         ret = sqlite3_step(result_obj->stmt_obj->stmt);
    1758          69 :         switch (ret) {
    1759             :                 case SQLITE_ROW:
    1760             :                         /* If there was no return value then just skip fetching */
    1761          43 :                         if (!USED_RET()) {
    1762           0 :                                 return;
    1763             :                         }
    1764             : 
    1765          43 :                         array_init(return_value);
    1766             : 
    1767         127 :                         for (i = 0; i < sqlite3_data_count(result_obj->stmt_obj->stmt); i++) {
    1768             :                                 zval data;
    1769             : 
    1770          84 :                                 sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
    1771             : 
    1772          84 :                                 if (mode & PHP_SQLITE3_NUM) {
    1773          64 :                                         add_index_zval(return_value, i, &data);
    1774             :                                 }
    1775             : 
    1776          84 :                                 if (mode & PHP_SQLITE3_ASSOC) {
    1777          29 :                                         if (mode & PHP_SQLITE3_NUM) {
    1778           9 :                                                 if (Z_REFCOUNTED(data)) {
    1779             :                                                         Z_ADDREF(data);
    1780             :                                                 }
    1781             :                                         }
    1782          29 :                                         add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), &data);
    1783             :                                 }
    1784             :                         }
    1785          43 :                         break;
    1786             : 
    1787             :                 case SQLITE_DONE:
    1788          26 :                         result_obj->complete = 1;
    1789          26 :                         RETURN_FALSE;
    1790             :                         break;
    1791             : 
    1792             :                 default:
    1793           0 :                         php_sqlite3_error(result_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt)));
    1794             :         }
    1795             : }
    1796             : /* }}} */
    1797             : 
    1798             : /* {{{ proto bool SQLite3Result::reset()
    1799             :    Resets the result set back to the first row. */
    1800           2 : PHP_METHOD(sqlite3result, reset)
    1801             : {
    1802             :         php_sqlite3_result *result_obj;
    1803           4 :         zval *object = getThis();
    1804           2 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1805             : 
    1806           2 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1807             : 
    1808           2 :         if (zend_parse_parameters_none() == FAILURE) {
    1809           1 :                 return;
    1810             :         }
    1811             : 
    1812           1 :         if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) {
    1813           0 :                 RETURN_FALSE;
    1814             :         }
    1815             : 
    1816           1 :         result_obj->complete = 0;
    1817             : 
    1818           1 :         RETURN_TRUE;
    1819             : }
    1820             : /* }}} */
    1821             : 
    1822             : /* {{{ proto bool SQLite3Result::finalize()
    1823             :    Closes the result set. */
    1824          19 : PHP_METHOD(sqlite3result, finalize)
    1825             : {
    1826             :         php_sqlite3_result *result_obj;
    1827          38 :         zval *object = getThis();
    1828          19 :         result_obj = Z_SQLITE3_RESULT_P(object);
    1829             : 
    1830          19 :         SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
    1831             : 
    1832          19 :         if (zend_parse_parameters_none() == FAILURE) {
    1833           0 :                 return;
    1834             :         }
    1835             : 
    1836             :         /* We need to finalize an internal statement */
    1837          19 :         if (result_obj->is_prepared_statement == 0) {
    1838          12 :                 zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
    1839             :                         (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
    1840             :         } else {
    1841           7 :                 sqlite3_reset(result_obj->stmt_obj->stmt);
    1842             :         }
    1843             : 
    1844          19 :         RETURN_TRUE;
    1845             : }
    1846             : /* }}} */
    1847             : 
    1848             : /* {{{ proto int SQLite3Result::__construct()
    1849             :    __constructor for SQLite3Result. */
    1850           0 : PHP_METHOD(sqlite3result, __construct)
    1851             : {
    1852           0 :         zend_throw_exception(zend_ce_exception, "SQLite3Result cannot be directly instantiated", 0);
    1853           0 : }
    1854             : /* }}} */
    1855             : 
    1856             : /* {{{ arginfo */
    1857             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_open, 0, 0, 1)
    1858             :         ZEND_ARG_INFO(0, filename)
    1859             :         ZEND_ARG_INFO(0, flags)
    1860             :         ZEND_ARG_INFO(0, encryption_key)
    1861             : ZEND_END_ARG_INFO()
    1862             : 
    1863             : ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_busytimeout, 0)
    1864             :         ZEND_ARG_INFO(0, ms)
    1865             : ZEND_END_ARG_INFO()
    1866             : 
    1867             : #ifndef SQLITE_OMIT_LOAD_EXTENSION
    1868             : ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_loadextension, 0)
    1869             :         ZEND_ARG_INFO(0, shared_library)
    1870             : ZEND_END_ARG_INFO()
    1871             : #endif
    1872             : 
    1873             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_escapestring, 0, 0, 1)
    1874             :         ZEND_ARG_INFO(0, value)
    1875             : ZEND_END_ARG_INFO()
    1876             : 
    1877             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_query, 0, 0, 1)
    1878             :         ZEND_ARG_INFO(0, query)
    1879             : ZEND_END_ARG_INFO()
    1880             : 
    1881             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_querysingle, 0, 0, 1)
    1882             :         ZEND_ARG_INFO(0, query)
    1883             :         ZEND_ARG_INFO(0, entire_row)
    1884             : ZEND_END_ARG_INFO()
    1885             : 
    1886             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createfunction, 0, 0, 2)
    1887             :         ZEND_ARG_INFO(0, name)
    1888             :         ZEND_ARG_INFO(0, callback)
    1889             :         ZEND_ARG_INFO(0, argument_count)
    1890             : ZEND_END_ARG_INFO()
    1891             : 
    1892             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createaggregate, 0, 0, 3)
    1893             :         ZEND_ARG_INFO(0, name)
    1894             :         ZEND_ARG_INFO(0, step_callback)
    1895             :         ZEND_ARG_INFO(0, final_callback)
    1896             :         ZEND_ARG_INFO(0, argument_count)
    1897             : ZEND_END_ARG_INFO()
    1898             : 
    1899             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createcollation, 0, 0, 2)
    1900             :         ZEND_ARG_INFO(0, name)
    1901             :         ZEND_ARG_INFO(0, callback)
    1902             : ZEND_END_ARG_INFO()
    1903             : 
    1904             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_openblob, 0, 0, 3)
    1905             :         ZEND_ARG_INFO(0, table)
    1906             :         ZEND_ARG_INFO(0, column)
    1907             :         ZEND_ARG_INFO(0, rowid)
    1908             :         ZEND_ARG_INFO(0, dbname)
    1909             : ZEND_END_ARG_INFO()
    1910             : 
    1911             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_enableexceptions, 0, 0, 1)
    1912             :         ZEND_ARG_INFO(0, enableExceptions)
    1913             : ZEND_END_ARG_INFO()
    1914             : 
    1915             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_bindparam, 0, 0, 2)
    1916             :         ZEND_ARG_INFO(0, param_number)
    1917             :         ZEND_ARG_INFO(1, param)
    1918             :         ZEND_ARG_INFO(0, type)
    1919             : ZEND_END_ARG_INFO()
    1920             : 
    1921             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_bindvalue, 0, 0, 2)
    1922             :         ZEND_ARG_INFO(0, param_number)
    1923             :         ZEND_ARG_INFO(0, param)
    1924             :         ZEND_ARG_INFO(0, type)
    1925             : ZEND_END_ARG_INFO()
    1926             : 
    1927             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_construct, 0, 0, 1)
    1928             :         ZEND_ARG_INFO(0, sqlite3)
    1929             : ZEND_END_ARG_INFO()
    1930             : 
    1931             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columnname, 0, 0, 1)
    1932             :         ZEND_ARG_INFO(0, column_number)
    1933             : ZEND_END_ARG_INFO()
    1934             : 
    1935             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columntype, 0, 0, 1)
    1936             :         ZEND_ARG_INFO(0, column_number)
    1937             : ZEND_END_ARG_INFO()
    1938             : 
    1939             : ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_fetcharray, 0, 0, 0)
    1940             :         ZEND_ARG_INFO(0, mode)
    1941             : ZEND_END_ARG_INFO()
    1942             : 
    1943             : ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_void, 0)
    1944             : ZEND_END_ARG_INFO()
    1945             : /* }}} */
    1946             : 
    1947             : /* {{{ php_sqlite3_class_methods */
    1948             : static zend_function_entry php_sqlite3_class_methods[] = {
    1949             :         PHP_ME(sqlite3,         open,                           arginfo_sqlite3_open, ZEND_ACC_PUBLIC)
    1950             :         PHP_ME(sqlite3,         close,                          arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1951             :         PHP_ME(sqlite3,         exec,                           arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
    1952             :         PHP_ME(sqlite3,         version,                        arginfo_sqlite3_void, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
    1953             :         PHP_ME(sqlite3,         lastInsertRowID,        arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1954             :         PHP_ME(sqlite3,         lastErrorCode,          arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1955             :         PHP_ME(sqlite3,         lastErrorMsg,           arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1956             :         PHP_ME(sqlite3,         busyTimeout,            arginfo_sqlite3_busytimeout, ZEND_ACC_PUBLIC)
    1957             : #ifndef SQLITE_OMIT_LOAD_EXTENSION
    1958             :         PHP_ME(sqlite3,         loadExtension,          arginfo_sqlite3_loadextension, ZEND_ACC_PUBLIC)
    1959             : #endif
    1960             :         PHP_ME(sqlite3,         changes,                        arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1961             :         PHP_ME(sqlite3,         escapeString,           arginfo_sqlite3_escapestring, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
    1962             :         PHP_ME(sqlite3,         prepare,                        arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
    1963             :         PHP_ME(sqlite3,         query,                          arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
    1964             :         PHP_ME(sqlite3,         querySingle,            arginfo_sqlite3_querysingle, ZEND_ACC_PUBLIC)
    1965             :         PHP_ME(sqlite3,         createFunction,         arginfo_sqlite3_createfunction, ZEND_ACC_PUBLIC)
    1966             :         PHP_ME(sqlite3,         createAggregate,        arginfo_sqlite3_createaggregate, ZEND_ACC_PUBLIC)
    1967             :         PHP_ME(sqlite3,         createCollation,        arginfo_sqlite3_createcollation, ZEND_ACC_PUBLIC)
    1968             :         PHP_ME(sqlite3,         openBlob,                       arginfo_sqlite3_openblob, ZEND_ACC_PUBLIC)
    1969             :         PHP_ME(sqlite3,         enableExceptions,       arginfo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC)
    1970             :         /* Aliases */
    1971             :         PHP_MALIAS(sqlite3,     __construct, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
    1972             :         PHP_FE_END
    1973             : };
    1974             : /* }}} */
    1975             : 
    1976             : /* {{{ php_sqlite3_stmt_class_methods */
    1977             : static zend_function_entry php_sqlite3_stmt_class_methods[] = {
    1978             :         PHP_ME(sqlite3stmt, paramCount, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1979             :         PHP_ME(sqlite3stmt, close,              arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1980             :         PHP_ME(sqlite3stmt, reset,              arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1981             :         PHP_ME(sqlite3stmt, clear,              arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1982             :         PHP_ME(sqlite3stmt, execute,    arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1983             :         PHP_ME(sqlite3stmt, bindParam,  arginfo_sqlite3stmt_bindparam, ZEND_ACC_PUBLIC)
    1984             :         PHP_ME(sqlite3stmt, bindValue,  arginfo_sqlite3stmt_bindvalue, ZEND_ACC_PUBLIC)
    1985             :         PHP_ME(sqlite3stmt, readOnly,   arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1986             :         PHP_ME(sqlite3stmt, __construct, arginfo_sqlite3stmt_construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
    1987             :         PHP_FE_END
    1988             : };
    1989             : /* }}} */
    1990             : 
    1991             : /* {{{ php_sqlite3_result_class_methods */
    1992             : static zend_function_entry php_sqlite3_result_class_methods[] = {
    1993             :         PHP_ME(sqlite3result, numColumns,               arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1994             :         PHP_ME(sqlite3result, columnName,               arginfo_sqlite3result_columnname, ZEND_ACC_PUBLIC)
    1995             :         PHP_ME(sqlite3result, columnType,               arginfo_sqlite3result_columntype, ZEND_ACC_PUBLIC)
    1996             :         PHP_ME(sqlite3result, fetchArray,               arginfo_sqlite3result_fetcharray, ZEND_ACC_PUBLIC)
    1997             :         PHP_ME(sqlite3result, reset,                    arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1998             :         PHP_ME(sqlite3result, finalize,                 arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
    1999             :         PHP_ME(sqlite3result, __construct,              arginfo_sqlite3_void, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
    2000             :         PHP_FE_END
    2001             : };
    2002             : /* }}} */
    2003             : 
    2004             : /* {{{ Authorization Callback
    2005             : */
    2006           0 : static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6)
    2007             : {
    2008           0 :         switch (access_type) {
    2009             :                 case SQLITE_ATTACH:
    2010             :                 {
    2011           0 :                         if (memcmp(arg3, ":memory:", sizeof(":memory:")) && *arg3) {
    2012           0 :                                 if (php_check_open_basedir(arg3)) {
    2013           0 :                                         return SQLITE_DENY;
    2014             :                                 }
    2015             :                         }
    2016           0 :                         return SQLITE_OK;
    2017             :                 }
    2018             : 
    2019             :                 default:
    2020             :                         /* access allowed */
    2021           0 :                         return SQLITE_OK;
    2022             :         }
    2023             : }
    2024             : /* }}} */
    2025             : 
    2026             : /* {{{ php_sqlite3_free_list_dtor
    2027             : */
    2028          58 : static void php_sqlite3_free_list_dtor(void **item)
    2029             : {
    2030          58 :         php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item;
    2031             : 
    2032          58 :         if (free_item->stmt_obj && free_item->stmt_obj->initialised) {
    2033          58 :                 sqlite3_finalize(free_item->stmt_obj->stmt);
    2034          58 :                 free_item->stmt_obj->initialised = 0;
    2035             :         }
    2036          58 :         efree(*item);
    2037          58 : }
    2038             : /* }}} */
    2039             : 
    2040          19 : static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
    2041             : {
    2042          19 :         return  ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));
    2043             : }
    2044             : /* }}} */
    2045             : 
    2046          23 : static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */
    2047             : {
    2048          23 :         return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);
    2049             : }
    2050             : /* }}} */
    2051             : 
    2052          78 : static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
    2053             : {
    2054          78 :         php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
    2055             :         php_sqlite3_func *func;
    2056             :         php_sqlite3_collation *collation;
    2057             : 
    2058          78 :         if (!intern) {
    2059           0 :                 return;
    2060             :         }
    2061             : 
    2062         163 :         while (intern->funcs) {
    2063           7 :                 func = intern->funcs;
    2064           7 :                 intern->funcs = func->next;
    2065           7 :                 if (intern->initialised && intern->db) {
    2066           4 :                         sqlite3_create_function(intern->db, func->func_name, func->argc, SQLITE_UTF8, func, NULL, NULL, NULL);
    2067             :                 }
    2068             : 
    2069           7 :                 efree((char*)func->func_name);
    2070             : 
    2071          14 :                 if (!Z_ISUNDEF(func->func)) {
    2072           5 :                         zval_ptr_dtor(&func->func);
    2073             :                 }
    2074          14 :                 if (!Z_ISUNDEF(func->step)) {
    2075           2 :                         zval_ptr_dtor(&func->step);
    2076             :                 }
    2077          14 :                 if (!Z_ISUNDEF(func->fini)) {
    2078           2 :                         zval_ptr_dtor(&func->fini);
    2079             :                 }
    2080           7 :                 efree(func);
    2081             :         }
    2082             : 
    2083         158 :         while (intern->collations){
    2084           2 :                 collation = intern->collations;
    2085           2 :                 intern->collations = collation->next;
    2086           2 :                 if (intern->initialised && intern->db){
    2087           1 :                         sqlite3_create_collation(intern->db, collation->collation_name, SQLITE_UTF8, NULL, NULL);
    2088             :                 }
    2089           2 :                 efree((char*)collation->collation_name);
    2090           4 :                 if (!Z_ISUNDEF(collation->cmp_func)) {
    2091           2 :                         zval_ptr_dtor(&collation->cmp_func);
    2092             :                 }
    2093           2 :                 efree(collation);
    2094             :         }
    2095             : 
    2096          78 :         if (intern->initialised && intern->db) {
    2097          31 :                 sqlite3_close(intern->db);
    2098          31 :                 intern->initialised = 0;
    2099             :         }
    2100             : 
    2101          78 :         zend_object_std_dtor(&intern->zo);
    2102             : }
    2103             : /* }}} */
    2104             : 
    2105          62 : static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
    2106             : {
    2107          62 :         php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);
    2108             : 
    2109          62 :         if (!intern) {
    2110           0 :                 return;
    2111             :         }
    2112             : 
    2113          62 :         if (intern->bound_params) {
    2114          21 :                 zend_hash_destroy(intern->bound_params);
    2115          21 :                 FREE_HASHTABLE(intern->bound_params);
    2116          21 :                 intern->bound_params = NULL;
    2117             :         }
    2118             : 
    2119          62 :         if (intern->initialised) {
    2120          23 :                 zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt,
    2121             :                         (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
    2122             :         }
    2123             : 
    2124         124 :         if (!Z_ISUNDEF(intern->db_obj_zval)) {
    2125          62 :                 zval_ptr_dtor(&intern->db_obj_zval);
    2126             :         }
    2127             : 
    2128          62 :         zend_object_std_dtor(&intern->zo);
    2129             : }
    2130             : /* }}} */
    2131             : 
    2132          53 : static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ */
    2133             : {
    2134          53 :         php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);
    2135             : 
    2136          53 :         if (!intern) {
    2137           0 :                 return;
    2138             :         }
    2139             : 
    2140         106 :         if (!Z_ISNULL(intern->stmt_obj_zval)) {
    2141          53 :                 if (intern->stmt_obj && intern->stmt_obj->initialised) {
    2142          28 :                         sqlite3_reset(intern->stmt_obj->stmt);
    2143             :                 }
    2144             : 
    2145          53 :                 zval_ptr_dtor(&intern->stmt_obj_zval);
    2146             :         }
    2147             : 
    2148          53 :         zend_object_std_dtor(&intern->zo);
    2149             : }
    2150             : /* }}} */
    2151             : 
    2152          78 : static zend_object *php_sqlite3_object_new(zend_class_entry *class_type) /* {{{ */
    2153             : {
    2154             :         php_sqlite3_db_object *intern;
    2155             : 
    2156             :         /* Allocate memory for it */
    2157          78 :         intern = ecalloc(1, sizeof(php_sqlite3_db_object) + zend_object_properties_size(class_type));
    2158             : 
    2159             :         /* Need to keep track of things to free */
    2160          78 :         zend_llist_init(&(intern->free_list),  sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
    2161             : 
    2162          78 :         zend_object_std_init(&intern->zo, class_type);
    2163          78 :         object_properties_init(&intern->zo, class_type);
    2164             : 
    2165          78 :         intern->zo.handlers = &sqlite3_object_handlers;
    2166             : 
    2167          78 :         return &intern->zo;
    2168             : }
    2169             : /* }}} */
    2170             : 
    2171          62 : static zend_object *php_sqlite3_stmt_object_new(zend_class_entry *class_type) /* {{{ */
    2172             : {
    2173             :         php_sqlite3_stmt *intern;
    2174             : 
    2175             :         /* Allocate memory for it */
    2176          62 :         intern = ecalloc(1, sizeof(php_sqlite3_stmt) + zend_object_properties_size(class_type));
    2177             : 
    2178          62 :         zend_object_std_init(&intern->zo, class_type);
    2179          62 :         object_properties_init(&intern->zo, class_type);
    2180             : 
    2181          62 :         intern->zo.handlers = &sqlite3_stmt_object_handlers;
    2182             : 
    2183          62 :         return &intern->zo;
    2184             : }
    2185             : /* }}} */
    2186             : 
    2187          53 : static zend_object *php_sqlite3_result_object_new(zend_class_entry *class_type) /* {{{ */
    2188             : {
    2189             :         php_sqlite3_result *intern;
    2190             : 
    2191             :         /* Allocate memory for it */
    2192          53 :         intern = ecalloc(1, sizeof(php_sqlite3_result) + zend_object_properties_size(class_type));
    2193             : 
    2194          53 :         zend_object_std_init(&intern->zo, class_type);
    2195          53 :         object_properties_init(&intern->zo, class_type);
    2196             : 
    2197          53 :         intern->zo.handlers = &sqlite3_result_object_handlers;
    2198             : 
    2199          53 :         return &intern->zo;
    2200             : }
    2201             : /* }}} */
    2202             : 
    2203          32 : static void sqlite3_param_dtor(zval *data) /* {{{ */
    2204             : {
    2205          32 :         struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)Z_PTR_P(data);
    2206             : 
    2207          32 :         if (param->name) {
    2208          10 :                 zend_string_release(param->name);
    2209             :         }
    2210             : 
    2211          64 :         if (!Z_ISNULL(param->parameter)) {
    2212          32 :                 zval_ptr_dtor(&(param->parameter));
    2213          32 :                 ZVAL_UNDEF(&param->parameter);
    2214             :         }
    2215          32 :         efree(param);
    2216          32 : }
    2217             : /* }}} */
    2218             : 
    2219             : /* {{{ PHP_MINIT_FUNCTION
    2220             : */
    2221       23922 : PHP_MINIT_FUNCTION(sqlite3)
    2222             : {
    2223             :         zend_class_entry ce;
    2224             : 
    2225             : #if defined(ZTS)
    2226             :         /* Refuse to load if this wasn't a threasafe library loaded */
    2227             :         if (!sqlite3_threadsafe()) {
    2228             :                 php_error_docref(NULL, E_WARNING, "A thread safe version of SQLite is required when using a thread safe version of PHP.");
    2229             :                 return FAILURE;
    2230             :         }
    2231             : #endif
    2232             : 
    2233       23922 :         memcpy(&sqlite3_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    2234       23922 :         memcpy(&sqlite3_stmt_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    2235       23922 :         memcpy(&sqlite3_result_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    2236             : 
    2237             :         /* Register SQLite 3 Class */
    2238       23922 :         INIT_CLASS_ENTRY(ce, "SQLite3", php_sqlite3_class_methods);
    2239       23922 :         ce.create_object = php_sqlite3_object_new;
    2240       23922 :         sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo);
    2241       23922 :         sqlite3_object_handlers.clone_obj = NULL;
    2242       23922 :         sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage;
    2243       23922 :         php_sqlite3_sc_entry = zend_register_internal_class(&ce);
    2244             : 
    2245             :         /* Register SQLite 3 Prepared Statement Class */
    2246       23922 :         INIT_CLASS_ENTRY(ce, "SQLite3Stmt", php_sqlite3_stmt_class_methods);
    2247       23922 :         ce.create_object = php_sqlite3_stmt_object_new;
    2248       23922 :         sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo);
    2249       23922 :         sqlite3_stmt_object_handlers.clone_obj = NULL;
    2250       23922 :         sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage;
    2251       23922 :         php_sqlite3_stmt_entry = zend_register_internal_class(&ce);
    2252             : 
    2253             :         /* Register SQLite 3 Result Class */
    2254       23922 :         INIT_CLASS_ENTRY(ce, "SQLite3Result", php_sqlite3_result_class_methods);
    2255       23922 :         ce.create_object = php_sqlite3_result_object_new;
    2256       23922 :         sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo);
    2257       23922 :         sqlite3_result_object_handlers.clone_obj = NULL;
    2258       23922 :         sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage;
    2259       23922 :         php_sqlite3_result_entry = zend_register_internal_class(&ce);
    2260             : 
    2261       23922 :         REGISTER_INI_ENTRIES();
    2262             : 
    2263       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_ASSOC", PHP_SQLITE3_ASSOC, CONST_CS | CONST_PERSISTENT);
    2264       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_NUM", PHP_SQLITE3_NUM, CONST_CS | CONST_PERSISTENT);
    2265       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_BOTH", PHP_SQLITE3_BOTH, CONST_CS | CONST_PERSISTENT);
    2266             : 
    2267       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_INTEGER", SQLITE_INTEGER, CONST_CS | CONST_PERSISTENT);
    2268       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_FLOAT", SQLITE_FLOAT, CONST_CS | CONST_PERSISTENT);
    2269       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_TEXT", SQLITE3_TEXT, CONST_CS | CONST_PERSISTENT);
    2270       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_BLOB", SQLITE_BLOB, CONST_CS | CONST_PERSISTENT);
    2271       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_NULL", SQLITE_NULL, CONST_CS | CONST_PERSISTENT);
    2272             : 
    2273       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READONLY", SQLITE_OPEN_READONLY, CONST_CS | CONST_PERSISTENT);
    2274       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READWRITE", SQLITE_OPEN_READWRITE, CONST_CS | CONST_PERSISTENT);
    2275       23922 :         REGISTER_LONG_CONSTANT("SQLITE3_OPEN_CREATE", SQLITE_OPEN_CREATE, CONST_CS | CONST_PERSISTENT);
    2276             : 
    2277       23922 :         return SUCCESS;
    2278             : }
    2279             : /* }}} */
    2280             : 
    2281             : /* {{{ PHP_MSHUTDOWN_FUNCTION
    2282             : */
    2283       23963 : PHP_MSHUTDOWN_FUNCTION(sqlite3)
    2284             : {
    2285       23963 :         UNREGISTER_INI_ENTRIES();
    2286             : 
    2287       23963 :         return SUCCESS;
    2288             : }
    2289             : /* }}} */
    2290             : 
    2291             : /* {{{ PHP_MINFO_FUNCTION
    2292             : */
    2293         150 : PHP_MINFO_FUNCTION(sqlite3)
    2294             : {
    2295         150 :         php_info_print_table_start();
    2296         150 :         php_info_print_table_header(2, "SQLite3 support", "enabled");
    2297         150 :         php_info_print_table_row(2, "SQLite3 module version", PHP_SQLITE3_VERSION);
    2298         150 :         php_info_print_table_row(2, "SQLite Library", sqlite3_libversion());
    2299         150 :         php_info_print_table_end();
    2300             : 
    2301         150 :         DISPLAY_INI_ENTRIES();
    2302         150 : }
    2303             : /* }}} */
    2304             : 
    2305             : /* {{{ PHP_GINIT_FUNCTION
    2306             : */
    2307       23922 : static PHP_GINIT_FUNCTION(sqlite3)
    2308             : {
    2309             : #if defined(COMPILE_DL_SQLITE3) && defined(ZTS)
    2310             :         ZEND_TSRMLS_CACHE_UPDATE();
    2311             : #endif
    2312       23922 :         memset(sqlite3_globals, 0, sizeof(*sqlite3_globals));
    2313       23922 : }
    2314             : /* }}} */
    2315             : 
    2316             : /* {{{ sqlite3_module_entry
    2317             : */
    2318             : zend_module_entry sqlite3_module_entry = {
    2319             :         STANDARD_MODULE_HEADER,
    2320             :         "sqlite3",
    2321             :         NULL,
    2322             :         PHP_MINIT(sqlite3),
    2323             :         PHP_MSHUTDOWN(sqlite3),
    2324             :         NULL,
    2325             :         NULL,
    2326             :         PHP_MINFO(sqlite3),
    2327             :         PHP_SQLITE3_VERSION,
    2328             :         PHP_MODULE_GLOBALS(sqlite3),
    2329             :         PHP_GINIT(sqlite3),
    2330             :         NULL,
    2331             :         NULL,
    2332             :         STANDARD_MODULE_PROPERTIES_EX
    2333             : };
    2334             : /* }}} */
    2335             : 
    2336             : #ifdef COMPILE_DL_SQLITE3
    2337             : #ifdef ZTS
    2338             : ZEND_TSRMLS_CACHE_DEFINE()
    2339             : #endif
    2340             : ZEND_GET_MODULE(sqlite3)
    2341             : #endif
    2342             : 
    2343             : /*
    2344             :  * Local variables:
    2345             :  * tab-width: 4
    2346             :  * c-basic-offset: 4
    2347             :  * End:
    2348             :  * vim600: sw=4 ts=4 fdm=marker
    2349             :  * vim<600: sw=4 ts=4
    2350             :  */

Generated by: LCOV version 1.10

Generated at Sun, 18 Sep 2016 08:20:16 +0000 (6 days ago)

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