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