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: 834 1021 81.7 %
Date: 2021-12-03 Functions: 61 65 93.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 03 Dec 2021 18:13:36 +0000 (5 days ago)

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