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