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

LTP GCOV extension - code coverage report
Current view: directory - sqlite3 - sqlite3.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 912
Code covered: 78.1 % Executed lines: 712
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:39 +0000 (33 hours ago)

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