Back to index

php5  5.3.10
sqlite.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Wez Furlong <wez@thebrainroom.com>                          |
00016    |          Tal Peer <tal@php.net>                                      |
00017    |          Marcus Boerger <helly@php.net>                              |
00018    +----------------------------------------------------------------------+
00019 
00020    $Id: sqlite.c 321634 2012-01-01 13:15:04Z felipe $
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #define PHP_SQLITE_MODULE_VERSION  "2.0-dev"
00028 
00029 #include "php.h"
00030 #include "php_ini.h"
00031 #include "ext/standard/info.h"
00032 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
00033 #include "ext/session/php_session.h"
00034 #endif
00035 #include "php_sqlite.h"
00036 
00037 #if HAVE_TIME_H
00038 # include <time.h>
00039 #endif
00040 #if HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043 
00044 #include <sqlite.h>
00045 
00046 #include "zend_exceptions.h"
00047 #include "zend_interfaces.h"
00048 
00049 #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
00050 extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
00051 extern PHPAPI zend_class_entry *spl_ce_Countable;
00052 #endif
00053 
00054 #if PHP_SQLITE2_HAVE_PDO
00055 # include "pdo/php_pdo.h"
00056 # include "pdo/php_pdo_driver.h"
00057 extern pdo_driver_t pdo_sqlite2_driver;
00058 #endif
00059 
00060 #ifndef safe_emalloc
00061 # define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
00062 #endif
00063 
00064 ZEND_DECLARE_MODULE_GLOBALS(sqlite)
00065 static PHP_GINIT_FUNCTION(sqlite);
00066 
00067 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
00068 extern ps_module ps_mod_sqlite;
00069 #define ps_sqlite_ptr &ps_mod_sqlite
00070 #endif
00071 
00072 extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
00073 extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
00074 
00075 #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
00076 #define php_sqlite_decode_binary(in, out) in && *in ? sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out) : 0
00077 
00078 static int sqlite_count_elements(zval *object, long *count TSRMLS_DC);
00079 
00080 static int le_sqlite_db, le_sqlite_result, le_sqlite_pdb;
00081 
00082 static inline void php_sqlite_strtoupper(char *s)
00083 {
00084        while (*s!='\0') {
00085               *s = toupper(*s);
00086               s++;
00087        }
00088 }
00089 
00090 static inline void php_sqlite_strtolower(char *s)
00091 {
00092        while (*s!='\0') {
00093               *s = tolower(*s);
00094               s++;
00095        }
00096 }
00097 
00098 /* {{{ PHP_INI
00099  */
00100 PHP_INI_BEGIN()
00101 STD_PHP_INI_ENTRY_EX("sqlite.assoc_case", "0", PHP_INI_ALL, OnUpdateLong, assoc_case, zend_sqlite_globals, sqlite_globals, display_link_numbers)
00102 PHP_INI_END()
00103 /* }}} */
00104 
00105 #define DB_FROM_ZVAL(db, zv)       ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
00106 
00107 #define DB_FROM_OBJECT(db, object) \
00108        { \
00109               sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
00110               db = obj->u.db; \
00111               if (!db) { \
00112                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "The database wasn't opened"); \
00113                      RETURN_NULL(); \
00114               } \
00115        }
00116 
00117 #define RES_FROM_OBJECT_RESTORE_ERH(res, object, error_handling) \
00118        { \
00119               sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
00120               res = obj->u.res; \
00121               if (!res) { \
00122                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "No result set available"); \
00123                      if (error_handling) \
00124                             zend_restore_error_handling(error_handling TSRMLS_CC); \
00125                      RETURN_NULL(); \
00126               } \
00127        }
00128 
00129 #define RES_FROM_OBJECT(res, object) RES_FROM_OBJECT_RESTORE_ERH(res, object, NULL)
00130 
00131 #define PHP_SQLITE_EMPTY_QUERY \
00132        if (!sql_len || !*sql) { \
00133               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute empty query."); \
00134               RETURN_FALSE; \
00135        }
00136 
00137 struct php_sqlite_result {
00138        struct php_sqlite_db *db;
00139        sqlite_vm *vm;
00140        int buffered;
00141        int ncolumns;
00142        int nrows;
00143        int curr_row;
00144        char **col_names;
00145        int alloc_rows;
00146        int mode;
00147        char **table;
00148 };
00149 
00150 struct php_sqlite_db {
00151        sqlite *db;
00152        int last_err_code;
00153        zend_bool is_persistent;
00154        long rsrc_id;
00155 
00156        HashTable callbacks;
00157 };
00158 
00159 struct php_sqlite_agg_functions {
00160        struct php_sqlite_db *db;
00161        int is_valid;
00162        zval *step;
00163        zval *fini;
00164 };
00165 
00166 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);
00167 static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC);
00168 
00169 enum { PHPSQLITE_ASSOC = 1, PHPSQLITE_NUM = 2, PHPSQLITE_BOTH = PHPSQLITE_ASSOC|PHPSQLITE_NUM };
00170 
00171 /* {{{ arginfo */
00172 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_popen, 0, 0, 1)
00173        ZEND_ARG_INFO(0, filename)
00174        ZEND_ARG_INFO(0, mode)
00175        ZEND_ARG_INFO(1, error_message)
00176 ZEND_END_ARG_INFO()
00177 
00178 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_open, 0, 0, 1)
00179        ZEND_ARG_INFO(0, filename)
00180        ZEND_ARG_INFO(0, mode)
00181        ZEND_ARG_INFO(1, error_message)
00182 ZEND_END_ARG_INFO()
00183 
00184 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_factory, 0, 0, 1)
00185        ZEND_ARG_INFO(0, filename)
00186        ZEND_ARG_INFO(0, mode)
00187        ZEND_ARG_INFO(1, error_message)
00188 ZEND_END_ARG_INFO()
00189 
00190 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_busy_timeout, 0, 0, 2)
00191        ZEND_ARG_INFO(0, db)
00192        ZEND_ARG_INFO(0, ms)
00193 ZEND_END_ARG_INFO()
00194 
00195 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_busy_timeout, 0, 0, 1)
00196        ZEND_ARG_INFO(0, ms)
00197 ZEND_END_ARG_INFO()
00198 
00199 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_close, 0, 0, 1)
00200        ZEND_ARG_INFO(0, db)
00201 ZEND_END_ARG_INFO()
00202 
00203 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_unbuffered_query, 0, 0, 2)
00204        ZEND_ARG_INFO(0, query)
00205        ZEND_ARG_INFO(0, db)
00206        ZEND_ARG_INFO(0, result_type)
00207        ZEND_ARG_INFO(1, error_message)
00208 ZEND_END_ARG_INFO()
00209 
00210 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_unbuffered_query, 0, 0, 1)
00211        ZEND_ARG_INFO(0, query)
00212        ZEND_ARG_INFO(0, result_type)
00213        ZEND_ARG_INFO(1, error_message)
00214 ZEND_END_ARG_INFO()
00215 
00216 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_column_types, 0, 0, 2)
00217        ZEND_ARG_INFO(0, table_name)
00218        ZEND_ARG_INFO(0, db)
00219        ZEND_ARG_INFO(0, result_type)
00220 ZEND_END_ARG_INFO()
00221 
00222 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_column_types, 0, 0, 1)
00223        ZEND_ARG_INFO(0, table_name)
00224        ZEND_ARG_INFO(0, result_type)
00225 ZEND_END_ARG_INFO()
00226 
00227 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_query, 0, 0, 2)
00228        ZEND_ARG_INFO(0, query)
00229        ZEND_ARG_INFO(0, db)
00230        ZEND_ARG_INFO(0, result_type)
00231        ZEND_ARG_INFO(1, error_message)
00232 ZEND_END_ARG_INFO()
00233 
00234 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_query, 0, 0, 1)
00235        ZEND_ARG_INFO(0, query)
00236        ZEND_ARG_INFO(0, result_type)
00237        ZEND_ARG_INFO(1, error_message)
00238 ZEND_END_ARG_INFO()
00239 
00240 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_exec, 0, 0, 2)
00241        ZEND_ARG_INFO(0, query)
00242        ZEND_ARG_INFO(0, db)
00243        ZEND_ARG_INFO(1, error_message)
00244 ZEND_END_ARG_INFO()
00245 
00246 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_exec, 0, 0, 1)
00247        ZEND_ARG_INFO(0, query)
00248        ZEND_ARG_INFO(1, error_message)
00249 ZEND_END_ARG_INFO()
00250 
00251 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_all, 0, 0, 1)
00252        ZEND_ARG_INFO(0, result)
00253        ZEND_ARG_INFO(0, result_type)
00254        ZEND_ARG_INFO(0, decode_binary)
00255 ZEND_END_ARG_INFO()
00256 
00257 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_all, 0, 0, 0)
00258        ZEND_ARG_INFO(0, result_type)
00259        ZEND_ARG_INFO(0, decode_binary)
00260 ZEND_END_ARG_INFO()
00261 
00262 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_array, 0, 0, 1)
00263        ZEND_ARG_INFO(0, result)
00264        ZEND_ARG_INFO(0, result_type)
00265        ZEND_ARG_INFO(0, decode_binary)
00266 ZEND_END_ARG_INFO()
00267 
00268 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_array, 0, 0, 0)
00269        ZEND_ARG_INFO(0, result_type)
00270        ZEND_ARG_INFO(0, decode_binary)
00271 ZEND_END_ARG_INFO()
00272 
00273 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_object, 0, 0, 1)
00274        ZEND_ARG_INFO(0, result)
00275        ZEND_ARG_INFO(0, class_name)
00276        ZEND_ARG_INFO(0, ctor_params)
00277        ZEND_ARG_INFO(0, decode_binary)
00278 ZEND_END_ARG_INFO()
00279 
00280 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_object, 0, 0, 0)
00281        ZEND_ARG_INFO(0, class_name)
00282        ZEND_ARG_INFO(0, ctor_params)
00283        ZEND_ARG_INFO(0, decode_binary)
00284 ZEND_END_ARG_INFO()
00285 
00286 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_array_query, 0, 0, 2)
00287        ZEND_ARG_INFO(0, db)
00288        ZEND_ARG_INFO(0, query)
00289        ZEND_ARG_INFO(0, result_type)
00290        ZEND_ARG_INFO(0, decode_binary)
00291 ZEND_END_ARG_INFO()
00292 
00293 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_array_query, 0, 0, 1)
00294        ZEND_ARG_INFO(0, query)
00295        ZEND_ARG_INFO(0, result_type)
00296        ZEND_ARG_INFO(0, decode_binary)
00297 ZEND_END_ARG_INFO()
00298 
00299 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_single_query, 0, 0, 2)
00300        ZEND_ARG_INFO(0, db)
00301        ZEND_ARG_INFO(0, query)
00302        ZEND_ARG_INFO(0, first_row_only)
00303        ZEND_ARG_INFO(0, decode_binary)
00304 ZEND_END_ARG_INFO()
00305 
00306 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_single_query, 0, 0, 1)
00307        ZEND_ARG_INFO(0, query)
00308        ZEND_ARG_INFO(0, first_row_only)
00309        ZEND_ARG_INFO(0, decode_binary)
00310 ZEND_END_ARG_INFO()
00311 
00312 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_single, 0, 0, 1)
00313        ZEND_ARG_INFO(0, result)
00314        ZEND_ARG_INFO(0, decode_binary)
00315 ZEND_END_ARG_INFO()
00316 
00317 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_single, 0, 0, 0)
00318        ZEND_ARG_INFO(0, decode_binary)
00319 ZEND_END_ARG_INFO()
00320 
00321 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_current, 0, 0, 1)
00322        ZEND_ARG_INFO(0, result)
00323        ZEND_ARG_INFO(0, result_type)
00324        ZEND_ARG_INFO(0, decode_binary)
00325 ZEND_END_ARG_INFO()
00326 
00327 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_current, 0, 0, 0)
00328        ZEND_ARG_INFO(0, result_type)
00329        ZEND_ARG_INFO(0, decode_binary)
00330 ZEND_END_ARG_INFO()
00331 
00332 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_column, 0, 0, 2)
00333        ZEND_ARG_INFO(0, result)
00334        ZEND_ARG_INFO(0, index_or_name)
00335        ZEND_ARG_INFO(0, decode_binary)
00336 ZEND_END_ARG_INFO()
00337 
00338 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_column, 0, 0, 1)
00339        ZEND_ARG_INFO(0, index_or_name)
00340        ZEND_ARG_INFO(0, decode_binary)
00341 ZEND_END_ARG_INFO()
00342 
00343 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libversion, 0)
00344 ZEND_END_ARG_INFO()
00345 
00346 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libencoding, 0)
00347 ZEND_END_ARG_INFO()
00348 
00349 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_changes, 0, 0, 1)
00350        ZEND_ARG_INFO(0, db)
00351 ZEND_END_ARG_INFO()
00352 
00353 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_changes, 0)
00354 ZEND_END_ARG_INFO()
00355 
00356 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_insert_rowid, 0, 0, 1)
00357        ZEND_ARG_INFO(0, db)
00358 ZEND_END_ARG_INFO()
00359 
00360 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_insert_rowid, 0)
00361 ZEND_END_ARG_INFO()
00362 
00363 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_rows, 0, 0, 1)
00364        ZEND_ARG_INFO(0, result)
00365 ZEND_END_ARG_INFO()
00366 
00367 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_rows, 0)
00368 ZEND_END_ARG_INFO()
00369 
00370 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_valid, 0, 0, 1)
00371        ZEND_ARG_INFO(0, result)
00372 ZEND_END_ARG_INFO()
00373 
00374 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_valid, 0)
00375 ZEND_END_ARG_INFO()
00376 
00377 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_has_prev, 0, 0, 1)
00378        ZEND_ARG_INFO(0, result)
00379 ZEND_END_ARG_INFO()
00380 
00381 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_has_prev, 0)
00382 ZEND_END_ARG_INFO()
00383 
00384 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_fields, 0, 0, 1)
00385        ZEND_ARG_INFO(0, result)
00386 ZEND_END_ARG_INFO()
00387 
00388 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_fields, 0)
00389 ZEND_END_ARG_INFO()
00390 
00391 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_field_name, 0, 0, 2)
00392        ZEND_ARG_INFO(0, result)
00393        ZEND_ARG_INFO(0, field_index)
00394 ZEND_END_ARG_INFO()
00395 
00396 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_field_name, 0, 0, 1)
00397        ZEND_ARG_INFO(0, field_index)
00398 ZEND_END_ARG_INFO()
00399 
00400 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_seek, 0, 0, 2)
00401        ZEND_ARG_INFO(0, result)
00402        ZEND_ARG_INFO(0, row)
00403 ZEND_END_ARG_INFO()
00404 
00405 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_seek, 0, 0, 1)
00406        ZEND_ARG_INFO(0, row)
00407 ZEND_END_ARG_INFO()
00408 
00409 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_rewind, 0, 0, 1)
00410        ZEND_ARG_INFO(0, result)
00411 ZEND_END_ARG_INFO()
00412 
00413 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_rewind, 0)
00414 ZEND_END_ARG_INFO()
00415 
00416 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_next, 0, 0, 1)
00417        ZEND_ARG_INFO(0, result)
00418 ZEND_END_ARG_INFO()
00419 
00420 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_next, 0)
00421 ZEND_END_ARG_INFO()
00422 
00423 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_key, 0, 0, 1)
00424        ZEND_ARG_INFO(0, result)
00425 ZEND_END_ARG_INFO()
00426 
00427 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_key, 0)
00428 ZEND_END_ARG_INFO()
00429 
00430 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_prev, 0, 0, 1)
00431        ZEND_ARG_INFO(0, result)
00432 ZEND_END_ARG_INFO()
00433 
00434 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_prev, 0)
00435 ZEND_END_ARG_INFO()
00436 
00437 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_escape_string, 0, 0, 1)
00438        ZEND_ARG_INFO(0, item)
00439 ZEND_END_ARG_INFO()
00440 
00441 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_error, 0, 0, 1)
00442        ZEND_ARG_INFO(0, db)
00443 ZEND_END_ARG_INFO()
00444 
00445 ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_error, 0)
00446 ZEND_END_ARG_INFO()
00447 
00448 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_error_string, 0, 0, 1)
00449        ZEND_ARG_INFO(0, error_code)
00450 ZEND_END_ARG_INFO()
00451 
00452 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_aggregate, 0, 0, 4)
00453        ZEND_ARG_INFO(0, db)
00454        ZEND_ARG_INFO(0, funcname)
00455        ZEND_ARG_INFO(0, step_func)
00456        ZEND_ARG_INFO(0, finalize_func)
00457        ZEND_ARG_INFO(0, num_args)
00458 ZEND_END_ARG_INFO()
00459 
00460 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_aggregate, 0, 0, 3)
00461        ZEND_ARG_INFO(0, funcname)
00462        ZEND_ARG_INFO(0, step_func)
00463        ZEND_ARG_INFO(0, finalize_func)
00464        ZEND_ARG_INFO(0, num_args)
00465 ZEND_END_ARG_INFO()
00466 
00467 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_function, 0, 0, 3)
00468        ZEND_ARG_INFO(0, db)
00469        ZEND_ARG_INFO(0, funcname)
00470        ZEND_ARG_INFO(0, callback)
00471        ZEND_ARG_INFO(0, num_args)
00472 ZEND_END_ARG_INFO()
00473 
00474 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_function, 0, 0, 2)
00475        ZEND_ARG_INFO(0, funcname)
00476        ZEND_ARG_INFO(0, callback)
00477        ZEND_ARG_INFO(0, num_args)
00478 ZEND_END_ARG_INFO()
00479 
00480 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_encode_binary, 0, 0, 1)
00481        ZEND_ARG_INFO(0, data)
00482 ZEND_END_ARG_INFO()
00483 
00484 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_decode_binary, 0, 0, 1)
00485        ZEND_ARG_INFO(0, data)
00486 ZEND_END_ARG_INFO()
00487 /* }}} */
00488 
00489 const zend_function_entry sqlite_functions[] = {
00490        PHP_FE(sqlite_open,                       arginfo_sqlite_open)
00491        PHP_FE(sqlite_popen,                             arginfo_sqlite_popen)
00492        PHP_FE(sqlite_close,                             arginfo_sqlite_close)
00493        PHP_FE(sqlite_query,                             arginfo_sqlite_query)
00494        PHP_FE(sqlite_exec,                       arginfo_sqlite_exec)
00495        PHP_FE(sqlite_array_query,                arginfo_sqlite_array_query)
00496        PHP_FE(sqlite_single_query,               arginfo_sqlite_single_query)
00497        PHP_FE(sqlite_fetch_array,                arginfo_sqlite_fetch_array)
00498        PHP_FE(sqlite_fetch_object,               arginfo_sqlite_fetch_object)
00499        PHP_FE(sqlite_fetch_single,               arginfo_sqlite_fetch_single)
00500        PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, arginfo_sqlite_fetch_single)
00501        PHP_FE(sqlite_fetch_all,                  arginfo_sqlite_fetch_all)
00502        PHP_FE(sqlite_current,                           arginfo_sqlite_current)
00503        PHP_FE(sqlite_column,                            arginfo_sqlite_column)
00504        PHP_FE(sqlite_libversion,                 arginfo_sqlite_libversion)
00505        PHP_FE(sqlite_libencoding,                arginfo_sqlite_libencoding)
00506        PHP_FE(sqlite_changes,                           arginfo_sqlite_changes)
00507        PHP_FE(sqlite_last_insert_rowid,   arginfo_sqlite_last_insert_rowid)
00508        PHP_FE(sqlite_num_rows,                   arginfo_sqlite_num_rows)
00509        PHP_FE(sqlite_num_fields,                 arginfo_sqlite_num_fields)
00510        PHP_FE(sqlite_field_name,                 arginfo_sqlite_field_name)
00511        PHP_FE(sqlite_seek,                       arginfo_sqlite_seek)
00512        PHP_FE(sqlite_rewind,                            arginfo_sqlite_rewind)
00513        PHP_FE(sqlite_next,                       arginfo_sqlite_next)
00514        PHP_FE(sqlite_prev,                       arginfo_sqlite_prev)
00515        PHP_FE(sqlite_valid,                             arginfo_sqlite_valid)
00516        PHP_FALIAS(sqlite_has_more, sqlite_valid, arginfo_sqlite_valid)
00517        PHP_FE(sqlite_has_prev,                   arginfo_sqlite_has_prev)
00518        PHP_FE(sqlite_escape_string,              arginfo_sqlite_escape_string)
00519        PHP_FE(sqlite_busy_timeout,               arginfo_sqlite_busy_timeout)
00520        PHP_FE(sqlite_last_error,                 arginfo_sqlite_last_error)
00521        PHP_FE(sqlite_error_string,               arginfo_sqlite_error_string)
00522        PHP_FE(sqlite_unbuffered_query,    arginfo_sqlite_unbuffered_query)
00523        PHP_FE(sqlite_create_aggregate,    arginfo_sqlite_create_aggregate)
00524        PHP_FE(sqlite_create_function,            arginfo_sqlite_create_function)
00525        PHP_FE(sqlite_factory,                           arginfo_sqlite_factory)
00526        PHP_FE(sqlite_udf_encode_binary,   arginfo_sqlite_udf_encode_binary)
00527        PHP_FE(sqlite_udf_decode_binary,   arginfo_sqlite_udf_decode_binary)
00528        PHP_FE(sqlite_fetch_column_types,  arginfo_sqlite_fetch_column_types)
00529        {NULL, NULL, NULL}
00530 };
00531 
00532 const zend_function_entry sqlite_funcs_db[] = {
00533        PHP_ME_MAPPING(__construct, sqlite_open, arginfo_sqlite_open, 0)
00534 /*     PHP_ME_MAPPING(close, sqlite_close, NULL, 0)*/
00535        PHP_ME_MAPPING(query, sqlite_query, arginfo_sqlite_method_query, 0)
00536        PHP_ME_MAPPING(queryExec, sqlite_exec, arginfo_sqlite_method_exec, 0)
00537        PHP_ME_MAPPING(arrayQuery, sqlite_array_query, arginfo_sqlite_method_array_query, 0)
00538        PHP_ME_MAPPING(singleQuery, sqlite_single_query, arginfo_sqlite_method_single_query, 0)
00539        PHP_ME_MAPPING(unbufferedQuery, sqlite_unbuffered_query, arginfo_sqlite_method_unbuffered_query, 0)
00540        PHP_ME_MAPPING(lastInsertRowid, sqlite_last_insert_rowid, arginfo_sqlite_method_last_insert_rowid, 0)
00541        PHP_ME_MAPPING(changes, sqlite_changes, arginfo_sqlite_method_changes, 0)
00542        PHP_ME_MAPPING(createAggregate, sqlite_create_aggregate, arginfo_sqlite_method_create_aggregate, 0)
00543        PHP_ME_MAPPING(createFunction, sqlite_create_function, arginfo_sqlite_method_create_function, 0)
00544        PHP_ME_MAPPING(busyTimeout, sqlite_busy_timeout, arginfo_sqlite_method_busy_timeout, 0)
00545        PHP_ME_MAPPING(lastError, sqlite_last_error, arginfo_sqlite_method_last_error, 0)
00546        PHP_ME_MAPPING(fetchColumnTypes, sqlite_fetch_column_types, arginfo_sqlite_method_fetch_column_types, 0)
00547 /*     PHP_ME_MAPPING(error_string, sqlite_error_string, NULL, 0) static */
00548 /*     PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL, 0) static */
00549        {NULL, NULL, NULL}
00550 };
00551 
00552 const zend_function_entry sqlite_funcs_query[] = {
00553        PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
00554        PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
00555        PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
00556        PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
00557        PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
00558        PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
00559        PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
00560        /* iterator */
00561        PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
00562        PHP_ME_MAPPING(key, sqlite_key, arginfo_sqlite_method_key, 0)
00563        PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
00564        PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
00565        PHP_ME_MAPPING(rewind, sqlite_rewind, arginfo_sqlite_method_rewind, 0)
00566        /* countable */
00567        PHP_ME_MAPPING(count, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
00568        /* additional */
00569        PHP_ME_MAPPING(prev, sqlite_prev, arginfo_sqlite_method_prev, 0)
00570        PHP_ME_MAPPING(hasPrev, sqlite_has_prev, arginfo_sqlite_method_has_prev, 0)
00571        PHP_ME_MAPPING(numRows, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
00572        PHP_ME_MAPPING(seek, sqlite_seek, arginfo_sqlite_method_seek, 0)
00573        {NULL, NULL, NULL}
00574 };
00575 
00576 const zend_function_entry sqlite_funcs_ub_query[] = {
00577        PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
00578        PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
00579        PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
00580        PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
00581        PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
00582        PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
00583        PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
00584        /* iterator */
00585        PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
00586        PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
00587        PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
00588        {NULL, NULL, NULL}
00589 };
00590 
00591 const zend_function_entry sqlite_funcs_exception[] = {
00592        {NULL, NULL, NULL}
00593 };
00594 
00595 /* Dependancies */
00596 static const zend_module_dep sqlite_deps[] = {
00597 #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
00598        ZEND_MOD_REQUIRED("spl")
00599 #endif
00600 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
00601        ZEND_MOD_REQUIRED("session")
00602 #endif
00603 #ifdef PHP_SQLITE2_HAVE_PDO
00604        ZEND_MOD_REQUIRED("pdo")
00605 #endif
00606        {NULL, NULL, NULL}
00607 };
00608 
00609 zend_module_entry sqlite_module_entry = {
00610 #if ZEND_MODULE_API_NO >= 20050922
00611        STANDARD_MODULE_HEADER_EX, NULL,
00612        sqlite_deps,
00613 #elif ZEND_MODULE_API_NO >= 20010901
00614        STANDARD_MODULE_HEADER,
00615 #endif
00616        "SQLite",
00617        sqlite_functions,
00618        PHP_MINIT(sqlite),
00619        PHP_MSHUTDOWN(sqlite),
00620        NULL,
00621        PHP_RSHUTDOWN(sqlite),
00622        PHP_MINFO(sqlite),
00623 #if ZEND_MODULE_API_NO >= 20010901
00624        PHP_SQLITE_MODULE_VERSION,
00625 #endif
00626 #if ZEND_MODULE_API_NO >= 20060613
00627        PHP_MODULE_GLOBALS(sqlite),
00628        PHP_GINIT(sqlite),
00629        NULL,
00630        NULL,
00631        STANDARD_MODULE_PROPERTIES_EX
00632 #else
00633        STANDARD_MODULE_PROPERTIES
00634 #endif
00635 };
00636 
00637 
00638 #ifdef COMPILE_DL_SQLITE
00639 ZEND_GET_MODULE(sqlite)
00640 #endif
00641 
00642 static int php_sqlite_callback_invalidator(struct php_sqlite_agg_functions *funcs TSRMLS_DC)
00643 {
00644        if (!funcs->is_valid) {
00645               return 0;
00646        }
00647 
00648        if (funcs->step) {
00649               zval_ptr_dtor(&funcs->step);
00650               funcs->step = NULL;
00651        }
00652 
00653        if (funcs->fini) {
00654               zval_ptr_dtor(&funcs->fini);
00655               funcs->fini = NULL;
00656        }
00657 
00658        funcs->is_valid = 0;
00659 
00660        return 0;
00661 }
00662 
00663 
00664 static void php_sqlite_callback_dtor(void *pDest)
00665 {
00666        struct php_sqlite_agg_functions *funcs = (struct php_sqlite_agg_functions*)pDest;
00667 
00668        if (funcs->is_valid) {
00669               TSRMLS_FETCH();
00670 
00671               php_sqlite_callback_invalidator(funcs TSRMLS_CC);
00672        }
00673 }
00674 
00675 static ZEND_RSRC_DTOR_FUNC(php_sqlite_db_dtor)
00676 {
00677        if (rsrc->ptr) {
00678               struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
00679 
00680               sqlite_close(db->db);
00681 
00682               zend_hash_destroy(&db->callbacks);
00683 
00684               pefree(db, db->is_persistent);
00685 
00686               rsrc->ptr = NULL;
00687        }
00688 }
00689 
00690 static void real_result_dtor(struct php_sqlite_result *res TSRMLS_DC)
00691 {
00692        int i, j, base;
00693 
00694        if (res->vm) {
00695               sqlite_finalize(res->vm, NULL);
00696        }
00697 
00698        if (res->table) {
00699               if (!res->buffered && res->nrows) {
00700                      res->nrows = 1; /* only one row is stored */
00701               }
00702               for (i = 0; i < res->nrows; i++) {
00703                      base = i * res->ncolumns;
00704                      for (j = 0; j < res->ncolumns; j++) {
00705                             if (res->table[base + j] != NULL) {
00706                                    efree(res->table[base + j]);
00707                             }
00708                      }
00709               }
00710               efree(res->table);
00711        }
00712        if (res->col_names) {
00713               for (j = 0; j < res->ncolumns; j++) {
00714                      efree(res->col_names[j]);
00715               }
00716               efree(res->col_names);
00717        }
00718 
00719        if (res->db) {
00720               zend_list_delete(res->db->rsrc_id);
00721        }
00722        efree(res);
00723 }
00724 
00725 static int _clean_unfinished_results(zend_rsrc_list_entry *le, void *db TSRMLS_DC)
00726 {
00727        if (Z_TYPE_P(le) == le_sqlite_result) {
00728               struct php_sqlite_result *res = (struct php_sqlite_result *)le->ptr;
00729               if (res->db->rsrc_id == ((struct php_sqlite_db*)db)->rsrc_id) {
00730                      return ZEND_HASH_APPLY_REMOVE;
00731               }
00732        }
00733        return ZEND_HASH_APPLY_KEEP;
00734 }
00735 
00736 static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor)
00737 {
00738        struct php_sqlite_result *res = (struct php_sqlite_result *)rsrc->ptr;
00739        real_result_dtor(res TSRMLS_CC);
00740 }
00741 
00742 static int php_sqlite_forget_persistent_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
00743 {
00744        struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
00745 
00746        if (Z_TYPE_P(rsrc) != le_sqlite_pdb) {
00747               return 0;
00748        }
00749 
00750        /* prevent bad mojo if someone tries to use a previously registered function in the next request */
00751        zend_hash_apply(&db->callbacks, (apply_func_t)php_sqlite_callback_invalidator TSRMLS_CC);
00752 
00753        db->rsrc_id = FAILURE;
00754 
00755        /* don't leave pending commits hanging around */
00756        sqlite_exec(db->db, "ROLLBACK", NULL, NULL, NULL);
00757 
00758        return 0;
00759 }
00760 
00761 PHP_RSHUTDOWN_FUNCTION(sqlite)
00762 {
00763        zend_hash_apply(&EG(persistent_list), (apply_func_t)php_sqlite_forget_persistent_id_numbers TSRMLS_CC);
00764        return SUCCESS;
00765 }
00766 
00767 /* {{{ PHP Function interface */
00768 static void php_sqlite_generic_function_callback(sqlite_func *func, int argc, const char **argv)
00769 {
00770        zval *retval = NULL;
00771        zval ***zargs = NULL;
00772        zval funcname;
00773        int i, res;
00774        char *callable = NULL, *errbuf=NULL;
00775        TSRMLS_FETCH();
00776 
00777        /* sanity check the args */
00778        if (argc == 0) {
00779               sqlite_set_result_error(func, "not enough parameters", -1);
00780               return;
00781        }
00782 
00783        ZVAL_STRING(&funcname, (char*)argv[0], 1);
00784 
00785        if (!zend_make_callable(&funcname, &callable TSRMLS_CC)) {
00786               spprintf(&errbuf, 0, "function `%s' is not a function name", callable);
00787               sqlite_set_result_error(func, errbuf, -1);
00788               efree(errbuf);
00789               efree(callable);
00790               zval_dtor(&funcname);
00791               return;
00792        }
00793 
00794        if (argc > 1) {
00795               zargs = (zval ***)safe_emalloc((argc - 1), sizeof(zval **), 0);
00796 
00797               for (i = 0; i < argc-1; i++) {
00798                      zargs[i] = emalloc(sizeof(zval *));
00799                      MAKE_STD_ZVAL(*zargs[i]);
00800                      ZVAL_STRING(*zargs[i], (char*)argv[i+1], 1);
00801               }
00802        }
00803 
00804        res = call_user_function_ex(EG(function_table),
00805                      NULL,
00806                      &funcname,
00807                      &retval,
00808                      argc-1,
00809                      zargs,
00810                      0, NULL TSRMLS_CC);
00811 
00812        zval_dtor(&funcname);
00813 
00814        if (res == SUCCESS) {
00815               if (retval == NULL) {
00816                      sqlite_set_result_string(func, NULL, 0);
00817               } else {
00818                      switch (Z_TYPE_P(retval)) {
00819                             case IS_STRING:
00820                                    sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
00821                                    break;
00822                             case IS_LONG:
00823                             case IS_BOOL:
00824                                    sqlite_set_result_int(func, Z_LVAL_P(retval));
00825                                    break;
00826                             case IS_DOUBLE:
00827                                    sqlite_set_result_double(func, Z_DVAL_P(retval));
00828                                    break;
00829                             case IS_NULL:
00830                             default:
00831                                    sqlite_set_result_string(func, NULL, 0);
00832                      }
00833               }
00834        } else {
00835               char *errbuf;
00836               spprintf(&errbuf, 0, "call_user_function_ex failed for function %s()", callable);
00837               sqlite_set_result_error(func, errbuf, -1);
00838               efree(errbuf);
00839        }
00840 
00841        efree(callable);
00842 
00843        if (retval) {
00844               zval_ptr_dtor(&retval);
00845        }
00846 
00847        if (zargs) {
00848               for (i = 0; i < argc-1; i++) {
00849                      zval_ptr_dtor(zargs[i]);
00850                      efree(zargs[i]);
00851               }
00852               efree(zargs);
00853        }
00854 }
00855 /* }}} */
00856 
00857 /* {{{ callback for sqlite_create_function */
00858 static void php_sqlite_function_callback(sqlite_func *func, int argc, const char **argv)
00859 {
00860        zval *retval = NULL;
00861        zval ***zargs = NULL;
00862        int i, res;
00863        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
00864        TSRMLS_FETCH();
00865 
00866        if (!funcs->is_valid) {
00867               sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
00868               return;
00869        }
00870 
00871        if (argc > 0) {
00872               zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
00873 
00874               for (i = 0; i < argc; i++) {
00875                      zargs[i] = emalloc(sizeof(zval *));
00876                      MAKE_STD_ZVAL(*zargs[i]);
00877 
00878                      if (argv[i] == NULL) {
00879                             ZVAL_NULL(*zargs[i]);
00880                      } else {
00881                             ZVAL_STRING(*zargs[i], (char*)argv[i], 1);
00882                      }
00883               }
00884        }
00885 
00886        res = call_user_function_ex(EG(function_table),
00887                      NULL,
00888                      funcs->step,
00889                      &retval,
00890                      argc,
00891                      zargs,
00892                      0, NULL TSRMLS_CC);
00893 
00894        if (res == SUCCESS) {
00895               if (retval == NULL) {
00896                      sqlite_set_result_string(func, NULL, 0);
00897               } else {
00898                      switch (Z_TYPE_P(retval)) {
00899                             case IS_STRING:
00900                                    /* TODO: for binary results, need to encode the string */
00901                                    sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
00902                                    break;
00903                             case IS_LONG:
00904                             case IS_BOOL:
00905                                    sqlite_set_result_int(func, Z_LVAL_P(retval));
00906                                    break;
00907                             case IS_DOUBLE:
00908                                    sqlite_set_result_double(func, Z_DVAL_P(retval));
00909                                    break;
00910                             case IS_NULL:
00911                             default:
00912                                    sqlite_set_result_string(func, NULL, 0);
00913                      }
00914               }
00915        } else {
00916               sqlite_set_result_error(func, "call_user_function_ex failed", -1);
00917        }
00918 
00919        if (retval) {
00920               zval_ptr_dtor(&retval);
00921        }
00922 
00923        if (zargs) {
00924               for (i = 0; i < argc; i++) {
00925                      zval_ptr_dtor(zargs[i]);
00926                      efree(zargs[i]);
00927               }
00928               efree(zargs);
00929        }
00930 }
00931 /* }}} */
00932 
00933 /* {{{ callback for sqlite_create_aggregate: step function */
00934 static void php_sqlite_agg_step_function_callback(sqlite_func *func, int argc, const char **argv)
00935 {
00936        zval *retval = NULL;
00937        zval ***zargs;
00938        zval **context_p;
00939        int i, res, zargc;
00940        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
00941        TSRMLS_FETCH();
00942 
00943        if (!funcs->is_valid) {
00944               sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
00945               return;
00946        }
00947 
00948        /* sanity check the args */
00949        if (argc < 1) {
00950               return;
00951        }
00952 
00953        zargc = argc + 1;
00954        zargs = (zval ***)safe_emalloc(zargc, sizeof(zval **), 0);
00955 
00956        /* first arg is always the context zval */
00957        context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
00958 
00959        if (*context_p == NULL) {
00960               MAKE_STD_ZVAL(*context_p);
00961               Z_SET_ISREF_PP(context_p);
00962               Z_TYPE_PP(context_p) = IS_NULL;
00963        }
00964 
00965        zargs[0] = context_p;
00966 
00967        /* copy the other args */
00968        for (i = 0; i < argc; i++) {
00969               zargs[i+1] = emalloc(sizeof(zval *));
00970               MAKE_STD_ZVAL(*zargs[i+1]);
00971               if (argv[i] == NULL) {
00972                      ZVAL_NULL(*zargs[i+1]);
00973               } else {
00974                      ZVAL_STRING(*zargs[i+1], (char*)argv[i], 1);
00975               }
00976        }
00977 
00978        res = call_user_function_ex(EG(function_table),
00979                      NULL,
00980                      funcs->step,
00981                      &retval,
00982                      zargc,
00983                      zargs,
00984                      0, NULL TSRMLS_CC);
00985 
00986        if (res != SUCCESS) {
00987               php_error_docref(NULL TSRMLS_CC, E_WARNING, "call_user_function_ex failed");
00988        }
00989 
00990        if (retval) {
00991               zval_ptr_dtor(&retval);
00992        }
00993 
00994        if (zargs) {
00995               for (i = 1; i < zargc; i++) {
00996                      zval_ptr_dtor(zargs[i]);
00997                      efree(zargs[i]);
00998               }
00999               efree(zargs);
01000        }
01001 }
01002 /* }}} */
01003 
01004 /* {{{ callback for sqlite_create_aggregate: finalize function */
01005 static void php_sqlite_agg_fini_function_callback(sqlite_func *func)
01006 {
01007        zval *retval = NULL;
01008        int res;
01009        struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
01010        zval **context_p;
01011        TSRMLS_FETCH();
01012 
01013        if (!funcs->is_valid) {
01014               sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
01015               return;
01016        }
01017 
01018        context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
01019 
01020        res = call_user_function_ex(EG(function_table),
01021                      NULL,
01022                      funcs->fini,
01023                      &retval,
01024                      1,
01025                      &context_p,
01026                      0, NULL TSRMLS_CC);
01027 
01028        if (res == SUCCESS) {
01029               if (retval == NULL) {
01030                      sqlite_set_result_string(func, NULL, 0);
01031               } else {
01032                      switch (Z_TYPE_P(retval)) {
01033                             case IS_STRING:
01034                                    /* TODO: for binary results, need to encode the string */
01035                                    sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
01036                                    break;
01037                             case IS_LONG:
01038                             case IS_BOOL:
01039                                    sqlite_set_result_int(func, Z_LVAL_P(retval));
01040                                    break;
01041                             case IS_DOUBLE:
01042                                    sqlite_set_result_double(func, Z_DVAL_P(retval));
01043                                    break;
01044                             case IS_NULL:
01045                             default:
01046                                    sqlite_set_result_string(func, NULL, 0);
01047                      }
01048               }
01049        } else {
01050               sqlite_set_result_error(func, "call_user_function_ex failed", -1);
01051        }
01052 
01053        if (retval) {
01054               zval_ptr_dtor(&retval);
01055        }
01056 
01057        zval_ptr_dtor(context_p);
01058 }
01059 /* }}} */
01060 
01061 /* {{{ Authorization Callback */
01062 static int php_sqlite_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
01063               const char *arg5, const char *arg6)
01064 {
01065        switch (access_type) {
01066               case SQLITE_COPY:
01067                      if (strncmp(arg4, ":memory:", sizeof(":memory:") - 1)) {
01068                             TSRMLS_FETCH();
01069                             if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
01070                                    return SQLITE_DENY;
01071                             }
01072 
01073                             if (php_check_open_basedir(arg4 TSRMLS_CC)) {
01074                                    return SQLITE_DENY;
01075                             }
01076                      }
01077                      return SQLITE_OK;
01078 #ifdef SQLITE_ATTACH
01079               case SQLITE_ATTACH:
01080                      if (strncmp(arg3, ":memory:", sizeof(":memory:") - 1)) {
01081                             TSRMLS_FETCH();
01082                             if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
01083                                    return SQLITE_DENY;
01084                             }
01085 
01086                             if (php_check_open_basedir(arg3 TSRMLS_CC)) {
01087                                    return SQLITE_DENY;
01088                             }
01089                      }
01090                      return SQLITE_OK;
01091 #endif
01092 
01093               default:
01094                      /* access allowed */
01095                      return SQLITE_OK;
01096        }
01097 }
01098 /* }}} */
01099 
01100 /* {{{ OO init/structure stuff */
01101 #define REGISTER_SQLITE_CLASS(name, c_name, parent) \
01102        { \
01103               zend_class_entry ce; \
01104               INIT_CLASS_ENTRY(ce, "SQLite" # name, sqlite_funcs_ ## c_name); \
01105               ce.create_object = sqlite_object_new_ ## c_name; \
01106               sqlite_ce_ ## c_name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
01107               memcpy(&sqlite_object_handlers_ ## c_name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
01108               sqlite_object_handlers_ ## c_name.clone_obj = NULL; \
01109               sqlite_ce_ ## c_name->ce_flags |= ZEND_ACC_FINAL_CLASS; \
01110        }
01111 
01112 zend_class_entry *sqlite_ce_db, *sqlite_ce_exception;
01113 zend_class_entry *sqlite_ce_query, *sqlite_ce_ub_query;
01114 
01115 static zend_object_handlers sqlite_object_handlers_db;
01116 static zend_object_handlers sqlite_object_handlers_query;
01117 static zend_object_handlers sqlite_object_handlers_ub_query;
01118 static zend_object_handlers sqlite_object_handlers_exception;
01119 
01120 typedef enum {
01121        is_db,
01122        is_result
01123 } sqlite_obj_type;
01124 
01125 typedef struct _sqlite_object {
01126        zend_object       std;
01127        sqlite_obj_type   type;
01128        union {
01129               struct php_sqlite_db     *db;
01130               struct php_sqlite_result *res;
01131               void *ptr;
01132        } u;
01133 } sqlite_object;
01134 
01135 static int sqlite_free_persistent(zend_rsrc_list_entry *le, void *ptr TSRMLS_DC)
01136 {
01137        return le->ptr == ptr ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
01138 }
01139 
01140 static void sqlite_object_free_storage(void *object TSRMLS_DC)
01141 {
01142        sqlite_object *intern = (sqlite_object *)object;
01143 
01144        zend_object_std_dtor(&intern->std TSRMLS_CC);
01145 
01146        if (intern->u.ptr) {
01147               if (intern->type == is_db) {
01148                      if (intern->u.db->rsrc_id) {
01149                             zend_list_delete(intern->u.db->rsrc_id);
01150                             zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) sqlite_free_persistent, &intern->u.ptr TSRMLS_CC);
01151                      }
01152               } else {
01153                      real_result_dtor(intern->u.res TSRMLS_CC);
01154               }
01155        }
01156 
01157        efree(object);
01158 }
01159 
01160 static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
01161 {
01162        sqlite_object *intern;
01163        zval *tmp;
01164 
01165        intern = emalloc(sizeof(sqlite_object));
01166        memset(intern, 0, sizeof(sqlite_object));
01167 
01168        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
01169        zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
01170 
01171        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);
01172        retval->handlers = handlers;
01173 }
01174 
01175 static zend_object_value sqlite_object_new_db(zend_class_entry *class_type TSRMLS_DC)
01176 {
01177        zend_object_value retval;
01178 
01179        sqlite_object_new(class_type, &sqlite_object_handlers_db, &retval TSRMLS_CC);
01180        return retval;
01181 }
01182 
01183 static zend_object_value sqlite_object_new_query(zend_class_entry *class_type TSRMLS_DC)
01184 {
01185        zend_object_value retval;
01186 
01187        sqlite_object_new(class_type, &sqlite_object_handlers_query, &retval TSRMLS_CC);
01188        return retval;
01189 }
01190 
01191 static zend_object_value sqlite_object_new_ub_query(zend_class_entry *class_type TSRMLS_DC)
01192 {
01193        zend_object_value retval;
01194 
01195        sqlite_object_new(class_type, &sqlite_object_handlers_ub_query, &retval TSRMLS_CC);
01196        return retval;
01197 }
01198 
01199 static zend_object_value sqlite_object_new_exception(zend_class_entry *class_type TSRMLS_DC)
01200 {
01201        zend_object_value retval;
01202 
01203        sqlite_object_new(class_type, &sqlite_object_handlers_exception, &retval TSRMLS_CC);
01204        return retval;
01205 }
01206 
01207 #define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
01208        { \
01209               sqlite_object *obj; \
01210               obj = (sqlite_object*)zend_object_store_get_object(_object TSRMLS_CC); \
01211               obj->type = is_ ## _type; \
01212               obj->u._type = _ptr; \
01213        }
01214 
01215 static zend_class_entry *sqlite_get_ce_query(const zval *object TSRMLS_DC)
01216 {
01217        return sqlite_ce_query;
01218 }
01219 
01220 static zend_class_entry *sqlite_get_ce_ub_query(const zval *object TSRMLS_DC)
01221 {
01222        return sqlite_ce_ub_query;
01223 }
01224 
01225 static zval * sqlite_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
01226 {
01227        if (!object) {
01228               ALLOC_ZVAL(object);
01229        }
01230        Z_TYPE_P(object) = IS_OBJECT;
01231        object_init_ex(object, pce);
01232        Z_SET_REFCOUNT_P(object, 1);
01233        Z_SET_ISREF_P(object);
01234        return object;
01235 }
01236 
01237 typedef struct _sqlite_object_iterator {
01238        zend_object_iterator     it;
01239        struct php_sqlite_result *res;
01240        zval *value;
01241 } sqlite_object_iterator;
01242 
01243 void sqlite_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
01244 {
01245        zval *object = (zval*)((sqlite_object_iterator*)iter)->it.data;
01246 
01247        if (((sqlite_object_iterator*)iter)->value) {
01248               zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
01249               ((sqlite_object_iterator*)iter)->value = NULL;
01250        }
01251        zval_ptr_dtor(&object);
01252        efree(iter);
01253 }
01254 
01255 void sqlite_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
01256 {
01257        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
01258 
01259        if (((sqlite_object_iterator*)iter)->value) {
01260               zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
01261               ((sqlite_object_iterator*)iter)->value = NULL;
01262        }
01263        if (res) {
01264               res->curr_row = 0;
01265        }
01266 }
01267 
01268 int sqlite_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
01269 {
01270        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
01271 
01272        if (res && res->curr_row < res->nrows && res->nrows) { /* curr_row may be -1 */
01273               return SUCCESS;
01274        } else {
01275               return FAILURE;
01276        }
01277 }
01278 
01279 void sqlite_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
01280 {
01281        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
01282 
01283        *data = &((sqlite_object_iterator*)iter)->value;
01284        if (res && !**data) {
01285               MAKE_STD_ZVAL(**data);
01286               php_sqlite_fetch_array(res, res->mode, 1, 0, **data TSRMLS_CC);
01287        }
01288 
01289 }
01290 
01291 int sqlite_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
01292 {
01293        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
01294 
01295        *str_key = NULL;
01296        *str_key_len = 0;
01297        *int_key = res ? res->curr_row : 0;
01298        return HASH_KEY_IS_LONG;
01299 }
01300 
01301 void sqlite_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
01302 {
01303        struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
01304 
01305        if (((sqlite_object_iterator*)iter)->value) {
01306               zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
01307               ((sqlite_object_iterator*)iter)->value = NULL;
01308        }
01309        if (res) {
01310               if (!res->buffered && res->vm) {
01311                      php_sqlite_fetch(res TSRMLS_CC);
01312               }
01313               if (res->curr_row >= res->nrows) {
01314                      /* php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available"); */
01315                      return;
01316               }
01317 
01318               res->curr_row++;
01319        }
01320 }
01321 
01322 zend_object_iterator_funcs sqlite_ub_query_iterator_funcs = {
01323        sqlite_iterator_dtor,
01324        sqlite_iterator_valid,
01325        sqlite_iterator_get_current_data,
01326        sqlite_iterator_get_current_key,
01327        sqlite_iterator_move_forward,
01328        NULL
01329 };
01330 
01331 zend_object_iterator_funcs sqlite_query_iterator_funcs = {
01332        sqlite_iterator_dtor,
01333        sqlite_iterator_valid,
01334        sqlite_iterator_get_current_data,
01335        sqlite_iterator_get_current_key,
01336        sqlite_iterator_move_forward,
01337        sqlite_iterator_rewind
01338 };
01339 
01340 zend_object_iterator *sqlite_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
01341 {
01342        sqlite_object_iterator *iterator = emalloc(sizeof(sqlite_object_iterator));
01343 
01344        sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
01345 
01346        if (by_ref) {
01347               zend_error(E_RECOVERABLE_ERROR, "An iterator cannot be used with foreach by reference");
01348        }
01349        Z_ADDREF_P(object);
01350        iterator->it.data = (void*)object;
01351        iterator->it.funcs = ce->iterator_funcs.funcs;
01352        iterator->res = obj->u.res;
01353        iterator->value = NULL;
01354        return (zend_object_iterator*)iterator;
01355 }
01356 /* }}} */
01357 
01358 static PHP_GINIT_FUNCTION(sqlite)
01359 {
01360        sqlite_globals->assoc_case = 0;
01361 }
01362 
01363 PHP_MINIT_FUNCTION(sqlite)
01364 {
01365        REGISTER_SQLITE_CLASS(Database,   db,        NULL);
01366        REGISTER_SQLITE_CLASS(Result,     query,     NULL);
01367        REGISTER_SQLITE_CLASS(Unbuffered, ub_query,  NULL);
01368 #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
01369        REGISTER_SQLITE_CLASS(Exception,  exception, spl_ce_RuntimeException);
01370 #else
01371        REGISTER_SQLITE_CLASS(Exception,  exception, zend_exception_get_default(TSRMLS_C));
01372 #endif
01373 
01374        sqlite_ce_db->ce_flags &= ~ZEND_ACC_FINAL_CLASS;
01375        sqlite_ce_db->constructor->common.fn_flags |= ZEND_ACC_FINAL;
01376 
01377        sqlite_object_handlers_query.get_class_entry = sqlite_get_ce_query;
01378        sqlite_object_handlers_ub_query.get_class_entry = sqlite_get_ce_ub_query;
01379        sqlite_object_handlers_ub_query.count_elements = sqlite_count_elements;
01380 
01381        sqlite_ce_ub_query->get_iterator = sqlite_get_iterator;
01382        sqlite_ce_ub_query->iterator_funcs.funcs = &sqlite_ub_query_iterator_funcs;
01383 
01384 #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
01385        zend_class_implements(sqlite_ce_query TSRMLS_CC, 2, zend_ce_iterator, spl_ce_Countable);
01386 #else
01387        zend_class_implements(sqlite_ce_query TSRMLS_CC, 1, zend_ce_iterator);
01388 #endif
01389        sqlite_ce_query->get_iterator = sqlite_get_iterator;
01390        sqlite_ce_query->iterator_funcs.funcs = &sqlite_query_iterator_funcs;
01391 
01392        REGISTER_INI_ENTRIES();
01393 
01394 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
01395        php_session_register_module(ps_sqlite_ptr);
01396 #endif
01397 
01398        le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number);
01399        le_sqlite_pdb = zend_register_list_destructors_ex(NULL, php_sqlite_db_dtor, "sqlite database (persistent)", module_number);
01400        le_sqlite_result = zend_register_list_destructors_ex(php_sqlite_result_dtor, NULL, "sqlite result", module_number);
01401 
01402        REGISTER_LONG_CONSTANT("SQLITE_BOTH",     PHPSQLITE_BOTH, CONST_CS|CONST_PERSISTENT);
01403        REGISTER_LONG_CONSTANT("SQLITE_NUM",      PHPSQLITE_NUM, CONST_CS|CONST_PERSISTENT);
01404        REGISTER_LONG_CONSTANT("SQLITE_ASSOC",    PHPSQLITE_ASSOC, CONST_CS|CONST_PERSISTENT);
01405 
01406        REGISTER_LONG_CONSTANT("SQLITE_OK",                            SQLITE_OK, CONST_CS|CONST_PERSISTENT);
01407        REGISTER_LONG_CONSTANT("SQLITE_ERROR",                  SQLITE_ERROR, CONST_CS|CONST_PERSISTENT);
01408        REGISTER_LONG_CONSTANT("SQLITE_INTERNAL",        SQLITE_INTERNAL, CONST_CS|CONST_PERSISTENT);
01409        REGISTER_LONG_CONSTANT("SQLITE_PERM",                   SQLITE_PERM, CONST_CS|CONST_PERSISTENT);
01410        REGISTER_LONG_CONSTANT("SQLITE_ABORT",                  SQLITE_ABORT, CONST_CS|CONST_PERSISTENT);
01411        REGISTER_LONG_CONSTANT("SQLITE_BUSY",                   SQLITE_BUSY, CONST_CS|CONST_PERSISTENT);
01412        REGISTER_LONG_CONSTANT("SQLITE_LOCKED",                 SQLITE_LOCKED, CONST_CS|CONST_PERSISTENT);
01413        REGISTER_LONG_CONSTANT("SQLITE_NOMEM",                  SQLITE_NOMEM, CONST_CS|CONST_PERSISTENT);
01414        REGISTER_LONG_CONSTANT("SQLITE_READONLY",        SQLITE_READONLY, CONST_CS|CONST_PERSISTENT);
01415        REGISTER_LONG_CONSTANT("SQLITE_INTERRUPT",              SQLITE_INTERRUPT, CONST_CS|CONST_PERSISTENT);
01416        REGISTER_LONG_CONSTANT("SQLITE_IOERR",                  SQLITE_IOERR, CONST_CS|CONST_PERSISTENT);
01417        REGISTER_LONG_CONSTANT("SQLITE_CORRUPT",         SQLITE_CORRUPT, CONST_CS|CONST_PERSISTENT);
01418        REGISTER_LONG_CONSTANT("SQLITE_NOTFOUND",        SQLITE_NOTFOUND, CONST_CS|CONST_PERSISTENT);
01419        REGISTER_LONG_CONSTANT("SQLITE_FULL",                   SQLITE_FULL, CONST_CS|CONST_PERSISTENT);
01420        REGISTER_LONG_CONSTANT("SQLITE_CANTOPEN",        SQLITE_CANTOPEN, CONST_CS|CONST_PERSISTENT);
01421        REGISTER_LONG_CONSTANT("SQLITE_PROTOCOL",        SQLITE_PROTOCOL, CONST_CS|CONST_PERSISTENT);
01422        REGISTER_LONG_CONSTANT("SQLITE_EMPTY",                  SQLITE_EMPTY, CONST_CS|CONST_PERSISTENT);
01423        REGISTER_LONG_CONSTANT("SQLITE_SCHEMA",                 SQLITE_SCHEMA, CONST_CS|CONST_PERSISTENT);
01424        REGISTER_LONG_CONSTANT("SQLITE_TOOBIG",                 SQLITE_TOOBIG, CONST_CS|CONST_PERSISTENT);
01425        REGISTER_LONG_CONSTANT("SQLITE_CONSTRAINT",             SQLITE_CONSTRAINT, CONST_CS|CONST_PERSISTENT);
01426        REGISTER_LONG_CONSTANT("SQLITE_MISMATCH",        SQLITE_MISMATCH, CONST_CS|CONST_PERSISTENT);
01427        REGISTER_LONG_CONSTANT("SQLITE_MISUSE",                 SQLITE_MISUSE, CONST_CS|CONST_PERSISTENT);
01428        REGISTER_LONG_CONSTANT("SQLITE_NOLFS",                  SQLITE_NOLFS, CONST_CS|CONST_PERSISTENT);
01429        REGISTER_LONG_CONSTANT("SQLITE_AUTH",                   SQLITE_AUTH, CONST_CS|CONST_PERSISTENT);
01430        REGISTER_LONG_CONSTANT("SQLITE_NOTADB",                 SQLITE_NOTADB, CONST_CS|CONST_PERSISTENT);
01431 #ifdef SQLITE_FORMAT
01432        REGISTER_LONG_CONSTANT("SQLITE_FORMAT",                 SQLITE_FORMAT, CONST_CS|CONST_PERSISTENT);
01433 #endif
01434        REGISTER_LONG_CONSTANT("SQLITE_ROW",                    SQLITE_ROW, CONST_CS|CONST_PERSISTENT);
01435        REGISTER_LONG_CONSTANT("SQLITE_DONE",                   SQLITE_DONE, CONST_CS|CONST_PERSISTENT);
01436 
01437 #ifdef PHP_SQLITE2_HAVE_PDO
01438     if (FAILURE == php_pdo_register_driver(&pdo_sqlite2_driver)) {
01439        return FAILURE;
01440     }
01441 #endif
01442 
01443        return SUCCESS;
01444 }
01445 
01446 PHP_MSHUTDOWN_FUNCTION(sqlite)
01447 {
01448        UNREGISTER_INI_ENTRIES();
01449 
01450 #ifdef PHP_SQLITE2_HAVE_PDO
01451     php_pdo_unregister_driver(&pdo_sqlite2_driver);
01452 #endif
01453 
01454        return SUCCESS;
01455 }
01456 
01457 PHP_MINFO_FUNCTION(sqlite)
01458 {
01459        php_info_print_table_start();
01460        php_info_print_table_header(2, "SQLite support", "enabled");
01461        php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c 321634 2012-01-01 13:15:04Z felipe $");
01462        php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
01463        php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
01464        php_info_print_table_end();
01465 
01466        DISPLAY_INI_ENTRIES();
01467 }
01468 
01469 static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg, zval *object TSRMLS_DC)
01470 {
01471        char *errtext = NULL;
01472        sqlite *sdb = NULL;
01473        struct php_sqlite_db *db = NULL;
01474 
01475        sdb = sqlite_open(filename, mode, &errtext);
01476 
01477        if (sdb == NULL) {
01478 
01479               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
01480 
01481               if (errmsg) {
01482                      ZVAL_STRING(errmsg, errtext, 1);
01483               }
01484 
01485               sqlite_freemem(errtext);
01486 
01487               /* if object is not an object then we're called from the factory() function */
01488               if (object && Z_TYPE_P(object) != IS_OBJECT) {
01489                      RETVAL_NULL();
01490               } else {
01491                      RETVAL_FALSE;
01492               }
01493               return NULL;
01494        }
01495 
01496        db = (struct php_sqlite_db *)pemalloc(sizeof(struct php_sqlite_db), persistent_id ? 1 : 0);
01497        db->is_persistent = persistent_id ? 1 : 0;
01498        db->last_err_code = SQLITE_OK;
01499        db->db = sdb;
01500 
01501        zend_hash_init(&db->callbacks, 0, NULL, php_sqlite_callback_dtor, db->is_persistent);
01502 
01503        /* register the PHP functions */
01504        sqlite_create_function(sdb, "php", -1, php_sqlite_generic_function_callback, 0);
01505 
01506        /* set default busy handler; keep retrying up until 1 minute has passed,
01507         * then fail with a busy status code */
01508        sqlite_busy_timeout(sdb, 60000);
01509 
01510        /* authorizer hook so we can enforce safe mode
01511         * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
01512         * and IS backwards binary compatible with earlier versions */
01513        if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
01514               sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
01515        }
01516 
01517        db->rsrc_id = ZEND_REGISTER_RESOURCE(object ? NULL : return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
01518        if (object) {
01519               /* if object is not an object then we're called from the factory() function */
01520               if (Z_TYPE_P(object) != IS_OBJECT) {
01521                      sqlite_instanciate(sqlite_ce_db, object TSRMLS_CC);
01522               }
01523               /* and now register the object */
01524               SQLITE_REGISTER_OBJECT(db, object, db)
01525        }
01526 
01527        if (persistent_id) {
01528               zend_rsrc_list_entry le;
01529 
01530               Z_TYPE(le) = le_sqlite_pdb;
01531               le.ptr = db;
01532 
01533               if (FAILURE == zend_hash_update(&EG(persistent_list), persistent_id,
01534                                    strlen(persistent_id)+1,
01535                                    (void *)&le, sizeof(le), NULL)) {
01536                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource");
01537               }
01538        }
01539 
01540        return db;
01541 }
01542 
01543 /* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
01544    Opens a persistent handle to a SQLite database. Will create the database if it does not exist. */
01545 PHP_FUNCTION(sqlite_popen)
01546 {
01547        long mode = 0666;
01548        char *filename, *fullpath, *hashkey;
01549        int filename_len, hashkeylen;
01550        zval *errmsg = NULL;
01551        struct php_sqlite_db *db = NULL;
01552        zend_rsrc_list_entry *le;
01553 
01554        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
01555                             &filename, &filename_len, &mode, &errmsg)) {
01556               return;
01557        }
01558        if (errmsg) {
01559               zval_dtor(errmsg);
01560               ZVAL_NULL(errmsg);
01561        }
01562 
01563        if (strlen(filename) != filename_len) {
01564               RETURN_FALSE;
01565        }
01566        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
01567               /* resolve the fully-qualified path name to use as the hash key */
01568               if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
01569                      RETURN_FALSE;
01570               }
01571 
01572               if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || 
01573                             php_check_open_basedir(fullpath TSRMLS_CC)) {
01574                      efree(fullpath);
01575                      RETURN_FALSE;
01576               }
01577        } else {
01578               fullpath = estrndup(filename, filename_len);
01579        }
01580 
01581        hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%ld", fullpath, mode);
01582 
01583        /* do we have an existing persistent connection ? */
01584        if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkeylen+1, (void*)&le)) {
01585               if (Z_TYPE_P(le) == le_sqlite_pdb) {
01586                      db = (struct php_sqlite_db*)le->ptr;
01587 
01588                      if (db->rsrc_id == FAILURE) {
01589                             /* give it a valid resource id for this request */
01590                             db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
01591                      } else {
01592                             int type;
01593                             /* sanity check to ensure that the resource is still a valid regular resource
01594                              * number */
01595                             if (zend_list_find(db->rsrc_id, &type) == db) {
01596                                    /* already accessed this request; map it */
01597                                    zend_list_addref(db->rsrc_id);
01598                                    ZVAL_RESOURCE(return_value, db->rsrc_id);
01599                             } else {
01600                                    db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
01601                             }
01602                      }
01603 
01604                      /* all set */
01605                      goto done;
01606               }
01607 
01608               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Some other type of persistent resource is using this hash key!?");
01609               RETVAL_FALSE;
01610               goto done;
01611        }
01612 
01613        /* now we need to open the database */
01614        php_sqlite_open(fullpath, (int)mode, hashkey, return_value, errmsg, NULL TSRMLS_CC);
01615 done:
01616        efree(fullpath);
01617        efree(hashkey);
01618 }
01619 /* }}} */
01620 
01621 /* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
01622    Opens a SQLite database. Will create the database if it does not exist. */
01623 PHP_FUNCTION(sqlite_open)
01624 {
01625        long mode = 0666;
01626        char *filename, *fullpath = NULL;
01627        int filename_len;
01628        zval *errmsg = NULL;
01629        zval *object = getThis();
01630        zend_error_handling error_handling;
01631 
01632        zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
01633        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
01634                             &filename, &filename_len, &mode, &errmsg)) {
01635               zend_restore_error_handling(&error_handling TSRMLS_CC);
01636               return;
01637        }
01638        if (errmsg) {
01639               zval_dtor(errmsg);
01640               ZVAL_NULL(errmsg);
01641        }
01642 
01643        if (strlen(filename) != filename_len) {
01644               zend_restore_error_handling(&error_handling TSRMLS_CC);
01645               RETURN_FALSE;
01646        }
01647 
01648        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
01649               /* resolve the fully-qualified path name to use as the hash key */
01650               if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
01651                      zend_restore_error_handling(&error_handling TSRMLS_CC);
01652                      if (object) {
01653                             RETURN_NULL();
01654                      } else {
01655                             RETURN_FALSE;
01656                      }
01657               }
01658 
01659               if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
01660                             php_check_open_basedir(fullpath TSRMLS_CC)) {
01661                      efree(fullpath);
01662                      zend_restore_error_handling(&error_handling TSRMLS_CC);
01663                      if (object) {
01664                             RETURN_NULL();
01665                      } else {
01666                             RETURN_FALSE;
01667                      }
01668               }
01669        }
01670 
01671        php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, object TSRMLS_CC);
01672 
01673        if (fullpath) {
01674               efree(fullpath);
01675        }
01676        zend_restore_error_handling(&error_handling TSRMLS_CC);
01677 }
01678 /* }}} */
01679 
01680 /* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
01681    Opens a SQLite database and creates an object for it. Will create the database if it does not exist. */
01682 PHP_FUNCTION(sqlite_factory)
01683 {
01684        long mode = 0666;
01685        char *filename, *fullpath = NULL;
01686        int filename_len;
01687        zval *errmsg = NULL;
01688        zend_error_handling error_handling;
01689 
01690        zend_replace_error_handling(EH_THROW, sqlite_ce_exception, &error_handling TSRMLS_CC);
01691        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
01692                             &filename, &filename_len, &mode, &errmsg)) {
01693               zend_restore_error_handling(&error_handling TSRMLS_CC);
01694               RETURN_NULL();
01695        }
01696        if (errmsg) {
01697               zval_dtor(errmsg);
01698               ZVAL_NULL(errmsg);
01699        }
01700 
01701        if (strlen(filename) != filename_len) {
01702               zend_restore_error_handling(&error_handling TSRMLS_CC);
01703               RETURN_FALSE;
01704        }
01705 
01706        if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
01707               /* resolve the fully-qualified path name to use as the hash key */
01708               if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
01709                      zend_restore_error_handling(&error_handling TSRMLS_CC);
01710                      RETURN_NULL();
01711               }
01712 
01713               if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
01714                             php_check_open_basedir(fullpath TSRMLS_CC)) {
01715                      efree(fullpath);
01716                      zend_restore_error_handling(&error_handling TSRMLS_CC);
01717                      RETURN_NULL();
01718               }
01719        }
01720 
01721        php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, return_value TSRMLS_CC);
01722        if (fullpath) {
01723               efree(fullpath);
01724        }
01725        zend_restore_error_handling(&error_handling TSRMLS_CC);
01726 }
01727 /* }}} */
01728 
01729 /* {{{ proto void sqlite_busy_timeout(resource db, int ms)
01730    Set busy timeout duration. If ms <= 0, all busy handlers are disabled. */
01731 PHP_FUNCTION(sqlite_busy_timeout)
01732 {
01733        zval *zdb;
01734        struct php_sqlite_db *db;
01735        long ms;
01736        zval *object = getThis();
01737 
01738        if (object) {
01739               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) {
01740                      return;
01741               }
01742               DB_FROM_OBJECT(db, object);
01743        } else {
01744               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
01745                      return;
01746               }
01747               DB_FROM_ZVAL(db, &zdb);
01748        }
01749 
01750        sqlite_busy_timeout(db->db, ms);
01751 }
01752 /* }}} */
01753 
01754 /* {{{ proto void sqlite_close(resource db)
01755    Closes an open sqlite database. */
01756 PHP_FUNCTION(sqlite_close)
01757 {
01758        zval *zdb;
01759        struct php_sqlite_db *db;
01760        zval *object = getThis();
01761 
01762        if (object) {
01763               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Ignored, you must destruct the object instead");
01764        } else {
01765               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
01766                      return;
01767               }
01768               DB_FROM_ZVAL(db, &zdb);
01769        }
01770 
01771        zend_hash_apply_with_argument(&EG(regular_list),
01772               (apply_func_arg_t) _clean_unfinished_results,
01773               db TSRMLS_CC);
01774 
01775        zend_list_delete(Z_RESVAL_P(zdb));
01776 }
01777 /* }}} */
01778 
01779 /* {{{ php_sqlite_fetch */
01780 static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
01781 {
01782        const char **rowdata, **colnames;
01783        int ret, i, base;
01784        char *errtext = NULL;
01785 
01786 next_row:
01787        ret = sqlite_step(rres->vm, &rres->ncolumns, &rowdata, &colnames);
01788        if (!rres->nrows) {
01789               /* first row - lets copy the column names */
01790               rres->col_names = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
01791               for (i = 0; i < rres->ncolumns; i++) {
01792                      rres->col_names[i] = estrdup((char*)colnames[i]);
01793 
01794                      if (SQLITE_G(assoc_case) == 1) {
01795                             php_sqlite_strtoupper(rres->col_names[i]);
01796                      } else if (SQLITE_G(assoc_case) == 2) {
01797                             php_sqlite_strtolower(rres->col_names[i]);
01798                      }
01799               }
01800               if (!rres->buffered) {
01801                      /* non buffered mode - also fetch memory for on single row */
01802                      rres->table = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
01803               }
01804        }
01805 
01806        switch (ret) {
01807               case SQLITE_ROW:
01808                      if (rres->buffered) {
01809                             /* add the row to our collection */
01810                             if (rres->nrows + 1 >= rres->alloc_rows) {
01811                                    rres->alloc_rows = rres->alloc_rows ? rres->alloc_rows * 2 : 16;
01812                                    rres->table = safe_erealloc(rres->table, rres->alloc_rows, rres->ncolumns*sizeof(char *), 0);
01813                             }
01814                             base = rres->nrows * rres->ncolumns;
01815                             for (i = 0; i < rres->ncolumns; i++) {
01816                                    if (rowdata[i]) {
01817                                           rres->table[base + i] = estrdup(rowdata[i]);
01818                                    } else {
01819                                           rres->table[base + i] = NULL;
01820                                    }
01821                             }
01822                             rres->nrows++;
01823                             goto next_row;
01824                      } else {
01825                             /* non buffered: only fetch one row but first free data if not first row */
01826                             if (rres->nrows++) {
01827                                    for (i = 0; i < rres->ncolumns; i++) {
01828                                           if (rres->table[i]) {
01829                                                  efree(rres->table[i]);
01830                                           }
01831                                    }
01832                             }
01833                             for (i = 0; i < rres->ncolumns; i++) {
01834                                    if (rowdata[i]) {
01835                                           rres->table[i] = estrdup(rowdata[i]);
01836                                    } else {
01837                                           rres->table[i] = NULL;
01838                                    }
01839                             }
01840                      }
01841                      ret = SQLITE_OK;
01842                      break;
01843 
01844               case SQLITE_BUSY:
01845               case SQLITE_ERROR:
01846               case SQLITE_MISUSE:
01847               case SQLITE_DONE:
01848               default:
01849                      if (rres->vm) {
01850                             ret = sqlite_finalize(rres->vm, &errtext);
01851                      }
01852                      rres->vm = NULL;
01853                      if (ret != SQLITE_OK) {
01854                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
01855                             sqlite_freemem(errtext);
01856                      }
01857                      break;
01858        }
01859        rres->db->last_err_code = ret;
01860 
01861        return ret;
01862 }
01863 /* }}} */
01864 
01865 /* {{{ sqlite_query */
01866 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)
01867 {
01868        struct php_sqlite_result res, *rres;
01869        int ret;
01870        char *errtext = NULL;
01871        const char *tail;
01872 
01873        memset(&res, 0, sizeof(res));
01874        res.buffered = buffered;
01875        res.mode = mode;
01876 
01877        ret = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
01878        db->last_err_code = ret;
01879 
01880        if (ret != SQLITE_OK) {
01881               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
01882               if (errmsg) {
01883                      ZVAL_STRING(errmsg, errtext, 1);
01884               }
01885               sqlite_freemem(errtext);
01886               goto terminate;
01887        } else if (!res.vm) { /* empty query */
01888 terminate:
01889               if (return_value) {
01890                      RETURN_FALSE;
01891               } else {
01892                      return;
01893               }
01894        }
01895 
01896        if (!prres) {
01897               rres = NULL;
01898               prres = &rres;
01899        }
01900        if (!*prres) {
01901               *prres = (struct php_sqlite_result*)emalloc(sizeof(**prres));
01902        }
01903        memcpy(*prres, &res, sizeof(**prres));
01904        (*prres)->db = db;
01905        zend_list_addref(db->rsrc_id);
01906 
01907 
01908        /* now the result set is ready for stepping: get first row */
01909        if (php_sqlite_fetch((*prres) TSRMLS_CC) != SQLITE_OK) {
01910               real_result_dtor((*prres) TSRMLS_CC);
01911               *prres = NULL;
01912               if (return_value) {
01913                      RETURN_FALSE;
01914               } else {
01915                      return;
01916               }
01917        }
01918 
01919        (*prres)->curr_row = 0;
01920 
01921        if (object) {
01922               sqlite_object *obj;
01923               if (buffered) {
01924                      sqlite_instanciate(sqlite_ce_query, return_value TSRMLS_CC);
01925               } else {
01926                      sqlite_instanciate(sqlite_ce_ub_query, return_value TSRMLS_CC);
01927               }
01928               obj = (sqlite_object *) zend_object_store_get_object(return_value TSRMLS_CC);
01929               obj->type = is_result;
01930               obj->u.res = (*prres);
01931        } else if (return_value) {
01932               ZEND_REGISTER_RESOURCE(object ? NULL : return_value, (*prres), le_sqlite_result);
01933        }
01934 }
01935 /* }}} */
01936 
01937 /* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &error_message]])
01938    Executes a query that does not prefetch and buffer all data. */
01939 PHP_FUNCTION(sqlite_unbuffered_query)
01940 {
01941        zval *zdb;
01942        struct php_sqlite_db *db;
01943        char *sql;
01944        int sql_len;
01945        long mode = PHPSQLITE_BOTH;
01946        char *errtext = NULL;
01947        zval *errmsg = NULL;
01948        zval *object = getThis();
01949 
01950        if (object) {
01951               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
01952                      return;
01953               }
01954               DB_FROM_OBJECT(db, object);
01955        } else {
01956               if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
01957                             ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
01958                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
01959                      return;
01960               }
01961               DB_FROM_ZVAL(db, &zdb);
01962        }
01963 
01964        if (errmsg) {
01965               zval_dtor(errmsg);
01966               ZVAL_NULL(errmsg);
01967        }
01968 
01969        PHP_SQLITE_EMPTY_QUERY;
01970 
01971        /* avoid doing work if we can */
01972        if (!return_value_used) {
01973               db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
01974 
01975               if (db->last_err_code != SQLITE_OK) {
01976                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
01977                      if (errmsg) {
01978                             ZVAL_STRING(errmsg, errtext, 1);
01979                      }
01980                      sqlite_freemem(errtext);
01981               }
01982               return;
01983        }
01984 
01985        sqlite_query(object, db, sql, sql_len, (int)mode, 0, return_value, NULL, errmsg TSRMLS_CC);
01986 }
01987 /* }}} */
01988 
01989 /* {{{ proto resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])
01990    Return an array of column types from a particular table. */
01991 PHP_FUNCTION(sqlite_fetch_column_types)
01992 {
01993        zval *zdb;
01994        struct php_sqlite_db *db;
01995        char *tbl, *sql;
01996        int tbl_len;
01997        char *errtext = NULL;
01998        zval *object = getThis();
01999        struct php_sqlite_result res;
02000        const char **rowdata, **colnames, *tail;
02001        int i, ncols;
02002        long result_type = PHPSQLITE_ASSOC;
02003 
02004        if (object) {
02005               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &tbl, &tbl_len, &result_type)) {
02006                      return;
02007               }
02008               DB_FROM_OBJECT(db, object);
02009        } else {
02010               if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
02011                             ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &tbl, &tbl_len, &zdb, &result_type) &&
02012                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &tbl, &tbl_len, &result_type)) {
02013                      return;
02014               }
02015               DB_FROM_ZVAL(db, &zdb);
02016        }
02017 
02018        if (!(sql = sqlite_mprintf("SELECT * FROM '%q' LIMIT 1", tbl))) {
02019               RETURN_FALSE;
02020        }
02021 
02022        sqlite_exec(db->db, "PRAGMA show_datatypes = ON", NULL, NULL, NULL);
02023 
02024        db->last_err_code = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
02025 
02026        sqlite_freemem(sql);
02027 
02028        if (db->last_err_code != SQLITE_OK) {
02029               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
02030               sqlite_freemem(errtext);
02031               RETVAL_FALSE;
02032               goto done;
02033        }
02034 
02035        sqlite_step(res.vm, &ncols, &rowdata, &colnames);
02036 
02037        array_init(return_value);
02038 
02039        for (i = 0; i < ncols; i++) {
02040               if (result_type == PHPSQLITE_ASSOC) {
02041                      char *colname = estrdup((char *)colnames[i]);
02042 
02043                      if (SQLITE_G(assoc_case) == 1) {
02044                             php_sqlite_strtoupper(colname);
02045                      } else if (SQLITE_G(assoc_case) == 2) {
02046                             php_sqlite_strtolower(colname);
02047                      }
02048 
02049                      add_assoc_string(return_value, colname, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
02050                      efree(colname);
02051               }
02052               if (result_type == PHPSQLITE_NUM) {
02053                      add_index_string(return_value, i, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
02054               }
02055        }
02056        if (res.vm) {
02057               sqlite_finalize(res.vm, NULL);
02058        }
02059 done:
02060        sqlite_exec(db->db, "PRAGMA show_datatypes = OFF", NULL, NULL, NULL);
02061 }
02062 /* }}} */
02063 
02064 /* {{{ proto resource sqlite_query(string query, resource db [, int result_type [, string &error_message]])
02065    Executes a query against a given database and returns a result handle. */
02066 PHP_FUNCTION(sqlite_query)
02067 {
02068        zval *zdb;
02069        struct php_sqlite_db *db;
02070        char *sql;
02071        int sql_len;
02072        long mode = PHPSQLITE_BOTH;
02073        char *errtext = NULL;
02074        zval *errmsg = NULL;
02075        zval *object = getThis();
02076 
02077        if (object) {
02078               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
02079                      return;
02080               }
02081               DB_FROM_OBJECT(db, object);
02082        } else {
02083               if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
02084                             ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
02085                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
02086                      return;
02087               }
02088               DB_FROM_ZVAL(db, &zdb);
02089        }
02090 
02091        if (errmsg) {
02092               zval_dtor(errmsg);
02093               ZVAL_NULL(errmsg);
02094        }
02095 
02096        PHP_SQLITE_EMPTY_QUERY;
02097 
02098        /* avoid doing work if we can */
02099        if (!return_value_used) {
02100               db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
02101 
02102               if (db->last_err_code != SQLITE_OK) {
02103                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
02104                      if (errmsg) {
02105                             ZVAL_STRING(errmsg, errtext, 1);
02106                      }
02107                      sqlite_freemem(errtext);
02108               }
02109               return;
02110        }
02111 
02112        sqlite_query(object, db, sql, sql_len, (int)mode, 1, return_value, NULL, errmsg TSRMLS_CC);
02113 }
02114 /* }}} */
02115 
02116 /* {{{ proto boolean sqlite_exec(string query, resource db[, string &error_message])
02117    Executes a result-less query against a given database */
02118 PHP_FUNCTION(sqlite_exec)
02119 {
02120        zval *zdb;
02121        struct php_sqlite_db *db;
02122        char *sql;
02123        int sql_len;
02124        char *errtext = NULL;
02125        zval *errmsg = NULL;
02126        zval *object = getThis();
02127 
02128        if (object) {
02129               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &sql, &sql_len, &errmsg)) {
02130                      return;
02131               }
02132               DB_FROM_OBJECT(db, object);
02133        } else {
02134               if(FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
02135                      ZEND_NUM_ARGS() TSRMLS_CC, "sr", &sql, &sql_len, &zdb) &&
02136                  FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &zdb, &sql, &sql_len, &errmsg)) {
02137                      return;
02138               }
02139               DB_FROM_ZVAL(db, &zdb);
02140        }
02141 
02142        if (errmsg) {
02143               zval_dtor(errmsg);
02144               ZVAL_NULL(errmsg);
02145        }
02146 
02147        PHP_SQLITE_EMPTY_QUERY;
02148 
02149        db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
02150 
02151        if (db->last_err_code != SQLITE_OK) {
02152               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
02153               if (errmsg) {
02154                      ZVAL_STRING(errmsg, errtext, 1);
02155               }
02156               sqlite_freemem(errtext);
02157               RETURN_FALSE;
02158        }
02159 
02160        RETURN_TRUE;
02161 }
02162 /* }}} */
02163 
02164 /* {{{ php_sqlite_fetch_array */
02165 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)
02166 {
02167        int j, n = res->ncolumns, buffered = res->buffered;
02168        const char **rowdata, **colnames;
02169 
02170        /* check range of the row */
02171        if (res->curr_row >= res->nrows) {
02172               /* no more */
02173               RETURN_FALSE;
02174        }
02175        colnames = (const char**)res->col_names;
02176        if (res->buffered) {
02177               rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
02178        } else {
02179               rowdata = (const char**)res->table;
02180        }
02181 
02182        /* now populate the result */
02183        array_init(return_value);
02184 
02185        for (j = 0; j < n; j++) {
02186               zval *decoded;
02187               MAKE_STD_ZVAL(decoded);
02188 
02189               if (rowdata[j] == NULL) {
02190                      ZVAL_NULL(decoded);
02191               } else if (decode_binary && rowdata[j][0] == '\x01') {
02192                      Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
02193                      Z_STRLEN_P(decoded) = php_sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
02194                      Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
02195                      Z_TYPE_P(decoded) = IS_STRING;
02196                      if (!buffered) {
02197                             efree((char*)rowdata[j]);
02198                             rowdata[j] = NULL;
02199                      }
02200               } else {
02201                      ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
02202                      if (!buffered) {
02203                             rowdata[j] = NULL;
02204                      }
02205               }
02206 
02207               if (mode & PHPSQLITE_NUM) {
02208                      if (mode & PHPSQLITE_ASSOC) {
02209                             add_index_zval(return_value, j, decoded);
02210                             Z_ADDREF_P(decoded);
02211                             add_assoc_zval(return_value, (char*)colnames[j], decoded);
02212                      } else {
02213                             add_next_index_zval(return_value, decoded);
02214                      }
02215               } else {
02216                      add_assoc_zval(return_value, (char*)colnames[j], decoded);
02217               }
02218        }
02219 
02220        if (move_next) {
02221               if (!res->buffered) {
02222                      /* non buffered: fetch next row */
02223                      php_sqlite_fetch(res TSRMLS_CC);
02224               }
02225               /* advance the row pointer */
02226               res->curr_row++;
02227        }
02228 }
02229 /* }}} */
02230 
02231 /* {{{ php_sqlite_fetch_column */
02232 static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which, zend_bool decode_binary, zval *return_value TSRMLS_DC)
02233 {
02234        int j;
02235        const char **rowdata, **colnames;
02236 
02237        /* check range of the row */
02238        if (res->curr_row >= res->nrows) {
02239               /* no more */
02240               RETURN_FALSE;
02241        }
02242        colnames = (const char**)res->col_names;
02243 
02244        if (Z_TYPE_P(which) == IS_LONG) {
02245               j = Z_LVAL_P(which);
02246        } else {
02247               convert_to_string_ex(&which);
02248               for (j = 0; j < res->ncolumns; j++) {
02249                      if (!strcasecmp((char*)colnames[j], Z_STRVAL_P(which))) {
02250                             break;
02251                      }
02252               }
02253        }
02254        if (j < 0 || j >= res->ncolumns) {
02255               php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such column %d", j);
02256               RETURN_FALSE;
02257        }
02258 
02259        if (res->buffered) {
02260               rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
02261        } else {
02262               rowdata = (const char**)res->table;
02263        }
02264 
02265        if (rowdata[j] == NULL) {
02266               RETURN_NULL();
02267        } else if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
02268               int l = strlen(rowdata[j]);
02269               char *decoded = emalloc(l);
02270               l = php_sqlite_decode_binary(rowdata[j]+1, decoded);
02271               decoded[l] = '\0';
02272               RETVAL_STRINGL(decoded, l, 0);
02273               if (!res->buffered) {
02274                      efree((char*)rowdata[j]);
02275                      rowdata[j] = NULL;
02276               }
02277        } else {
02278               RETVAL_STRING((char*)rowdata[j], res->buffered);
02279               if (!res->buffered) {
02280                      rowdata[j] = NULL;
02281               }
02282        }
02283 }
02284 /* }}} */
02285 
02286 /* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
02287    Fetches all rows from a result set as an array of arrays. */
02288 PHP_FUNCTION(sqlite_fetch_all)
02289 {
02290        zval *zres, *ent;
02291        long mode = PHPSQLITE_BOTH;
02292        zend_bool decode_binary = 1;
02293        struct php_sqlite_result *res;
02294        zval *object = getThis();
02295 
02296        if (object) {
02297               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
02298                      return;
02299               }
02300               RES_FROM_OBJECT(res, object);
02301               if (!ZEND_NUM_ARGS()) {
02302                      mode = res->mode;
02303               }
02304        } else {
02305               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
02306                      return;
02307               }
02308               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02309               if (ZEND_NUM_ARGS() < 2) {
02310                      mode = res->mode;
02311               }
02312        }
02313 
02314        if (res->curr_row >= res->nrows && res->nrows) {
02315               if (!res->buffered) {
02316                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "One or more rowsets were already returned; returning NULL this time");
02317               } else {
02318                      res->curr_row = 0;
02319               }
02320        }
02321 
02322        array_init(return_value);
02323 
02324        while (res->curr_row < res->nrows) {
02325               MAKE_STD_ZVAL(ent);
02326               php_sqlite_fetch_array(res, mode, decode_binary, 1, ent TSRMLS_CC);
02327               add_next_index_zval(return_value, ent);
02328        }
02329 }
02330 /* }}} */
02331 
02332 /* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
02333    Fetches the next row from a result set as an array. */
02334 PHP_FUNCTION(sqlite_fetch_array)
02335 {
02336        zval *zres;
02337        long mode = PHPSQLITE_BOTH;
02338        zend_bool decode_binary = 1;
02339        struct php_sqlite_result *res;
02340        zval *object = getThis();
02341 
02342        if (object) {
02343               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
02344                      return;
02345               }
02346               RES_FROM_OBJECT(res, object);
02347               if (!ZEND_NUM_ARGS()) {
02348                      mode = res->mode;
02349               }
02350        } else {
02351               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
02352                      return;
02353               }
02354               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02355               if (ZEND_NUM_ARGS() < 2) {
02356                      mode = res->mode;
02357               }
02358        }
02359 
02360        php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
02361 }
02362 /* }}} */
02363 
02364 /* {{{ proto object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])
02365    Fetches the next row from a result set as an object. */
02366    /* note that you can do array(&$val) for param ctor_params */
02367 PHP_FUNCTION(sqlite_fetch_object)
02368 {
02369        zval *zres;
02370        zend_bool decode_binary = 1;
02371        struct php_sqlite_result *res;
02372        zval *object = getThis();
02373        char *class_name = NULL;
02374        int class_name_len;
02375        zend_class_entry *ce;
02376        zval dataset;
02377        zend_fcall_info fci;
02378        zend_fcall_info_cache fcc;
02379        zval *retval_ptr;
02380        zval *ctor_params = NULL;
02381        zend_error_handling error_handling;
02382 
02383        zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
02384        if (object) {
02385               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szb", &class_name, &class_name_len, &ctor_params, &decode_binary)) {
02386                      zend_restore_error_handling(&error_handling TSRMLS_CC);
02387                      return;
02388               }
02389               RES_FROM_OBJECT_RESTORE_ERH(res, object, &error_handling);
02390               if (!class_name) {
02391                      ce = zend_standard_class_def;
02392               } else {
02393                      ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
02394               }
02395        } else {
02396               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|szb", &zres, &class_name, &class_name_len, &ctor_params, &decode_binary)) {
02397                      zend_restore_error_handling(&error_handling TSRMLS_CC);
02398                      return;
02399               }
02400               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02401               if (!class_name) {
02402                      ce = zend_standard_class_def;
02403               } else {
02404                      ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
02405               }
02406        }
02407 
02408        if (!ce) {
02409               zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not find class '%s'", class_name);
02410               zend_restore_error_handling(&error_handling TSRMLS_CC);
02411               return;
02412        }
02413 
02414        if (res->curr_row < res->nrows) {
02415               php_sqlite_fetch_array(res, PHPSQLITE_ASSOC, decode_binary, 1, &dataset TSRMLS_CC);
02416        } else {
02417               zend_restore_error_handling(&error_handling TSRMLS_CC);
02418               RETURN_FALSE;
02419        }
02420 
02421        object_and_properties_init(return_value, ce, NULL);
02422        zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
02423 
02424        zend_restore_error_handling(&error_handling TSRMLS_CC);
02425 
02426        if (ce->constructor) {
02427               fci.size = sizeof(fci);
02428               fci.function_table = &ce->function_table;
02429               fci.function_name = NULL;
02430               fci.symbol_table = NULL;
02431               fci.object_ptr = return_value;
02432               fci.retval_ptr_ptr = &retval_ptr;
02433               if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
02434                      if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
02435                             HashTable *ht = Z_ARRVAL_P(ctor_params);
02436                             Bucket *p;
02437 
02438                             fci.param_count = 0;
02439                             fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
02440                             p = ht->pListHead;
02441                             while (p != NULL) {
02442                                    fci.params[fci.param_count++] = (zval**)p->pData;
02443                                    p = p->pListNext;
02444                             }
02445                      } else {
02446                             /* Two problems why we throw exceptions here: PHP is typeless
02447                              * and hence passing one argument that's not an array could be
02448                              * by mistake and the other way round is possible, too. The
02449                              * single value is an array. Also we'd have to make that one
02450                              * argument passed by reference.
02451                              */
02452                             zend_throw_exception(sqlite_ce_exception, "Parameter ctor_params must be an array", 0 TSRMLS_CC);
02453                             return;
02454                      }
02455               } else {
02456                      fci.param_count = 0;
02457                      fci.params = NULL;
02458               }
02459               fci.no_separation = 1;
02460 
02461               fcc.initialized = 1;
02462               fcc.function_handler = ce->constructor;
02463               fcc.calling_scope = EG(scope);
02464               fcc.called_scope = Z_OBJCE_P(return_value);
02465               fcc.object_ptr = return_value;
02466 
02467               if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
02468                      zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not execute %s::%s()", class_name, ce->constructor->common.function_name);
02469               } else {
02470                      if (retval_ptr) {
02471                             zval_ptr_dtor(&retval_ptr);
02472                      }
02473               }
02474               if (fci.params) {
02475                      efree(fci.params);
02476               }
02477        } else if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
02478               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);
02479        }
02480 }
02481 /* }}} */
02482 
02483 /* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
02484    Executes a query against a given database and returns an array of arrays. */
02485 PHP_FUNCTION(sqlite_array_query)
02486 {
02487        zval *zdb, *ent;
02488        struct php_sqlite_db *db;
02489        struct php_sqlite_result *rres;
02490        char *sql;
02491        int sql_len;
02492        long mode = PHPSQLITE_BOTH;
02493        char *errtext = NULL;
02494        zend_bool decode_binary = 1;
02495        zval *object = getThis();
02496 
02497        if (object) {
02498               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &sql, &sql_len, &mode, &decode_binary)) {
02499                      return;
02500               }
02501               DB_FROM_OBJECT(db, object);
02502        } else {
02503               if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
02504                             ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
02505                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
02506                      return;
02507               }
02508               DB_FROM_ZVAL(db, &zdb);
02509        }
02510 
02511        PHP_SQLITE_EMPTY_QUERY;
02512 
02513        /* avoid doing work if we can */
02514        if (!return_value_used) {
02515               db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
02516 
02517               if (db->last_err_code != SQLITE_OK) {
02518                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
02519                      sqlite_freemem(errtext);
02520               }
02521               return;
02522        }
02523 
02524        rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
02525        sqlite_query(NULL, db, sql, sql_len, (int)mode, 0, NULL, &rres, NULL TSRMLS_CC);
02526        if (db->last_err_code != SQLITE_OK) {
02527               if (rres) {
02528                      efree(rres);
02529               }
02530               RETURN_FALSE;
02531        }
02532 
02533        array_init(return_value);
02534 
02535        while (rres->curr_row < rres->nrows) {
02536               MAKE_STD_ZVAL(ent);
02537               php_sqlite_fetch_array(rres, mode, decode_binary, 1, ent TSRMLS_CC);
02538               add_next_index_zval(return_value, ent);
02539        }
02540        real_result_dtor(rres TSRMLS_CC);
02541 }
02542 /* }}} */
02543 
02544 /* {{{ php_sqlite_fetch_single */
02545 static void php_sqlite_fetch_single(struct php_sqlite_result *res, zend_bool decode_binary, zval *return_value TSRMLS_DC)
02546 {
02547        const char **rowdata;
02548        char *decoded;
02549        int decoded_len;
02550 
02551        /* check range of the row */
02552        if (res->curr_row >= res->nrows) {
02553               /* no more */
02554               RETURN_FALSE;
02555        }
02556 
02557        if (res->buffered) {
02558               rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
02559        } else {
02560               rowdata = (const char**)res->table;
02561        }
02562 
02563        if (decode_binary && rowdata[0] != NULL && rowdata[0][0] == '\x01') {
02564               decoded = emalloc(strlen(rowdata[0]));
02565               decoded_len = php_sqlite_decode_binary(rowdata[0]+1, decoded);
02566               if (!res->buffered) {
02567                      efree((char*)rowdata[0]);
02568                      rowdata[0] = NULL;
02569               }
02570        } else if (rowdata[0]) {
02571               decoded_len = strlen((char*)rowdata[0]);
02572               if (res->buffered) {
02573                      decoded = estrndup((char*)rowdata[0], decoded_len);
02574               } else {
02575                      decoded = (char*)rowdata[0];
02576                      rowdata[0] = NULL;
02577               }
02578        } else {
02579               decoded = NULL;
02580               decoded_len = 0;
02581        }
02582 
02583        if (!res->buffered) {
02584               /* non buffered: fetch next row */
02585               php_sqlite_fetch(res TSRMLS_CC);
02586        }
02587        /* advance the row pointer */
02588        res->curr_row++;
02589 
02590        if (decoded == NULL) {
02591               RETURN_NULL();
02592        } else {
02593               RETURN_STRINGL(decoded, decoded_len, 0);
02594        }
02595 }
02596 /* }}} */
02597 
02598 
02599 /* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
02600    Executes a query and returns either an array for one single column or the value of the first row. */
02601 PHP_FUNCTION(sqlite_single_query)
02602 {
02603        zval *zdb, *ent;
02604        struct php_sqlite_db *db;
02605        struct php_sqlite_result *rres;
02606        char *sql;
02607        int sql_len;
02608        char *errtext = NULL;
02609        zend_bool decode_binary = 1;
02610        zend_bool srow = 1;
02611        zval *object = getThis();
02612 
02613        if (object) {
02614               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb", &sql, &sql_len, &srow, &decode_binary)) {
02615                      return;
02616               }
02617               RES_FROM_OBJECT(db, object);
02618        } else {
02619               if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
02620                             ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) &&
02621                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
02622                      return;
02623               }
02624               DB_FROM_ZVAL(db, &zdb);
02625        }
02626 
02627        PHP_SQLITE_EMPTY_QUERY;
02628 
02629        /* avoid doing work if we can */
02630        if (!return_value_used) {
02631               db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
02632 
02633               if (db->last_err_code != SQLITE_OK) {
02634                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
02635                      sqlite_freemem(errtext);
02636               }
02637               return;
02638        }
02639 
02640        rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
02641        sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, &rres, NULL TSRMLS_CC);
02642        if (db->last_err_code != SQLITE_OK) {
02643               if (rres) {
02644                      efree(rres);
02645               }
02646               RETURN_FALSE;
02647        }
02648 
02649        if (!srow) {
02650               array_init(return_value);
02651        }
02652 
02653        while (rres->curr_row < rres->nrows) {
02654               MAKE_STD_ZVAL(ent);
02655               php_sqlite_fetch_single(rres, decode_binary, ent TSRMLS_CC);
02656 
02657               /* if set and we only have 1 row in the result set, return the result as a string. */
02658               if (srow) {
02659                      if (rres->curr_row == 1 && rres->curr_row >= rres->nrows) {
02660                             *return_value = *ent;
02661                             zval_copy_ctor(return_value);
02662                             zval_dtor(ent);
02663                             FREE_ZVAL(ent);
02664                             break;
02665                      } else {
02666                             srow = 0;
02667                             array_init(return_value);
02668                      }
02669               }
02670               add_next_index_zval(return_value, ent);
02671        }
02672 
02673        real_result_dtor(rres TSRMLS_CC);
02674 }
02675 /* }}} */
02676 
02677 
02678 /* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
02679    Fetches the first column of a result set as a string. */
02680 PHP_FUNCTION(sqlite_fetch_single)
02681 {
02682        zval *zres;
02683        zend_bool decode_binary = 1;
02684        struct php_sqlite_result *res;
02685        zval *object = getThis();
02686 
02687        if (object) {
02688               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &decode_binary)) {
02689                      return;
02690               }
02691               RES_FROM_OBJECT(res, object);
02692        } else {
02693               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
02694                      return;
02695               }
02696               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02697        }
02698 
02699        php_sqlite_fetch_single(res, decode_binary, return_value TSRMLS_CC);
02700 }
02701 /* }}} */
02702 
02703 /* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
02704    Fetches the current row from a result set as an array. */
02705 PHP_FUNCTION(sqlite_current)
02706 {
02707        zval *zres;
02708        long mode = PHPSQLITE_BOTH;
02709        zend_bool decode_binary = 1;
02710        struct php_sqlite_result *res;
02711        zval *object = getThis();
02712 
02713        if (object) {
02714               if (ZEND_NUM_ARGS() && FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
02715                      return;
02716               }
02717               RES_FROM_OBJECT(res, object);
02718               if (!ZEND_NUM_ARGS()) {
02719                      mode = res->mode;
02720               }
02721        } else {
02722               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
02723                      return;
02724               }
02725               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02726               if (ZEND_NUM_ARGS() < 2) {
02727                      mode = res->mode;
02728               }
02729        }
02730 
02731        php_sqlite_fetch_array(res, mode, decode_binary, 0, return_value TSRMLS_CC);
02732 }
02733 /* }}} */
02734 
02735 /* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
02736    Fetches a column from the current row of a result set. */
02737 PHP_FUNCTION(sqlite_column)
02738 {
02739        zval *zres;
02740        zval *which;
02741        zend_bool decode_binary = 1;
02742        struct php_sqlite_result *res;
02743        zval *object = getThis();
02744 
02745        if (object) {
02746               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &which, &decode_binary)) {
02747                      return;
02748               }
02749               RES_FROM_OBJECT(res, object);
02750        } else {
02751               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
02752                      return;
02753               }
02754               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02755        }
02756 
02757        php_sqlite_fetch_column(res, which, decode_binary, return_value TSRMLS_CC);
02758 }
02759 /* }}} */
02760 
02761 /* {{{ proto string sqlite_libversion()
02762    Returns the version of the linked SQLite library. */
02763 PHP_FUNCTION(sqlite_libversion)
02764 {
02765        if (zend_parse_parameters_none() == FAILURE) {
02766               return;
02767        }
02768        RETURN_STRING((char*)sqlite_libversion(), 1);
02769 }
02770 /* }}} */
02771 
02772 /* {{{ proto string sqlite_libencoding()
02773    Returns the encoding (iso8859 or UTF-8) of the linked SQLite library. */
02774 PHP_FUNCTION(sqlite_libencoding)
02775 {
02776        if (zend_parse_parameters_none() == FAILURE) {
02777               return;
02778        }
02779        RETURN_STRING((char*)sqlite_libencoding(), 1);
02780 }
02781 /* }}} */
02782 
02783 /* {{{ proto int sqlite_changes(resource db)
02784    Returns the number of rows that were changed by the most recent SQL statement. */
02785 PHP_FUNCTION(sqlite_changes)
02786 {
02787        zval *zdb;
02788        struct php_sqlite_db *db;
02789        zval *object = getThis();
02790 
02791        if (object) {
02792               if (zend_parse_parameters_none() == FAILURE) {
02793                      return;
02794               }
02795               DB_FROM_OBJECT(db, object);
02796        } else {
02797               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
02798                      return;
02799               }
02800               DB_FROM_ZVAL(db, &zdb);
02801        }
02802 
02803        RETURN_LONG(sqlite_changes(db->db));
02804 }
02805 /* }}} */
02806 
02807 /* {{{ proto int sqlite_last_insert_rowid(resource db)
02808    Returns the rowid of the most recently inserted row. */
02809 PHP_FUNCTION(sqlite_last_insert_rowid)
02810 {
02811        zval *zdb;
02812        struct php_sqlite_db *db;
02813        zval *object = getThis();
02814 
02815        if (object) {
02816               if (zend_parse_parameters_none() == FAILURE) {
02817                      return;
02818               }
02819               DB_FROM_OBJECT(db, object);
02820        } else {
02821               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
02822                      return;
02823               }
02824               DB_FROM_ZVAL(db, &zdb);
02825        }
02826 
02827        RETURN_LONG(sqlite_last_insert_rowid(db->db));
02828 }
02829 /* }}} */
02830 
02831 static int sqlite_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
02832 {
02833        sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
02834 
02835        if (obj->u.res == NULL) {
02836               zend_throw_exception(sqlite_ce_exception, "Row count is not available for this query", 0 TSRMLS_CC);
02837               return FAILURE;
02838        }
02839 
02840        if (obj->u.res->buffered) {
02841               * count = obj->u.res->nrows;
02842               return SUCCESS;
02843        } else {
02844               zend_throw_exception(sqlite_ce_exception, "Row count is not available for unbuffered queries", 0 TSRMLS_CC);
02845               return FAILURE;
02846        }
02847 } /* }}} */
02848 
02849 /* {{{ proto int sqlite_num_rows(resource result)
02850    Returns the number of rows in a buffered result set. */
02851 PHP_FUNCTION(sqlite_num_rows)
02852 {
02853        zval *zres;
02854        struct php_sqlite_result *res;
02855        zval *object = getThis();
02856 
02857        if (object) {
02858               if (zend_parse_parameters_none() == FAILURE) {
02859                      return;
02860               }
02861               RES_FROM_OBJECT(res, object);
02862        } else {
02863               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
02864                      return;
02865               }
02866               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02867        }
02868 
02869        if (res->buffered) {
02870               RETURN_LONG(res->nrows);
02871        } else {
02872               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Row count is not available for unbuffered queries");
02873               RETURN_FALSE;
02874        }
02875 }
02876 /* }}} */
02877 
02878 /* {{{ proto bool sqlite_valid(resource result)
02879    Returns whether more rows are available. */
02880 PHP_FUNCTION(sqlite_valid)
02881 {
02882        zval *zres;
02883        struct php_sqlite_result *res;
02884        zval *object = getThis();
02885 
02886        if (object) {
02887               if (zend_parse_parameters_none() == FAILURE) {
02888                      return;
02889               }
02890               RES_FROM_OBJECT(res, object);
02891        } else {
02892               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
02893                      return;
02894               }
02895               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02896        }
02897 
02898        RETURN_BOOL(res->curr_row < res->nrows && res->nrows); /* curr_row may be -1 */
02899 }
02900 /* }}} */
02901 
02902 /* {{{ proto bool sqlite_has_prev(resource result)
02903  * Returns whether a previous row is available. */
02904 PHP_FUNCTION(sqlite_has_prev)
02905 {
02906        zval *zres;
02907        struct php_sqlite_result *res;
02908        zval *object = getThis();
02909 
02910        if (object) {
02911               if (zend_parse_parameters_none() == FAILURE) {
02912                      return;
02913               }
02914               RES_FROM_OBJECT(res, object);
02915        } else {
02916               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
02917                      return;
02918               }
02919               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02920        }
02921 
02922        if(!res->buffered) {
02923               php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_has_prev on unbuffered querys");
02924               RETURN_FALSE;
02925        }
02926 
02927        RETURN_BOOL(res->curr_row);
02928 }
02929 /* }}} */
02930 
02931 /* {{{ proto int sqlite_num_fields(resource result)
02932    Returns the number of fields in a result set. */
02933 PHP_FUNCTION(sqlite_num_fields)
02934 {
02935        zval *zres;
02936        struct php_sqlite_result *res;
02937        zval *object = getThis();
02938 
02939        if (object) {
02940               if (zend_parse_parameters_none() == FAILURE) {
02941                      return;
02942               }
02943               RES_FROM_OBJECT(res, object);
02944        } else {
02945               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
02946                      return;
02947               }
02948               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02949        }
02950 
02951        RETURN_LONG(res->ncolumns);
02952 }
02953 /* }}} */
02954 
02955 /* {{{ proto string sqlite_field_name(resource result, int field_index)
02956    Returns the name of a particular field of a result set. */
02957 PHP_FUNCTION(sqlite_field_name)
02958 {
02959        zval *zres;
02960        struct php_sqlite_result *res;
02961        long field;
02962        zval *object = getThis();
02963 
02964        if (object) {
02965               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &field)) {
02966                      return;
02967               }
02968               RES_FROM_OBJECT(res, object);
02969        } else {
02970               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
02971                      return;
02972               }
02973               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
02974        }
02975 
02976        if (field < 0 || field >= res->ncolumns) {
02977               php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %ld out of range", field);
02978               RETURN_FALSE;
02979        }
02980 
02981        RETURN_STRING(res->col_names[field], 1);
02982 }
02983 /* }}} */
02984 
02985 /* {{{ proto bool sqlite_seek(resource result, int row)
02986    Seek to a particular row number of a buffered result set. */
02987 PHP_FUNCTION(sqlite_seek)
02988 {
02989        zval *zres;
02990        struct php_sqlite_result *res;
02991        long row;
02992        zval *object = getThis();
02993 
02994        if (object) {
02995               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &row)) {
02996                      return;
02997               }
02998               RES_FROM_OBJECT(res, object);
02999        } else {
03000               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
03001                      return;
03002               }
03003               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
03004        }
03005 
03006        if (!res->buffered) {
03007               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
03008               RETURN_FALSE;
03009        }
03010 
03011        if (row < 0 || row >= res->nrows) {
03012               php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %ld out of range", row);
03013               RETURN_FALSE;
03014        }
03015 
03016        res->curr_row = row;
03017        RETURN_TRUE;
03018 }
03019 /* }}} */
03020 
03021 /* {{{ proto bool sqlite_rewind(resource result)
03022    Seek to the first row number of a buffered result set. */
03023 PHP_FUNCTION(sqlite_rewind)
03024 {
03025        zval *zres;
03026        struct php_sqlite_result *res;
03027        zval *object = getThis();
03028 
03029        if (object) {
03030               if (zend_parse_parameters_none() == FAILURE) {
03031                      return;
03032               }
03033               RES_FROM_OBJECT(res, object);
03034        } else {
03035               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
03036                      return;
03037               }
03038               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
03039        }
03040 
03041        if (!res->buffered) {
03042               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rewind an unbuffered result set");
03043               RETURN_FALSE;
03044        }
03045 
03046        if (!res->nrows) {
03047               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "no rows received");
03048               RETURN_FALSE;
03049        }
03050 
03051        res->curr_row = 0;
03052        RETURN_TRUE;
03053 }
03054 /* }}} */
03055 
03056 /* {{{ proto bool sqlite_next(resource result)
03057    Seek to the next row number of a result set. */
03058 PHP_FUNCTION(sqlite_next)
03059 {
03060        zval *zres;
03061        struct php_sqlite_result *res;
03062        zval *object = getThis();
03063 
03064        if (object) {
03065               if (zend_parse_parameters_none() == FAILURE) {
03066                      return;
03067               }
03068               RES_FROM_OBJECT(res, object);
03069        } else {
03070               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
03071                      return;
03072               }
03073               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
03074        }
03075 
03076        if (!res->buffered && res->vm) {
03077               php_sqlite_fetch(res TSRMLS_CC);
03078        }
03079 
03080        if (res->curr_row >= res->nrows) {
03081               php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available");
03082               RETURN_FALSE;
03083        }
03084 
03085        res->curr_row++;
03086 
03087        RETURN_TRUE;
03088 }
03089 /* }}} */
03090 
03091 /* {{{ proto int sqlite_key(resource result)
03092    Return the current row index of a buffered result. */
03093 PHP_FUNCTION(sqlite_key)
03094 {
03095        zval *zres;
03096        struct php_sqlite_result *res;
03097        zval *object = getThis();
03098 
03099        if (object) {
03100               if (zend_parse_parameters_none() == FAILURE) {
03101                      return;
03102               }
03103               RES_FROM_OBJECT(res, object);
03104        } else {
03105               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
03106                      return;
03107               }
03108               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
03109        }
03110 
03111        RETURN_LONG(res->curr_row);
03112 }
03113 /* }}} */
03114 
03115 /* {{{ proto bool sqlite_prev(resource result)
03116  * Seek to the previous row number of a result set. */
03117 PHP_FUNCTION(sqlite_prev)
03118 {
03119        zval *zres;
03120        struct php_sqlite_result *res;
03121        zval *object = getThis();
03122 
03123        if (object) {
03124               if (zend_parse_parameters_none() == FAILURE) {
03125                      return;
03126               }
03127               RES_FROM_OBJECT(res, object);
03128        } else {
03129               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
03130                      return;
03131               }
03132               ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
03133        }
03134 
03135        if (!res->buffered) {
03136               php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_prev on unbuffered querys");
03137               RETURN_FALSE;
03138        }
03139 
03140        if (res->curr_row <= 0) {
03141               php_error_docref(NULL TSRMLS_CC, E_WARNING, "no previous row available");
03142               RETURN_FALSE;
03143        }
03144 
03145        res->curr_row--;
03146 
03147        RETURN_TRUE;
03148 }
03149 /* }}} */
03150 
03151 /* {{{ proto string sqlite_escape_string(string item)
03152    Escapes a string for use as a query parameter. */
03153 PHP_FUNCTION(sqlite_escape_string)
03154 {
03155        char *string = NULL;
03156        int stringlen;
03157        char *ret;
03158 
03159        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &stringlen)) {
03160               return;
03161        }
03162 
03163        if (stringlen && (string[0] == '\x01' || memchr(string, '\0', stringlen) != NULL)) {
03164               /* binary string */
03165               int enclen;
03166 
03167               ret = safe_emalloc(1 + stringlen / 254, 257, 3);
03168               ret[0] = '\x01';
03169               enclen = php_sqlite_encode_binary(string, stringlen, ret+1);
03170               RETVAL_STRINGL(ret, enclen+1, 0);
03171 
03172        } else if (stringlen) {
03173               ret = sqlite_mprintf("%q", string);
03174               if (ret) {
03175                      RETVAL_STRING(ret, 1);
03176                      sqlite_freemem(ret);
03177               }
03178        } else {
03179               RETURN_EMPTY_STRING();
03180        }
03181 }
03182 /* }}} */
03183 
03184 /* {{{ proto int sqlite_last_error(resource db)
03185    Returns the error code of the last error for a database. */
03186 PHP_FUNCTION(sqlite_last_error)
03187 {
03188        zval *zdb;
03189        struct php_sqlite_db *db;
03190        zval *object = getThis();
03191 
03192        if (object) {
03193               if (zend_parse_parameters_none() == FAILURE) {
03194                      return;
03195               }
03196               DB_FROM_OBJECT(db, object);
03197        } else {
03198               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
03199                      return;
03200               }
03201               DB_FROM_ZVAL(db, &zdb);
03202        }
03203 
03204        RETURN_LONG(db->last_err_code);
03205 }
03206 /* }}} */
03207 
03208 /* {{{ proto string sqlite_error_string(int error_code)
03209    Returns the textual description of an error code. */
03210 PHP_FUNCTION(sqlite_error_string)
03211 {
03212        long code;
03213        const char *msg;
03214 
03215        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
03216               return;
03217        }
03218 
03219        msg = sqlite_error_string(code);
03220 
03221        if (msg) {
03222               RETURN_STRING((char*)msg, 1);
03223        } else {
03224               RETURN_NULL();
03225        }
03226 }
03227 /* }}} */
03228 
03229 /* manages duplicate registrations of a particular function, and
03230  * also handles the case where the db is using a persistent connection */
03231 enum callback_prep_t { DO_REG, SKIP_REG, ERR };
03232 
03233 static enum callback_prep_t prep_callback_struct(struct php_sqlite_db *db, int is_agg,
03234               char *funcname,
03235               zval *step, zval *fini, struct php_sqlite_agg_functions **funcs)
03236 {
03237        struct php_sqlite_agg_functions *alloc_funcs, func_tmp;
03238        char *hashkey;
03239        int hashkeylen;
03240        enum callback_prep_t ret;
03241 
03242        hashkeylen = spprintf(&hashkey, 0, "%s-%s", is_agg ? "agg" : "reg", funcname);
03243 
03244        /* is it already registered ? */
03245        if (SUCCESS == zend_hash_find(&db->callbacks, hashkey, hashkeylen+1, (void*)&alloc_funcs)) {
03246               /* override the previous definition */
03247 
03248               if (alloc_funcs->is_valid) {
03249                      /* release these */
03250 
03251                      if (alloc_funcs->step) {
03252                             zval_ptr_dtor(&alloc_funcs->step);
03253                             alloc_funcs->step = NULL;
03254                      }
03255 
03256                      if (alloc_funcs->fini) {
03257                             zval_ptr_dtor(&alloc_funcs->fini);
03258                             alloc_funcs->fini = NULL;
03259                      }
03260               }
03261 
03262               ret = SKIP_REG;
03263        } else {
03264               /* add a new one */
03265               func_tmp.db = db;
03266 
03267               ret = SUCCESS == zend_hash_update(&db->callbacks, hashkey, hashkeylen+1,
03268                             (void*)&func_tmp, sizeof(func_tmp), (void**)&alloc_funcs) ? DO_REG : ERR;
03269        }
03270 
03271        efree(hashkey);
03272 
03273        MAKE_STD_ZVAL(alloc_funcs->step);
03274        *(alloc_funcs->step)  = *step;
03275        zval_copy_ctor(alloc_funcs->step);
03276        INIT_PZVAL(alloc_funcs->step);
03277 
03278        if (is_agg) {
03279               MAKE_STD_ZVAL(alloc_funcs->fini);
03280               *(alloc_funcs->fini) = *fini;
03281               zval_copy_ctor(alloc_funcs->fini);
03282               INIT_PZVAL(alloc_funcs->fini);
03283        } else {
03284               alloc_funcs->fini = NULL;
03285        }
03286        alloc_funcs->is_valid = 1;
03287        *funcs = alloc_funcs;
03288 
03289        return ret;
03290 }
03291 
03292 
03293 /* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
03294     Registers an aggregate function for queries. */
03295 PHP_FUNCTION(sqlite_create_aggregate)
03296 {
03297        char *funcname = NULL;
03298        int funcname_len;
03299        zval *zstep, *zfinal, *zdb;
03300        struct php_sqlite_db *db;
03301        struct php_sqlite_agg_functions *funcs;
03302        char *callable = NULL;
03303        long num_args = -1;
03304        zval *object = getThis();
03305 
03306        if (object) {
03307               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
03308                      return;
03309               }
03310               DB_FROM_OBJECT(db, object);
03311        } else {
03312               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
03313                      return;
03314               }
03315               DB_FROM_ZVAL(db, &zdb);
03316        }
03317 
03318        if (!zend_is_callable(zstep, 0, &callable TSRMLS_CC)) {
03319               php_error_docref(NULL TSRMLS_CC, E_WARNING, "step function `%s' is not callable", callable);
03320               efree(callable);
03321               return;
03322        }
03323        efree(callable);
03324 
03325        if (!zend_is_callable(zfinal, 0, &callable TSRMLS_CC)) {
03326               php_error_docref(NULL TSRMLS_CC, E_WARNING, "finalize function `%s' is not callable", callable);
03327               efree(callable);
03328               return;
03329        }
03330        efree(callable);
03331 
03332 
03333        if (prep_callback_struct(db, 1, funcname, zstep, zfinal, &funcs) == DO_REG) {
03334               sqlite_create_aggregate(db->db, funcname, num_args,
03335                             php_sqlite_agg_step_function_callback,
03336                             php_sqlite_agg_fini_function_callback, funcs);
03337        }
03338 
03339 
03340 }
03341 /* }}} */
03342 
03343 /* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
03344     Registers a "regular" function for queries. */
03345 PHP_FUNCTION(sqlite_create_function)
03346 {
03347        char *funcname = NULL;
03348        int funcname_len;
03349        zval *zcall, *zdb;
03350        struct php_sqlite_db *db;
03351        struct php_sqlite_agg_functions *funcs;
03352        char *callable = NULL;
03353        long num_args = -1;
03354 
03355        zval *object = getThis();
03356 
03357        if (object) {
03358               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &funcname, &funcname_len, &zcall, &num_args)) {
03359                      return;
03360               }
03361               DB_FROM_OBJECT(db, object);
03362        } else {
03363               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
03364                      return;
03365               }
03366               DB_FROM_ZVAL(db, &zdb);
03367        }
03368 
03369        if (!zend_is_callable(zcall, 0, &callable TSRMLS_CC)) {
03370               php_error_docref(NULL TSRMLS_CC, E_WARNING, "function `%s' is not callable", callable);
03371               efree(callable);
03372               return;
03373        }
03374        efree(callable);
03375 
03376        if (prep_callback_struct(db, 0, funcname, zcall, NULL, &funcs) == DO_REG) {
03377               sqlite_create_function(db->db, funcname, num_args, php_sqlite_function_callback, funcs);
03378        }
03379 }
03380 /* }}} */
03381 
03382 /* {{{ proto string sqlite_udf_encode_binary(string data)
03383    Apply binary encoding (if required) to a string to return from an UDF. */
03384 PHP_FUNCTION(sqlite_udf_encode_binary)
03385 {
03386        char *data = NULL;
03387        int datalen;
03388 
03389        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
03390               return;
03391        }
03392 
03393        if (data == NULL) {
03394               RETURN_NULL();
03395        }
03396        if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) {
03397               /* binary string */
03398               int enclen;
03399               char *ret;
03400 
03401               ret = safe_emalloc(1 + datalen / 254, 257, 3);
03402               ret[0] = '\x01';
03403               enclen = php_sqlite_encode_binary(data, datalen, ret+1);
03404               RETVAL_STRINGL(ret, enclen+1, 0);
03405        } else {
03406               RETVAL_STRINGL(data, datalen, 1);
03407        }
03408 }
03409 /* }}} */
03410 
03411 /* {{{ proto string sqlite_udf_decode_binary(string data)
03412    Decode binary encoding on a string parameter passed to an UDF. */
03413 PHP_FUNCTION(sqlite_udf_decode_binary)
03414 {
03415        char *data = NULL;
03416        int datalen;
03417 
03418        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
03419               return;
03420        }
03421 
03422        if (data == NULL) {
03423               RETURN_NULL();
03424        }
03425        if (datalen && data[0] == '\x01') {
03426               /* encoded string */
03427               int enclen;
03428               char *ret;
03429 
03430               ret = emalloc(datalen);
03431               enclen = php_sqlite_decode_binary(data+1, ret);
03432               ret[enclen] = '\0';
03433               RETVAL_STRINGL(ret, enclen, 0);
03434        } else {
03435               RETVAL_STRINGL(data, datalen, 1);
03436        }
03437 }
03438 /* }}} */
03439 
03440 
03441 /*
03442  * Local variables:
03443  * tab-width: 4
03444  * c-basic-offset: 4
03445  * End:
03446  * vim600: sw=4 ts=4 fdm=marker
03447  * vim<600: sw=4 ts=4
03448  */