PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - sqlite - sqlite.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 1415
Code covered: 73.6 % Executed lines: 1041
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:39 +0000 (34 hours ago)

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