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 : */
|