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-21 Instrumented lines: 901
Code covered: 77.9 % Executed lines: 702
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:10 +0000 (3 days ago)

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