Annotation of embedaddon/php/ext/sqlite/sqlite.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 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: Wez Furlong <wez@thebrainroom.com>                          |
        !            16:    |          Tal Peer <tal@php.net>                                      |
        !            17:    |          Marcus Boerger <helly@php.net>                              |
        !            18:    +----------------------------------------------------------------------+
        !            19: 
        !            20:    $Id: sqlite.c 321634 2012-01-01 13:15:04Z felipe $
        !            21: */
        !            22: 
        !            23: #ifdef HAVE_CONFIG_H
        !            24: #include "config.h"
        !            25: #endif
        !            26: 
        !            27: #define PHP_SQLITE_MODULE_VERSION      "2.0-dev"
        !            28: 
        !            29: #include "php.h"
        !            30: #include "php_ini.h"
        !            31: #include "ext/standard/info.h"
        !            32: #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
        !            33: #include "ext/session/php_session.h"
        !            34: #endif
        !            35: #include "php_sqlite.h"
        !            36: 
        !            37: #if HAVE_TIME_H
        !            38: # include <time.h>
        !            39: #endif
        !            40: #if HAVE_UNISTD_H
        !            41: #include <unistd.h>
        !            42: #endif
        !            43: 
        !            44: #include <sqlite.h>
        !            45: 
        !            46: #include "zend_exceptions.h"
        !            47: #include "zend_interfaces.h"
        !            48: 
        !            49: #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
        !            50: extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
        !            51: extern PHPAPI zend_class_entry *spl_ce_Countable;
        !            52: #endif
        !            53: 
        !            54: #if PHP_SQLITE2_HAVE_PDO
        !            55: # include "pdo/php_pdo.h"
        !            56: # include "pdo/php_pdo_driver.h"
        !            57: extern pdo_driver_t pdo_sqlite2_driver;
        !            58: #endif
        !            59: 
        !            60: #ifndef safe_emalloc
        !            61: # define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
        !            62: #endif
        !            63: 
        !            64: ZEND_DECLARE_MODULE_GLOBALS(sqlite)
        !            65: static PHP_GINIT_FUNCTION(sqlite);
        !            66: 
        !            67: #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
        !            68: extern ps_module ps_mod_sqlite;
        !            69: #define ps_sqlite_ptr &ps_mod_sqlite
        !            70: #endif
        !            71: 
        !            72: extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
        !            73: extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
        !            74: 
        !            75: #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
        !            76: #define php_sqlite_decode_binary(in, out) in && *in ? sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out) : 0
        !            77: 
        !            78: static int sqlite_count_elements(zval *object, long *count TSRMLS_DC);
        !            79: 
        !            80: static int le_sqlite_db, le_sqlite_result, le_sqlite_pdb;
        !            81: 
        !            82: static inline void php_sqlite_strtoupper(char *s)
        !            83: {
        !            84:        while (*s!='\0') {
        !            85:                *s = toupper(*s);
        !            86:                s++;
        !            87:        }
        !            88: }
        !            89: 
        !            90: static inline void php_sqlite_strtolower(char *s)
        !            91: {
        !            92:        while (*s!='\0') {
        !            93:                *s = tolower(*s);
        !            94:                s++;
        !            95:        }
        !            96: }
        !            97: 
        !            98: /* {{{ PHP_INI
        !            99:  */
        !           100: PHP_INI_BEGIN()
        !           101: STD_PHP_INI_ENTRY_EX("sqlite.assoc_case", "0", PHP_INI_ALL, OnUpdateLong, assoc_case, zend_sqlite_globals, sqlite_globals, display_link_numbers)
        !           102: PHP_INI_END()
        !           103: /* }}} */
        !           104: 
        !           105: #define DB_FROM_ZVAL(db, zv)   ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
        !           106: 
        !           107: #define DB_FROM_OBJECT(db, object) \
        !           108:        { \
        !           109:                sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
        !           110:                db = obj->u.db; \
        !           111:                if (!db) { \
        !           112:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "The database wasn't opened"); \
        !           113:                        RETURN_NULL(); \
        !           114:                } \
        !           115:        }
        !           116: 
        !           117: #define RES_FROM_OBJECT_RESTORE_ERH(res, object, error_handling) \
        !           118:        { \
        !           119:                sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
        !           120:                res = obj->u.res; \
        !           121:                if (!res) { \
        !           122:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "No result set available"); \
        !           123:                        if (error_handling) \
        !           124:                                zend_restore_error_handling(error_handling TSRMLS_CC); \
        !           125:                        RETURN_NULL(); \
        !           126:                } \
        !           127:        }
        !           128: 
        !           129: #define RES_FROM_OBJECT(res, object) RES_FROM_OBJECT_RESTORE_ERH(res, object, NULL)
        !           130: 
        !           131: #define PHP_SQLITE_EMPTY_QUERY \
        !           132:        if (!sql_len || !*sql) { \
        !           133:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute empty query."); \
        !           134:                RETURN_FALSE; \
        !           135:        }
        !           136: 
        !           137: struct php_sqlite_result {
        !           138:        struct php_sqlite_db *db;
        !           139:        sqlite_vm *vm;
        !           140:        int buffered;
        !           141:        int ncolumns;
        !           142:        int nrows;
        !           143:        int curr_row;
        !           144:        char **col_names;
        !           145:        int alloc_rows;
        !           146:        int mode;
        !           147:        char **table;
        !           148: };
        !           149: 
        !           150: struct php_sqlite_db {
        !           151:        sqlite *db;
        !           152:        int last_err_code;
        !           153:        zend_bool is_persistent;
        !           154:        long rsrc_id;
        !           155: 
        !           156:        HashTable callbacks;
        !           157: };
        !           158: 
        !           159: struct php_sqlite_agg_functions {
        !           160:        struct php_sqlite_db *db;
        !           161:        int is_valid;
        !           162:        zval *step;
        !           163:        zval *fini;
        !           164: };
        !           165: 
        !           166: static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC);
        !           167: static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC);
        !           168: 
        !           169: enum { PHPSQLITE_ASSOC = 1, PHPSQLITE_NUM = 2, PHPSQLITE_BOTH = PHPSQLITE_ASSOC|PHPSQLITE_NUM };
        !           170: 
        !           171: /* {{{ arginfo */
        !           172: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_popen, 0, 0, 1)
        !           173:        ZEND_ARG_INFO(0, filename)
        !           174:        ZEND_ARG_INFO(0, mode)
        !           175:        ZEND_ARG_INFO(1, error_message)
        !           176: ZEND_END_ARG_INFO()
        !           177: 
        !           178: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_open, 0, 0, 1)
        !           179:        ZEND_ARG_INFO(0, filename)
        !           180:        ZEND_ARG_INFO(0, mode)
        !           181:        ZEND_ARG_INFO(1, error_message)
        !           182: ZEND_END_ARG_INFO()
        !           183: 
        !           184: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_factory, 0, 0, 1)
        !           185:        ZEND_ARG_INFO(0, filename)
        !           186:        ZEND_ARG_INFO(0, mode)
        !           187:        ZEND_ARG_INFO(1, error_message)
        !           188: ZEND_END_ARG_INFO()
        !           189: 
        !           190: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_busy_timeout, 0, 0, 2)
        !           191:        ZEND_ARG_INFO(0, db)
        !           192:        ZEND_ARG_INFO(0, ms)
        !           193: ZEND_END_ARG_INFO()
        !           194: 
        !           195: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_busy_timeout, 0, 0, 1)
        !           196:        ZEND_ARG_INFO(0, ms)
        !           197: ZEND_END_ARG_INFO()
        !           198: 
        !           199: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_close, 0, 0, 1)
        !           200:        ZEND_ARG_INFO(0, db)
        !           201: ZEND_END_ARG_INFO()
        !           202: 
        !           203: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_unbuffered_query, 0, 0, 2)
        !           204:        ZEND_ARG_INFO(0, query)
        !           205:        ZEND_ARG_INFO(0, db)
        !           206:        ZEND_ARG_INFO(0, result_type)
        !           207:        ZEND_ARG_INFO(1, error_message)
        !           208: ZEND_END_ARG_INFO()
        !           209: 
        !           210: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_unbuffered_query, 0, 0, 1)
        !           211:        ZEND_ARG_INFO(0, query)
        !           212:        ZEND_ARG_INFO(0, result_type)
        !           213:        ZEND_ARG_INFO(1, error_message)
        !           214: ZEND_END_ARG_INFO()
        !           215: 
        !           216: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_column_types, 0, 0, 2)
        !           217:        ZEND_ARG_INFO(0, table_name)
        !           218:        ZEND_ARG_INFO(0, db)
        !           219:        ZEND_ARG_INFO(0, result_type)
        !           220: ZEND_END_ARG_INFO()
        !           221: 
        !           222: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_column_types, 0, 0, 1)
        !           223:        ZEND_ARG_INFO(0, table_name)
        !           224:        ZEND_ARG_INFO(0, result_type)
        !           225: ZEND_END_ARG_INFO()
        !           226: 
        !           227: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_query, 0, 0, 2)
        !           228:        ZEND_ARG_INFO(0, query)
        !           229:        ZEND_ARG_INFO(0, db)
        !           230:        ZEND_ARG_INFO(0, result_type)
        !           231:        ZEND_ARG_INFO(1, error_message)
        !           232: ZEND_END_ARG_INFO()
        !           233: 
        !           234: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_query, 0, 0, 1)
        !           235:        ZEND_ARG_INFO(0, query)
        !           236:        ZEND_ARG_INFO(0, result_type)
        !           237:        ZEND_ARG_INFO(1, error_message)
        !           238: ZEND_END_ARG_INFO()
        !           239: 
        !           240: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_exec, 0, 0, 2)
        !           241:        ZEND_ARG_INFO(0, query)
        !           242:        ZEND_ARG_INFO(0, db)
        !           243:        ZEND_ARG_INFO(1, error_message)
        !           244: ZEND_END_ARG_INFO()
        !           245: 
        !           246: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_exec, 0, 0, 1)
        !           247:        ZEND_ARG_INFO(0, query)
        !           248:        ZEND_ARG_INFO(1, error_message)
        !           249: ZEND_END_ARG_INFO()
        !           250: 
        !           251: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_all, 0, 0, 1)
        !           252:        ZEND_ARG_INFO(0, result)
        !           253:        ZEND_ARG_INFO(0, result_type)
        !           254:        ZEND_ARG_INFO(0, decode_binary)
        !           255: ZEND_END_ARG_INFO()
        !           256: 
        !           257: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_all, 0, 0, 0)
        !           258:        ZEND_ARG_INFO(0, result_type)
        !           259:        ZEND_ARG_INFO(0, decode_binary)
        !           260: ZEND_END_ARG_INFO()
        !           261: 
        !           262: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_array, 0, 0, 1)
        !           263:        ZEND_ARG_INFO(0, result)
        !           264:        ZEND_ARG_INFO(0, result_type)
        !           265:        ZEND_ARG_INFO(0, decode_binary)
        !           266: ZEND_END_ARG_INFO()
        !           267: 
        !           268: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_array, 0, 0, 0)
        !           269:        ZEND_ARG_INFO(0, result_type)
        !           270:        ZEND_ARG_INFO(0, decode_binary)
        !           271: ZEND_END_ARG_INFO()
        !           272: 
        !           273: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_object, 0, 0, 1)
        !           274:        ZEND_ARG_INFO(0, result)
        !           275:        ZEND_ARG_INFO(0, class_name)
        !           276:        ZEND_ARG_INFO(0, ctor_params)
        !           277:        ZEND_ARG_INFO(0, decode_binary)
        !           278: ZEND_END_ARG_INFO()
        !           279: 
        !           280: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_object, 0, 0, 0)
        !           281:        ZEND_ARG_INFO(0, class_name)
        !           282:        ZEND_ARG_INFO(0, ctor_params)
        !           283:        ZEND_ARG_INFO(0, decode_binary)
        !           284: ZEND_END_ARG_INFO()
        !           285: 
        !           286: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_array_query, 0, 0, 2)
        !           287:        ZEND_ARG_INFO(0, db)
        !           288:        ZEND_ARG_INFO(0, query)
        !           289:        ZEND_ARG_INFO(0, result_type)
        !           290:        ZEND_ARG_INFO(0, decode_binary)
        !           291: ZEND_END_ARG_INFO()
        !           292: 
        !           293: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_array_query, 0, 0, 1)
        !           294:        ZEND_ARG_INFO(0, query)
        !           295:        ZEND_ARG_INFO(0, result_type)
        !           296:        ZEND_ARG_INFO(0, decode_binary)
        !           297: ZEND_END_ARG_INFO()
        !           298: 
        !           299: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_single_query, 0, 0, 2)
        !           300:        ZEND_ARG_INFO(0, db)
        !           301:        ZEND_ARG_INFO(0, query)
        !           302:        ZEND_ARG_INFO(0, first_row_only)
        !           303:        ZEND_ARG_INFO(0, decode_binary)
        !           304: ZEND_END_ARG_INFO()
        !           305: 
        !           306: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_single_query, 0, 0, 1)
        !           307:        ZEND_ARG_INFO(0, query)
        !           308:        ZEND_ARG_INFO(0, first_row_only)
        !           309:        ZEND_ARG_INFO(0, decode_binary)
        !           310: ZEND_END_ARG_INFO()
        !           311: 
        !           312: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_single, 0, 0, 1)
        !           313:        ZEND_ARG_INFO(0, result)
        !           314:        ZEND_ARG_INFO(0, decode_binary)
        !           315: ZEND_END_ARG_INFO()
        !           316: 
        !           317: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_single, 0, 0, 0)
        !           318:        ZEND_ARG_INFO(0, decode_binary)
        !           319: ZEND_END_ARG_INFO()
        !           320: 
        !           321: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_current, 0, 0, 1)
        !           322:        ZEND_ARG_INFO(0, result)
        !           323:        ZEND_ARG_INFO(0, result_type)
        !           324:        ZEND_ARG_INFO(0, decode_binary)
        !           325: ZEND_END_ARG_INFO()
        !           326: 
        !           327: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_current, 0, 0, 0)
        !           328:        ZEND_ARG_INFO(0, result_type)
        !           329:        ZEND_ARG_INFO(0, decode_binary)
        !           330: ZEND_END_ARG_INFO()
        !           331: 
        !           332: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_column, 0, 0, 2)
        !           333:        ZEND_ARG_INFO(0, result)
        !           334:        ZEND_ARG_INFO(0, index_or_name)
        !           335:        ZEND_ARG_INFO(0, decode_binary)
        !           336: ZEND_END_ARG_INFO()
        !           337: 
        !           338: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_column, 0, 0, 1)
        !           339:        ZEND_ARG_INFO(0, index_or_name)
        !           340:        ZEND_ARG_INFO(0, decode_binary)
        !           341: ZEND_END_ARG_INFO()
        !           342: 
        !           343: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libversion, 0)
        !           344: ZEND_END_ARG_INFO()
        !           345: 
        !           346: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libencoding, 0)
        !           347: ZEND_END_ARG_INFO()
        !           348: 
        !           349: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_changes, 0, 0, 1)
        !           350:        ZEND_ARG_INFO(0, db)
        !           351: ZEND_END_ARG_INFO()
        !           352: 
        !           353: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_changes, 0)
        !           354: ZEND_END_ARG_INFO()
        !           355: 
        !           356: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_insert_rowid, 0, 0, 1)
        !           357:        ZEND_ARG_INFO(0, db)
        !           358: ZEND_END_ARG_INFO()
        !           359: 
        !           360: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_insert_rowid, 0)
        !           361: ZEND_END_ARG_INFO()
        !           362: 
        !           363: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_rows, 0, 0, 1)
        !           364:        ZEND_ARG_INFO(0, result)
        !           365: ZEND_END_ARG_INFO()
        !           366: 
        !           367: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_rows, 0)
        !           368: ZEND_END_ARG_INFO()
        !           369: 
        !           370: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_valid, 0, 0, 1)
        !           371:        ZEND_ARG_INFO(0, result)
        !           372: ZEND_END_ARG_INFO()
        !           373: 
        !           374: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_valid, 0)
        !           375: ZEND_END_ARG_INFO()
        !           376: 
        !           377: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_has_prev, 0, 0, 1)
        !           378:        ZEND_ARG_INFO(0, result)
        !           379: ZEND_END_ARG_INFO()
        !           380: 
        !           381: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_has_prev, 0)
        !           382: ZEND_END_ARG_INFO()
        !           383: 
        !           384: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_fields, 0, 0, 1)
        !           385:        ZEND_ARG_INFO(0, result)
        !           386: ZEND_END_ARG_INFO()
        !           387: 
        !           388: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_fields, 0)
        !           389: ZEND_END_ARG_INFO()
        !           390: 
        !           391: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_field_name, 0, 0, 2)
        !           392:        ZEND_ARG_INFO(0, result)
        !           393:        ZEND_ARG_INFO(0, field_index)
        !           394: ZEND_END_ARG_INFO()
        !           395: 
        !           396: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_field_name, 0, 0, 1)
        !           397:        ZEND_ARG_INFO(0, field_index)
        !           398: ZEND_END_ARG_INFO()
        !           399: 
        !           400: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_seek, 0, 0, 2)
        !           401:        ZEND_ARG_INFO(0, result)
        !           402:        ZEND_ARG_INFO(0, row)
        !           403: ZEND_END_ARG_INFO()
        !           404: 
        !           405: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_seek, 0, 0, 1)
        !           406:        ZEND_ARG_INFO(0, row)
        !           407: ZEND_END_ARG_INFO()
        !           408: 
        !           409: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_rewind, 0, 0, 1)
        !           410:        ZEND_ARG_INFO(0, result)
        !           411: ZEND_END_ARG_INFO()
        !           412: 
        !           413: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_rewind, 0)
        !           414: ZEND_END_ARG_INFO()
        !           415: 
        !           416: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_next, 0, 0, 1)
        !           417:        ZEND_ARG_INFO(0, result)
        !           418: ZEND_END_ARG_INFO()
        !           419: 
        !           420: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_next, 0)
        !           421: ZEND_END_ARG_INFO()
        !           422: 
        !           423: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_key, 0, 0, 1)
        !           424:        ZEND_ARG_INFO(0, result)
        !           425: ZEND_END_ARG_INFO()
        !           426: 
        !           427: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_key, 0)
        !           428: ZEND_END_ARG_INFO()
        !           429: 
        !           430: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_prev, 0, 0, 1)
        !           431:        ZEND_ARG_INFO(0, result)
        !           432: ZEND_END_ARG_INFO()
        !           433: 
        !           434: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_prev, 0)
        !           435: ZEND_END_ARG_INFO()
        !           436: 
        !           437: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_escape_string, 0, 0, 1)
        !           438:        ZEND_ARG_INFO(0, item)
        !           439: ZEND_END_ARG_INFO()
        !           440: 
        !           441: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_error, 0, 0, 1)
        !           442:        ZEND_ARG_INFO(0, db)
        !           443: ZEND_END_ARG_INFO()
        !           444: 
        !           445: ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_error, 0)
        !           446: ZEND_END_ARG_INFO()
        !           447: 
        !           448: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_error_string, 0, 0, 1)
        !           449:        ZEND_ARG_INFO(0, error_code)
        !           450: ZEND_END_ARG_INFO()
        !           451: 
        !           452: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_aggregate, 0, 0, 4)
        !           453:        ZEND_ARG_INFO(0, db)
        !           454:        ZEND_ARG_INFO(0, funcname)
        !           455:        ZEND_ARG_INFO(0, step_func)
        !           456:        ZEND_ARG_INFO(0, finalize_func)
        !           457:        ZEND_ARG_INFO(0, num_args)
        !           458: ZEND_END_ARG_INFO()
        !           459: 
        !           460: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_aggregate, 0, 0, 3)
        !           461:        ZEND_ARG_INFO(0, funcname)
        !           462:        ZEND_ARG_INFO(0, step_func)
        !           463:        ZEND_ARG_INFO(0, finalize_func)
        !           464:        ZEND_ARG_INFO(0, num_args)
        !           465: ZEND_END_ARG_INFO()
        !           466: 
        !           467: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_function, 0, 0, 3)
        !           468:        ZEND_ARG_INFO(0, db)
        !           469:        ZEND_ARG_INFO(0, funcname)
        !           470:        ZEND_ARG_INFO(0, callback)
        !           471:        ZEND_ARG_INFO(0, num_args)
        !           472: ZEND_END_ARG_INFO()
        !           473: 
        !           474: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_function, 0, 0, 2)
        !           475:        ZEND_ARG_INFO(0, funcname)
        !           476:        ZEND_ARG_INFO(0, callback)
        !           477:        ZEND_ARG_INFO(0, num_args)
        !           478: ZEND_END_ARG_INFO()
        !           479: 
        !           480: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_encode_binary, 0, 0, 1)
        !           481:        ZEND_ARG_INFO(0, data)
        !           482: ZEND_END_ARG_INFO()
        !           483: 
        !           484: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_decode_binary, 0, 0, 1)
        !           485:        ZEND_ARG_INFO(0, data)
        !           486: ZEND_END_ARG_INFO()
        !           487: /* }}} */
        !           488: 
        !           489: const zend_function_entry sqlite_functions[] = {
        !           490:        PHP_FE(sqlite_open,                             arginfo_sqlite_open)
        !           491:        PHP_FE(sqlite_popen,                            arginfo_sqlite_popen)
        !           492:        PHP_FE(sqlite_close,                            arginfo_sqlite_close)
        !           493:        PHP_FE(sqlite_query,                            arginfo_sqlite_query)
        !           494:        PHP_FE(sqlite_exec,                             arginfo_sqlite_exec)
        !           495:        PHP_FE(sqlite_array_query,                      arginfo_sqlite_array_query)
        !           496:        PHP_FE(sqlite_single_query,             arginfo_sqlite_single_query)
        !           497:        PHP_FE(sqlite_fetch_array,                      arginfo_sqlite_fetch_array)
        !           498:        PHP_FE(sqlite_fetch_object,             arginfo_sqlite_fetch_object)
        !           499:        PHP_FE(sqlite_fetch_single,             arginfo_sqlite_fetch_single)
        !           500:        PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, arginfo_sqlite_fetch_single)
        !           501:        PHP_FE(sqlite_fetch_all,                        arginfo_sqlite_fetch_all)
        !           502:        PHP_FE(sqlite_current,                          arginfo_sqlite_current)
        !           503:        PHP_FE(sqlite_column,                           arginfo_sqlite_column)
        !           504:        PHP_FE(sqlite_libversion,                       arginfo_sqlite_libversion)
        !           505:        PHP_FE(sqlite_libencoding,                      arginfo_sqlite_libencoding)
        !           506:        PHP_FE(sqlite_changes,                          arginfo_sqlite_changes)
        !           507:        PHP_FE(sqlite_last_insert_rowid,        arginfo_sqlite_last_insert_rowid)
        !           508:        PHP_FE(sqlite_num_rows,                         arginfo_sqlite_num_rows)
        !           509:        PHP_FE(sqlite_num_fields,                       arginfo_sqlite_num_fields)
        !           510:        PHP_FE(sqlite_field_name,                       arginfo_sqlite_field_name)
        !           511:        PHP_FE(sqlite_seek,                             arginfo_sqlite_seek)
        !           512:        PHP_FE(sqlite_rewind,                           arginfo_sqlite_rewind)
        !           513:        PHP_FE(sqlite_next,                             arginfo_sqlite_next)
        !           514:        PHP_FE(sqlite_prev,                             arginfo_sqlite_prev)
        !           515:        PHP_FE(sqlite_valid,                            arginfo_sqlite_valid)
        !           516:        PHP_FALIAS(sqlite_has_more, sqlite_valid, arginfo_sqlite_valid)
        !           517:        PHP_FE(sqlite_has_prev,                         arginfo_sqlite_has_prev)
        !           518:        PHP_FE(sqlite_escape_string,            arginfo_sqlite_escape_string)
        !           519:        PHP_FE(sqlite_busy_timeout,             arginfo_sqlite_busy_timeout)
        !           520:        PHP_FE(sqlite_last_error,                       arginfo_sqlite_last_error)
        !           521:        PHP_FE(sqlite_error_string,             arginfo_sqlite_error_string)
        !           522:        PHP_FE(sqlite_unbuffered_query,         arginfo_sqlite_unbuffered_query)
        !           523:        PHP_FE(sqlite_create_aggregate,         arginfo_sqlite_create_aggregate)
        !           524:        PHP_FE(sqlite_create_function,          arginfo_sqlite_create_function)
        !           525:        PHP_FE(sqlite_factory,                          arginfo_sqlite_factory)
        !           526:        PHP_FE(sqlite_udf_encode_binary,        arginfo_sqlite_udf_encode_binary)
        !           527:        PHP_FE(sqlite_udf_decode_binary,        arginfo_sqlite_udf_decode_binary)
        !           528:        PHP_FE(sqlite_fetch_column_types,       arginfo_sqlite_fetch_column_types)
        !           529:        {NULL, NULL, NULL}
        !           530: };
        !           531: 
        !           532: const zend_function_entry sqlite_funcs_db[] = {
        !           533:        PHP_ME_MAPPING(__construct, sqlite_open, arginfo_sqlite_open, 0)
        !           534: /*     PHP_ME_MAPPING(close, sqlite_close, NULL, 0)*/
        !           535:        PHP_ME_MAPPING(query, sqlite_query, arginfo_sqlite_method_query, 0)
        !           536:        PHP_ME_MAPPING(queryExec, sqlite_exec, arginfo_sqlite_method_exec, 0)
        !           537:        PHP_ME_MAPPING(arrayQuery, sqlite_array_query, arginfo_sqlite_method_array_query, 0)
        !           538:        PHP_ME_MAPPING(singleQuery, sqlite_single_query, arginfo_sqlite_method_single_query, 0)
        !           539:        PHP_ME_MAPPING(unbufferedQuery, sqlite_unbuffered_query, arginfo_sqlite_method_unbuffered_query, 0)
        !           540:        PHP_ME_MAPPING(lastInsertRowid, sqlite_last_insert_rowid, arginfo_sqlite_method_last_insert_rowid, 0)
        !           541:        PHP_ME_MAPPING(changes, sqlite_changes, arginfo_sqlite_method_changes, 0)
        !           542:        PHP_ME_MAPPING(createAggregate, sqlite_create_aggregate, arginfo_sqlite_method_create_aggregate, 0)
        !           543:        PHP_ME_MAPPING(createFunction, sqlite_create_function, arginfo_sqlite_method_create_function, 0)
        !           544:        PHP_ME_MAPPING(busyTimeout, sqlite_busy_timeout, arginfo_sqlite_method_busy_timeout, 0)
        !           545:        PHP_ME_MAPPING(lastError, sqlite_last_error, arginfo_sqlite_method_last_error, 0)
        !           546:        PHP_ME_MAPPING(fetchColumnTypes, sqlite_fetch_column_types, arginfo_sqlite_method_fetch_column_types, 0)
        !           547: /*     PHP_ME_MAPPING(error_string, sqlite_error_string, NULL, 0) static */
        !           548: /*     PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL, 0) static */
        !           549:        {NULL, NULL, NULL}
        !           550: };
        !           551: 
        !           552: const zend_function_entry sqlite_funcs_query[] = {
        !           553:        PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
        !           554:        PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
        !           555:        PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
        !           556:        PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
        !           557:        PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
        !           558:        PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
        !           559:        PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
        !           560:        /* iterator */
        !           561:        PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
        !           562:        PHP_ME_MAPPING(key, sqlite_key, arginfo_sqlite_method_key, 0)
        !           563:        PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
        !           564:        PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
        !           565:        PHP_ME_MAPPING(rewind, sqlite_rewind, arginfo_sqlite_method_rewind, 0)
        !           566:        /* countable */
        !           567:        PHP_ME_MAPPING(count, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
        !           568:        /* additional */
        !           569:        PHP_ME_MAPPING(prev, sqlite_prev, arginfo_sqlite_method_prev, 0)
        !           570:        PHP_ME_MAPPING(hasPrev, sqlite_has_prev, arginfo_sqlite_method_has_prev, 0)
        !           571:        PHP_ME_MAPPING(numRows, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
        !           572:        PHP_ME_MAPPING(seek, sqlite_seek, arginfo_sqlite_method_seek, 0)
        !           573:        {NULL, NULL, NULL}
        !           574: };
        !           575: 
        !           576: const zend_function_entry sqlite_funcs_ub_query[] = {
        !           577:        PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
        !           578:        PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
        !           579:        PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
        !           580:        PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
        !           581:        PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
        !           582:        PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
        !           583:        PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
        !           584:        /* iterator */
        !           585:        PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
        !           586:        PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
        !           587:        PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
        !           588:        {NULL, NULL, NULL}
        !           589: };
        !           590: 
        !           591: const zend_function_entry sqlite_funcs_exception[] = {
        !           592:        {NULL, NULL, NULL}
        !           593: };
        !           594: 
        !           595: /* Dependancies */
        !           596: static const zend_module_dep sqlite_deps[] = {
        !           597: #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
        !           598:        ZEND_MOD_REQUIRED("spl")
        !           599: #endif
        !           600: #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
        !           601:        ZEND_MOD_REQUIRED("session")
        !           602: #endif
        !           603: #ifdef PHP_SQLITE2_HAVE_PDO
        !           604:        ZEND_MOD_REQUIRED("pdo")
        !           605: #endif
        !           606:        {NULL, NULL, NULL}
        !           607: };
        !           608: 
        !           609: zend_module_entry sqlite_module_entry = {
        !           610: #if ZEND_MODULE_API_NO >= 20050922
        !           611:        STANDARD_MODULE_HEADER_EX, NULL,
        !           612:        sqlite_deps,
        !           613: #elif ZEND_MODULE_API_NO >= 20010901
        !           614:        STANDARD_MODULE_HEADER,
        !           615: #endif
        !           616:        "SQLite",
        !           617:        sqlite_functions,
        !           618:        PHP_MINIT(sqlite),
        !           619:        PHP_MSHUTDOWN(sqlite),
        !           620:        NULL,
        !           621:        PHP_RSHUTDOWN(sqlite),
        !           622:        PHP_MINFO(sqlite),
        !           623: #if ZEND_MODULE_API_NO >= 20010901
        !           624:        PHP_SQLITE_MODULE_VERSION,
        !           625: #endif
        !           626: #if ZEND_MODULE_API_NO >= 20060613
        !           627:        PHP_MODULE_GLOBALS(sqlite),
        !           628:        PHP_GINIT(sqlite),
        !           629:        NULL,
        !           630:        NULL,
        !           631:        STANDARD_MODULE_PROPERTIES_EX
        !           632: #else
        !           633:        STANDARD_MODULE_PROPERTIES
        !           634: #endif
        !           635: };
        !           636: 
        !           637: 
        !           638: #ifdef COMPILE_DL_SQLITE
        !           639: ZEND_GET_MODULE(sqlite)
        !           640: #endif
        !           641: 
        !           642: static int php_sqlite_callback_invalidator(struct php_sqlite_agg_functions *funcs TSRMLS_DC)
        !           643: {
        !           644:        if (!funcs->is_valid) {
        !           645:                return 0;
        !           646:        }
        !           647: 
        !           648:        if (funcs->step) {
        !           649:                zval_ptr_dtor(&funcs->step);
        !           650:                funcs->step = NULL;
        !           651:        }
        !           652: 
        !           653:        if (funcs->fini) {
        !           654:                zval_ptr_dtor(&funcs->fini);
        !           655:                funcs->fini = NULL;
        !           656:        }
        !           657: 
        !           658:        funcs->is_valid = 0;
        !           659: 
        !           660:        return 0;
        !           661: }
        !           662: 
        !           663: 
        !           664: static void php_sqlite_callback_dtor(void *pDest)
        !           665: {
        !           666:        struct php_sqlite_agg_functions *funcs = (struct php_sqlite_agg_functions*)pDest;
        !           667: 
        !           668:        if (funcs->is_valid) {
        !           669:                TSRMLS_FETCH();
        !           670: 
        !           671:                php_sqlite_callback_invalidator(funcs TSRMLS_CC);
        !           672:        }
        !           673: }
        !           674: 
        !           675: static ZEND_RSRC_DTOR_FUNC(php_sqlite_db_dtor)
        !           676: {
        !           677:        if (rsrc->ptr) {
        !           678:                struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
        !           679: 
        !           680:                sqlite_close(db->db);
        !           681: 
        !           682:                zend_hash_destroy(&db->callbacks);
        !           683: 
        !           684:                pefree(db, db->is_persistent);
        !           685: 
        !           686:                rsrc->ptr = NULL;
        !           687:        }
        !           688: }
        !           689: 
        !           690: static void real_result_dtor(struct php_sqlite_result *res TSRMLS_DC)
        !           691: {
        !           692:        int i, j, base;
        !           693: 
        !           694:        if (res->vm) {
        !           695:                sqlite_finalize(res->vm, NULL);
        !           696:        }
        !           697: 
        !           698:        if (res->table) {
        !           699:                if (!res->buffered && res->nrows) {
        !           700:                        res->nrows = 1; /* only one row is stored */
        !           701:                }
        !           702:                for (i = 0; i < res->nrows; i++) {
        !           703:                        base = i * res->ncolumns;
        !           704:                        for (j = 0; j < res->ncolumns; j++) {
        !           705:                                if (res->table[base + j] != NULL) {
        !           706:                                        efree(res->table[base + j]);
        !           707:                                }
        !           708:                        }
        !           709:                }
        !           710:                efree(res->table);
        !           711:        }
        !           712:        if (res->col_names) {
        !           713:                for (j = 0; j < res->ncolumns; j++) {
        !           714:                        efree(res->col_names[j]);
        !           715:                }
        !           716:                efree(res->col_names);
        !           717:        }
        !           718: 
        !           719:        if (res->db) {
        !           720:                zend_list_delete(res->db->rsrc_id);
        !           721:        }
        !           722:        efree(res);
        !           723: }
        !           724: 
        !           725: static int _clean_unfinished_results(zend_rsrc_list_entry *le, void *db TSRMLS_DC)
        !           726: {
        !           727:        if (Z_TYPE_P(le) == le_sqlite_result) {
        !           728:                struct php_sqlite_result *res = (struct php_sqlite_result *)le->ptr;
        !           729:                if (res->db->rsrc_id == ((struct php_sqlite_db*)db)->rsrc_id) {
        !           730:                        return ZEND_HASH_APPLY_REMOVE;
        !           731:                }
        !           732:        }
        !           733:        return ZEND_HASH_APPLY_KEEP;
        !           734: }
        !           735: 
        !           736: static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor)
        !           737: {
        !           738:        struct php_sqlite_result *res = (struct php_sqlite_result *)rsrc->ptr;
        !           739:        real_result_dtor(res TSRMLS_CC);
        !           740: }
        !           741: 
        !           742: static int php_sqlite_forget_persistent_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
        !           743: {
        !           744:        struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
        !           745: 
        !           746:        if (Z_TYPE_P(rsrc) != le_sqlite_pdb) {
        !           747:                return 0;
        !           748:        }
        !           749: 
        !           750:        /* prevent bad mojo if someone tries to use a previously registered function in the next request */
        !           751:        zend_hash_apply(&db->callbacks, (apply_func_t)php_sqlite_callback_invalidator TSRMLS_CC);
        !           752: 
        !           753:        db->rsrc_id = FAILURE;
        !           754: 
        !           755:        /* don't leave pending commits hanging around */
        !           756:        sqlite_exec(db->db, "ROLLBACK", NULL, NULL, NULL);
        !           757: 
        !           758:        return 0;
        !           759: }
        !           760: 
        !           761: PHP_RSHUTDOWN_FUNCTION(sqlite)
        !           762: {
        !           763:        zend_hash_apply(&EG(persistent_list), (apply_func_t)php_sqlite_forget_persistent_id_numbers TSRMLS_CC);
        !           764:        return SUCCESS;
        !           765: }
        !           766: 
        !           767: /* {{{ PHP Function interface */
        !           768: static void php_sqlite_generic_function_callback(sqlite_func *func, int argc, const char **argv)
        !           769: {
        !           770:        zval *retval = NULL;
        !           771:        zval ***zargs = NULL;
        !           772:        zval funcname;
        !           773:        int i, res;
        !           774:        char *callable = NULL, *errbuf=NULL;
        !           775:        TSRMLS_FETCH();
        !           776: 
        !           777:        /* sanity check the args */
        !           778:        if (argc == 0) {
        !           779:                sqlite_set_result_error(func, "not enough parameters", -1);
        !           780:                return;
        !           781:        }
        !           782: 
        !           783:        ZVAL_STRING(&funcname, (char*)argv[0], 1);
        !           784: 
        !           785:        if (!zend_make_callable(&funcname, &callable TSRMLS_CC)) {
        !           786:                spprintf(&errbuf, 0, "function `%s' is not a function name", callable);
        !           787:                sqlite_set_result_error(func, errbuf, -1);
        !           788:                efree(errbuf);
        !           789:                efree(callable);
        !           790:                zval_dtor(&funcname);
        !           791:                return;
        !           792:        }
        !           793: 
        !           794:        if (argc > 1) {
        !           795:                zargs = (zval ***)safe_emalloc((argc - 1), sizeof(zval **), 0);
        !           796: 
        !           797:                for (i = 0; i < argc-1; i++) {
        !           798:                        zargs[i] = emalloc(sizeof(zval *));
        !           799:                        MAKE_STD_ZVAL(*zargs[i]);
        !           800:                        ZVAL_STRING(*zargs[i], (char*)argv[i+1], 1);
        !           801:                }
        !           802:        }
        !           803: 
        !           804:        res = call_user_function_ex(EG(function_table),
        !           805:                        NULL,
        !           806:                        &funcname,
        !           807:                        &retval,
        !           808:                        argc-1,
        !           809:                        zargs,
        !           810:                        0, NULL TSRMLS_CC);
        !           811: 
        !           812:        zval_dtor(&funcname);
        !           813: 
        !           814:        if (res == SUCCESS) {
        !           815:                if (retval == NULL) {
        !           816:                        sqlite_set_result_string(func, NULL, 0);
        !           817:                } else {
        !           818:                        switch (Z_TYPE_P(retval)) {
        !           819:                                case IS_STRING:
        !           820:                                        sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
        !           821:                                        break;
        !           822:                                case IS_LONG:
        !           823:                                case IS_BOOL:
        !           824:                                        sqlite_set_result_int(func, Z_LVAL_P(retval));
        !           825:                                        break;
        !           826:                                case IS_DOUBLE:
        !           827:                                        sqlite_set_result_double(func, Z_DVAL_P(retval));
        !           828:                                        break;
        !           829:                                case IS_NULL:
        !           830:                                default:
        !           831:                                        sqlite_set_result_string(func, NULL, 0);
        !           832:                        }
        !           833:                }
        !           834:        } else {
        !           835:                char *errbuf;
        !           836:                spprintf(&errbuf, 0, "call_user_function_ex failed for function %s()", callable);
        !           837:                sqlite_set_result_error(func, errbuf, -1);
        !           838:                efree(errbuf);
        !           839:        }
        !           840: 
        !           841:        efree(callable);
        !           842: 
        !           843:        if (retval) {
        !           844:                zval_ptr_dtor(&retval);
        !           845:        }
        !           846: 
        !           847:        if (zargs) {
        !           848:                for (i = 0; i < argc-1; i++) {
        !           849:                        zval_ptr_dtor(zargs[i]);
        !           850:                        efree(zargs[i]);
        !           851:                }
        !           852:                efree(zargs);
        !           853:        }
        !           854: }
        !           855: /* }}} */
        !           856: 
        !           857: /* {{{ callback for sqlite_create_function */
        !           858: static void php_sqlite_function_callback(sqlite_func *func, int argc, const char **argv)
        !           859: {
        !           860:        zval *retval = NULL;
        !           861:        zval ***zargs = NULL;
        !           862:        int i, res;
        !           863:        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
        !           864:        TSRMLS_FETCH();
        !           865: 
        !           866:        if (!funcs->is_valid) {
        !           867:                sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
        !           868:                return;
        !           869:        }
        !           870: 
        !           871:        if (argc > 0) {
        !           872:                zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
        !           873: 
        !           874:                for (i = 0; i < argc; i++) {
        !           875:                        zargs[i] = emalloc(sizeof(zval *));
        !           876:                        MAKE_STD_ZVAL(*zargs[i]);
        !           877: 
        !           878:                        if (argv[i] == NULL) {
        !           879:                                ZVAL_NULL(*zargs[i]);
        !           880:                        } else {
        !           881:                                ZVAL_STRING(*zargs[i], (char*)argv[i], 1);
        !           882:                        }
        !           883:                }
        !           884:        }
        !           885: 
        !           886:        res = call_user_function_ex(EG(function_table),
        !           887:                        NULL,
        !           888:                        funcs->step,
        !           889:                        &retval,
        !           890:                        argc,
        !           891:                        zargs,
        !           892:                        0, NULL TSRMLS_CC);
        !           893: 
        !           894:        if (res == SUCCESS) {
        !           895:                if (retval == NULL) {
        !           896:                        sqlite_set_result_string(func, NULL, 0);
        !           897:                } else {
        !           898:                        switch (Z_TYPE_P(retval)) {
        !           899:                                case IS_STRING:
        !           900:                                        /* TODO: for binary results, need to encode the string */
        !           901:                                        sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
        !           902:                                        break;
        !           903:                                case IS_LONG:
        !           904:                                case IS_BOOL:
        !           905:                                        sqlite_set_result_int(func, Z_LVAL_P(retval));
        !           906:                                        break;
        !           907:                                case IS_DOUBLE:
        !           908:                                        sqlite_set_result_double(func, Z_DVAL_P(retval));
        !           909:                                        break;
        !           910:                                case IS_NULL:
        !           911:                                default:
        !           912:                                        sqlite_set_result_string(func, NULL, 0);
        !           913:                        }
        !           914:                }
        !           915:        } else {
        !           916:                sqlite_set_result_error(func, "call_user_function_ex failed", -1);
        !           917:        }
        !           918: 
        !           919:        if (retval) {
        !           920:                zval_ptr_dtor(&retval);
        !           921:        }
        !           922: 
        !           923:        if (zargs) {
        !           924:                for (i = 0; i < argc; i++) {
        !           925:                        zval_ptr_dtor(zargs[i]);
        !           926:                        efree(zargs[i]);
        !           927:                }
        !           928:                efree(zargs);
        !           929:        }
        !           930: }
        !           931: /* }}} */
        !           932: 
        !           933: /* {{{ callback for sqlite_create_aggregate: step function */
        !           934: static void php_sqlite_agg_step_function_callback(sqlite_func *func, int argc, const char **argv)
        !           935: {
        !           936:        zval *retval = NULL;
        !           937:        zval ***zargs;
        !           938:        zval **context_p;
        !           939:        int i, res, zargc;
        !           940:        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
        !           941:        TSRMLS_FETCH();
        !           942: 
        !           943:        if (!funcs->is_valid) {
        !           944:                sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
        !           945:                return;
        !           946:        }
        !           947: 
        !           948:        /* sanity check the args */
        !           949:        if (argc < 1) {
        !           950:                return;
        !           951:        }
        !           952: 
        !           953:        zargc = argc + 1;
        !           954:        zargs = (zval ***)safe_emalloc(zargc, sizeof(zval **), 0);
        !           955: 
        !           956:        /* first arg is always the context zval */
        !           957:        context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
        !           958: 
        !           959:        if (*context_p == NULL) {
        !           960:                MAKE_STD_ZVAL(*context_p);
        !           961:                Z_SET_ISREF_PP(context_p);
        !           962:                Z_TYPE_PP(context_p) = IS_NULL;
        !           963:        }
        !           964: 
        !           965:        zargs[0] = context_p;
        !           966: 
        !           967:        /* copy the other args */
        !           968:        for (i = 0; i < argc; i++) {
        !           969:                zargs[i+1] = emalloc(sizeof(zval *));
        !           970:                MAKE_STD_ZVAL(*zargs[i+1]);
        !           971:                if (argv[i] == NULL) {
        !           972:                        ZVAL_NULL(*zargs[i+1]);
        !           973:                } else {
        !           974:                        ZVAL_STRING(*zargs[i+1], (char*)argv[i], 1);
        !           975:                }
        !           976:        }
        !           977: 
        !           978:        res = call_user_function_ex(EG(function_table),
        !           979:                        NULL,
        !           980:                        funcs->step,
        !           981:                        &retval,
        !           982:                        zargc,
        !           983:                        zargs,
        !           984:                        0, NULL TSRMLS_CC);
        !           985: 
        !           986:        if (res != SUCCESS) {
        !           987:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "call_user_function_ex failed");
        !           988:        }
        !           989: 
        !           990:        if (retval) {
        !           991:                zval_ptr_dtor(&retval);
        !           992:        }
        !           993: 
        !           994:        if (zargs) {
        !           995:                for (i = 1; i < zargc; i++) {
        !           996:                        zval_ptr_dtor(zargs[i]);
        !           997:                        efree(zargs[i]);
        !           998:                }
        !           999:                efree(zargs);
        !          1000:        }
        !          1001: }
        !          1002: /* }}} */
        !          1003: 
        !          1004: /* {{{ callback for sqlite_create_aggregate: finalize function */
        !          1005: static void php_sqlite_agg_fini_function_callback(sqlite_func *func)
        !          1006: {
        !          1007:        zval *retval = NULL;
        !          1008:        int res;
        !          1009:        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
        !          1010:        zval **context_p;
        !          1011:        TSRMLS_FETCH();
        !          1012: 
        !          1013:        if (!funcs->is_valid) {
        !          1014:                sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
        !          1015:                return;
        !          1016:        }
        !          1017: 
        !          1018:        context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
        !          1019: 
        !          1020:        res = call_user_function_ex(EG(function_table),
        !          1021:                        NULL,
        !          1022:                        funcs->fini,
        !          1023:                        &retval,
        !          1024:                        1,
        !          1025:                        &context_p,
        !          1026:                        0, NULL TSRMLS_CC);
        !          1027: 
        !          1028:        if (res == SUCCESS) {
        !          1029:                if (retval == NULL) {
        !          1030:                        sqlite_set_result_string(func, NULL, 0);
        !          1031:                } else {
        !          1032:                        switch (Z_TYPE_P(retval)) {
        !          1033:                                case IS_STRING:
        !          1034:                                        /* TODO: for binary results, need to encode the string */
        !          1035:                                        sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
        !          1036:                                        break;
        !          1037:                                case IS_LONG:
        !          1038:                                case IS_BOOL:
        !          1039:                                        sqlite_set_result_int(func, Z_LVAL_P(retval));
        !          1040:                                        break;
        !          1041:                                case IS_DOUBLE:
        !          1042:                                        sqlite_set_result_double(func, Z_DVAL_P(retval));
        !          1043:                                        break;
        !          1044:                                case IS_NULL:
        !          1045:                                default:
        !          1046:                                        sqlite_set_result_string(func, NULL, 0);
        !          1047:                        }
        !          1048:                }
        !          1049:        } else {
        !          1050:                sqlite_set_result_error(func, "call_user_function_ex failed", -1);
        !          1051:        }
        !          1052: 
        !          1053:        if (retval) {
        !          1054:                zval_ptr_dtor(&retval);
        !          1055:        }
        !          1056: 
        !          1057:        zval_ptr_dtor(context_p);
        !          1058: }
        !          1059: /* }}} */
        !          1060: 
        !          1061: /* {{{ Authorization Callback */
        !          1062: static int php_sqlite_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
        !          1063:                const char *arg5, const char *arg6)
        !          1064: {
        !          1065:        switch (access_type) {
        !          1066:                case SQLITE_COPY:
        !          1067:                        if (strncmp(arg4, ":memory:", sizeof(":memory:") - 1)) {
        !          1068:                                TSRMLS_FETCH();
        !          1069:                                if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
        !          1070:                                        return SQLITE_DENY;
        !          1071:                                }
        !          1072: 
        !          1073:                                if (php_check_open_basedir(arg4 TSRMLS_CC)) {
        !          1074:                                        return SQLITE_DENY;
        !          1075:                                }
        !          1076:                        }
        !          1077:                        return SQLITE_OK;
        !          1078: #ifdef SQLITE_ATTACH
        !          1079:                case SQLITE_ATTACH:
        !          1080:                        if (strncmp(arg3, ":memory:", sizeof(":memory:") - 1)) {
        !          1081:                                TSRMLS_FETCH();
        !          1082:                                if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
        !          1083:                                        return SQLITE_DENY;
        !          1084:                                }
        !          1085: 
        !          1086:                                if (php_check_open_basedir(arg3 TSRMLS_CC)) {
        !          1087:                                        return SQLITE_DENY;
        !          1088:                                }
        !          1089:                        }
        !          1090:                        return SQLITE_OK;
        !          1091: #endif
        !          1092: 
        !          1093:                default:
        !          1094:                        /* access allowed */
        !          1095:                        return SQLITE_OK;
        !          1096:        }
        !          1097: }
        !          1098: /* }}} */
        !          1099: 
        !          1100: /* {{{ OO init/structure stuff */
        !          1101: #define REGISTER_SQLITE_CLASS(name, c_name, parent) \
        !          1102:        { \
        !          1103:                zend_class_entry ce; \
        !          1104:                INIT_CLASS_ENTRY(ce, "SQLite" # name, sqlite_funcs_ ## c_name); \
        !          1105:                ce.create_object = sqlite_object_new_ ## c_name; \
        !          1106:                sqlite_ce_ ## c_name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
        !          1107:                memcpy(&sqlite_object_handlers_ ## c_name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
        !          1108:                sqlite_object_handlers_ ## c_name.clone_obj = NULL; \
        !          1109:                sqlite_ce_ ## c_name->ce_flags |= ZEND_ACC_FINAL_CLASS; \
        !          1110:        }
        !          1111: 
        !          1112: zend_class_entry *sqlite_ce_db, *sqlite_ce_exception;
        !          1113: zend_class_entry *sqlite_ce_query, *sqlite_ce_ub_query;
        !          1114: 
        !          1115: static zend_object_handlers sqlite_object_handlers_db;
        !          1116: static zend_object_handlers sqlite_object_handlers_query;
        !          1117: static zend_object_handlers sqlite_object_handlers_ub_query;
        !          1118: static zend_object_handlers sqlite_object_handlers_exception;
        !          1119: 
        !          1120: typedef enum {
        !          1121:        is_db,
        !          1122:        is_result
        !          1123: } sqlite_obj_type;
        !          1124: 
        !          1125: typedef struct _sqlite_object {
        !          1126:        zend_object       std;
        !          1127:        sqlite_obj_type   type;
        !          1128:        union {
        !          1129:                struct php_sqlite_db     *db;
        !          1130:                struct php_sqlite_result *res;
        !          1131:                void *ptr;
        !          1132:        } u;
        !          1133: } sqlite_object;
        !          1134: 
        !          1135: static int sqlite_free_persistent(zend_rsrc_list_entry *le, void *ptr TSRMLS_DC)
        !          1136: {
        !          1137:        return le->ptr == ptr ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
        !          1138: }
        !          1139: 
        !          1140: static void sqlite_object_free_storage(void *object TSRMLS_DC)
        !          1141: {
        !          1142:        sqlite_object *intern = (sqlite_object *)object;
        !          1143: 
        !          1144:        zend_object_std_dtor(&intern->std TSRMLS_CC);
        !          1145: 
        !          1146:        if (intern->u.ptr) {
        !          1147:                if (intern->type == is_db) {
        !          1148:                        if (intern->u.db->rsrc_id) {
        !          1149:                                zend_list_delete(intern->u.db->rsrc_id);
        !          1150:                                zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) sqlite_free_persistent, &intern->u.ptr TSRMLS_CC);
        !          1151:                        }
        !          1152:                } else {
        !          1153:                        real_result_dtor(intern->u.res TSRMLS_CC);
        !          1154:                }
        !          1155:        }
        !          1156: 
        !          1157:        efree(object);
        !          1158: }
        !          1159: 
        !          1160: static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
        !          1161: {
        !          1162:        sqlite_object *intern;
        !          1163:        zval *tmp;
        !          1164: 
        !          1165:        intern = emalloc(sizeof(sqlite_object));
        !          1166:        memset(intern, 0, sizeof(sqlite_object));
        !          1167: 
        !          1168:        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        !          1169:        zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
        !          1170: 
        !          1171:        retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) sqlite_object_free_storage, NULL TSRMLS_CC);
        !          1172:        retval->handlers = handlers;
        !          1173: }
        !          1174: 
        !          1175: static zend_object_value sqlite_object_new_db(zend_class_entry *class_type TSRMLS_DC)
        !          1176: {
        !          1177:        zend_object_value retval;
        !          1178: 
        !          1179:        sqlite_object_new(class_type, &sqlite_object_handlers_db, &retval TSRMLS_CC);
        !          1180:        return retval;
        !          1181: }
        !          1182: 
        !          1183: static zend_object_value sqlite_object_new_query(zend_class_entry *class_type TSRMLS_DC)
        !          1184: {
        !          1185:        zend_object_value retval;
        !          1186: 
        !          1187:        sqlite_object_new(class_type, &sqlite_object_handlers_query, &retval TSRMLS_CC);
        !          1188:        return retval;
        !          1189: }
        !          1190: 
        !          1191: static zend_object_value sqlite_object_new_ub_query(zend_class_entry *class_type TSRMLS_DC)
        !          1192: {
        !          1193:        zend_object_value retval;
        !          1194: 
        !          1195:        sqlite_object_new(class_type, &sqlite_object_handlers_ub_query, &retval TSRMLS_CC);
        !          1196:        return retval;
        !          1197: }
        !          1198: 
        !          1199: static zend_object_value sqlite_object_new_exception(zend_class_entry *class_type TSRMLS_DC)
        !          1200: {
        !          1201:        zend_object_value retval;
        !          1202: 
        !          1203:        sqlite_object_new(class_type, &sqlite_object_handlers_exception, &retval TSRMLS_CC);
        !          1204:        return retval;
        !          1205: }
        !          1206: 
        !          1207: #define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
        !          1208:        { \
        !          1209:                sqlite_object *obj; \
        !          1210:                obj = (sqlite_object*)zend_object_store_get_object(_object TSRMLS_CC); \
        !          1211:                obj->type = is_ ## _type; \
        !          1212:                obj->u._type = _ptr; \
        !          1213:        }
        !          1214: 
        !          1215: static zend_class_entry *sqlite_get_ce_query(const zval *object TSRMLS_DC)
        !          1216: {
        !          1217:        return sqlite_ce_query;
        !          1218: }
        !          1219: 
        !          1220: static zend_class_entry *sqlite_get_ce_ub_query(const zval *object TSRMLS_DC)
        !          1221: {
        !          1222:        return sqlite_ce_ub_query;
        !          1223: }
        !          1224: 
        !          1225: static zval * sqlite_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
        !          1226: {
        !          1227:        if (!object) {
        !          1228:                ALLOC_ZVAL(object);
        !          1229:        }
        !          1230:        Z_TYPE_P(object) = IS_OBJECT;
        !          1231:        object_init_ex(object, pce);
        !          1232:        Z_SET_REFCOUNT_P(object, 1);
        !          1233:        Z_SET_ISREF_P(object);
        !          1234:        return object;
        !          1235: }
        !          1236: 
        !          1237: typedef struct _sqlite_object_iterator {
        !          1238:        zend_object_iterator     it;
        !          1239:        struct php_sqlite_result *res;
        !          1240:        zval *value;
        !          1241: } sqlite_object_iterator;
        !          1242: 
        !          1243: void sqlite_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
        !          1244: {
        !          1245:        zval *object = (zval*)((sqlite_object_iterator*)iter)->it.data;
        !          1246: 
        !          1247:        if (((sqlite_object_iterator*)iter)->value) {
        !          1248:                zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
        !          1249:                ((sqlite_object_iterator*)iter)->value = NULL;
        !          1250:        }
        !          1251:        zval_ptr_dtor(&object);
        !          1252:        efree(iter);
        !          1253: }
        !          1254: 
        !          1255: void sqlite_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
        !          1256: {
        !          1257:        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
        !          1258: 
        !          1259:        if (((sqlite_object_iterator*)iter)->value) {
        !          1260:                zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
        !          1261:                ((sqlite_object_iterator*)iter)->value = NULL;
        !          1262:        }
        !          1263:        if (res) {
        !          1264:                res->curr_row = 0;
        !          1265:        }
        !          1266: }
        !          1267: 
        !          1268: int sqlite_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
        !          1269: {
        !          1270:        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
        !          1271: 
        !          1272:        if (res && res->curr_row < res->nrows && res->nrows) { /* curr_row may be -1 */
        !          1273:                return SUCCESS;
        !          1274:        } else {
        !          1275:                return FAILURE;
        !          1276:        }
        !          1277: }
        !          1278: 
        !          1279: void sqlite_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
        !          1280: {
        !          1281:        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
        !          1282: 
        !          1283:        *data = &((sqlite_object_iterator*)iter)->value;
        !          1284:        if (res && !**data) {
        !          1285:                MAKE_STD_ZVAL(**data);
        !          1286:                php_sqlite_fetch_array(res, res->mode, 1, 0, **data TSRMLS_CC);
        !          1287:        }
        !          1288: 
        !          1289: }
        !          1290: 
        !          1291: int sqlite_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
        !          1292: {
        !          1293:        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
        !          1294: 
        !          1295:        *str_key = NULL;
        !          1296:        *str_key_len = 0;
        !          1297:        *int_key = res ? res->curr_row : 0;
        !          1298:        return HASH_KEY_IS_LONG;
        !          1299: }
        !          1300: 
        !          1301: void sqlite_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
        !          1302: {
        !          1303:        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
        !          1304: 
        !          1305:        if (((sqlite_object_iterator*)iter)->value) {
        !          1306:                zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
        !          1307:                ((sqlite_object_iterator*)iter)->value = NULL;
        !          1308:        }
        !          1309:        if (res) {
        !          1310:                if (!res->buffered && res->vm) {
        !          1311:                        php_sqlite_fetch(res TSRMLS_CC);
        !          1312:                }
        !          1313:                if (res->curr_row >= res->nrows) {
        !          1314:                        /* php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available"); */
        !          1315:                        return;
        !          1316:                }
        !          1317: 
        !          1318:                res->curr_row++;
        !          1319:        }
        !          1320: }
        !          1321: 
        !          1322: zend_object_iterator_funcs sqlite_ub_query_iterator_funcs = {
        !          1323:        sqlite_iterator_dtor,
        !          1324:        sqlite_iterator_valid,
        !          1325:        sqlite_iterator_get_current_data,
        !          1326:        sqlite_iterator_get_current_key,
        !          1327:        sqlite_iterator_move_forward,
        !          1328:        NULL
        !          1329: };
        !          1330: 
        !          1331: zend_object_iterator_funcs sqlite_query_iterator_funcs = {
        !          1332:        sqlite_iterator_dtor,
        !          1333:        sqlite_iterator_valid,
        !          1334:        sqlite_iterator_get_current_data,
        !          1335:        sqlite_iterator_get_current_key,
        !          1336:        sqlite_iterator_move_forward,
        !          1337:        sqlite_iterator_rewind
        !          1338: };
        !          1339: 
        !          1340: zend_object_iterator *sqlite_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
        !          1341: {
        !          1342:        sqlite_object_iterator *iterator = emalloc(sizeof(sqlite_object_iterator));
        !          1343: 
        !          1344:        sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
        !          1345: 
        !          1346:        if (by_ref) {
        !          1347:                zend_error(E_RECOVERABLE_ERROR, "An iterator cannot be used with foreach by reference");
        !          1348:        }
        !          1349:        Z_ADDREF_P(object);
        !          1350:        iterator->it.data = (void*)object;
        !          1351:        iterator->it.funcs = ce->iterator_funcs.funcs;
        !          1352:        iterator->res = obj->u.res;
        !          1353:        iterator->value = NULL;
        !          1354:        return (zend_object_iterator*)iterator;
        !          1355: }
        !          1356: /* }}} */
        !          1357: 
        !          1358: static PHP_GINIT_FUNCTION(sqlite)
        !          1359: {
        !          1360:        sqlite_globals->assoc_case = 0;
        !          1361: }
        !          1362: 
        !          1363: PHP_MINIT_FUNCTION(sqlite)
        !          1364: {
        !          1365:        REGISTER_SQLITE_CLASS(Database,   db,        NULL);
        !          1366:        REGISTER_SQLITE_CLASS(Result,     query,     NULL);
        !          1367:        REGISTER_SQLITE_CLASS(Unbuffered, ub_query,  NULL);
        !          1368: #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
        !          1369:        REGISTER_SQLITE_CLASS(Exception,  exception, spl_ce_RuntimeException);
        !          1370: #else
        !          1371:        REGISTER_SQLITE_CLASS(Exception,  exception, zend_exception_get_default(TSRMLS_C));
        !          1372: #endif
        !          1373: 
        !          1374:        sqlite_ce_db->ce_flags &= ~ZEND_ACC_FINAL_CLASS;
        !          1375:        sqlite_ce_db->constructor->common.fn_flags |= ZEND_ACC_FINAL;
        !          1376: 
        !          1377:        sqlite_object_handlers_query.get_class_entry = sqlite_get_ce_query;
        !          1378:        sqlite_object_handlers_ub_query.get_class_entry = sqlite_get_ce_ub_query;
        !          1379:        sqlite_object_handlers_ub_query.count_elements = sqlite_count_elements;
        !          1380: 
        !          1381:        sqlite_ce_ub_query->get_iterator = sqlite_get_iterator;
        !          1382:        sqlite_ce_ub_query->iterator_funcs.funcs = &sqlite_ub_query_iterator_funcs;
        !          1383: 
        !          1384: #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
        !          1385:        zend_class_implements(sqlite_ce_query TSRMLS_CC, 2, zend_ce_iterator, spl_ce_Countable);
        !          1386: #else
        !          1387:        zend_class_implements(sqlite_ce_query TSRMLS_CC, 1, zend_ce_iterator);
        !          1388: #endif
        !          1389:        sqlite_ce_query->get_iterator = sqlite_get_iterator;
        !          1390:        sqlite_ce_query->iterator_funcs.funcs = &sqlite_query_iterator_funcs;
        !          1391: 
        !          1392:        REGISTER_INI_ENTRIES();
        !          1393: 
        !          1394: #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
        !          1395:        php_session_register_module(ps_sqlite_ptr);
        !          1396: #endif
        !          1397: 
        !          1398:        le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number);
        !          1399:        le_sqlite_pdb = zend_register_list_destructors_ex(NULL, php_sqlite_db_dtor, "sqlite database (persistent)", module_number);
        !          1400:        le_sqlite_result = zend_register_list_destructors_ex(php_sqlite_result_dtor, NULL, "sqlite result", module_number);
        !          1401: 
        !          1402:        REGISTER_LONG_CONSTANT("SQLITE_BOTH",   PHPSQLITE_BOTH, CONST_CS|CONST_PERSISTENT);
        !          1403:        REGISTER_LONG_CONSTANT("SQLITE_NUM",    PHPSQLITE_NUM, CONST_CS|CONST_PERSISTENT);
        !          1404:        REGISTER_LONG_CONSTANT("SQLITE_ASSOC",  PHPSQLITE_ASSOC, CONST_CS|CONST_PERSISTENT);
        !          1405: 
        !          1406:        REGISTER_LONG_CONSTANT("SQLITE_OK",                             SQLITE_OK, CONST_CS|CONST_PERSISTENT);
        !          1407:        REGISTER_LONG_CONSTANT("SQLITE_ERROR",                  SQLITE_ERROR, CONST_CS|CONST_PERSISTENT);
        !          1408:        REGISTER_LONG_CONSTANT("SQLITE_INTERNAL",               SQLITE_INTERNAL, CONST_CS|CONST_PERSISTENT);
        !          1409:        REGISTER_LONG_CONSTANT("SQLITE_PERM",                   SQLITE_PERM, CONST_CS|CONST_PERSISTENT);
        !          1410:        REGISTER_LONG_CONSTANT("SQLITE_ABORT",                  SQLITE_ABORT, CONST_CS|CONST_PERSISTENT);
        !          1411:        REGISTER_LONG_CONSTANT("SQLITE_BUSY",                   SQLITE_BUSY, CONST_CS|CONST_PERSISTENT);
        !          1412:        REGISTER_LONG_CONSTANT("SQLITE_LOCKED",                 SQLITE_LOCKED, CONST_CS|CONST_PERSISTENT);
        !          1413:        REGISTER_LONG_CONSTANT("SQLITE_NOMEM",                  SQLITE_NOMEM, CONST_CS|CONST_PERSISTENT);
        !          1414:        REGISTER_LONG_CONSTANT("SQLITE_READONLY",               SQLITE_READONLY, CONST_CS|CONST_PERSISTENT);
        !          1415:        REGISTER_LONG_CONSTANT("SQLITE_INTERRUPT",              SQLITE_INTERRUPT, CONST_CS|CONST_PERSISTENT);
        !          1416:        REGISTER_LONG_CONSTANT("SQLITE_IOERR",                  SQLITE_IOERR, CONST_CS|CONST_PERSISTENT);
        !          1417:        REGISTER_LONG_CONSTANT("SQLITE_CORRUPT",                SQLITE_CORRUPT, CONST_CS|CONST_PERSISTENT);
        !          1418:        REGISTER_LONG_CONSTANT("SQLITE_NOTFOUND",               SQLITE_NOTFOUND, CONST_CS|CONST_PERSISTENT);
        !          1419:        REGISTER_LONG_CONSTANT("SQLITE_FULL",                   SQLITE_FULL, CONST_CS|CONST_PERSISTENT);
        !          1420:        REGISTER_LONG_CONSTANT("SQLITE_CANTOPEN",               SQLITE_CANTOPEN, CONST_CS|CONST_PERSISTENT);
        !          1421:        REGISTER_LONG_CONSTANT("SQLITE_PROTOCOL",               SQLITE_PROTOCOL, CONST_CS|CONST_PERSISTENT);
        !          1422:        REGISTER_LONG_CONSTANT("SQLITE_EMPTY",                  SQLITE_EMPTY, CONST_CS|CONST_PERSISTENT);
        !          1423:        REGISTER_LONG_CONSTANT("SQLITE_SCHEMA",                 SQLITE_SCHEMA, CONST_CS|CONST_PERSISTENT);
        !          1424:        REGISTER_LONG_CONSTANT("SQLITE_TOOBIG",                 SQLITE_TOOBIG, CONST_CS|CONST_PERSISTENT);
        !          1425:        REGISTER_LONG_CONSTANT("SQLITE_CONSTRAINT",             SQLITE_CONSTRAINT, CONST_CS|CONST_PERSISTENT);
        !          1426:        REGISTER_LONG_CONSTANT("SQLITE_MISMATCH",               SQLITE_MISMATCH, CONST_CS|CONST_PERSISTENT);
        !          1427:        REGISTER_LONG_CONSTANT("SQLITE_MISUSE",                 SQLITE_MISUSE, CONST_CS|CONST_PERSISTENT);
        !          1428:        REGISTER_LONG_CONSTANT("SQLITE_NOLFS",                  SQLITE_NOLFS, CONST_CS|CONST_PERSISTENT);
        !          1429:        REGISTER_LONG_CONSTANT("SQLITE_AUTH",                   SQLITE_AUTH, CONST_CS|CONST_PERSISTENT);
        !          1430:        REGISTER_LONG_CONSTANT("SQLITE_NOTADB",                 SQLITE_NOTADB, CONST_CS|CONST_PERSISTENT);
        !          1431: #ifdef SQLITE_FORMAT
        !          1432:        REGISTER_LONG_CONSTANT("SQLITE_FORMAT",                 SQLITE_FORMAT, CONST_CS|CONST_PERSISTENT);
        !          1433: #endif
        !          1434:        REGISTER_LONG_CONSTANT("SQLITE_ROW",                    SQLITE_ROW, CONST_CS|CONST_PERSISTENT);
        !          1435:        REGISTER_LONG_CONSTANT("SQLITE_DONE",                   SQLITE_DONE, CONST_CS|CONST_PERSISTENT);
        !          1436: 
        !          1437: #ifdef PHP_SQLITE2_HAVE_PDO
        !          1438:     if (FAILURE == php_pdo_register_driver(&pdo_sqlite2_driver)) {
        !          1439:        return FAILURE;
        !          1440:     }
        !          1441: #endif
        !          1442: 
        !          1443:        return SUCCESS;
        !          1444: }
        !          1445: 
        !          1446: PHP_MSHUTDOWN_FUNCTION(sqlite)
        !          1447: {
        !          1448:        UNREGISTER_INI_ENTRIES();
        !          1449: 
        !          1450: #ifdef PHP_SQLITE2_HAVE_PDO
        !          1451:     php_pdo_unregister_driver(&pdo_sqlite2_driver);
        !          1452: #endif
        !          1453: 
        !          1454:        return SUCCESS;
        !          1455: }
        !          1456: 
        !          1457: PHP_MINFO_FUNCTION(sqlite)
        !          1458: {
        !          1459:        php_info_print_table_start();
        !          1460:        php_info_print_table_header(2, "SQLite support", "enabled");
        !          1461:        php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c 321634 2012-01-01 13:15:04Z felipe $");
        !          1462:        php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
        !          1463:        php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
        !          1464:        php_info_print_table_end();
        !          1465: 
        !          1466:        DISPLAY_INI_ENTRIES();
        !          1467: }
        !          1468: 
        !          1469: static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg, zval *object TSRMLS_DC)
        !          1470: {
        !          1471:        char *errtext = NULL;
        !          1472:        sqlite *sdb = NULL;
        !          1473:        struct php_sqlite_db *db = NULL;
        !          1474: 
        !          1475:        sdb = sqlite_open(filename, mode, &errtext);
        !          1476: 
        !          1477:        if (sdb == NULL) {
        !          1478: 
        !          1479:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          1480: 
        !          1481:                if (errmsg) {
        !          1482:                        ZVAL_STRING(errmsg, errtext, 1);
        !          1483:                }
        !          1484: 
        !          1485:                sqlite_freemem(errtext);
        !          1486: 
        !          1487:                /* if object is not an object then we're called from the factory() function */
        !          1488:                if (object && Z_TYPE_P(object) != IS_OBJECT) {
        !          1489:                        RETVAL_NULL();
        !          1490:                } else {
        !          1491:                        RETVAL_FALSE;
        !          1492:                }
        !          1493:                return NULL;
        !          1494:        }
        !          1495: 
        !          1496:        db = (struct php_sqlite_db *)pemalloc(sizeof(struct php_sqlite_db), persistent_id ? 1 : 0);
        !          1497:        db->is_persistent = persistent_id ? 1 : 0;
        !          1498:        db->last_err_code = SQLITE_OK;
        !          1499:        db->db = sdb;
        !          1500: 
        !          1501:        zend_hash_init(&db->callbacks, 0, NULL, php_sqlite_callback_dtor, db->is_persistent);
        !          1502: 
        !          1503:        /* register the PHP functions */
        !          1504:        sqlite_create_function(sdb, "php", -1, php_sqlite_generic_function_callback, 0);
        !          1505: 
        !          1506:        /* set default busy handler; keep retrying up until 1 minute has passed,
        !          1507:         * then fail with a busy status code */
        !          1508:        sqlite_busy_timeout(sdb, 60000);
        !          1509: 
        !          1510:        /* authorizer hook so we can enforce safe mode
        !          1511:         * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
        !          1512:         * and IS backwards binary compatible with earlier versions */
        !          1513:        if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
        !          1514:                sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
        !          1515:        }
        !          1516: 
        !          1517:        db->rsrc_id = ZEND_REGISTER_RESOURCE(object ? NULL : return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
        !          1518:        if (object) {
        !          1519:                /* if object is not an object then we're called from the factory() function */
        !          1520:                if (Z_TYPE_P(object) != IS_OBJECT) {
        !          1521:                        sqlite_instanciate(sqlite_ce_db, object TSRMLS_CC);
        !          1522:                }
        !          1523:                /* and now register the object */
        !          1524:                SQLITE_REGISTER_OBJECT(db, object, db)
        !          1525:        }
        !          1526: 
        !          1527:        if (persistent_id) {
        !          1528:                zend_rsrc_list_entry le;
        !          1529: 
        !          1530:                Z_TYPE(le) = le_sqlite_pdb;
        !          1531:                le.ptr = db;
        !          1532: 
        !          1533:                if (FAILURE == zend_hash_update(&EG(persistent_list), persistent_id,
        !          1534:                                        strlen(persistent_id)+1,
        !          1535:                                        (void *)&le, sizeof(le), NULL)) {
        !          1536:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource");
        !          1537:                }
        !          1538:        }
        !          1539: 
        !          1540:        return db;
        !          1541: }
        !          1542: 
        !          1543: /* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
        !          1544:    Opens a persistent handle to a SQLite database. Will create the database if it does not exist. */
        !          1545: PHP_FUNCTION(sqlite_popen)
        !          1546: {
        !          1547:        long mode = 0666;
        !          1548:        char *filename, *fullpath, *hashkey;
        !          1549:        int filename_len, hashkeylen;
        !          1550:        zval *errmsg = NULL;
        !          1551:        struct php_sqlite_db *db = NULL;
        !          1552:        zend_rsrc_list_entry *le;
        !          1553: 
        !          1554:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
        !          1555:                                &filename, &filename_len, &mode, &errmsg)) {
        !          1556:                return;
        !          1557:        }
        !          1558:        if (errmsg) {
        !          1559:                zval_dtor(errmsg);
        !          1560:                ZVAL_NULL(errmsg);
        !          1561:        }
        !          1562: 
        !          1563:        if (strlen(filename) != filename_len) {
        !          1564:                RETURN_FALSE;
        !          1565:        }
        !          1566:        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
        !          1567:                /* resolve the fully-qualified path name to use as the hash key */
        !          1568:                if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
        !          1569:                        RETURN_FALSE;
        !          1570:                }
        !          1571: 
        !          1572:                if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || 
        !          1573:                                php_check_open_basedir(fullpath TSRMLS_CC)) {
        !          1574:                        efree(fullpath);
        !          1575:                        RETURN_FALSE;
        !          1576:                }
        !          1577:        } else {
        !          1578:                fullpath = estrndup(filename, filename_len);
        !          1579:        }
        !          1580: 
        !          1581:        hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%ld", fullpath, mode);
        !          1582: 
        !          1583:        /* do we have an existing persistent connection ? */
        !          1584:        if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkeylen+1, (void*)&le)) {
        !          1585:                if (Z_TYPE_P(le) == le_sqlite_pdb) {
        !          1586:                        db = (struct php_sqlite_db*)le->ptr;
        !          1587: 
        !          1588:                        if (db->rsrc_id == FAILURE) {
        !          1589:                                /* give it a valid resource id for this request */
        !          1590:                                db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
        !          1591:                        } else {
        !          1592:                                int type;
        !          1593:                                /* sanity check to ensure that the resource is still a valid regular resource
        !          1594:                                 * number */
        !          1595:                                if (zend_list_find(db->rsrc_id, &type) == db) {
        !          1596:                                        /* already accessed this request; map it */
        !          1597:                                        zend_list_addref(db->rsrc_id);
        !          1598:                                        ZVAL_RESOURCE(return_value, db->rsrc_id);
        !          1599:                                } else {
        !          1600:                                        db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
        !          1601:                                }
        !          1602:                        }
        !          1603: 
        !          1604:                        /* all set */
        !          1605:                        goto done;
        !          1606:                }
        !          1607: 
        !          1608:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Some other type of persistent resource is using this hash key!?");
        !          1609:                RETVAL_FALSE;
        !          1610:                goto done;
        !          1611:        }
        !          1612: 
        !          1613:        /* now we need to open the database */
        !          1614:        php_sqlite_open(fullpath, (int)mode, hashkey, return_value, errmsg, NULL TSRMLS_CC);
        !          1615: done:
        !          1616:        efree(fullpath);
        !          1617:        efree(hashkey);
        !          1618: }
        !          1619: /* }}} */
        !          1620: 
        !          1621: /* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
        !          1622:    Opens a SQLite database. Will create the database if it does not exist. */
        !          1623: PHP_FUNCTION(sqlite_open)
        !          1624: {
        !          1625:        long mode = 0666;
        !          1626:        char *filename, *fullpath = NULL;
        !          1627:        int filename_len;
        !          1628:        zval *errmsg = NULL;
        !          1629:        zval *object = getThis();
        !          1630:        zend_error_handling error_handling;
        !          1631: 
        !          1632:        zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
        !          1633:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
        !          1634:                                &filename, &filename_len, &mode, &errmsg)) {
        !          1635:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1636:                return;
        !          1637:        }
        !          1638:        if (errmsg) {
        !          1639:                zval_dtor(errmsg);
        !          1640:                ZVAL_NULL(errmsg);
        !          1641:        }
        !          1642: 
        !          1643:        if (strlen(filename) != filename_len) {
        !          1644:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1645:                RETURN_FALSE;
        !          1646:        }
        !          1647: 
        !          1648:        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
        !          1649:                /* resolve the fully-qualified path name to use as the hash key */
        !          1650:                if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
        !          1651:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1652:                        if (object) {
        !          1653:                                RETURN_NULL();
        !          1654:                        } else {
        !          1655:                                RETURN_FALSE;
        !          1656:                        }
        !          1657:                }
        !          1658: 
        !          1659:                if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
        !          1660:                                php_check_open_basedir(fullpath TSRMLS_CC)) {
        !          1661:                        efree(fullpath);
        !          1662:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1663:                        if (object) {
        !          1664:                                RETURN_NULL();
        !          1665:                        } else {
        !          1666:                                RETURN_FALSE;
        !          1667:                        }
        !          1668:                }
        !          1669:        }
        !          1670: 
        !          1671:        php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, object TSRMLS_CC);
        !          1672: 
        !          1673:        if (fullpath) {
        !          1674:                efree(fullpath);
        !          1675:        }
        !          1676:        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1677: }
        !          1678: /* }}} */
        !          1679: 
        !          1680: /* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
        !          1681:    Opens a SQLite database and creates an object for it. Will create the database if it does not exist. */
        !          1682: PHP_FUNCTION(sqlite_factory)
        !          1683: {
        !          1684:        long mode = 0666;
        !          1685:        char *filename, *fullpath = NULL;
        !          1686:        int filename_len;
        !          1687:        zval *errmsg = NULL;
        !          1688:        zend_error_handling error_handling;
        !          1689: 
        !          1690:        zend_replace_error_handling(EH_THROW, sqlite_ce_exception, &error_handling TSRMLS_CC);
        !          1691:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
        !          1692:                                &filename, &filename_len, &mode, &errmsg)) {
        !          1693:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1694:                RETURN_NULL();
        !          1695:        }
        !          1696:        if (errmsg) {
        !          1697:                zval_dtor(errmsg);
        !          1698:                ZVAL_NULL(errmsg);
        !          1699:        }
        !          1700: 
        !          1701:        if (strlen(filename) != filename_len) {
        !          1702:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1703:                RETURN_FALSE;
        !          1704:        }
        !          1705: 
        !          1706:        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
        !          1707:                /* resolve the fully-qualified path name to use as the hash key */
        !          1708:                if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
        !          1709:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1710:                        RETURN_NULL();
        !          1711:                }
        !          1712: 
        !          1713:                if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
        !          1714:                                php_check_open_basedir(fullpath TSRMLS_CC)) {
        !          1715:                        efree(fullpath);
        !          1716:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1717:                        RETURN_NULL();
        !          1718:                }
        !          1719:        }
        !          1720: 
        !          1721:        php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, return_value TSRMLS_CC);
        !          1722:        if (fullpath) {
        !          1723:                efree(fullpath);
        !          1724:        }
        !          1725:        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          1726: }
        !          1727: /* }}} */
        !          1728: 
        !          1729: /* {{{ proto void sqlite_busy_timeout(resource db, int ms)
        !          1730:    Set busy timeout duration. If ms <= 0, all busy handlers are disabled. */
        !          1731: PHP_FUNCTION(sqlite_busy_timeout)
        !          1732: {
        !          1733:        zval *zdb;
        !          1734:        struct php_sqlite_db *db;
        !          1735:        long ms;
        !          1736:        zval *object = getThis();
        !          1737: 
        !          1738:        if (object) {
        !          1739:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) {
        !          1740:                        return;
        !          1741:                }
        !          1742:                DB_FROM_OBJECT(db, object);
        !          1743:        } else {
        !          1744:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
        !          1745:                        return;
        !          1746:                }
        !          1747:                DB_FROM_ZVAL(db, &zdb);
        !          1748:        }
        !          1749: 
        !          1750:        sqlite_busy_timeout(db->db, ms);
        !          1751: }
        !          1752: /* }}} */
        !          1753: 
        !          1754: /* {{{ proto void sqlite_close(resource db)
        !          1755:    Closes an open sqlite database. */
        !          1756: PHP_FUNCTION(sqlite_close)
        !          1757: {
        !          1758:        zval *zdb;
        !          1759:        struct php_sqlite_db *db;
        !          1760:        zval *object = getThis();
        !          1761: 
        !          1762:        if (object) {
        !          1763:                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Ignored, you must destruct the object instead");
        !          1764:        } else {
        !          1765:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
        !          1766:                        return;
        !          1767:                }
        !          1768:                DB_FROM_ZVAL(db, &zdb);
        !          1769:        }
        !          1770: 
        !          1771:        zend_hash_apply_with_argument(&EG(regular_list),
        !          1772:                (apply_func_arg_t) _clean_unfinished_results,
        !          1773:                db TSRMLS_CC);
        !          1774: 
        !          1775:        zend_list_delete(Z_RESVAL_P(zdb));
        !          1776: }
        !          1777: /* }}} */
        !          1778: 
        !          1779: /* {{{ php_sqlite_fetch */
        !          1780: static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
        !          1781: {
        !          1782:        const char **rowdata, **colnames;
        !          1783:        int ret, i, base;
        !          1784:        char *errtext = NULL;
        !          1785: 
        !          1786: next_row:
        !          1787:        ret = sqlite_step(rres->vm, &rres->ncolumns, &rowdata, &colnames);
        !          1788:        if (!rres->nrows) {
        !          1789:                /* first row - lets copy the column names */
        !          1790:                rres->col_names = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
        !          1791:                for (i = 0; i < rres->ncolumns; i++) {
        !          1792:                        rres->col_names[i] = estrdup((char*)colnames[i]);
        !          1793: 
        !          1794:                        if (SQLITE_G(assoc_case) == 1) {
        !          1795:                                php_sqlite_strtoupper(rres->col_names[i]);
        !          1796:                        } else if (SQLITE_G(assoc_case) == 2) {
        !          1797:                                php_sqlite_strtolower(rres->col_names[i]);
        !          1798:                        }
        !          1799:                }
        !          1800:                if (!rres->buffered) {
        !          1801:                        /* non buffered mode - also fetch memory for on single row */
        !          1802:                        rres->table = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
        !          1803:                }
        !          1804:        }
        !          1805: 
        !          1806:        switch (ret) {
        !          1807:                case SQLITE_ROW:
        !          1808:                        if (rres->buffered) {
        !          1809:                                /* add the row to our collection */
        !          1810:                                if (rres->nrows + 1 >= rres->alloc_rows) {
        !          1811:                                        rres->alloc_rows = rres->alloc_rows ? rres->alloc_rows * 2 : 16;
        !          1812:                                        rres->table = safe_erealloc(rres->table, rres->alloc_rows, rres->ncolumns*sizeof(char *), 0);
        !          1813:                                }
        !          1814:                                base = rres->nrows * rres->ncolumns;
        !          1815:                                for (i = 0; i < rres->ncolumns; i++) {
        !          1816:                                        if (rowdata[i]) {
        !          1817:                                                rres->table[base + i] = estrdup(rowdata[i]);
        !          1818:                                        } else {
        !          1819:                                                rres->table[base + i] = NULL;
        !          1820:                                        }
        !          1821:                                }
        !          1822:                                rres->nrows++;
        !          1823:                                goto next_row;
        !          1824:                        } else {
        !          1825:                                /* non buffered: only fetch one row but first free data if not first row */
        !          1826:                                if (rres->nrows++) {
        !          1827:                                        for (i = 0; i < rres->ncolumns; i++) {
        !          1828:                                                if (rres->table[i]) {
        !          1829:                                                        efree(rres->table[i]);
        !          1830:                                                }
        !          1831:                                        }
        !          1832:                                }
        !          1833:                                for (i = 0; i < rres->ncolumns; i++) {
        !          1834:                                        if (rowdata[i]) {
        !          1835:                                                rres->table[i] = estrdup(rowdata[i]);
        !          1836:                                        } else {
        !          1837:                                                rres->table[i] = NULL;
        !          1838:                                        }
        !          1839:                                }
        !          1840:                        }
        !          1841:                        ret = SQLITE_OK;
        !          1842:                        break;
        !          1843: 
        !          1844:                case SQLITE_BUSY:
        !          1845:                case SQLITE_ERROR:
        !          1846:                case SQLITE_MISUSE:
        !          1847:                case SQLITE_DONE:
        !          1848:                default:
        !          1849:                        if (rres->vm) {
        !          1850:                                ret = sqlite_finalize(rres->vm, &errtext);
        !          1851:                        }
        !          1852:                        rres->vm = NULL;
        !          1853:                        if (ret != SQLITE_OK) {
        !          1854:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          1855:                                sqlite_freemem(errtext);
        !          1856:                        }
        !          1857:                        break;
        !          1858:        }
        !          1859:        rres->db->last_err_code = ret;
        !          1860: 
        !          1861:        return ret;
        !          1862: }
        !          1863: /* }}} */
        !          1864: 
        !          1865: /* {{{ sqlite_query */
        !          1866: void sqlite_query(zval *object, struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result **prres, zval *errmsg TSRMLS_DC)
        !          1867: {
        !          1868:        struct php_sqlite_result res, *rres;
        !          1869:        int ret;
        !          1870:        char *errtext = NULL;
        !          1871:        const char *tail;
        !          1872: 
        !          1873:        memset(&res, 0, sizeof(res));
        !          1874:        res.buffered = buffered;
        !          1875:        res.mode = mode;
        !          1876: 
        !          1877:        ret = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
        !          1878:        db->last_err_code = ret;
        !          1879: 
        !          1880:        if (ret != SQLITE_OK) {
        !          1881:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          1882:                if (errmsg) {
        !          1883:                        ZVAL_STRING(errmsg, errtext, 1);
        !          1884:                }
        !          1885:                sqlite_freemem(errtext);
        !          1886:                goto terminate;
        !          1887:        } else if (!res.vm) { /* empty query */
        !          1888: terminate:
        !          1889:                if (return_value) {
        !          1890:                        RETURN_FALSE;
        !          1891:                } else {
        !          1892:                        return;
        !          1893:                }
        !          1894:        }
        !          1895: 
        !          1896:        if (!prres) {
        !          1897:                rres = NULL;
        !          1898:                prres = &rres;
        !          1899:        }
        !          1900:        if (!*prres) {
        !          1901:                *prres = (struct php_sqlite_result*)emalloc(sizeof(**prres));
        !          1902:        }
        !          1903:        memcpy(*prres, &res, sizeof(**prres));
        !          1904:        (*prres)->db = db;
        !          1905:        zend_list_addref(db->rsrc_id);
        !          1906: 
        !          1907: 
        !          1908:        /* now the result set is ready for stepping: get first row */
        !          1909:        if (php_sqlite_fetch((*prres) TSRMLS_CC) != SQLITE_OK) {
        !          1910:                real_result_dtor((*prres) TSRMLS_CC);
        !          1911:                *prres = NULL;
        !          1912:                if (return_value) {
        !          1913:                        RETURN_FALSE;
        !          1914:                } else {
        !          1915:                        return;
        !          1916:                }
        !          1917:        }
        !          1918: 
        !          1919:        (*prres)->curr_row = 0;
        !          1920: 
        !          1921:        if (object) {
        !          1922:                sqlite_object *obj;
        !          1923:                if (buffered) {
        !          1924:                        sqlite_instanciate(sqlite_ce_query, return_value TSRMLS_CC);
        !          1925:                } else {
        !          1926:                        sqlite_instanciate(sqlite_ce_ub_query, return_value TSRMLS_CC);
        !          1927:                }
        !          1928:                obj = (sqlite_object *) zend_object_store_get_object(return_value TSRMLS_CC);
        !          1929:                obj->type = is_result;
        !          1930:                obj->u.res = (*prres);
        !          1931:        } else if (return_value) {
        !          1932:                ZEND_REGISTER_RESOURCE(object ? NULL : return_value, (*prres), le_sqlite_result);
        !          1933:        }
        !          1934: }
        !          1935: /* }}} */
        !          1936: 
        !          1937: /* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &error_message]])
        !          1938:    Executes a query that does not prefetch and buffer all data. */
        !          1939: PHP_FUNCTION(sqlite_unbuffered_query)
        !          1940: {
        !          1941:        zval *zdb;
        !          1942:        struct php_sqlite_db *db;
        !          1943:        char *sql;
        !          1944:        int sql_len;
        !          1945:        long mode = PHPSQLITE_BOTH;
        !          1946:        char *errtext = NULL;
        !          1947:        zval *errmsg = NULL;
        !          1948:        zval *object = getThis();
        !          1949: 
        !          1950:        if (object) {
        !          1951:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
        !          1952:                        return;
        !          1953:                }
        !          1954:                DB_FROM_OBJECT(db, object);
        !          1955:        } else {
        !          1956:                if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          1957:                                ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
        !          1958:                        FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
        !          1959:                        return;
        !          1960:                }
        !          1961:                DB_FROM_ZVAL(db, &zdb);
        !          1962:        }
        !          1963: 
        !          1964:        if (errmsg) {
        !          1965:                zval_dtor(errmsg);
        !          1966:                ZVAL_NULL(errmsg);
        !          1967:        }
        !          1968: 
        !          1969:        PHP_SQLITE_EMPTY_QUERY;
        !          1970: 
        !          1971:        /* avoid doing work if we can */
        !          1972:        if (!return_value_used) {
        !          1973:                db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
        !          1974: 
        !          1975:                if (db->last_err_code != SQLITE_OK) {
        !          1976:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          1977:                        if (errmsg) {
        !          1978:                                ZVAL_STRING(errmsg, errtext, 1);
        !          1979:                        }
        !          1980:                        sqlite_freemem(errtext);
        !          1981:                }
        !          1982:                return;
        !          1983:        }
        !          1984: 
        !          1985:        sqlite_query(object, db, sql, sql_len, (int)mode, 0, return_value, NULL, errmsg TSRMLS_CC);
        !          1986: }
        !          1987: /* }}} */
        !          1988: 
        !          1989: /* {{{ proto resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])
        !          1990:    Return an array of column types from a particular table. */
        !          1991: PHP_FUNCTION(sqlite_fetch_column_types)
        !          1992: {
        !          1993:        zval *zdb;
        !          1994:        struct php_sqlite_db *db;
        !          1995:        char *tbl, *sql;
        !          1996:        int tbl_len;
        !          1997:        char *errtext = NULL;
        !          1998:        zval *object = getThis();
        !          1999:        struct php_sqlite_result res;
        !          2000:        const char **rowdata, **colnames, *tail;
        !          2001:        int i, ncols;
        !          2002:        long result_type = PHPSQLITE_ASSOC;
        !          2003: 
        !          2004:        if (object) {
        !          2005:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &tbl, &tbl_len, &result_type)) {
        !          2006:                        return;
        !          2007:                }
        !          2008:                DB_FROM_OBJECT(db, object);
        !          2009:        } else {
        !          2010:                if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          2011:                                ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &tbl, &tbl_len, &zdb, &result_type) &&
        !          2012:                        FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &tbl, &tbl_len, &result_type)) {
        !          2013:                        return;
        !          2014:                }
        !          2015:                DB_FROM_ZVAL(db, &zdb);
        !          2016:        }
        !          2017: 
        !          2018:        if (!(sql = sqlite_mprintf("SELECT * FROM '%q' LIMIT 1", tbl))) {
        !          2019:                RETURN_FALSE;
        !          2020:        }
        !          2021: 
        !          2022:        sqlite_exec(db->db, "PRAGMA show_datatypes = ON", NULL, NULL, NULL);
        !          2023: 
        !          2024:        db->last_err_code = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
        !          2025: 
        !          2026:        sqlite_freemem(sql);
        !          2027: 
        !          2028:        if (db->last_err_code != SQLITE_OK) {
        !          2029:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          2030:                sqlite_freemem(errtext);
        !          2031:                RETVAL_FALSE;
        !          2032:                goto done;
        !          2033:        }
        !          2034: 
        !          2035:        sqlite_step(res.vm, &ncols, &rowdata, &colnames);
        !          2036: 
        !          2037:        array_init(return_value);
        !          2038: 
        !          2039:        for (i = 0; i < ncols; i++) {
        !          2040:                if (result_type == PHPSQLITE_ASSOC) {
        !          2041:                        char *colname = estrdup((char *)colnames[i]);
        !          2042: 
        !          2043:                        if (SQLITE_G(assoc_case) == 1) {
        !          2044:                                php_sqlite_strtoupper(colname);
        !          2045:                        } else if (SQLITE_G(assoc_case) == 2) {
        !          2046:                                php_sqlite_strtolower(colname);
        !          2047:                        }
        !          2048: 
        !          2049:                        add_assoc_string(return_value, colname, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
        !          2050:                        efree(colname);
        !          2051:                }
        !          2052:                if (result_type == PHPSQLITE_NUM) {
        !          2053:                        add_index_string(return_value, i, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
        !          2054:                }
        !          2055:        }
        !          2056:        if (res.vm) {
        !          2057:                sqlite_finalize(res.vm, NULL);
        !          2058:        }
        !          2059: done:
        !          2060:        sqlite_exec(db->db, "PRAGMA show_datatypes = OFF", NULL, NULL, NULL);
        !          2061: }
        !          2062: /* }}} */
        !          2063: 
        !          2064: /* {{{ proto resource sqlite_query(string query, resource db [, int result_type [, string &error_message]])
        !          2065:    Executes a query against a given database and returns a result handle. */
        !          2066: PHP_FUNCTION(sqlite_query)
        !          2067: {
        !          2068:        zval *zdb;
        !          2069:        struct php_sqlite_db *db;
        !          2070:        char *sql;
        !          2071:        int sql_len;
        !          2072:        long mode = PHPSQLITE_BOTH;
        !          2073:        char *errtext = NULL;
        !          2074:        zval *errmsg = NULL;
        !          2075:        zval *object = getThis();
        !          2076: 
        !          2077:        if (object) {
        !          2078:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
        !          2079:                        return;
        !          2080:                }
        !          2081:                DB_FROM_OBJECT(db, object);
        !          2082:        } else {
        !          2083:                if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          2084:                                ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
        !          2085:                        FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
        !          2086:                        return;
        !          2087:                }
        !          2088:                DB_FROM_ZVAL(db, &zdb);
        !          2089:        }
        !          2090: 
        !          2091:        if (errmsg) {
        !          2092:                zval_dtor(errmsg);
        !          2093:                ZVAL_NULL(errmsg);
        !          2094:        }
        !          2095: 
        !          2096:        PHP_SQLITE_EMPTY_QUERY;
        !          2097: 
        !          2098:        /* avoid doing work if we can */
        !          2099:        if (!return_value_used) {
        !          2100:                db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
        !          2101: 
        !          2102:                if (db->last_err_code != SQLITE_OK) {
        !          2103:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          2104:                        if (errmsg) {
        !          2105:                                ZVAL_STRING(errmsg, errtext, 1);
        !          2106:                        }
        !          2107:                        sqlite_freemem(errtext);
        !          2108:                }
        !          2109:                return;
        !          2110:        }
        !          2111: 
        !          2112:        sqlite_query(object, db, sql, sql_len, (int)mode, 1, return_value, NULL, errmsg TSRMLS_CC);
        !          2113: }
        !          2114: /* }}} */
        !          2115: 
        !          2116: /* {{{ proto boolean sqlite_exec(string query, resource db[, string &error_message])
        !          2117:    Executes a result-less query against a given database */
        !          2118: PHP_FUNCTION(sqlite_exec)
        !          2119: {
        !          2120:        zval *zdb;
        !          2121:        struct php_sqlite_db *db;
        !          2122:        char *sql;
        !          2123:        int sql_len;
        !          2124:        char *errtext = NULL;
        !          2125:        zval *errmsg = NULL;
        !          2126:        zval *object = getThis();
        !          2127: 
        !          2128:        if (object) {
        !          2129:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &sql, &sql_len, &errmsg)) {
        !          2130:                        return;
        !          2131:                }
        !          2132:                DB_FROM_OBJECT(db, object);
        !          2133:        } else {
        !          2134:                if(FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          2135:                        ZEND_NUM_ARGS() TSRMLS_CC, "sr", &sql, &sql_len, &zdb) &&
        !          2136:                   FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &zdb, &sql, &sql_len, &errmsg)) {
        !          2137:                        return;
        !          2138:                }
        !          2139:                DB_FROM_ZVAL(db, &zdb);
        !          2140:        }
        !          2141: 
        !          2142:        if (errmsg) {
        !          2143:                zval_dtor(errmsg);
        !          2144:                ZVAL_NULL(errmsg);
        !          2145:        }
        !          2146: 
        !          2147:        PHP_SQLITE_EMPTY_QUERY;
        !          2148: 
        !          2149:        db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
        !          2150: 
        !          2151:        if (db->last_err_code != SQLITE_OK) {
        !          2152:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          2153:                if (errmsg) {
        !          2154:                        ZVAL_STRING(errmsg, errtext, 1);
        !          2155:                }
        !          2156:                sqlite_freemem(errtext);
        !          2157:                RETURN_FALSE;
        !          2158:        }
        !          2159: 
        !          2160:        RETURN_TRUE;
        !          2161: }
        !          2162: /* }}} */
        !          2163: 
        !          2164: /* {{{ php_sqlite_fetch_array */
        !          2165: static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
        !          2166: {
        !          2167:        int j, n = res->ncolumns, buffered = res->buffered;
        !          2168:        const char **rowdata, **colnames;
        !          2169: 
        !          2170:        /* check range of the row */
        !          2171:        if (res->curr_row >= res->nrows) {
        !          2172:                /* no more */
        !          2173:                RETURN_FALSE;
        !          2174:        }
        !          2175:        colnames = (const char**)res->col_names;
        !          2176:        if (res->buffered) {
        !          2177:                rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
        !          2178:        } else {
        !          2179:                rowdata = (const char**)res->table;
        !          2180:        }
        !          2181: 
        !          2182:        /* now populate the result */
        !          2183:        array_init(return_value);
        !          2184: 
        !          2185:        for (j = 0; j < n; j++) {
        !          2186:                zval *decoded;
        !          2187:                MAKE_STD_ZVAL(decoded);
        !          2188: 
        !          2189:                if (rowdata[j] == NULL) {
        !          2190:                        ZVAL_NULL(decoded);
        !          2191:                } else if (decode_binary && rowdata[j][0] == '\x01') {
        !          2192:                        Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
        !          2193:                        Z_STRLEN_P(decoded) = php_sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
        !          2194:                        Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
        !          2195:                        Z_TYPE_P(decoded) = IS_STRING;
        !          2196:                        if (!buffered) {
        !          2197:                                efree((char*)rowdata[j]);
        !          2198:                                rowdata[j] = NULL;
        !          2199:                        }
        !          2200:                } else {
        !          2201:                        ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
        !          2202:                        if (!buffered) {
        !          2203:                                rowdata[j] = NULL;
        !          2204:                        }
        !          2205:                }
        !          2206: 
        !          2207:                if (mode & PHPSQLITE_NUM) {
        !          2208:                        if (mode & PHPSQLITE_ASSOC) {
        !          2209:                                add_index_zval(return_value, j, decoded);
        !          2210:                                Z_ADDREF_P(decoded);
        !          2211:                                add_assoc_zval(return_value, (char*)colnames[j], decoded);
        !          2212:                        } else {
        !          2213:                                add_next_index_zval(return_value, decoded);
        !          2214:                        }
        !          2215:                } else {
        !          2216:                        add_assoc_zval(return_value, (char*)colnames[j], decoded);
        !          2217:                }
        !          2218:        }
        !          2219: 
        !          2220:        if (move_next) {
        !          2221:                if (!res->buffered) {
        !          2222:                        /* non buffered: fetch next row */
        !          2223:                        php_sqlite_fetch(res TSRMLS_CC);
        !          2224:                }
        !          2225:                /* advance the row pointer */
        !          2226:                res->curr_row++;
        !          2227:        }
        !          2228: }
        !          2229: /* }}} */
        !          2230: 
        !          2231: /* {{{ php_sqlite_fetch_column */
        !          2232: static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which, zend_bool decode_binary, zval *return_value TSRMLS_DC)
        !          2233: {
        !          2234:        int j;
        !          2235:        const char **rowdata, **colnames;
        !          2236: 
        !          2237:        /* check range of the row */
        !          2238:        if (res->curr_row >= res->nrows) {
        !          2239:                /* no more */
        !          2240:                RETURN_FALSE;
        !          2241:        }
        !          2242:        colnames = (const char**)res->col_names;
        !          2243: 
        !          2244:        if (Z_TYPE_P(which) == IS_LONG) {
        !          2245:                j = Z_LVAL_P(which);
        !          2246:        } else {
        !          2247:                convert_to_string_ex(&which);
        !          2248:                for (j = 0; j < res->ncolumns; j++) {
        !          2249:                        if (!strcasecmp((char*)colnames[j], Z_STRVAL_P(which))) {
        !          2250:                                break;
        !          2251:                        }
        !          2252:                }
        !          2253:        }
        !          2254:        if (j < 0 || j >= res->ncolumns) {
        !          2255:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such column %d", j);
        !          2256:                RETURN_FALSE;
        !          2257:        }
        !          2258: 
        !          2259:        if (res->buffered) {
        !          2260:                rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
        !          2261:        } else {
        !          2262:                rowdata = (const char**)res->table;
        !          2263:        }
        !          2264: 
        !          2265:        if (rowdata[j] == NULL) {
        !          2266:                RETURN_NULL();
        !          2267:        } else if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
        !          2268:                int l = strlen(rowdata[j]);
        !          2269:                char *decoded = emalloc(l);
        !          2270:                l = php_sqlite_decode_binary(rowdata[j]+1, decoded);
        !          2271:                decoded[l] = '\0';
        !          2272:                RETVAL_STRINGL(decoded, l, 0);
        !          2273:                if (!res->buffered) {
        !          2274:                        efree((char*)rowdata[j]);
        !          2275:                        rowdata[j] = NULL;
        !          2276:                }
        !          2277:        } else {
        !          2278:                RETVAL_STRING((char*)rowdata[j], res->buffered);
        !          2279:                if (!res->buffered) {
        !          2280:                        rowdata[j] = NULL;
        !          2281:                }
        !          2282:        }
        !          2283: }
        !          2284: /* }}} */
        !          2285: 
        !          2286: /* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
        !          2287:    Fetches all rows from a result set as an array of arrays. */
        !          2288: PHP_FUNCTION(sqlite_fetch_all)
        !          2289: {
        !          2290:        zval *zres, *ent;
        !          2291:        long mode = PHPSQLITE_BOTH;
        !          2292:        zend_bool decode_binary = 1;
        !          2293:        struct php_sqlite_result *res;
        !          2294:        zval *object = getThis();
        !          2295: 
        !          2296:        if (object) {
        !          2297:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
        !          2298:                        return;
        !          2299:                }
        !          2300:                RES_FROM_OBJECT(res, object);
        !          2301:                if (!ZEND_NUM_ARGS()) {
        !          2302:                        mode = res->mode;
        !          2303:                }
        !          2304:        } else {
        !          2305:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
        !          2306:                        return;
        !          2307:                }
        !          2308:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2309:                if (ZEND_NUM_ARGS() < 2) {
        !          2310:                        mode = res->mode;
        !          2311:                }
        !          2312:        }
        !          2313: 
        !          2314:        if (res->curr_row >= res->nrows && res->nrows) {
        !          2315:                if (!res->buffered) {
        !          2316:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "One or more rowsets were already returned; returning NULL this time");
        !          2317:                } else {
        !          2318:                        res->curr_row = 0;
        !          2319:                }
        !          2320:        }
        !          2321: 
        !          2322:        array_init(return_value);
        !          2323: 
        !          2324:        while (res->curr_row < res->nrows) {
        !          2325:                MAKE_STD_ZVAL(ent);
        !          2326:                php_sqlite_fetch_array(res, mode, decode_binary, 1, ent TSRMLS_CC);
        !          2327:                add_next_index_zval(return_value, ent);
        !          2328:        }
        !          2329: }
        !          2330: /* }}} */
        !          2331: 
        !          2332: /* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
        !          2333:    Fetches the next row from a result set as an array. */
        !          2334: PHP_FUNCTION(sqlite_fetch_array)
        !          2335: {
        !          2336:        zval *zres;
        !          2337:        long mode = PHPSQLITE_BOTH;
        !          2338:        zend_bool decode_binary = 1;
        !          2339:        struct php_sqlite_result *res;
        !          2340:        zval *object = getThis();
        !          2341: 
        !          2342:        if (object) {
        !          2343:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
        !          2344:                        return;
        !          2345:                }
        !          2346:                RES_FROM_OBJECT(res, object);
        !          2347:                if (!ZEND_NUM_ARGS()) {
        !          2348:                        mode = res->mode;
        !          2349:                }
        !          2350:        } else {
        !          2351:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
        !          2352:                        return;
        !          2353:                }
        !          2354:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2355:                if (ZEND_NUM_ARGS() < 2) {
        !          2356:                        mode = res->mode;
        !          2357:                }
        !          2358:        }
        !          2359: 
        !          2360:        php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
        !          2361: }
        !          2362: /* }}} */
        !          2363: 
        !          2364: /* {{{ proto object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])
        !          2365:    Fetches the next row from a result set as an object. */
        !          2366:    /* note that you can do array(&$val) for param ctor_params */
        !          2367: PHP_FUNCTION(sqlite_fetch_object)
        !          2368: {
        !          2369:        zval *zres;
        !          2370:        zend_bool decode_binary = 1;
        !          2371:        struct php_sqlite_result *res;
        !          2372:        zval *object = getThis();
        !          2373:        char *class_name = NULL;
        !          2374:        int class_name_len;
        !          2375:        zend_class_entry *ce;
        !          2376:        zval dataset;
        !          2377:        zend_fcall_info fci;
        !          2378:        zend_fcall_info_cache fcc;
        !          2379:        zval *retval_ptr;
        !          2380:        zval *ctor_params = NULL;
        !          2381:        zend_error_handling error_handling;
        !          2382: 
        !          2383:        zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
        !          2384:        if (object) {
        !          2385:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szb", &class_name, &class_name_len, &ctor_params, &decode_binary)) {
        !          2386:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2387:                        return;
        !          2388:                }
        !          2389:                RES_FROM_OBJECT_RESTORE_ERH(res, object, &error_handling);
        !          2390:                if (!class_name) {
        !          2391:                        ce = zend_standard_class_def;
        !          2392:                } else {
        !          2393:                        ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
        !          2394:                }
        !          2395:        } else {
        !          2396:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|szb", &zres, &class_name, &class_name_len, &ctor_params, &decode_binary)) {
        !          2397:                        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2398:                        return;
        !          2399:                }
        !          2400:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2401:                if (!class_name) {
        !          2402:                        ce = zend_standard_class_def;
        !          2403:                } else {
        !          2404:                        ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
        !          2405:                }
        !          2406:        }
        !          2407: 
        !          2408:        if (!ce) {
        !          2409:                zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not find class '%s'", class_name);
        !          2410:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2411:                return;
        !          2412:        }
        !          2413: 
        !          2414:        if (res->curr_row < res->nrows) {
        !          2415:                php_sqlite_fetch_array(res, PHPSQLITE_ASSOC, decode_binary, 1, &dataset TSRMLS_CC);
        !          2416:        } else {
        !          2417:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2418:                RETURN_FALSE;
        !          2419:        }
        !          2420: 
        !          2421:        object_and_properties_init(return_value, ce, NULL);
        !          2422:        zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
        !          2423: 
        !          2424:        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2425: 
        !          2426:        if (ce->constructor) {
        !          2427:                fci.size = sizeof(fci);
        !          2428:                fci.function_table = &ce->function_table;
        !          2429:                fci.function_name = NULL;
        !          2430:                fci.symbol_table = NULL;
        !          2431:                fci.object_ptr = return_value;
        !          2432:                fci.retval_ptr_ptr = &retval_ptr;
        !          2433:                if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
        !          2434:                        if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
        !          2435:                                HashTable *ht = Z_ARRVAL_P(ctor_params);
        !          2436:                                Bucket *p;
        !          2437: 
        !          2438:                                fci.param_count = 0;
        !          2439:                                fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
        !          2440:                                p = ht->pListHead;
        !          2441:                                while (p != NULL) {
        !          2442:                                        fci.params[fci.param_count++] = (zval**)p->pData;
        !          2443:                                        p = p->pListNext;
        !          2444:                                }
        !          2445:                        } else {
        !          2446:                                /* Two problems why we throw exceptions here: PHP is typeless
        !          2447:                                 * and hence passing one argument that's not an array could be
        !          2448:                                 * by mistake and the other way round is possible, too. The
        !          2449:                                 * single value is an array. Also we'd have to make that one
        !          2450:                                 * argument passed by reference.
        !          2451:                                 */
        !          2452:                                zend_throw_exception(sqlite_ce_exception, "Parameter ctor_params must be an array", 0 TSRMLS_CC);
        !          2453:                                return;
        !          2454:                        }
        !          2455:                } else {
        !          2456:                        fci.param_count = 0;
        !          2457:                        fci.params = NULL;
        !          2458:                }
        !          2459:                fci.no_separation = 1;
        !          2460: 
        !          2461:                fcc.initialized = 1;
        !          2462:                fcc.function_handler = ce->constructor;
        !          2463:                fcc.calling_scope = EG(scope);
        !          2464:                fcc.called_scope = Z_OBJCE_P(return_value);
        !          2465:                fcc.object_ptr = return_value;
        !          2466: 
        !          2467:                if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
        !          2468:                        zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not execute %s::%s()", class_name, ce->constructor->common.function_name);
        !          2469:                } else {
        !          2470:                        if (retval_ptr) {
        !          2471:                                zval_ptr_dtor(&retval_ptr);
        !          2472:                        }
        !          2473:                }
        !          2474:                if (fci.params) {
        !          2475:                        efree(fci.params);
        !          2476:                }
        !          2477:        } else if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
        !          2478:                zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Class %s does not have a constructor, use NULL for parameter ctor_params or omit it", class_name);
        !          2479:        }
        !          2480: }
        !          2481: /* }}} */
        !          2482: 
        !          2483: /* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
        !          2484:    Executes a query against a given database and returns an array of arrays. */
        !          2485: PHP_FUNCTION(sqlite_array_query)
        !          2486: {
        !          2487:        zval *zdb, *ent;
        !          2488:        struct php_sqlite_db *db;
        !          2489:        struct php_sqlite_result *rres;
        !          2490:        char *sql;
        !          2491:        int sql_len;
        !          2492:        long mode = PHPSQLITE_BOTH;
        !          2493:        char *errtext = NULL;
        !          2494:        zend_bool decode_binary = 1;
        !          2495:        zval *object = getThis();
        !          2496: 
        !          2497:        if (object) {
        !          2498:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &sql, &sql_len, &mode, &decode_binary)) {
        !          2499:                        return;
        !          2500:                }
        !          2501:                DB_FROM_OBJECT(db, object);
        !          2502:        } else {
        !          2503:                if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          2504:                                ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
        !          2505:                        FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
        !          2506:                        return;
        !          2507:                }
        !          2508:                DB_FROM_ZVAL(db, &zdb);
        !          2509:        }
        !          2510: 
        !          2511:        PHP_SQLITE_EMPTY_QUERY;
        !          2512: 
        !          2513:        /* avoid doing work if we can */
        !          2514:        if (!return_value_used) {
        !          2515:                db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
        !          2516: 
        !          2517:                if (db->last_err_code != SQLITE_OK) {
        !          2518:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          2519:                        sqlite_freemem(errtext);
        !          2520:                }
        !          2521:                return;
        !          2522:        }
        !          2523: 
        !          2524:        rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
        !          2525:        sqlite_query(NULL, db, sql, sql_len, (int)mode, 0, NULL, &rres, NULL TSRMLS_CC);
        !          2526:        if (db->last_err_code != SQLITE_OK) {
        !          2527:                if (rres) {
        !          2528:                        efree(rres);
        !          2529:                }
        !          2530:                RETURN_FALSE;
        !          2531:        }
        !          2532: 
        !          2533:        array_init(return_value);
        !          2534: 
        !          2535:        while (rres->curr_row < rres->nrows) {
        !          2536:                MAKE_STD_ZVAL(ent);
        !          2537:                php_sqlite_fetch_array(rres, mode, decode_binary, 1, ent TSRMLS_CC);
        !          2538:                add_next_index_zval(return_value, ent);
        !          2539:        }
        !          2540:        real_result_dtor(rres TSRMLS_CC);
        !          2541: }
        !          2542: /* }}} */
        !          2543: 
        !          2544: /* {{{ php_sqlite_fetch_single */
        !          2545: static void php_sqlite_fetch_single(struct php_sqlite_result *res, zend_bool decode_binary, zval *return_value TSRMLS_DC)
        !          2546: {
        !          2547:        const char **rowdata;
        !          2548:        char *decoded;
        !          2549:        int decoded_len;
        !          2550: 
        !          2551:        /* check range of the row */
        !          2552:        if (res->curr_row >= res->nrows) {
        !          2553:                /* no more */
        !          2554:                RETURN_FALSE;
        !          2555:        }
        !          2556: 
        !          2557:        if (res->buffered) {
        !          2558:                rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
        !          2559:        } else {
        !          2560:                rowdata = (const char**)res->table;
        !          2561:        }
        !          2562: 
        !          2563:        if (decode_binary && rowdata[0] != NULL && rowdata[0][0] == '\x01') {
        !          2564:                decoded = emalloc(strlen(rowdata[0]));
        !          2565:                decoded_len = php_sqlite_decode_binary(rowdata[0]+1, decoded);
        !          2566:                if (!res->buffered) {
        !          2567:                        efree((char*)rowdata[0]);
        !          2568:                        rowdata[0] = NULL;
        !          2569:                }
        !          2570:        } else if (rowdata[0]) {
        !          2571:                decoded_len = strlen((char*)rowdata[0]);
        !          2572:                if (res->buffered) {
        !          2573:                        decoded = estrndup((char*)rowdata[0], decoded_len);
        !          2574:                } else {
        !          2575:                        decoded = (char*)rowdata[0];
        !          2576:                        rowdata[0] = NULL;
        !          2577:                }
        !          2578:        } else {
        !          2579:                decoded = NULL;
        !          2580:                decoded_len = 0;
        !          2581:        }
        !          2582: 
        !          2583:        if (!res->buffered) {
        !          2584:                /* non buffered: fetch next row */
        !          2585:                php_sqlite_fetch(res TSRMLS_CC);
        !          2586:        }
        !          2587:        /* advance the row pointer */
        !          2588:        res->curr_row++;
        !          2589: 
        !          2590:        if (decoded == NULL) {
        !          2591:                RETURN_NULL();
        !          2592:        } else {
        !          2593:                RETURN_STRINGL(decoded, decoded_len, 0);
        !          2594:        }
        !          2595: }
        !          2596: /* }}} */
        !          2597: 
        !          2598: 
        !          2599: /* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
        !          2600:    Executes a query and returns either an array for one single column or the value of the first row. */
        !          2601: PHP_FUNCTION(sqlite_single_query)
        !          2602: {
        !          2603:        zval *zdb, *ent;
        !          2604:        struct php_sqlite_db *db;
        !          2605:        struct php_sqlite_result *rres;
        !          2606:        char *sql;
        !          2607:        int sql_len;
        !          2608:        char *errtext = NULL;
        !          2609:        zend_bool decode_binary = 1;
        !          2610:        zend_bool srow = 1;
        !          2611:        zval *object = getThis();
        !          2612: 
        !          2613:        if (object) {
        !          2614:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb", &sql, &sql_len, &srow, &decode_binary)) {
        !          2615:                        return;
        !          2616:                }
        !          2617:                RES_FROM_OBJECT(db, object);
        !          2618:        } else {
        !          2619:                if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
        !          2620:                                ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) &&
        !          2621:                        FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
        !          2622:                        return;
        !          2623:                }
        !          2624:                DB_FROM_ZVAL(db, &zdb);
        !          2625:        }
        !          2626: 
        !          2627:        PHP_SQLITE_EMPTY_QUERY;
        !          2628: 
        !          2629:        /* avoid doing work if we can */
        !          2630:        if (!return_value_used) {
        !          2631:                db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
        !          2632: 
        !          2633:                if (db->last_err_code != SQLITE_OK) {
        !          2634:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
        !          2635:                        sqlite_freemem(errtext);
        !          2636:                }
        !          2637:                return;
        !          2638:        }
        !          2639: 
        !          2640:        rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
        !          2641:        sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, &rres, NULL TSRMLS_CC);
        !          2642:        if (db->last_err_code != SQLITE_OK) {
        !          2643:                if (rres) {
        !          2644:                        efree(rres);
        !          2645:                }
        !          2646:                RETURN_FALSE;
        !          2647:        }
        !          2648: 
        !          2649:        if (!srow) {
        !          2650:                array_init(return_value);
        !          2651:        }
        !          2652: 
        !          2653:        while (rres->curr_row < rres->nrows) {
        !          2654:                MAKE_STD_ZVAL(ent);
        !          2655:                php_sqlite_fetch_single(rres, decode_binary, ent TSRMLS_CC);
        !          2656: 
        !          2657:                /* if set and we only have 1 row in the result set, return the result as a string. */
        !          2658:                if (srow) {
        !          2659:                        if (rres->curr_row == 1 && rres->curr_row >= rres->nrows) {
        !          2660:                                *return_value = *ent;
        !          2661:                                zval_copy_ctor(return_value);
        !          2662:                                zval_dtor(ent);
        !          2663:                                FREE_ZVAL(ent);
        !          2664:                                break;
        !          2665:                        } else {
        !          2666:                                srow = 0;
        !          2667:                                array_init(return_value);
        !          2668:                        }
        !          2669:                }
        !          2670:                add_next_index_zval(return_value, ent);
        !          2671:        }
        !          2672: 
        !          2673:        real_result_dtor(rres TSRMLS_CC);
        !          2674: }
        !          2675: /* }}} */
        !          2676: 
        !          2677: 
        !          2678: /* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
        !          2679:    Fetches the first column of a result set as a string. */
        !          2680: PHP_FUNCTION(sqlite_fetch_single)
        !          2681: {
        !          2682:        zval *zres;
        !          2683:        zend_bool decode_binary = 1;
        !          2684:        struct php_sqlite_result *res;
        !          2685:        zval *object = getThis();
        !          2686: 
        !          2687:        if (object) {
        !          2688:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &decode_binary)) {
        !          2689:                        return;
        !          2690:                }
        !          2691:                RES_FROM_OBJECT(res, object);
        !          2692:        } else {
        !          2693:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
        !          2694:                        return;
        !          2695:                }
        !          2696:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2697:        }
        !          2698: 
        !          2699:        php_sqlite_fetch_single(res, decode_binary, return_value TSRMLS_CC);
        !          2700: }
        !          2701: /* }}} */
        !          2702: 
        !          2703: /* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
        !          2704:    Fetches the current row from a result set as an array. */
        !          2705: PHP_FUNCTION(sqlite_current)
        !          2706: {
        !          2707:        zval *zres;
        !          2708:        long mode = PHPSQLITE_BOTH;
        !          2709:        zend_bool decode_binary = 1;
        !          2710:        struct php_sqlite_result *res;
        !          2711:        zval *object = getThis();
        !          2712: 
        !          2713:        if (object) {
        !          2714:                if (ZEND_NUM_ARGS() && FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
        !          2715:                        return;
        !          2716:                }
        !          2717:                RES_FROM_OBJECT(res, object);
        !          2718:                if (!ZEND_NUM_ARGS()) {
        !          2719:                        mode = res->mode;
        !          2720:                }
        !          2721:        } else {
        !          2722:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
        !          2723:                        return;
        !          2724:                }
        !          2725:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2726:                if (ZEND_NUM_ARGS() < 2) {
        !          2727:                        mode = res->mode;
        !          2728:                }
        !          2729:        }
        !          2730: 
        !          2731:        php_sqlite_fetch_array(res, mode, decode_binary, 0, return_value TSRMLS_CC);
        !          2732: }
        !          2733: /* }}} */
        !          2734: 
        !          2735: /* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
        !          2736:    Fetches a column from the current row of a result set. */
        !          2737: PHP_FUNCTION(sqlite_column)
        !          2738: {
        !          2739:        zval *zres;
        !          2740:        zval *which;
        !          2741:        zend_bool decode_binary = 1;
        !          2742:        struct php_sqlite_result *res;
        !          2743:        zval *object = getThis();
        !          2744: 
        !          2745:        if (object) {
        !          2746:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &which, &decode_binary)) {
        !          2747:                        return;
        !          2748:                }
        !          2749:                RES_FROM_OBJECT(res, object);
        !          2750:        } else {
        !          2751:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
        !          2752:                        return;
        !          2753:                }
        !          2754:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2755:        }
        !          2756: 
        !          2757:        php_sqlite_fetch_column(res, which, decode_binary, return_value TSRMLS_CC);
        !          2758: }
        !          2759: /* }}} */
        !          2760: 
        !          2761: /* {{{ proto string sqlite_libversion()
        !          2762:    Returns the version of the linked SQLite library. */
        !          2763: PHP_FUNCTION(sqlite_libversion)
        !          2764: {
        !          2765:        if (zend_parse_parameters_none() == FAILURE) {
        !          2766:                return;
        !          2767:        }
        !          2768:        RETURN_STRING((char*)sqlite_libversion(), 1);
        !          2769: }
        !          2770: /* }}} */
        !          2771: 
        !          2772: /* {{{ proto string sqlite_libencoding()
        !          2773:    Returns the encoding (iso8859 or UTF-8) of the linked SQLite library. */
        !          2774: PHP_FUNCTION(sqlite_libencoding)
        !          2775: {
        !          2776:        if (zend_parse_parameters_none() == FAILURE) {
        !          2777:                return;
        !          2778:        }
        !          2779:        RETURN_STRING((char*)sqlite_libencoding(), 1);
        !          2780: }
        !          2781: /* }}} */
        !          2782: 
        !          2783: /* {{{ proto int sqlite_changes(resource db)
        !          2784:    Returns the number of rows that were changed by the most recent SQL statement. */
        !          2785: PHP_FUNCTION(sqlite_changes)
        !          2786: {
        !          2787:        zval *zdb;
        !          2788:        struct php_sqlite_db *db;
        !          2789:        zval *object = getThis();
        !          2790: 
        !          2791:        if (object) {
        !          2792:                if (zend_parse_parameters_none() == FAILURE) {
        !          2793:                        return;
        !          2794:                }
        !          2795:                DB_FROM_OBJECT(db, object);
        !          2796:        } else {
        !          2797:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
        !          2798:                        return;
        !          2799:                }
        !          2800:                DB_FROM_ZVAL(db, &zdb);
        !          2801:        }
        !          2802: 
        !          2803:        RETURN_LONG(sqlite_changes(db->db));
        !          2804: }
        !          2805: /* }}} */
        !          2806: 
        !          2807: /* {{{ proto int sqlite_last_insert_rowid(resource db)
        !          2808:    Returns the rowid of the most recently inserted row. */
        !          2809: PHP_FUNCTION(sqlite_last_insert_rowid)
        !          2810: {
        !          2811:        zval *zdb;
        !          2812:        struct php_sqlite_db *db;
        !          2813:        zval *object = getThis();
        !          2814: 
        !          2815:        if (object) {
        !          2816:                if (zend_parse_parameters_none() == FAILURE) {
        !          2817:                        return;
        !          2818:                }
        !          2819:                DB_FROM_OBJECT(db, object);
        !          2820:        } else {
        !          2821:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
        !          2822:                        return;
        !          2823:                }
        !          2824:                DB_FROM_ZVAL(db, &zdb);
        !          2825:        }
        !          2826: 
        !          2827:        RETURN_LONG(sqlite_last_insert_rowid(db->db));
        !          2828: }
        !          2829: /* }}} */
        !          2830: 
        !          2831: static int sqlite_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
        !          2832: {
        !          2833:        sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
        !          2834: 
        !          2835:        if (obj->u.res == NULL) {
        !          2836:                zend_throw_exception(sqlite_ce_exception, "Row count is not available for this query", 0 TSRMLS_CC);
        !          2837:                return FAILURE;
        !          2838:        }
        !          2839: 
        !          2840:        if (obj->u.res->buffered) {
        !          2841:                * count = obj->u.res->nrows;
        !          2842:                return SUCCESS;
        !          2843:        } else {
        !          2844:                zend_throw_exception(sqlite_ce_exception, "Row count is not available for unbuffered queries", 0 TSRMLS_CC);
        !          2845:                return FAILURE;
        !          2846:        }
        !          2847: } /* }}} */
        !          2848: 
        !          2849: /* {{{ proto int sqlite_num_rows(resource result)
        !          2850:    Returns the number of rows in a buffered result set. */
        !          2851: PHP_FUNCTION(sqlite_num_rows)
        !          2852: {
        !          2853:        zval *zres;
        !          2854:        struct php_sqlite_result *res;
        !          2855:        zval *object = getThis();
        !          2856: 
        !          2857:        if (object) {
        !          2858:                if (zend_parse_parameters_none() == FAILURE) {
        !          2859:                        return;
        !          2860:                }
        !          2861:                RES_FROM_OBJECT(res, object);
        !          2862:        } else {
        !          2863:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          2864:                        return;
        !          2865:                }
        !          2866:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2867:        }
        !          2868: 
        !          2869:        if (res->buffered) {
        !          2870:                RETURN_LONG(res->nrows);
        !          2871:        } else {
        !          2872:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Row count is not available for unbuffered queries");
        !          2873:                RETURN_FALSE;
        !          2874:        }
        !          2875: }
        !          2876: /* }}} */
        !          2877: 
        !          2878: /* {{{ proto bool sqlite_valid(resource result)
        !          2879:    Returns whether more rows are available. */
        !          2880: PHP_FUNCTION(sqlite_valid)
        !          2881: {
        !          2882:        zval *zres;
        !          2883:        struct php_sqlite_result *res;
        !          2884:        zval *object = getThis();
        !          2885: 
        !          2886:        if (object) {
        !          2887:                if (zend_parse_parameters_none() == FAILURE) {
        !          2888:                        return;
        !          2889:                }
        !          2890:                RES_FROM_OBJECT(res, object);
        !          2891:        } else {
        !          2892:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          2893:                        return;
        !          2894:                }
        !          2895:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2896:        }
        !          2897: 
        !          2898:        RETURN_BOOL(res->curr_row < res->nrows && res->nrows); /* curr_row may be -1 */
        !          2899: }
        !          2900: /* }}} */
        !          2901: 
        !          2902: /* {{{ proto bool sqlite_has_prev(resource result)
        !          2903:  * Returns whether a previous row is available. */
        !          2904: PHP_FUNCTION(sqlite_has_prev)
        !          2905: {
        !          2906:        zval *zres;
        !          2907:        struct php_sqlite_result *res;
        !          2908:        zval *object = getThis();
        !          2909: 
        !          2910:        if (object) {
        !          2911:                if (zend_parse_parameters_none() == FAILURE) {
        !          2912:                        return;
        !          2913:                }
        !          2914:                RES_FROM_OBJECT(res, object);
        !          2915:        } else {
        !          2916:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          2917:                        return;
        !          2918:                }
        !          2919:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2920:        }
        !          2921: 
        !          2922:        if(!res->buffered) {
        !          2923:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_has_prev on unbuffered querys");
        !          2924:                RETURN_FALSE;
        !          2925:        }
        !          2926: 
        !          2927:        RETURN_BOOL(res->curr_row);
        !          2928: }
        !          2929: /* }}} */
        !          2930: 
        !          2931: /* {{{ proto int sqlite_num_fields(resource result)
        !          2932:    Returns the number of fields in a result set. */
        !          2933: PHP_FUNCTION(sqlite_num_fields)
        !          2934: {
        !          2935:        zval *zres;
        !          2936:        struct php_sqlite_result *res;
        !          2937:        zval *object = getThis();
        !          2938: 
        !          2939:        if (object) {
        !          2940:                if (zend_parse_parameters_none() == FAILURE) {
        !          2941:                        return;
        !          2942:                }
        !          2943:                RES_FROM_OBJECT(res, object);
        !          2944:        } else {
        !          2945:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          2946:                        return;
        !          2947:                }
        !          2948:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2949:        }
        !          2950: 
        !          2951:        RETURN_LONG(res->ncolumns);
        !          2952: }
        !          2953: /* }}} */
        !          2954: 
        !          2955: /* {{{ proto string sqlite_field_name(resource result, int field_index)
        !          2956:    Returns the name of a particular field of a result set. */
        !          2957: PHP_FUNCTION(sqlite_field_name)
        !          2958: {
        !          2959:        zval *zres;
        !          2960:        struct php_sqlite_result *res;
        !          2961:        long field;
        !          2962:        zval *object = getThis();
        !          2963: 
        !          2964:        if (object) {
        !          2965:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &field)) {
        !          2966:                        return;
        !          2967:                }
        !          2968:                RES_FROM_OBJECT(res, object);
        !          2969:        } else {
        !          2970:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
        !          2971:                        return;
        !          2972:                }
        !          2973:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          2974:        }
        !          2975: 
        !          2976:        if (field < 0 || field >= res->ncolumns) {
        !          2977:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %ld out of range", field);
        !          2978:                RETURN_FALSE;
        !          2979:        }
        !          2980: 
        !          2981:        RETURN_STRING(res->col_names[field], 1);
        !          2982: }
        !          2983: /* }}} */
        !          2984: 
        !          2985: /* {{{ proto bool sqlite_seek(resource result, int row)
        !          2986:    Seek to a particular row number of a buffered result set. */
        !          2987: PHP_FUNCTION(sqlite_seek)
        !          2988: {
        !          2989:        zval *zres;
        !          2990:        struct php_sqlite_result *res;
        !          2991:        long row;
        !          2992:        zval *object = getThis();
        !          2993: 
        !          2994:        if (object) {
        !          2995:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &row)) {
        !          2996:                        return;
        !          2997:                }
        !          2998:                RES_FROM_OBJECT(res, object);
        !          2999:        } else {
        !          3000:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
        !          3001:                        return;
        !          3002:                }
        !          3003:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          3004:        }
        !          3005: 
        !          3006:        if (!res->buffered) {
        !          3007:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
        !          3008:                RETURN_FALSE;
        !          3009:        }
        !          3010: 
        !          3011:        if (row < 0 || row >= res->nrows) {
        !          3012:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %ld out of range", row);
        !          3013:                RETURN_FALSE;
        !          3014:        }
        !          3015: 
        !          3016:        res->curr_row = row;
        !          3017:        RETURN_TRUE;
        !          3018: }
        !          3019: /* }}} */
        !          3020: 
        !          3021: /* {{{ proto bool sqlite_rewind(resource result)
        !          3022:    Seek to the first row number of a buffered result set. */
        !          3023: PHP_FUNCTION(sqlite_rewind)
        !          3024: {
        !          3025:        zval *zres;
        !          3026:        struct php_sqlite_result *res;
        !          3027:        zval *object = getThis();
        !          3028: 
        !          3029:        if (object) {
        !          3030:                if (zend_parse_parameters_none() == FAILURE) {
        !          3031:                        return;
        !          3032:                }
        !          3033:                RES_FROM_OBJECT(res, object);
        !          3034:        } else {
        !          3035:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          3036:                        return;
        !          3037:                }
        !          3038:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          3039:        }
        !          3040: 
        !          3041:        if (!res->buffered) {
        !          3042:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rewind an unbuffered result set");
        !          3043:                RETURN_FALSE;
        !          3044:        }
        !          3045: 
        !          3046:        if (!res->nrows) {
        !          3047:                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "no rows received");
        !          3048:                RETURN_FALSE;
        !          3049:        }
        !          3050: 
        !          3051:        res->curr_row = 0;
        !          3052:        RETURN_TRUE;
        !          3053: }
        !          3054: /* }}} */
        !          3055: 
        !          3056: /* {{{ proto bool sqlite_next(resource result)
        !          3057:    Seek to the next row number of a result set. */
        !          3058: PHP_FUNCTION(sqlite_next)
        !          3059: {
        !          3060:        zval *zres;
        !          3061:        struct php_sqlite_result *res;
        !          3062:        zval *object = getThis();
        !          3063: 
        !          3064:        if (object) {
        !          3065:                if (zend_parse_parameters_none() == FAILURE) {
        !          3066:                        return;
        !          3067:                }
        !          3068:                RES_FROM_OBJECT(res, object);
        !          3069:        } else {
        !          3070:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          3071:                        return;
        !          3072:                }
        !          3073:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          3074:        }
        !          3075: 
        !          3076:        if (!res->buffered && res->vm) {
        !          3077:                php_sqlite_fetch(res TSRMLS_CC);
        !          3078:        }
        !          3079: 
        !          3080:        if (res->curr_row >= res->nrows) {
        !          3081:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available");
        !          3082:                RETURN_FALSE;
        !          3083:        }
        !          3084: 
        !          3085:        res->curr_row++;
        !          3086: 
        !          3087:        RETURN_TRUE;
        !          3088: }
        !          3089: /* }}} */
        !          3090: 
        !          3091: /* {{{ proto int sqlite_key(resource result)
        !          3092:    Return the current row index of a buffered result. */
        !          3093: PHP_FUNCTION(sqlite_key)
        !          3094: {
        !          3095:        zval *zres;
        !          3096:        struct php_sqlite_result *res;
        !          3097:        zval *object = getThis();
        !          3098: 
        !          3099:        if (object) {
        !          3100:                if (zend_parse_parameters_none() == FAILURE) {
        !          3101:                        return;
        !          3102:                }
        !          3103:                RES_FROM_OBJECT(res, object);
        !          3104:        } else {
        !          3105:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          3106:                        return;
        !          3107:                }
        !          3108:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          3109:        }
        !          3110: 
        !          3111:        RETURN_LONG(res->curr_row);
        !          3112: }
        !          3113: /* }}} */
        !          3114: 
        !          3115: /* {{{ proto bool sqlite_prev(resource result)
        !          3116:  * Seek to the previous row number of a result set. */
        !          3117: PHP_FUNCTION(sqlite_prev)
        !          3118: {
        !          3119:        zval *zres;
        !          3120:        struct php_sqlite_result *res;
        !          3121:        zval *object = getThis();
        !          3122: 
        !          3123:        if (object) {
        !          3124:                if (zend_parse_parameters_none() == FAILURE) {
        !          3125:                        return;
        !          3126:                }
        !          3127:                RES_FROM_OBJECT(res, object);
        !          3128:        } else {
        !          3129:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
        !          3130:                        return;
        !          3131:                }
        !          3132:                ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
        !          3133:        }
        !          3134: 
        !          3135:        if (!res->buffered) {
        !          3136:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_prev on unbuffered querys");
        !          3137:                RETURN_FALSE;
        !          3138:        }
        !          3139: 
        !          3140:        if (res->curr_row <= 0) {
        !          3141:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no previous row available");
        !          3142:                RETURN_FALSE;
        !          3143:        }
        !          3144: 
        !          3145:        res->curr_row--;
        !          3146: 
        !          3147:        RETURN_TRUE;
        !          3148: }
        !          3149: /* }}} */
        !          3150: 
        !          3151: /* {{{ proto string sqlite_escape_string(string item)
        !          3152:    Escapes a string for use as a query parameter. */
        !          3153: PHP_FUNCTION(sqlite_escape_string)
        !          3154: {
        !          3155:        char *string = NULL;
        !          3156:        int stringlen;
        !          3157:        char *ret;
        !          3158: 
        !          3159:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &stringlen)) {
        !          3160:                return;
        !          3161:        }
        !          3162: 
        !          3163:        if (stringlen && (string[0] == '\x01' || memchr(string, '\0', stringlen) != NULL)) {
        !          3164:                /* binary string */
        !          3165:                int enclen;
        !          3166: 
        !          3167:                ret = safe_emalloc(1 + stringlen / 254, 257, 3);
        !          3168:                ret[0] = '\x01';
        !          3169:                enclen = php_sqlite_encode_binary(string, stringlen, ret+1);
        !          3170:                RETVAL_STRINGL(ret, enclen+1, 0);
        !          3171: 
        !          3172:        } else if (stringlen) {
        !          3173:                ret = sqlite_mprintf("%q", string);
        !          3174:                if (ret) {
        !          3175:                        RETVAL_STRING(ret, 1);
        !          3176:                        sqlite_freemem(ret);
        !          3177:                }
        !          3178:        } else {
        !          3179:                RETURN_EMPTY_STRING();
        !          3180:        }
        !          3181: }
        !          3182: /* }}} */
        !          3183: 
        !          3184: /* {{{ proto int sqlite_last_error(resource db)
        !          3185:    Returns the error code of the last error for a database. */
        !          3186: PHP_FUNCTION(sqlite_last_error)
        !          3187: {
        !          3188:        zval *zdb;
        !          3189:        struct php_sqlite_db *db;
        !          3190:        zval *object = getThis();
        !          3191: 
        !          3192:        if (object) {
        !          3193:                if (zend_parse_parameters_none() == FAILURE) {
        !          3194:                        return;
        !          3195:                }
        !          3196:                DB_FROM_OBJECT(db, object);
        !          3197:        } else {
        !          3198:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
        !          3199:                        return;
        !          3200:                }
        !          3201:                DB_FROM_ZVAL(db, &zdb);
        !          3202:        }
        !          3203: 
        !          3204:        RETURN_LONG(db->last_err_code);
        !          3205: }
        !          3206: /* }}} */
        !          3207: 
        !          3208: /* {{{ proto string sqlite_error_string(int error_code)
        !          3209:    Returns the textual description of an error code. */
        !          3210: PHP_FUNCTION(sqlite_error_string)
        !          3211: {
        !          3212:        long code;
        !          3213:        const char *msg;
        !          3214: 
        !          3215:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
        !          3216:                return;
        !          3217:        }
        !          3218: 
        !          3219:        msg = sqlite_error_string(code);
        !          3220: 
        !          3221:        if (msg) {
        !          3222:                RETURN_STRING((char*)msg, 1);
        !          3223:        } else {
        !          3224:                RETURN_NULL();
        !          3225:        }
        !          3226: }
        !          3227: /* }}} */
        !          3228: 
        !          3229: /* manages duplicate registrations of a particular function, and
        !          3230:  * also handles the case where the db is using a persistent connection */
        !          3231: enum callback_prep_t { DO_REG, SKIP_REG, ERR };
        !          3232: 
        !          3233: static enum callback_prep_t prep_callback_struct(struct php_sqlite_db *db, int is_agg,
        !          3234:                char *funcname,
        !          3235:                zval *step, zval *fini, struct php_sqlite_agg_functions **funcs)
        !          3236: {
        !          3237:        struct php_sqlite_agg_functions *alloc_funcs, func_tmp;
        !          3238:        char *hashkey;
        !          3239:        int hashkeylen;
        !          3240:        enum callback_prep_t ret;
        !          3241: 
        !          3242:        hashkeylen = spprintf(&hashkey, 0, "%s-%s", is_agg ? "agg" : "reg", funcname);
        !          3243: 
        !          3244:        /* is it already registered ? */
        !          3245:        if (SUCCESS == zend_hash_find(&db->callbacks, hashkey, hashkeylen+1, (void*)&alloc_funcs)) {
        !          3246:                /* override the previous definition */
        !          3247: 
        !          3248:                if (alloc_funcs->is_valid) {
        !          3249:                        /* release these */
        !          3250: 
        !          3251:                        if (alloc_funcs->step) {
        !          3252:                                zval_ptr_dtor(&alloc_funcs->step);
        !          3253:                                alloc_funcs->step = NULL;
        !          3254:                        }
        !          3255: 
        !          3256:                        if (alloc_funcs->fini) {
        !          3257:                                zval_ptr_dtor(&alloc_funcs->fini);
        !          3258:                                alloc_funcs->fini = NULL;
        !          3259:                        }
        !          3260:                }
        !          3261: 
        !          3262:                ret = SKIP_REG;
        !          3263:        } else {
        !          3264:                /* add a new one */
        !          3265:                func_tmp.db = db;
        !          3266: 
        !          3267:                ret = SUCCESS == zend_hash_update(&db->callbacks, hashkey, hashkeylen+1,
        !          3268:                                (void*)&func_tmp, sizeof(func_tmp), (void**)&alloc_funcs) ? DO_REG : ERR;
        !          3269:        }
        !          3270: 
        !          3271:        efree(hashkey);
        !          3272: 
        !          3273:        MAKE_STD_ZVAL(alloc_funcs->step);
        !          3274:        *(alloc_funcs->step)  = *step;
        !          3275:        zval_copy_ctor(alloc_funcs->step);
        !          3276:        INIT_PZVAL(alloc_funcs->step);
        !          3277: 
        !          3278:        if (is_agg) {
        !          3279:                MAKE_STD_ZVAL(alloc_funcs->fini);
        !          3280:                *(alloc_funcs->fini) = *fini;
        !          3281:                zval_copy_ctor(alloc_funcs->fini);
        !          3282:                INIT_PZVAL(alloc_funcs->fini);
        !          3283:        } else {
        !          3284:                alloc_funcs->fini = NULL;
        !          3285:        }
        !          3286:        alloc_funcs->is_valid = 1;
        !          3287:        *funcs = alloc_funcs;
        !          3288: 
        !          3289:        return ret;
        !          3290: }
        !          3291: 
        !          3292: 
        !          3293: /* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
        !          3294:     Registers an aggregate function for queries. */
        !          3295: PHP_FUNCTION(sqlite_create_aggregate)
        !          3296: {
        !          3297:        char *funcname = NULL;
        !          3298:        int funcname_len;
        !          3299:        zval *zstep, *zfinal, *zdb;
        !          3300:        struct php_sqlite_db *db;
        !          3301:        struct php_sqlite_agg_functions *funcs;
        !          3302:        char *callable = NULL;
        !          3303:        long num_args = -1;
        !          3304:        zval *object = getThis();
        !          3305: 
        !          3306:        if (object) {
        !          3307:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
        !          3308:                        return;
        !          3309:                }
        !          3310:                DB_FROM_OBJECT(db, object);
        !          3311:        } else {
        !          3312:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
        !          3313:                        return;
        !          3314:                }
        !          3315:                DB_FROM_ZVAL(db, &zdb);
        !          3316:        }
        !          3317: 
        !          3318:        if (!zend_is_callable(zstep, 0, &callable TSRMLS_CC)) {
        !          3319:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "step function `%s' is not callable", callable);
        !          3320:                efree(callable);
        !          3321:                return;
        !          3322:        }
        !          3323:        efree(callable);
        !          3324: 
        !          3325:        if (!zend_is_callable(zfinal, 0, &callable TSRMLS_CC)) {
        !          3326:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "finalize function `%s' is not callable", callable);
        !          3327:                efree(callable);
        !          3328:                return;
        !          3329:        }
        !          3330:        efree(callable);
        !          3331: 
        !          3332: 
        !          3333:        if (prep_callback_struct(db, 1, funcname, zstep, zfinal, &funcs) == DO_REG) {
        !          3334:                sqlite_create_aggregate(db->db, funcname, num_args,
        !          3335:                                php_sqlite_agg_step_function_callback,
        !          3336:                                php_sqlite_agg_fini_function_callback, funcs);
        !          3337:        }
        !          3338: 
        !          3339: 
        !          3340: }
        !          3341: /* }}} */
        !          3342: 
        !          3343: /* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
        !          3344:     Registers a "regular" function for queries. */
        !          3345: PHP_FUNCTION(sqlite_create_function)
        !          3346: {
        !          3347:        char *funcname = NULL;
        !          3348:        int funcname_len;
        !          3349:        zval *zcall, *zdb;
        !          3350:        struct php_sqlite_db *db;
        !          3351:        struct php_sqlite_agg_functions *funcs;
        !          3352:        char *callable = NULL;
        !          3353:        long num_args = -1;
        !          3354: 
        !          3355:        zval *object = getThis();
        !          3356: 
        !          3357:        if (object) {
        !          3358:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &funcname, &funcname_len, &zcall, &num_args)) {
        !          3359:                        return;
        !          3360:                }
        !          3361:                DB_FROM_OBJECT(db, object);
        !          3362:        } else {
        !          3363:                if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
        !          3364:                        return;
        !          3365:                }
        !          3366:                DB_FROM_ZVAL(db, &zdb);
        !          3367:        }
        !          3368: 
        !          3369:        if (!zend_is_callable(zcall, 0, &callable TSRMLS_CC)) {
        !          3370:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "function `%s' is not callable", callable);
        !          3371:                efree(callable);
        !          3372:                return;
        !          3373:        }
        !          3374:        efree(callable);
        !          3375: 
        !          3376:        if (prep_callback_struct(db, 0, funcname, zcall, NULL, &funcs) == DO_REG) {
        !          3377:                sqlite_create_function(db->db, funcname, num_args, php_sqlite_function_callback, funcs);
        !          3378:        }
        !          3379: }
        !          3380: /* }}} */
        !          3381: 
        !          3382: /* {{{ proto string sqlite_udf_encode_binary(string data)
        !          3383:    Apply binary encoding (if required) to a string to return from an UDF. */
        !          3384: PHP_FUNCTION(sqlite_udf_encode_binary)
        !          3385: {
        !          3386:        char *data = NULL;
        !          3387:        int datalen;
        !          3388: 
        !          3389:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
        !          3390:                return;
        !          3391:        }
        !          3392: 
        !          3393:        if (data == NULL) {
        !          3394:                RETURN_NULL();
        !          3395:        }
        !          3396:        if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) {
        !          3397:                /* binary string */
        !          3398:                int enclen;
        !          3399:                char *ret;
        !          3400: 
        !          3401:                ret = safe_emalloc(1 + datalen / 254, 257, 3);
        !          3402:                ret[0] = '\x01';
        !          3403:                enclen = php_sqlite_encode_binary(data, datalen, ret+1);
        !          3404:                RETVAL_STRINGL(ret, enclen+1, 0);
        !          3405:        } else {
        !          3406:                RETVAL_STRINGL(data, datalen, 1);
        !          3407:        }
        !          3408: }
        !          3409: /* }}} */
        !          3410: 
        !          3411: /* {{{ proto string sqlite_udf_decode_binary(string data)
        !          3412:    Decode binary encoding on a string parameter passed to an UDF. */
        !          3413: PHP_FUNCTION(sqlite_udf_decode_binary)
        !          3414: {
        !          3415:        char *data = NULL;
        !          3416:        int datalen;
        !          3417: 
        !          3418:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
        !          3419:                return;
        !          3420:        }
        !          3421: 
        !          3422:        if (data == NULL) {
        !          3423:                RETURN_NULL();
        !          3424:        }
        !          3425:        if (datalen && data[0] == '\x01') {
        !          3426:                /* encoded string */
        !          3427:                int enclen;
        !          3428:                char *ret;
        !          3429: 
        !          3430:                ret = emalloc(datalen);
        !          3431:                enclen = php_sqlite_decode_binary(data+1, ret);
        !          3432:                ret[enclen] = '\0';
        !          3433:                RETVAL_STRINGL(ret, enclen, 0);
        !          3434:        } else {
        !          3435:                RETVAL_STRINGL(data, datalen, 1);
        !          3436:        }
        !          3437: }
        !          3438: /* }}} */
        !          3439: 
        !          3440: 
        !          3441: /*
        !          3442:  * Local variables:
        !          3443:  * tab-width: 4
        !          3444:  * c-basic-offset: 4
        !          3445:  * End:
        !          3446:  * vim600: sw=4 ts=4 fdm=marker
        !          3447:  * vim<600: sw=4 ts=4
        !          3448:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>