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