Annotation of embedaddon/php/ext/sqlite/sqlite.c, revision 1.1.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>