1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Scott MacVicar <scottmac@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "php.h"
22 #include "php_ini.h"
23 #include "ext/standard/info.h"
24 #include "php_sqlite3.h"
25 #include "php_sqlite3_structs.h"
26 #include "sqlite3_arginfo.h"
27 #include "main/SAPI.h"
28
29 #include <sqlite3.h>
30
31 #include "zend_exceptions.h"
32 #include "zend_interfaces.h"
33 #include "SAPI.h"
34
35 ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
36
37 static PHP_GINIT_FUNCTION(sqlite3);
38 static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4);
39 static void sqlite3_param_dtor(zval *data);
40 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
41
42 /* {{{ Error Handler */
php_sqlite3_error(php_sqlite3_db_object * db_obj,char * format,...)43 static void php_sqlite3_error(php_sqlite3_db_object *db_obj, char *format, ...)
44 {
45 va_list arg;
46 char *message;
47
48 va_start(arg, format);
49 vspprintf(&message, 0, format, arg);
50 va_end(arg);
51
52 if (db_obj && db_obj->exception) {
53 zend_throw_exception(zend_ce_exception, message, 0);
54 } else {
55 php_error_docref(NULL, E_WARNING, "%s", message);
56 }
57
58 if (message) {
59 efree(message);
60 }
61 }
62 /* }}} */
63
64 #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
65 if (!(db_obj) || !(member)) { \
66 zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \
67 RETURN_THROWS(); \
68 }
69
70 #define SQLITE3_CHECK_INITIALIZED_STMT(member, class_name) \
71 if (!(member)) { \
72 zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \
73 RETURN_THROWS(); \
74 }
75
76 /* {{{ PHP_INI */
77 PHP_INI_BEGIN()
78 STD_PHP_INI_ENTRY("sqlite3.extension_dir", NULL, PHP_INI_SYSTEM, OnUpdateString, extension_dir, zend_sqlite3_globals, sqlite3_globals)
79 #if SQLITE_VERSION_NUMBER >= 3026000
80 STD_PHP_INI_BOOLEAN("sqlite3.defensive", "1", PHP_INI_SYSTEM, OnUpdateBool, dbconfig_defensive, zend_sqlite3_globals, sqlite3_globals)
81 #endif
82 PHP_INI_END()
83 /* }}} */
84
85 /* Handlers */
86 static zend_object_handlers sqlite3_object_handlers;
87 static zend_object_handlers sqlite3_stmt_object_handlers;
88 static zend_object_handlers sqlite3_result_object_handlers;
89
90 /* Class entries */
91 zend_class_entry *php_sqlite3_sc_entry;
92 zend_class_entry *php_sqlite3_stmt_entry;
93 zend_class_entry *php_sqlite3_result_entry;
94
95 /* {{{ Opens a SQLite 3 Database, if the build includes encryption then it will attempt to use the key. */
PHP_METHOD(SQLite3,open)96 PHP_METHOD(SQLite3, open)
97 {
98 php_sqlite3_db_object *db_obj;
99 zval *object = ZEND_THIS;
100 char *filename, *encryption_key, *fullpath;
101 size_t filename_len, encryption_key_len = 0;
102 zend_long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
103 int rc;
104
105 db_obj = Z_SQLITE3_DB_P(object);
106
107 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls", &filename, &filename_len, &flags, &encryption_key, &encryption_key_len)) {
108 RETURN_THROWS();
109 }
110
111 if (db_obj->initialised) {
112 zend_throw_exception(zend_ce_exception, "Already initialised DB Object", 0);
113 RETURN_THROWS();
114 }
115
116 if (filename_len != 0 && (filename_len != sizeof(":memory:")-1 ||
117 memcmp(filename, ":memory:", sizeof(":memory:")-1) != 0)) {
118 if (!(fullpath = expand_filepath(filename, NULL))) {
119 zend_throw_exception(zend_ce_exception, "Unable to expand filepath", 0);
120 RETURN_THROWS();
121 }
122
123 if (php_check_open_basedir(fullpath)) {
124 zend_throw_exception_ex(zend_ce_exception, 0, "open_basedir prohibits opening %s", fullpath);
125 efree(fullpath);
126 RETURN_THROWS();
127 }
128 } else {
129 /* filename equals "" or ":memory:" */
130 fullpath = filename;
131 }
132
133 rc = sqlite3_open_v2(fullpath, &(db_obj->db), flags, NULL);
134 if (rc != SQLITE_OK) {
135 zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s",
136 #ifdef HAVE_SQLITE3_ERRSTR
137 db_obj->db ? sqlite3_errmsg(db_obj->db) : sqlite3_errstr(rc));
138 #else
139 db_obj->db ? sqlite3_errmsg(db_obj->db) : "");
140 #endif
141 sqlite3_close(db_obj->db);
142 if (fullpath != filename) {
143 efree(fullpath);
144 }
145 return;
146 }
147
148 #ifdef SQLITE_HAS_CODEC
149 if (encryption_key_len > 0) {
150 if (sqlite3_key(db_obj->db, encryption_key, encryption_key_len) != SQLITE_OK) {
151 zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s", sqlite3_errmsg(db_obj->db));
152 sqlite3_close(db_obj->db);
153 RETURN_THROWS();
154 }
155 }
156 #endif
157
158 db_obj->initialised = 1;
159 db_obj->authorizer_fci = empty_fcall_info;
160 db_obj->authorizer_fcc = empty_fcall_info_cache;
161
162 sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, db_obj);
163
164 #if SQLITE_VERSION_NUMBER >= 3026000
165 if (SQLITE3G(dbconfig_defensive)) {
166 sqlite3_db_config(db_obj->db, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
167 }
168 #endif
169
170 if (fullpath != filename) {
171 efree(fullpath);
172 }
173 }
174 /* }}} */
175
176 /* {{{ Close a SQLite 3 Database. */
PHP_METHOD(SQLite3,close)177 PHP_METHOD(SQLite3, close)
178 {
179 php_sqlite3_db_object *db_obj;
180 zval *object = ZEND_THIS;
181 int errcode;
182 db_obj = Z_SQLITE3_DB_P(object);
183
184 if (zend_parse_parameters_none() == FAILURE) {
185 RETURN_THROWS();
186 }
187
188 if (db_obj->initialised) {
189 zend_llist_clean(&(db_obj->free_list));
190 if(db_obj->db) {
191 errcode = sqlite3_close(db_obj->db);
192 if (errcode != SQLITE_OK) {
193 php_sqlite3_error(db_obj, "Unable to close database: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
194 RETURN_FALSE;
195 }
196 }
197 db_obj->initialised = 0;
198 }
199
200 RETURN_TRUE;
201 }
202 /* }}} */
203
204 /* {{{ Executes a result-less query against a given database. */
PHP_METHOD(SQLite3,exec)205 PHP_METHOD(SQLite3, exec)
206 {
207 php_sqlite3_db_object *db_obj;
208 zval *object = ZEND_THIS;
209 zend_string *sql;
210 char *errtext = NULL;
211 db_obj = Z_SQLITE3_DB_P(object);
212
213 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
214 RETURN_THROWS();
215 }
216
217 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
218
219 if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
220 php_sqlite3_error(db_obj, "%s", errtext);
221 sqlite3_free(errtext);
222 RETURN_FALSE;
223 }
224
225 RETURN_TRUE;
226 }
227 /* }}} */
228
229 /* {{{ Returns the SQLite3 Library version as a string constant and as a number. */
PHP_METHOD(SQLite3,version)230 PHP_METHOD(SQLite3, version)
231 {
232 if (zend_parse_parameters_none() == FAILURE) {
233 RETURN_THROWS();
234 }
235
236 array_init(return_value);
237
238 add_assoc_string(return_value, "versionString", (char*)sqlite3_libversion());
239 add_assoc_long(return_value, "versionNumber", sqlite3_libversion_number());
240
241 return;
242 }
243 /* }}} */
244
245 /* {{{ Returns the rowid of the most recent INSERT into the database from the database connection. */
PHP_METHOD(SQLite3,lastInsertRowID)246 PHP_METHOD(SQLite3, lastInsertRowID)
247 {
248 php_sqlite3_db_object *db_obj;
249 zval *object = ZEND_THIS;
250 db_obj = Z_SQLITE3_DB_P(object);
251
252 if (zend_parse_parameters_none() == FAILURE) {
253 RETURN_THROWS();
254 }
255
256 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
257
258 RETURN_LONG((zend_long) sqlite3_last_insert_rowid(db_obj->db));
259 }
260 /* }}} */
261
262 /* {{{ Returns the numeric result code of the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastErrorCode)263 PHP_METHOD(SQLite3, lastErrorCode)
264 {
265 php_sqlite3_db_object *db_obj;
266 zval *object = ZEND_THIS;
267 db_obj = Z_SQLITE3_DB_P(object);
268
269 if (zend_parse_parameters_none() == FAILURE) {
270 RETURN_THROWS();
271 }
272
273 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
274
275 if (db_obj->initialised) {
276 RETURN_LONG(sqlite3_errcode(db_obj->db));
277 } else {
278 RETURN_LONG(0);
279 }
280 }
281 /* }}} */
282
283 /* {{{ Returns the numeric extended result code of the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastExtendedErrorCode)284 PHP_METHOD(SQLite3, lastExtendedErrorCode)
285 {
286 php_sqlite3_db_object *db_obj;
287 zval *object = ZEND_THIS;
288 db_obj = Z_SQLITE3_DB_P(object);
289
290 if (zend_parse_parameters_none() == FAILURE) {
291 RETURN_THROWS();
292 }
293
294 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
295
296 if (db_obj->initialised) {
297 RETURN_LONG(sqlite3_extended_errcode(db_obj->db));
298 } else {
299 RETURN_LONG(0);
300 }
301 }
302 /* }}} */
303
304 /* {{{ Turns on or off the extended result codes feature of SQLite. */
PHP_METHOD(SQLite3,enableExtendedResultCodes)305 PHP_METHOD(SQLite3, enableExtendedResultCodes)
306 {
307 php_sqlite3_db_object *db_obj;
308 zval *object = ZEND_THIS;
309 zend_bool enable = 1;
310 db_obj = Z_SQLITE3_DB_P(object);
311 int ret;
312
313 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enable) == FAILURE) {
314 RETURN_THROWS();
315 }
316
317 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
318
319 if (db_obj->initialised) {
320 ret = sqlite3_extended_result_codes(db_obj->db, enable ? 1 : 0);
321 if (ret == SQLITE_OK)
322 {
323 RETURN_TRUE;
324 }
325 }
326
327 RETURN_FALSE;
328 }
329 /* }}} */
330
331 /* {{{ Returns english text describing the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastErrorMsg)332 PHP_METHOD(SQLite3, lastErrorMsg)
333 {
334 php_sqlite3_db_object *db_obj;
335 zval *object = ZEND_THIS;
336 db_obj = Z_SQLITE3_DB_P(object);
337
338 if (zend_parse_parameters_none() == FAILURE) {
339 RETURN_THROWS();
340 }
341
342 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
343
344 if (db_obj->initialised) {
345 RETURN_STRING((char *)sqlite3_errmsg(db_obj->db));
346 } else {
347 RETURN_EMPTY_STRING();
348 }
349 }
350 /* }}} */
351
352 /* {{{ Sets a busy handler that will sleep until database is not locked or timeout is reached. Passing a value less than or equal to zero turns off all busy handlers. */
PHP_METHOD(SQLite3,busyTimeout)353 PHP_METHOD(SQLite3, busyTimeout)
354 {
355 php_sqlite3_db_object *db_obj;
356 zval *object = ZEND_THIS;
357 zend_long ms;
358 #ifdef SQLITE_ENABLE_API_ARMOR
359 int return_code;
360 #endif
361 db_obj = Z_SQLITE3_DB_P(object);
362
363 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &ms)) {
364 RETURN_THROWS();
365 }
366
367 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
368
369 #ifdef SQLITE_ENABLE_API_ARMOR
370 return_code = sqlite3_busy_timeout(db_obj->db, ms);
371 if (return_code != SQLITE_OK) {
372 php_sqlite3_error(db_obj, "Unable to set busy timeout: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
373 RETURN_FALSE;
374 }
375 #else
376 php_ignore_value(sqlite3_busy_timeout(db_obj->db, ms));
377 #endif
378
379 RETURN_TRUE;
380 }
381 /* }}} */
382
383
384 #ifndef SQLITE_OMIT_LOAD_EXTENSION
385 /* {{{ Attempts to load an SQLite extension library. */
PHP_METHOD(SQLite3,loadExtension)386 PHP_METHOD(SQLite3, loadExtension)
387 {
388 php_sqlite3_db_object *db_obj;
389 zval *object = ZEND_THIS;
390 char *extension, *lib_path, *extension_dir, *errtext = NULL;
391 char fullpath[MAXPATHLEN];
392 size_t extension_len, extension_dir_len;
393 db_obj = Z_SQLITE3_DB_P(object);
394
395 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &extension, &extension_len)) {
396 RETURN_THROWS();
397 }
398
399 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
400
401 #ifdef ZTS
402 if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
403 (strcmp(sapi_module.name, "cli") != 0) &&
404 (strncmp(sapi_module.name, "embed", 5) != 0)
405 ) { php_sqlite3_error(db_obj, "Not supported in multithreaded Web servers");
406 RETURN_FALSE;
407 }
408 #endif
409
410 if (!SQLITE3G(extension_dir)) {
411 php_sqlite3_error(db_obj, "SQLite Extension are disabled");
412 RETURN_FALSE;
413 }
414
415 if (extension_len == 0) {
416 php_sqlite3_error(db_obj, "Empty string as an extension");
417 RETURN_FALSE;
418 }
419
420 extension_dir = SQLITE3G(extension_dir);
421 extension_dir_len = strlen(SQLITE3G(extension_dir));
422
423 if (IS_SLASH(extension_dir[extension_dir_len-1])) {
424 spprintf(&lib_path, 0, "%s%s", extension_dir, extension);
425 } else {
426 spprintf(&lib_path, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, extension);
427 }
428
429 if (!VCWD_REALPATH(lib_path, fullpath)) {
430 php_sqlite3_error(db_obj, "Unable to load extension at '%s'", lib_path);
431 efree(lib_path);
432 RETURN_FALSE;
433 }
434
435 efree(lib_path);
436
437 if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) {
438 php_sqlite3_error(db_obj, "Unable to open extensions outside the defined directory");
439 RETURN_FALSE;
440 }
441
442 /* Extension loading should only be enabled for when we attempt to load */
443 sqlite3_enable_load_extension(db_obj->db, 1);
444 if (sqlite3_load_extension(db_obj->db, fullpath, 0, &errtext) != SQLITE_OK) {
445 php_sqlite3_error(db_obj, "%s", errtext);
446 sqlite3_free(errtext);
447 sqlite3_enable_load_extension(db_obj->db, 0);
448 RETURN_FALSE;
449 }
450 sqlite3_enable_load_extension(db_obj->db, 0);
451
452 RETURN_TRUE;
453 }
454 /* }}} */
455 #endif
456
457 /* {{{ Returns the number of database rows that were changed (or inserted or deleted) by the most recent SQL statement. */
PHP_METHOD(SQLite3,changes)458 PHP_METHOD(SQLite3, changes)
459 {
460 php_sqlite3_db_object *db_obj;
461 zval *object = ZEND_THIS;
462 db_obj = Z_SQLITE3_DB_P(object);
463
464 if (zend_parse_parameters_none() == FAILURE) {
465 RETURN_THROWS();
466 }
467
468 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
469
470 RETURN_LONG(sqlite3_changes(db_obj->db));
471 }
472 /* }}} */
473
474 /* {{{ Returns a string that has been properly escaped. */
PHP_METHOD(SQLite3,escapeString)475 PHP_METHOD(SQLite3, escapeString)
476 {
477 zend_string *sql;
478 char *ret;
479
480 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
481 RETURN_THROWS();
482 }
483
484 if (ZSTR_LEN(sql)) {
485 ret = sqlite3_mprintf("%q", ZSTR_VAL(sql));
486 if (ret) {
487 RETVAL_STRING(ret);
488 sqlite3_free(ret);
489 }
490 } else {
491 RETURN_EMPTY_STRING();
492 }
493 }
494 /* }}} */
495
496 /* {{{ Returns a prepared SQL statement for execution. */
PHP_METHOD(SQLite3,prepare)497 PHP_METHOD(SQLite3, prepare)
498 {
499 php_sqlite3_db_object *db_obj;
500 php_sqlite3_stmt *stmt_obj;
501 zval *object = ZEND_THIS;
502 zend_string *sql;
503 int errcode;
504 php_sqlite3_free_list *free_item;
505
506 db_obj = Z_SQLITE3_DB_P(object);
507
508 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
509 RETURN_THROWS();
510 }
511
512 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
513
514 if (!ZSTR_LEN(sql)) {
515 RETURN_FALSE;
516 }
517
518 object_init_ex(return_value, php_sqlite3_stmt_entry);
519 stmt_obj = Z_SQLITE3_STMT_P(return_value);
520 stmt_obj->db_obj = db_obj;
521 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
522
523 errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
524 if (errcode != SQLITE_OK) {
525 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
526 zval_ptr_dtor(return_value);
527 RETURN_FALSE;
528 }
529
530 stmt_obj->initialised = 1;
531
532 free_item = emalloc(sizeof(php_sqlite3_free_list));
533 free_item->stmt_obj = stmt_obj;
534 ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(return_value));
535
536 zend_llist_add_element(&(db_obj->free_list), &free_item);
537 }
538 /* }}} */
539
540 /* {{{ Returns true or false, for queries that return data it will return a SQLite3Result object. */
PHP_METHOD(SQLite3,query)541 PHP_METHOD(SQLite3, query)
542 {
543 php_sqlite3_db_object *db_obj;
544 php_sqlite3_result *result;
545 php_sqlite3_stmt *stmt_obj;
546 zval *object = ZEND_THIS;
547 zval stmt;
548 zend_string *sql;
549 char *errtext = NULL;
550 int return_code;
551 db_obj = Z_SQLITE3_DB_P(object);
552
553 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
554 RETURN_THROWS();
555 }
556
557 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
558
559 if (!ZSTR_LEN(sql)) {
560 RETURN_FALSE;
561 }
562
563 /* If there was no return value then just execute the query */
564 if (!USED_RET()) {
565 if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
566 php_sqlite3_error(db_obj, "%s", errtext);
567 sqlite3_free(errtext);
568 }
569 return;
570 }
571
572 object_init_ex(&stmt, php_sqlite3_stmt_entry);
573 stmt_obj = Z_SQLITE3_STMT_P(&stmt);
574 stmt_obj->db_obj = db_obj;
575 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
576
577 return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
578 if (return_code != SQLITE_OK) {
579 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
580 zval_ptr_dtor(&stmt);
581 RETURN_FALSE;
582 }
583
584 stmt_obj->initialised = 1;
585
586 object_init_ex(return_value, php_sqlite3_result_entry);
587 result = Z_SQLITE3_RESULT_P(return_value);
588 result->db_obj = db_obj;
589 result->stmt_obj = stmt_obj;
590 ZVAL_OBJ(&result->stmt_obj_zval, Z_OBJ(stmt));
591
592 return_code = sqlite3_step(result->stmt_obj->stmt);
593
594 switch (return_code) {
595 case SQLITE_ROW: /* Valid Row */
596 case SQLITE_DONE: /* Valid but no results */
597 {
598 php_sqlite3_free_list *free_item;
599 free_item = emalloc(sizeof(php_sqlite3_free_list));
600 free_item->stmt_obj = stmt_obj;
601 free_item->stmt_obj_zval = stmt;
602 zend_llist_add_element(&(db_obj->free_list), &free_item);
603 sqlite3_reset(result->stmt_obj->stmt);
604 break;
605 }
606 default:
607 if (!EG(exception)) {
608 php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
609 }
610 sqlite3_finalize(stmt_obj->stmt);
611 stmt_obj->initialised = 0;
612 zval_ptr_dtor(return_value);
613 RETURN_FALSE;
614 }
615 }
616 /* }}} */
617
sqlite_value_to_zval(sqlite3_stmt * stmt,int column,zval * data)618 static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* {{{ */
619 {
620 sqlite3_int64 val;
621
622 switch (sqlite3_column_type(stmt, column)) {
623 case SQLITE_INTEGER:
624 val = sqlite3_column_int64(stmt, column);
625 #if LONG_MAX <= 2147483647
626 if (val > ZEND_LONG_MAX || val < ZEND_LONG_MIN) {
627 ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column));
628 } else {
629 #endif
630 ZVAL_LONG(data, (zend_long) val);
631 #if LONG_MAX <= 2147483647
632 }
633 #endif
634 break;
635
636 case SQLITE_FLOAT:
637 ZVAL_DOUBLE(data, sqlite3_column_double(stmt, column));
638 break;
639
640 case SQLITE_NULL:
641 ZVAL_NULL(data);
642 break;
643
644 case SQLITE3_TEXT:
645 ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column));
646 break;
647
648 case SQLITE_BLOB:
649 default:
650 ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column));
651 }
652 }
653 /* }}} */
654
655 /* {{{ Returns a string of the first column, or an array of the entire row. */
PHP_METHOD(SQLite3,querySingle)656 PHP_METHOD(SQLite3, querySingle)
657 {
658 php_sqlite3_db_object *db_obj;
659 zval *object = ZEND_THIS;
660 zend_string *sql;
661 char *errtext = NULL;
662 int return_code;
663 zend_bool entire_row = 0;
664 sqlite3_stmt *stmt;
665 db_obj = Z_SQLITE3_DB_P(object);
666
667 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &sql, &entire_row)) {
668 RETURN_THROWS();
669 }
670
671 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
672
673 if (!ZSTR_LEN(sql)) {
674 RETURN_FALSE;
675 }
676
677 /* If there was no return value then just execute the query */
678 if (!USED_RET()) {
679 if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
680 php_sqlite3_error(db_obj, "%s", errtext);
681 sqlite3_free(errtext);
682 }
683 return;
684 }
685
686 return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &stmt, NULL);
687 if (return_code != SQLITE_OK) {
688 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
689 RETURN_FALSE;
690 }
691
692 return_code = sqlite3_step(stmt);
693
694 switch (return_code) {
695 case SQLITE_ROW: /* Valid Row */
696 {
697 if (!entire_row) {
698 sqlite_value_to_zval(stmt, 0, return_value);
699 } else {
700 int i = 0;
701 array_init(return_value);
702 for (i = 0; i < sqlite3_data_count(stmt); i++) {
703 zval data;
704 sqlite_value_to_zval(stmt, i, &data);
705 add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), &data);
706 }
707 }
708 break;
709 }
710 case SQLITE_DONE: /* Valid but no results */
711 {
712 if (!entire_row) {
713 RETVAL_NULL();
714 } else {
715 RETVAL_EMPTY_ARRAY();
716 }
717 break;
718 }
719 default:
720 if (!EG(exception)) {
721 php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
722 }
723 RETVAL_FALSE;
724 }
725 sqlite3_finalize(stmt);
726 }
727 /* }}} */
728
sqlite3_do_callback(struct php_sqlite3_fci * fc,zval * cb,int argc,sqlite3_value ** argv,sqlite3_context * context,int is_agg)729 static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg) /* {{{ */
730 {
731 zval *zargs = NULL;
732 zval retval;
733 int i;
734 int ret;
735 int fake_argc;
736 php_sqlite3_agg_context *agg_context = NULL;
737
738 if (is_agg) {
739 is_agg = 2;
740 }
741
742 fake_argc = argc + is_agg;
743
744 fc->fci.size = sizeof(fc->fci);
745 ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
746 fc->fci.object = NULL;
747 fc->fci.retval = &retval;
748 fc->fci.param_count = fake_argc;
749
750 /* build up the params */
751
752 if (fake_argc) {
753 zargs = (zval *)safe_emalloc(fake_argc, sizeof(zval), 0);
754 }
755
756 if (is_agg) {
757 /* summon the aggregation context */
758 agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
759
760 if (Z_ISUNDEF(agg_context->zval_context)) {
761 ZVAL_NULL(&agg_context->zval_context);
762 }
763 ZVAL_COPY(&zargs[0], &agg_context->zval_context);
764 ZVAL_LONG(&zargs[1], agg_context->row_count);
765 }
766
767 for (i = 0; i < argc; i++) {
768 switch (sqlite3_value_type(argv[i])) {
769 case SQLITE_INTEGER:
770 #if ZEND_LONG_MAX > 2147483647
771 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
772 #else
773 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
774 #endif
775 break;
776
777 case SQLITE_FLOAT:
778 ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
779 break;
780
781 case SQLITE_NULL:
782 ZVAL_NULL(&zargs[i + is_agg]);
783 break;
784
785 case SQLITE_BLOB:
786 case SQLITE3_TEXT:
787 default:
788 ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
789 break;
790 }
791 }
792
793 fc->fci.params = zargs;
794
795 if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
796 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
797 }
798
799 if (is_agg) {
800 zval_ptr_dtor(&zargs[0]);
801 }
802
803 /* clean up the params */
804 if (fake_argc) {
805 for (i = is_agg; i < argc + is_agg; i++) {
806 zval_ptr_dtor(&zargs[i]);
807 }
808 if (is_agg) {
809 zval_ptr_dtor(&zargs[1]);
810 }
811 efree(zargs);
812 }
813
814 if (!is_agg || !argv) {
815 /* only set the sqlite return value if we are a scalar function,
816 * or if we are finalizing an aggregate */
817 if (!Z_ISUNDEF(retval)) {
818 switch (Z_TYPE(retval)) {
819 case IS_LONG:
820 #if ZEND_LONG_MAX > 2147483647
821 sqlite3_result_int64(context, Z_LVAL(retval));
822 #else
823 sqlite3_result_int(context, Z_LVAL(retval));
824 #endif
825 break;
826
827 case IS_NULL:
828 sqlite3_result_null(context);
829 break;
830
831 case IS_DOUBLE:
832 sqlite3_result_double(context, Z_DVAL(retval));
833 break;
834
835 default: {
836 zend_string *str = zval_try_get_string(&retval);
837 if (UNEXPECTED(!str)) {
838 ret = FAILURE;
839 break;
840 }
841 sqlite3_result_text(context, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
842 zend_string_release(str);
843 break;
844 }
845 }
846 } else {
847 sqlite3_result_error(context, "failed to invoke callback", 0);
848 }
849
850 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
851 zval_ptr_dtor(&agg_context->zval_context);
852 }
853 } else {
854 /* we're stepping in an aggregate; the return value goes into
855 * the context */
856 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
857 zval_ptr_dtor(&agg_context->zval_context);
858 }
859 ZVAL_COPY_VALUE(&agg_context->zval_context, &retval);
860 ZVAL_UNDEF(&retval);
861 }
862
863 if (!Z_ISUNDEF(retval)) {
864 zval_ptr_dtor(&retval);
865 }
866 return ret;
867 }
868 /* }}}*/
869
php_sqlite3_callback_func(sqlite3_context * context,int argc,sqlite3_value ** argv)870 static void php_sqlite3_callback_func(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
871 {
872 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
873
874 sqlite3_do_callback(&func->afunc, &func->func, argc, argv, context, 0);
875 }
876 /* }}}*/
877
php_sqlite3_callback_step(sqlite3_context * context,int argc,sqlite3_value ** argv)878 static void php_sqlite3_callback_step(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
879 {
880 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
881 php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
882
883 agg_context->row_count++;
884
885 sqlite3_do_callback(&func->astep, &func->step, argc, argv, context, 1);
886 }
887 /* }}} */
888
php_sqlite3_callback_final(sqlite3_context * context)889 static void php_sqlite3_callback_final(sqlite3_context *context) /* {{{ */
890 {
891 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
892 php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
893
894 agg_context->row_count = 0;
895
896 sqlite3_do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
897 }
898 /* }}} */
899
php_sqlite3_callback_compare(void * coll,int a_len,const void * a,int b_len,const void * b)900 static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, int b_len, const void* b) /* {{{ */
901 {
902 php_sqlite3_collation *collation = (php_sqlite3_collation*)coll;
903 zval zargs[2];
904 zval retval;
905 int ret;
906
907 // Exception occurred on previous callback. Don't attempt to call function.
908 if (EG(exception)) {
909 return 0;
910 }
911
912 collation->fci.fci.size = (sizeof(collation->fci.fci));
913 ZVAL_COPY_VALUE(&collation->fci.fci.function_name, &collation->cmp_func);
914 collation->fci.fci.object = NULL;
915 collation->fci.fci.retval = &retval;
916 collation->fci.fci.param_count = 2;
917
918 ZVAL_STRINGL(&zargs[0], a, a_len);
919 ZVAL_STRINGL(&zargs[1], b, b_len);
920
921 collation->fci.fci.params = zargs;
922
923 if ((ret = zend_call_function(&collation->fci.fci, &collation->fci.fcc)) == FAILURE) {
924 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback");
925 }
926
927 zval_ptr_dtor(&zargs[0]);
928 zval_ptr_dtor(&zargs[1]);
929
930 if (EG(exception)) {
931 ret = 0;
932 } else if (Z_TYPE(retval) != IS_LONG){
933 //retval ought to contain a ZVAL_LONG by now
934 // (the result of a comparison, i.e. most likely -1, 0, or 1)
935 //I suppose we could accept any scalar return type, though.
936 php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined.");
937 } else {
938 ret = Z_LVAL(retval);
939 }
940
941 zval_ptr_dtor(&retval);
942
943 return ret;
944 }
945 /* }}} */
946
947 /* {{{ Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements. */
PHP_METHOD(SQLite3,createFunction)948 PHP_METHOD(SQLite3, createFunction)
949 {
950 php_sqlite3_db_object *db_obj;
951 zval *object = ZEND_THIS;
952 php_sqlite3_func *func;
953 char *sql_func;
954 size_t sql_func_len;
955 zend_fcall_info fci;
956 zend_fcall_info_cache fcc;
957 zend_long sql_func_num_args = -1;
958 zend_long flags = 0;
959 db_obj = Z_SQLITE3_DB_P(object);
960
961 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf|ll", &sql_func, &sql_func_len, &fci, &fcc, &sql_func_num_args, &flags) == FAILURE) {
962 RETURN_THROWS();
963 }
964
965 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
966
967 if (!sql_func_len) {
968 RETURN_FALSE;
969 }
970
971 func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
972
973 if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
974 func->func_name = estrdup(sql_func);
975
976 ZVAL_COPY(&func->func, &fci.function_name);
977
978 func->argc = sql_func_num_args;
979 func->next = db_obj->funcs;
980 db_obj->funcs = func;
981
982 RETURN_TRUE;
983 }
984 efree(func);
985
986 RETURN_FALSE;
987 }
988 /* }}} */
989
990 /* {{{ Allows registration of a PHP function for use as an aggregate. */
PHP_METHOD(SQLite3,createAggregate)991 PHP_METHOD(SQLite3, createAggregate)
992 {
993 php_sqlite3_db_object *db_obj;
994 zval *object = ZEND_THIS;
995 php_sqlite3_func *func;
996 char *sql_func;
997 size_t sql_func_len;
998 zend_fcall_info step_fci, fini_fci;
999 zend_fcall_info_cache step_fcc, fini_fcc;
1000 zend_long sql_func_num_args = -1;
1001 db_obj = Z_SQLITE3_DB_P(object);
1002
1003 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sff|l", &sql_func, &sql_func_len, &step_fci, &step_fcc, &fini_fci, &fini_fcc, &sql_func_num_args) == FAILURE) {
1004 RETURN_THROWS();
1005 }
1006
1007 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1008
1009 if (!sql_func_len) {
1010 RETURN_FALSE;
1011 }
1012
1013 func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
1014
1015 if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
1016 func->func_name = estrdup(sql_func);
1017
1018 ZVAL_COPY(&func->step, &step_fci.function_name);
1019 ZVAL_COPY(&func->fini, &fini_fci.function_name);
1020
1021 func->argc = sql_func_num_args;
1022 func->next = db_obj->funcs;
1023 db_obj->funcs = func;
1024
1025 RETURN_TRUE;
1026 }
1027 efree(func);
1028
1029 RETURN_FALSE;
1030 }
1031 /* }}} */
1032
1033 /* {{{ Registers a PHP function as a comparator that can be used with the SQL COLLATE operator. Callback must accept two strings and return an integer (as strcmp()). */
PHP_METHOD(SQLite3,createCollation)1034 PHP_METHOD(SQLite3, createCollation)
1035 {
1036 php_sqlite3_db_object *db_obj;
1037 zval *object = ZEND_THIS;
1038 php_sqlite3_collation *collation;
1039 char *collation_name;
1040 size_t collation_name_len;
1041 zend_fcall_info fci;
1042 zend_fcall_info_cache fcc;
1043 db_obj = Z_SQLITE3_DB_P(object);
1044
1045 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &collation_name, &collation_name_len, &fci, &fcc) == FAILURE) {
1046 RETURN_THROWS();
1047 }
1048
1049 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1050
1051 if (!collation_name_len) {
1052 RETURN_FALSE;
1053 }
1054
1055 collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation));
1056 if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
1057 collation->collation_name = estrdup(collation_name);
1058
1059 ZVAL_COPY(&collation->cmp_func, &fci.function_name);
1060
1061 collation->next = db_obj->collations;
1062 db_obj->collations = collation;
1063
1064 RETURN_TRUE;
1065 }
1066 efree(collation);
1067
1068 RETURN_FALSE;
1069 }
1070 /* }}} */
1071
1072 typedef struct {
1073 sqlite3_blob *blob;
1074 size_t position;
1075 size_t size;
1076 int flags;
1077 } php_stream_sqlite3_data;
1078
php_sqlite3_stream_write(php_stream * stream,const char * buf,size_t count)1079 static ssize_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
1080 {
1081 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1082
1083 if (sqlite3_stream->flags & SQLITE_OPEN_READONLY) {
1084 php_error_docref(NULL, E_WARNING, "Can't write to blob stream: is open as read only");
1085 return -1;
1086 }
1087
1088 if (sqlite3_stream->position + count > sqlite3_stream->size) {
1089 php_error_docref(NULL, E_WARNING, "It is not possible to increase the size of a BLOB");
1090 return -1;
1091 }
1092
1093 if (sqlite3_blob_write(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
1094 return -1;
1095 }
1096
1097 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
1098 stream->eof = 1;
1099 sqlite3_stream->position = sqlite3_stream->size;
1100 }
1101 else {
1102 sqlite3_stream->position += count;
1103 }
1104
1105 return count;
1106 }
1107
php_sqlite3_stream_read(php_stream * stream,char * buf,size_t count)1108 static ssize_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count)
1109 {
1110 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1111
1112 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
1113 count = sqlite3_stream->size - sqlite3_stream->position;
1114 stream->eof = 1;
1115 }
1116 if (count) {
1117 if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
1118 return -1;
1119 }
1120 sqlite3_stream->position += count;
1121 }
1122 return count;
1123 }
1124
php_sqlite3_stream_close(php_stream * stream,int close_handle)1125 static int php_sqlite3_stream_close(php_stream *stream, int close_handle)
1126 {
1127 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1128
1129 if (sqlite3_blob_close(sqlite3_stream->blob) != SQLITE_OK) {
1130 /* Error occurred, but it still closed */
1131 }
1132
1133 efree(sqlite3_stream);
1134
1135 return 0;
1136 }
1137
php_sqlite3_stream_flush(php_stream * stream)1138 static int php_sqlite3_stream_flush(php_stream *stream)
1139 {
1140 /* do nothing */
1141 return 0;
1142 }
1143
1144 /* {{{ */
php_sqlite3_stream_seek(php_stream * stream,zend_off_t offset,int whence,zend_off_t * newoffs)1145 static int php_sqlite3_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs)
1146 {
1147 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1148
1149 switch(whence) {
1150 case SEEK_CUR:
1151 if (offset < 0) {
1152 if (sqlite3_stream->position < (size_t)(-offset)) {
1153 sqlite3_stream->position = 0;
1154 *newoffs = -1;
1155 return -1;
1156 } else {
1157 sqlite3_stream->position = sqlite3_stream->position + offset;
1158 *newoffs = sqlite3_stream->position;
1159 stream->eof = 0;
1160 return 0;
1161 }
1162 } else {
1163 if (sqlite3_stream->position + (size_t)(offset) > sqlite3_stream->size) {
1164 sqlite3_stream->position = sqlite3_stream->size;
1165 *newoffs = -1;
1166 return -1;
1167 } else {
1168 sqlite3_stream->position = sqlite3_stream->position + offset;
1169 *newoffs = sqlite3_stream->position;
1170 stream->eof = 0;
1171 return 0;
1172 }
1173 }
1174 case SEEK_SET:
1175 if (sqlite3_stream->size < (size_t)(offset)) {
1176 sqlite3_stream->position = sqlite3_stream->size;
1177 *newoffs = -1;
1178 return -1;
1179 } else {
1180 sqlite3_stream->position = offset;
1181 *newoffs = sqlite3_stream->position;
1182 stream->eof = 0;
1183 return 0;
1184 }
1185 case SEEK_END:
1186 if (offset > 0) {
1187 sqlite3_stream->position = sqlite3_stream->size;
1188 *newoffs = -1;
1189 return -1;
1190 } else if (sqlite3_stream->size < (size_t)(-offset)) {
1191 sqlite3_stream->position = 0;
1192 *newoffs = -1;
1193 return -1;
1194 } else {
1195 sqlite3_stream->position = sqlite3_stream->size + offset;
1196 *newoffs = sqlite3_stream->position;
1197 stream->eof = 0;
1198 return 0;
1199 }
1200 default:
1201 *newoffs = sqlite3_stream->position;
1202 return -1;
1203 }
1204 }
1205 /* }}} */
1206
1207
php_sqlite3_stream_cast(php_stream * stream,int castas,void ** ret)1208 static int php_sqlite3_stream_cast(php_stream *stream, int castas, void **ret)
1209 {
1210 return FAILURE;
1211 }
1212
php_sqlite3_stream_stat(php_stream * stream,php_stream_statbuf * ssb)1213 static int php_sqlite3_stream_stat(php_stream *stream, php_stream_statbuf *ssb)
1214 {
1215 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1216 ssb->sb.st_size = sqlite3_stream->size;
1217 return 0;
1218 }
1219
1220 static const php_stream_ops php_stream_sqlite3_ops = {
1221 php_sqlite3_stream_write,
1222 php_sqlite3_stream_read,
1223 php_sqlite3_stream_close,
1224 php_sqlite3_stream_flush,
1225 "SQLite3",
1226 php_sqlite3_stream_seek,
1227 php_sqlite3_stream_cast,
1228 php_sqlite3_stream_stat,
1229 NULL
1230 };
1231
1232 /* {{{ Open a blob as a stream which we can read / write to. */
PHP_METHOD(SQLite3,openBlob)1233 PHP_METHOD(SQLite3, openBlob)
1234 {
1235 php_sqlite3_db_object *db_obj;
1236 zval *object = ZEND_THIS;
1237 char *table, *column, *dbname = "main", *mode = "rb";
1238 size_t table_len, column_len, dbname_len;
1239 zend_long rowid, flags = SQLITE_OPEN_READONLY, sqlite_flags = 0;
1240 sqlite3_blob *blob = NULL;
1241 php_stream_sqlite3_data *sqlite3_stream;
1242 php_stream *stream;
1243
1244 db_obj = Z_SQLITE3_DB_P(object);
1245
1246 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl|pl", &table, &table_len, &column, &column_len, &rowid, &dbname, &dbname_len, &flags) == FAILURE) {
1247 RETURN_THROWS();
1248 }
1249
1250 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1251
1252 sqlite_flags = (flags & SQLITE_OPEN_READWRITE) ? 1 : 0;
1253
1254 if (sqlite3_blob_open(db_obj->db, dbname, table, column, rowid, sqlite_flags, &blob) != SQLITE_OK) {
1255 php_sqlite3_error(db_obj, "Unable to open blob: %s", sqlite3_errmsg(db_obj->db));
1256 RETURN_FALSE;
1257 }
1258
1259 sqlite3_stream = emalloc(sizeof(php_stream_sqlite3_data));
1260 sqlite3_stream->blob = blob;
1261 sqlite3_stream->flags = flags;
1262 sqlite3_stream->position = 0;
1263 sqlite3_stream->size = sqlite3_blob_bytes(blob);
1264
1265 if (sqlite_flags != 0) {
1266 mode = "r+b";
1267 }
1268
1269 stream = php_stream_alloc(&php_stream_sqlite3_ops, sqlite3_stream, 0, mode);
1270
1271 if (stream) {
1272 php_stream_to_zval(stream, return_value);
1273 } else {
1274 RETURN_FALSE;
1275 }
1276 }
1277 /* }}} */
1278
1279 /* {{{ Enables an exception error mode. */
PHP_METHOD(SQLite3,enableExceptions)1280 PHP_METHOD(SQLite3, enableExceptions)
1281 {
1282 php_sqlite3_db_object *db_obj;
1283 zval *object = ZEND_THIS;
1284 zend_bool enableExceptions = 0;
1285
1286 db_obj = Z_SQLITE3_DB_P(object);
1287
1288 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enableExceptions) == FAILURE) {
1289 RETURN_THROWS();
1290 }
1291
1292 RETVAL_BOOL(db_obj->exception);
1293
1294 db_obj->exception = enableExceptions;
1295 }
1296 /* }}} */
1297
1298 /* {{{ Register a callback function to be used as an authorizer by SQLite. The callback should return SQLite3::OK, SQLite3::IGNORE or SQLite3::DENY. */
PHP_METHOD(SQLite3,setAuthorizer)1299 PHP_METHOD(SQLite3, setAuthorizer)
1300 {
1301 php_sqlite3_db_object *db_obj;
1302 zval *object = ZEND_THIS;
1303 db_obj = Z_SQLITE3_DB_P(object);
1304 zend_fcall_info fci;
1305 zend_fcall_info_cache fcc;
1306
1307 ZEND_PARSE_PARAMETERS_START(1, 1)
1308 Z_PARAM_FUNC_OR_NULL(fci, fcc)
1309 ZEND_PARSE_PARAMETERS_END();
1310
1311 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1312
1313 /* Clear previously set callback */
1314 if (ZEND_FCI_INITIALIZED(db_obj->authorizer_fci)) {
1315 zval_ptr_dtor(&db_obj->authorizer_fci.function_name);
1316 db_obj->authorizer_fci.size = 0;
1317 }
1318
1319 /* Only enable userland authorizer if argument is not NULL */
1320 if (ZEND_FCI_INITIALIZED(fci)) {
1321 db_obj->authorizer_fci = fci;
1322 Z_ADDREF(db_obj->authorizer_fci.function_name);
1323 db_obj->authorizer_fcc = fcc;
1324 }
1325
1326 RETURN_TRUE;
1327 }
1328 /* }}} */
1329
1330
1331 #if SQLITE_VERSION_NUMBER >= 3006011
1332 /* {{{ Backups the current database to another one. */
PHP_METHOD(SQLite3,backup)1333 PHP_METHOD(SQLite3, backup)
1334 {
1335 php_sqlite3_db_object *source_obj;
1336 php_sqlite3_db_object *destination_obj;
1337 char *source_dbname = "main", *destination_dbname = "main";
1338 size_t source_dbname_length, destination_dbname_length;
1339 zval *source_zval = ZEND_THIS;
1340 zval *destination_zval;
1341 sqlite3_backup *dbBackup;
1342 int rc; // Return code
1343
1344 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|pp", &destination_zval, php_sqlite3_sc_entry, &source_dbname, &source_dbname_length, &destination_dbname, &destination_dbname_length) == FAILURE) {
1345 RETURN_THROWS();
1346 }
1347
1348 source_obj = Z_SQLITE3_DB_P(source_zval);
1349 SQLITE3_CHECK_INITIALIZED(source_obj, source_obj->initialised, SQLite3)
1350
1351 destination_obj = Z_SQLITE3_DB_P(destination_zval);
1352
1353 SQLITE3_CHECK_INITIALIZED(destination_obj, destination_obj->initialised, SQLite3)
1354
1355 dbBackup = sqlite3_backup_init(destination_obj->db, destination_dbname, source_obj->db, source_dbname);
1356
1357 if (dbBackup) {
1358 do {
1359 rc = sqlite3_backup_step(dbBackup, -1);
1360 } while (rc == SQLITE_OK);
1361
1362 /* Release resources allocated by backup_init(). */
1363 rc = sqlite3_backup_finish(dbBackup);
1364 }
1365 else {
1366 rc = sqlite3_errcode(source_obj->db);
1367 }
1368
1369 if (rc != SQLITE_OK) {
1370 if (rc == SQLITE_BUSY) {
1371 php_sqlite3_error(source_obj, "Backup failed: source database is busy");
1372 }
1373 else if (rc == SQLITE_LOCKED) {
1374 php_sqlite3_error(source_obj, "Backup failed: source database is locked");
1375 }
1376 else {
1377 php_sqlite3_error(source_obj, "Backup failed: %d, %s", rc, sqlite3_errmsg(source_obj->db));
1378 }
1379 RETURN_FALSE;
1380 }
1381
1382 RETURN_TRUE;
1383 }
1384 /* }}} */
1385 #endif
1386
1387 /* {{{ Returns the number of parameters within the prepared statement. */
PHP_METHOD(SQLite3Stmt,paramCount)1388 PHP_METHOD(SQLite3Stmt, paramCount)
1389 {
1390 php_sqlite3_stmt *stmt_obj;
1391 zval *object = ZEND_THIS;
1392 stmt_obj = Z_SQLITE3_STMT_P(object);
1393
1394 if (zend_parse_parameters_none() == FAILURE) {
1395 RETURN_THROWS();
1396 }
1397
1398 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1399 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1400
1401 RETURN_LONG(sqlite3_bind_parameter_count(stmt_obj->stmt));
1402 }
1403 /* }}} */
1404
1405 /* {{{ Closes the prepared statement. */
PHP_METHOD(SQLite3Stmt,close)1406 PHP_METHOD(SQLite3Stmt, close)
1407 {
1408 php_sqlite3_stmt *stmt_obj;
1409 zval *object = ZEND_THIS;
1410 stmt_obj = Z_SQLITE3_STMT_P(object);
1411
1412 if (zend_parse_parameters_none() == FAILURE) {
1413 RETURN_THROWS();
1414 }
1415
1416 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1417
1418 if(stmt_obj->db_obj) {
1419 zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
1420 }
1421
1422 RETURN_TRUE;
1423 }
1424 /* }}} */
1425
1426 /* {{{ Reset the prepared statement to the state before it was executed, bindings still remain. */
PHP_METHOD(SQLite3Stmt,reset)1427 PHP_METHOD(SQLite3Stmt, reset)
1428 {
1429 php_sqlite3_stmt *stmt_obj;
1430 zval *object = ZEND_THIS;
1431 stmt_obj = Z_SQLITE3_STMT_P(object);
1432
1433 if (zend_parse_parameters_none() == FAILURE) {
1434 RETURN_THROWS();
1435 }
1436
1437 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1438 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1439
1440 if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) {
1441 php_sqlite3_error(stmt_obj->db_obj, "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1442 RETURN_FALSE;
1443 }
1444 RETURN_TRUE;
1445 }
1446 /* }}} */
1447
1448 /* {{{ Clear all current bound parameters. */
PHP_METHOD(SQLite3Stmt,clear)1449 PHP_METHOD(SQLite3Stmt, clear)
1450 {
1451 php_sqlite3_stmt *stmt_obj;
1452 zval *object = ZEND_THIS;
1453 stmt_obj = Z_SQLITE3_STMT_P(object);
1454
1455 if (zend_parse_parameters_none() == FAILURE) {
1456 RETURN_THROWS();
1457 }
1458
1459 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1460 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1461
1462 if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) {
1463 php_sqlite3_error(stmt_obj->db_obj, "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1464 RETURN_FALSE;
1465 }
1466
1467 if (stmt_obj->bound_params) {
1468 zend_hash_destroy(stmt_obj->bound_params);
1469 FREE_HASHTABLE(stmt_obj->bound_params);
1470 stmt_obj->bound_params = NULL;
1471 }
1472
1473 RETURN_TRUE;
1474 }
1475 /* }}} */
1476
1477 /* {{{ Returns true if a statement is definitely read only */
PHP_METHOD(SQLite3Stmt,readOnly)1478 PHP_METHOD(SQLite3Stmt, readOnly)
1479 {
1480 php_sqlite3_stmt *stmt_obj;
1481 zval *object = ZEND_THIS;
1482 stmt_obj = Z_SQLITE3_STMT_P(object);
1483
1484 if (zend_parse_parameters_none() == FAILURE) {
1485 RETURN_THROWS();
1486 }
1487
1488 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1489 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1490
1491 if (sqlite3_stmt_readonly(stmt_obj->stmt)) {
1492 RETURN_TRUE;
1493 }
1494 RETURN_FALSE;
1495 }
1496 /* }}} */
1497
1498 /* bind parameters to a statement before execution */
php_sqlite3_bind_params(php_sqlite3_stmt * stmt_obj)1499 static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
1500 {
1501 struct php_sqlite3_bound_param *param;
1502 int return_code;
1503
1504 if (stmt_obj->bound_params) {
1505 ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
1506 zval *parameter;
1507 /* parameter must be a reference? */
1508 if (Z_ISREF(param->parameter)) {
1509 parameter = Z_REFVAL(param->parameter);
1510 } else {
1511 parameter = ¶m->parameter;
1512 }
1513
1514 /* If the ZVAL is null then it should be bound as that */
1515 if (Z_TYPE_P(parameter) == IS_NULL) {
1516 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1517 if (return_code != SQLITE_OK) {
1518 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1519 }
1520 continue;
1521 }
1522
1523 switch (param->type) {
1524 case SQLITE_INTEGER:
1525 convert_to_long(parameter);
1526 #if ZEND_LONG_MAX > 2147483647
1527 return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1528 #else
1529 return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1530 #endif
1531 if (return_code != SQLITE_OK) {
1532 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1533 }
1534 break;
1535
1536 case SQLITE_FLOAT:
1537 convert_to_double(parameter);
1538 return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter));
1539 if (return_code != SQLITE_OK) {
1540 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1541 }
1542 break;
1543
1544 case SQLITE_BLOB:
1545 {
1546 php_stream *stream = NULL;
1547 zend_string *buffer = NULL;
1548 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
1549 php_stream_from_zval_no_verify(stream, parameter);
1550 if (stream == NULL) {
1551 php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number);
1552 return FAILURE;
1553 }
1554 buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
1555 } else {
1556 buffer = zval_get_string(parameter);
1557 }
1558
1559 if (buffer) {
1560 return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT);
1561 zend_string_release_ex(buffer, 0);
1562 if (return_code != SQLITE_OK) {
1563 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1564 }
1565 } else {
1566 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1567 if (return_code != SQLITE_OK) {
1568 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1569 }
1570 }
1571 break;
1572 }
1573
1574 case SQLITE3_TEXT: {
1575 zend_string *str = zval_try_get_string(parameter);
1576 if (UNEXPECTED(!str)) {
1577 return FAILURE;
1578 }
1579 return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
1580 if (return_code != SQLITE_OK) {
1581 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1582 }
1583 zend_string_release(str);
1584 break;
1585 }
1586
1587 case SQLITE_NULL:
1588 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1589 if (return_code != SQLITE_OK) {
1590 php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
1591 }
1592 break;
1593
1594 default:
1595 php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
1596 return FAILURE;
1597 }
1598 } ZEND_HASH_FOREACH_END();
1599 }
1600
1601 return SUCCESS;
1602 }
1603 /* }}} */
1604
1605
1606 /* {{{ Returns the SQL statement used to prepare the query. If expanded is true, binded parameters and values will be expanded. */
PHP_METHOD(SQLite3Stmt,getSQL)1607 PHP_METHOD(SQLite3Stmt, getSQL)
1608 {
1609 php_sqlite3_stmt *stmt_obj;
1610 zend_bool expanded = 0;
1611 zval *object = getThis();
1612 stmt_obj = Z_SQLITE3_STMT_P(object);
1613 int bind_rc;
1614
1615 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &expanded) == FAILURE) {
1616 RETURN_THROWS();
1617 }
1618
1619 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1620 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1621
1622 bind_rc = php_sqlite3_bind_params(stmt_obj);
1623
1624 if (bind_rc == FAILURE || EG(exception)) {
1625 RETURN_FALSE;
1626 }
1627
1628 if (expanded) {
1629 #ifdef HAVE_SQLITE3_EXPANDED_SQL
1630 char *sql = sqlite3_expanded_sql(stmt_obj->stmt);
1631 RETVAL_STRING(sql);
1632 sqlite3_free(sql);
1633 #else
1634 php_sqlite3_error(stmt_obj->db_obj, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
1635 RETURN_FALSE;
1636 #endif
1637 } else {
1638 const char *sql = sqlite3_sql(stmt_obj->stmt);
1639 RETVAL_STRING(sql);
1640 }
1641 }
1642 /* }}} */
1643
1644
register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param * param,php_sqlite3_stmt * stmt)1645 static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
1646 {
1647 HashTable *hash;
1648 hash = stmt->bound_params;
1649
1650 if (!hash) {
1651 ALLOC_HASHTABLE(hash);
1652 zend_hash_init(hash, 13, NULL, sqlite3_param_dtor, 0);
1653 stmt->bound_params = hash;
1654 }
1655
1656 /* We need a : prefix to resolve a name to a parameter number */
1657 if (param->name) {
1658 if (ZSTR_VAL(param->name)[0] != ':' && ZSTR_VAL(param->name)[0] != '@') {
1659 /* pre-increment for character + 1 for null */
1660 zend_string *temp = zend_string_alloc(ZSTR_LEN(param->name) + 1, 0);
1661 ZSTR_VAL(temp)[0] = ':';
1662 memmove(ZSTR_VAL(temp) + 1, ZSTR_VAL(param->name), ZSTR_LEN(param->name) + 1);
1663 param->name = temp;
1664 } else {
1665 param->name = zend_string_copy(param->name);
1666 }
1667 /* do lookup*/
1668 param->param_number = sqlite3_bind_parameter_index(stmt->stmt, ZSTR_VAL(param->name));
1669 }
1670
1671 if (param->param_number < 1) {
1672 if (param->name) {
1673 zend_string_release_ex(param->name, 0);
1674 }
1675 return 0;
1676 }
1677
1678 if (param->param_number >= 1) {
1679 zend_hash_index_del(hash, param->param_number);
1680 }
1681
1682 if (param->name) {
1683 zend_hash_update_mem(hash, param->name, param, sizeof(struct php_sqlite3_bound_param));
1684 } else {
1685 zend_hash_index_update_mem(hash, param->param_number, param, sizeof(struct php_sqlite3_bound_param));
1686 }
1687
1688 return 1;
1689 }
1690 /* }}} */
1691
1692 /* {{{ Best try to map between PHP and SQLite. Default is still text. */
1693 #define PHP_SQLITE3_SET_TYPE(z, p) \
1694 switch (Z_TYPE_P(z)) { \
1695 default: \
1696 (p).type = SQLITE_TEXT; \
1697 break; \
1698 case IS_LONG: \
1699 case IS_TRUE: \
1700 case IS_FALSE: \
1701 (p).type = SQLITE_INTEGER; \
1702 break; \
1703 case IS_DOUBLE: \
1704 (p).type = SQLITE_FLOAT; \
1705 break; \
1706 case IS_NULL: \
1707 (p).type = SQLITE_NULL; \
1708 break; \
1709 }
1710 /* }}} */
1711
1712 /* {{{ Common implementation of ::bindParam() and ::bindValue */
sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)1713 static void sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)
1714 {
1715 php_sqlite3_stmt *stmt_obj;
1716 zval *object = ZEND_THIS;
1717 struct php_sqlite3_bound_param param = {0};
1718 zval *parameter;
1719 stmt_obj = Z_SQLITE3_STMT_P(object);
1720
1721 param.param_number = -1;
1722 param.type = SQLITE3_TEXT;
1723
1724 ZEND_PARSE_PARAMETERS_START(2, 3)
1725 Z_PARAM_STR_OR_LONG(param.name, param.param_number)
1726 Z_PARAM_ZVAL(parameter)
1727 Z_PARAM_OPTIONAL
1728 Z_PARAM_LONG(param.type)
1729 ZEND_PARSE_PARAMETERS_END();
1730
1731 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1732 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1733
1734 ZVAL_COPY(¶m.parameter, parameter);
1735
1736 if (ZEND_NUM_ARGS() < 3) {
1737 PHP_SQLITE3_SET_TYPE(parameter, param);
1738 }
1739
1740 if (!register_bound_parameter_to_sqlite(¶m, stmt_obj)) {
1741 if (!Z_ISUNDEF(param.parameter)) {
1742 zval_ptr_dtor(&(param.parameter));
1743 ZVAL_UNDEF(¶m.parameter);
1744 }
1745 RETURN_FALSE;
1746 }
1747 RETURN_TRUE;
1748 }
1749 /* }}} */
1750
1751 /* {{{ Bind Parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindParam)1752 PHP_METHOD(SQLite3Stmt, bindParam)
1753 {
1754 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1755 }
1756 /* }}} */
1757
1758 /* {{{ Bind Value of a parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindValue)1759 PHP_METHOD(SQLite3Stmt, bindValue)
1760 {
1761 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1762 }
1763 /* }}} */
1764
1765 #undef PHP_SQLITE3_SET_TYPE
1766
1767 /* {{{ Executes a prepared statement and returns a result set object. */
PHP_METHOD(SQLite3Stmt,execute)1768 PHP_METHOD(SQLite3Stmt, execute)
1769 {
1770 php_sqlite3_stmt *stmt_obj;
1771 php_sqlite3_result *result;
1772 zval *object = ZEND_THIS;
1773 int return_code = 0;
1774 int bind_rc = 0;
1775
1776 stmt_obj = Z_SQLITE3_STMT_P(object);
1777
1778 if (zend_parse_parameters_none() == FAILURE) {
1779 RETURN_THROWS();
1780 }
1781
1782 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1783
1784 /* Always reset statement before execution, see bug #77051 */
1785 sqlite3_reset(stmt_obj->stmt);
1786
1787 /* Bind parameters to the statement */
1788 bind_rc = php_sqlite3_bind_params(stmt_obj);
1789
1790 if (bind_rc == FAILURE || EG(exception)) {
1791 RETURN_FALSE;
1792 }
1793
1794 return_code = sqlite3_step(stmt_obj->stmt);
1795
1796 switch (return_code) {
1797 case SQLITE_ROW: /* Valid Row */
1798 case SQLITE_DONE: /* Valid but no results */
1799 {
1800 sqlite3_reset(stmt_obj->stmt);
1801 object_init_ex(return_value, php_sqlite3_result_entry);
1802 result = Z_SQLITE3_RESULT_P(return_value);
1803
1804 result->is_prepared_statement = 1;
1805 result->db_obj = stmt_obj->db_obj;
1806 result->stmt_obj = stmt_obj;
1807 ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object));
1808
1809 break;
1810 }
1811 case SQLITE_ERROR:
1812 sqlite3_reset(stmt_obj->stmt);
1813
1814 default:
1815 if (!EG(exception)) {
1816 php_sqlite3_error(stmt_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1817 }
1818 zval_ptr_dtor(return_value);
1819 RETURN_FALSE;
1820 }
1821
1822 return;
1823 }
1824 /* }}} */
1825
1826 /* {{{ __constructor for SQLite3Stmt. */
PHP_METHOD(SQLite3Stmt,__construct)1827 PHP_METHOD(SQLite3Stmt, __construct)
1828 {
1829 php_sqlite3_stmt *stmt_obj;
1830 php_sqlite3_db_object *db_obj;
1831 zval *object = ZEND_THIS;
1832 zval *db_zval;
1833 zend_string *sql;
1834 int errcode;
1835 zend_error_handling error_handling;
1836 php_sqlite3_free_list *free_item;
1837
1838 stmt_obj = Z_SQLITE3_STMT_P(object);
1839
1840 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &db_zval, php_sqlite3_sc_entry, &sql) == FAILURE) {
1841 RETURN_THROWS();
1842 }
1843
1844 db_obj = Z_SQLITE3_DB_P(db_zval);
1845
1846 zend_replace_error_handling(EH_THROW, NULL, &error_handling);
1847 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1848 zend_restore_error_handling(&error_handling);
1849
1850 if (!ZSTR_LEN(sql)) {
1851 RETURN_FALSE;
1852 }
1853
1854 stmt_obj->db_obj = db_obj;
1855 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval));
1856
1857 errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
1858 if (errcode != SQLITE_OK) {
1859 php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
1860 zval_ptr_dtor(return_value);
1861 RETURN_FALSE;
1862 }
1863 stmt_obj->initialised = 1;
1864
1865 free_item = emalloc(sizeof(php_sqlite3_free_list));
1866 free_item->stmt_obj = stmt_obj;
1867 //?? free_item->stmt_obj_zval = ZEND_THIS;
1868 ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(object));
1869
1870 zend_llist_add_element(&(db_obj->free_list), &free_item);
1871 }
1872 /* }}} */
1873
1874 /* {{{ Number of columns in the result set. */
PHP_METHOD(SQLite3Result,numColumns)1875 PHP_METHOD(SQLite3Result, numColumns)
1876 {
1877 php_sqlite3_result *result_obj;
1878 zval *object = ZEND_THIS;
1879 result_obj = Z_SQLITE3_RESULT_P(object);
1880
1881 if (zend_parse_parameters_none() == FAILURE) {
1882 RETURN_THROWS();
1883 }
1884
1885 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1886
1887 RETURN_LONG(sqlite3_column_count(result_obj->stmt_obj->stmt));
1888 }
1889 /* }}} */
1890
1891 /* {{{ Returns the name of the nth column. */
PHP_METHOD(SQLite3Result,columnName)1892 PHP_METHOD(SQLite3Result, columnName)
1893 {
1894 php_sqlite3_result *result_obj;
1895 zval *object = ZEND_THIS;
1896 zend_long column = 0;
1897 char *column_name;
1898 result_obj = Z_SQLITE3_RESULT_P(object);
1899
1900 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &column) == FAILURE) {
1901 RETURN_THROWS();
1902 }
1903
1904 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1905
1906 column_name = (char*) sqlite3_column_name(result_obj->stmt_obj->stmt, column);
1907
1908 if (column_name == NULL) {
1909 RETURN_FALSE;
1910 }
1911
1912 RETVAL_STRING(column_name);
1913 }
1914 /* }}} */
1915
1916 /* {{{ Returns the type of the nth column. */
PHP_METHOD(SQLite3Result,columnType)1917 PHP_METHOD(SQLite3Result, columnType)
1918 {
1919 php_sqlite3_result *result_obj;
1920 zval *object = ZEND_THIS;
1921 zend_long column = 0;
1922 result_obj = Z_SQLITE3_RESULT_P(object);
1923
1924 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &column) == FAILURE) {
1925 RETURN_THROWS();
1926 }
1927
1928 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1929
1930 if (!sqlite3_data_count(result_obj->stmt_obj->stmt)) {
1931 RETURN_FALSE;
1932 }
1933
1934 RETURN_LONG(sqlite3_column_type(result_obj->stmt_obj->stmt, column));
1935 }
1936 /* }}} */
1937
1938 /* {{{ Fetch a result row as both an associative or numerically indexed array or both. */
PHP_METHOD(SQLite3Result,fetchArray)1939 PHP_METHOD(SQLite3Result, fetchArray)
1940 {
1941 php_sqlite3_result *result_obj;
1942 zval *object = ZEND_THIS;
1943 int i, ret;
1944 zend_long mode = PHP_SQLITE3_BOTH;
1945 result_obj = Z_SQLITE3_RESULT_P(object);
1946
1947 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &mode) == FAILURE) {
1948 RETURN_THROWS();
1949 }
1950
1951 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1952
1953 ret = sqlite3_step(result_obj->stmt_obj->stmt);
1954 switch (ret) {
1955 case SQLITE_ROW:
1956 /* If there was no return value then just skip fetching */
1957 if (!USED_RET()) {
1958 return;
1959 }
1960
1961 array_init(return_value);
1962
1963 for (i = 0; i < sqlite3_data_count(result_obj->stmt_obj->stmt); i++) {
1964 zval data;
1965
1966 sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
1967
1968 if (mode & PHP_SQLITE3_NUM) {
1969 add_index_zval(return_value, i, &data);
1970 }
1971
1972 if (mode & PHP_SQLITE3_ASSOC) {
1973 if (mode & PHP_SQLITE3_NUM) {
1974 if (Z_REFCOUNTED(data)) {
1975 Z_ADDREF(data);
1976 }
1977 }
1978 add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), &data);
1979 }
1980 }
1981 break;
1982
1983 case SQLITE_DONE:
1984 RETURN_FALSE;
1985 break;
1986
1987 default:
1988 php_sqlite3_error(result_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt)));
1989 }
1990 }
1991 /* }}} */
1992
1993 /* {{{ Resets the result set back to the first row. */
PHP_METHOD(SQLite3Result,reset)1994 PHP_METHOD(SQLite3Result, reset)
1995 {
1996 php_sqlite3_result *result_obj;
1997 zval *object = ZEND_THIS;
1998 result_obj = Z_SQLITE3_RESULT_P(object);
1999
2000 if (zend_parse_parameters_none() == FAILURE) {
2001 RETURN_THROWS();
2002 }
2003
2004 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2005
2006 if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) {
2007 RETURN_FALSE;
2008 }
2009
2010 RETURN_TRUE;
2011 }
2012 /* }}} */
2013
2014 /* {{{ Closes the result set. */
PHP_METHOD(SQLite3Result,finalize)2015 PHP_METHOD(SQLite3Result, finalize)
2016 {
2017 php_sqlite3_result *result_obj;
2018 zval *object = ZEND_THIS;
2019 result_obj = Z_SQLITE3_RESULT_P(object);
2020
2021 if (zend_parse_parameters_none() == FAILURE) {
2022 RETURN_THROWS();
2023 }
2024
2025 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2026
2027 /* We need to finalize an internal statement */
2028 if (result_obj->is_prepared_statement == 0) {
2029 zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
2030 (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
2031 } else {
2032 sqlite3_reset(result_obj->stmt_obj->stmt);
2033 }
2034
2035 RETURN_TRUE;
2036 }
2037 /* }}} */
2038
2039 /* {{{ __constructor for SQLite3Result. */
PHP_METHOD(SQLite3Result,__construct)2040 PHP_METHOD(SQLite3Result, __construct)
2041 {
2042 zend_throw_exception(zend_ce_exception, "SQLite3Result cannot be directly instantiated", 0);
2043 }
2044 /* }}} */
2045
2046 /* {{{ Authorization Callback */
php_sqlite3_authorizer(void * autharg,int action,const char * arg1,const char * arg2,const char * arg3,const char * arg4)2047 static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4)
2048 {
2049 /* Check open_basedir restrictions first */
2050 if (PG(open_basedir) && *PG(open_basedir)) {
2051 if (action == SQLITE_ATTACH) {
2052 if (!arg1) {
2053 return SQLITE_DENY;
2054 }
2055 if (memcmp(arg1, ":memory:", sizeof(":memory:")) && *arg1) {
2056 if (strncmp(arg1, "file:", 5) == 0) {
2057 /* starts with "file:" */
2058 if (!arg1[5]) {
2059 return SQLITE_DENY;
2060 }
2061 if (php_check_open_basedir(arg1 + 5)) {
2062 return SQLITE_DENY;
2063 }
2064 }
2065 if (php_check_open_basedir(arg1)) {
2066 return SQLITE_DENY;
2067 }
2068 }
2069 }
2070 }
2071
2072 php_sqlite3_db_object *db_obj = (php_sqlite3_db_object *)autharg;
2073 zend_fcall_info *fci = &db_obj->authorizer_fci;
2074
2075 /* fallback to access allowed if authorizer callback is not defined */
2076 if (fci->size == 0) {
2077 return SQLITE_OK;
2078 }
2079
2080 /* call userland authorizer callback, if set */
2081 zval retval;
2082 zval argv[5];
2083
2084 ZVAL_LONG(&argv[0], action);
2085
2086 if (NULL == arg1) {
2087 ZVAL_NULL(&argv[1]);
2088 } else {
2089 ZVAL_STRING(&argv[1], arg1);
2090 }
2091
2092 if (NULL == arg2) {
2093 ZVAL_NULL(&argv[2]);
2094 } else {
2095 ZVAL_STRING(&argv[2], arg2);
2096 }
2097
2098 if (NULL == arg3) {
2099 ZVAL_NULL(&argv[3]);
2100 } else {
2101 ZVAL_STRING(&argv[3], arg3);
2102 }
2103
2104 if (NULL == arg4) {
2105 ZVAL_NULL(&argv[4]);
2106 } else {
2107 ZVAL_STRING(&argv[4], arg4);
2108 }
2109
2110 fci->retval = &retval;
2111 fci->param_count = 5;
2112 fci->params = argv;
2113
2114 int authreturn = SQLITE_DENY;
2115
2116 if (zend_call_function(fci, &db_obj->authorizer_fcc) != SUCCESS || Z_ISUNDEF(retval)) {
2117 php_sqlite3_error(db_obj, "An error occurred while invoking the authorizer callback");
2118 } else {
2119 if (Z_TYPE(retval) != IS_LONG) {
2120 php_sqlite3_error(db_obj, "The authorizer callback returned an invalid type: expected int");
2121 } else {
2122 authreturn = Z_LVAL(retval);
2123
2124 if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY) {
2125 php_sqlite3_error(db_obj, "The authorizer callback returned an invalid value");
2126 authreturn = SQLITE_DENY;
2127 }
2128 }
2129 }
2130
2131 zend_fcall_info_args_clear(fci, 0);
2132 zval_ptr_dtor(&retval);
2133
2134 return authreturn;
2135 }
2136 /* }}} */
2137
2138 /* {{{ php_sqlite3_free_list_dtor */
php_sqlite3_free_list_dtor(void ** item)2139 static void php_sqlite3_free_list_dtor(void **item)
2140 {
2141 php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item;
2142
2143 if (free_item->stmt_obj && free_item->stmt_obj->initialised) {
2144 sqlite3_finalize(free_item->stmt_obj->stmt);
2145 free_item->stmt_obj->initialised = 0;
2146 }
2147 efree(*item);
2148 }
2149 /* }}} */
2150
php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list ** free_list,zval * statement)2151 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
2152 {
2153 return ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));
2154 }
2155 /* }}} */
2156
php_sqlite3_compare_stmt_free(php_sqlite3_free_list ** free_list,sqlite3_stmt * statement)2157 static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */
2158 {
2159 return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);
2160 }
2161 /* }}} */
2162
php_sqlite3_object_free_storage(zend_object * object)2163 static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
2164 {
2165 php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
2166 php_sqlite3_func *func;
2167 php_sqlite3_collation *collation;
2168
2169 if (!intern) {
2170 return;
2171 }
2172
2173 /* Release function_name from authorizer */
2174 if (intern->authorizer_fci.size > 0) {
2175 zval_ptr_dtor(&intern->authorizer_fci.function_name);
2176 }
2177
2178 while (intern->funcs) {
2179 func = intern->funcs;
2180 intern->funcs = func->next;
2181 if (intern->initialised && intern->db) {
2182 sqlite3_create_function(intern->db, func->func_name, func->argc, SQLITE_UTF8, func, NULL, NULL, NULL);
2183 }
2184
2185 efree((char*)func->func_name);
2186
2187 if (!Z_ISUNDEF(func->func)) {
2188 zval_ptr_dtor(&func->func);
2189 }
2190 if (!Z_ISUNDEF(func->step)) {
2191 zval_ptr_dtor(&func->step);
2192 }
2193 if (!Z_ISUNDEF(func->fini)) {
2194 zval_ptr_dtor(&func->fini);
2195 }
2196 efree(func);
2197 }
2198
2199 while (intern->collations){
2200 collation = intern->collations;
2201 intern->collations = collation->next;
2202 if (intern->initialised && intern->db){
2203 sqlite3_create_collation(intern->db, collation->collation_name, SQLITE_UTF8, NULL, NULL);
2204 }
2205 efree((char*)collation->collation_name);
2206 if (!Z_ISUNDEF(collation->cmp_func)) {
2207 zval_ptr_dtor(&collation->cmp_func);
2208 }
2209 efree(collation);
2210 }
2211
2212 if (intern->initialised && intern->db) {
2213 sqlite3_close(intern->db);
2214 intern->initialised = 0;
2215 }
2216
2217 zend_object_std_dtor(&intern->zo);
2218 }
2219 /* }}} */
2220
php_sqlite3_stmt_object_free_storage(zend_object * object)2221 static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
2222 {
2223 php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);
2224
2225 if (!intern) {
2226 return;
2227 }
2228
2229 if (intern->bound_params) {
2230 zend_hash_destroy(intern->bound_params);
2231 FREE_HASHTABLE(intern->bound_params);
2232 intern->bound_params = NULL;
2233 }
2234
2235 if (intern->initialised) {
2236 zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt,
2237 (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
2238 }
2239
2240 if (!Z_ISUNDEF(intern->db_obj_zval)) {
2241 zval_ptr_dtor(&intern->db_obj_zval);
2242 }
2243
2244 zend_object_std_dtor(&intern->zo);
2245 }
2246 /* }}} */
2247
php_sqlite3_result_object_free_storage(zend_object * object)2248 static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ */
2249 {
2250 php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);
2251
2252 if (!intern) {
2253 return;
2254 }
2255
2256 if (!Z_ISNULL(intern->stmt_obj_zval)) {
2257 if (intern->stmt_obj && intern->stmt_obj->initialised) {
2258 sqlite3_reset(intern->stmt_obj->stmt);
2259 }
2260
2261 zval_ptr_dtor(&intern->stmt_obj_zval);
2262 }
2263
2264 zend_object_std_dtor(&intern->zo);
2265 }
2266 /* }}} */
2267
php_sqlite3_object_new(zend_class_entry * class_type)2268 static zend_object *php_sqlite3_object_new(zend_class_entry *class_type) /* {{{ */
2269 {
2270 php_sqlite3_db_object *intern;
2271
2272 /* Allocate memory for it */
2273 intern = zend_object_alloc(sizeof(php_sqlite3_db_object), class_type);
2274
2275 /* Need to keep track of things to free */
2276 zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
2277
2278 zend_object_std_init(&intern->zo, class_type);
2279 object_properties_init(&intern->zo, class_type);
2280
2281 intern->zo.handlers = &sqlite3_object_handlers;
2282
2283 return &intern->zo;
2284 }
2285 /* }}} */
2286
php_sqlite3_stmt_object_new(zend_class_entry * class_type)2287 static zend_object *php_sqlite3_stmt_object_new(zend_class_entry *class_type) /* {{{ */
2288 {
2289 php_sqlite3_stmt *intern;
2290
2291 /* Allocate memory for it */
2292 intern = zend_object_alloc(sizeof(php_sqlite3_stmt), class_type);
2293
2294 zend_object_std_init(&intern->zo, class_type);
2295 object_properties_init(&intern->zo, class_type);
2296
2297 intern->zo.handlers = &sqlite3_stmt_object_handlers;
2298
2299 return &intern->zo;
2300 }
2301 /* }}} */
2302
php_sqlite3_result_object_new(zend_class_entry * class_type)2303 static zend_object *php_sqlite3_result_object_new(zend_class_entry *class_type) /* {{{ */
2304 {
2305 php_sqlite3_result *intern;
2306
2307 /* Allocate memory for it */
2308 intern = zend_object_alloc(sizeof(php_sqlite3_result), class_type);
2309
2310 zend_object_std_init(&intern->zo, class_type);
2311 object_properties_init(&intern->zo, class_type);
2312
2313 intern->zo.handlers = &sqlite3_result_object_handlers;
2314
2315 return &intern->zo;
2316 }
2317 /* }}} */
2318
sqlite3_param_dtor(zval * data)2319 static void sqlite3_param_dtor(zval *data) /* {{{ */
2320 {
2321 struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)Z_PTR_P(data);
2322
2323 if (param->name) {
2324 zend_string_release_ex(param->name, 0);
2325 }
2326
2327 if (!Z_ISNULL(param->parameter)) {
2328 zval_ptr_dtor(&(param->parameter));
2329 ZVAL_UNDEF(¶m->parameter);
2330 }
2331 efree(param);
2332 }
2333 /* }}} */
2334
2335 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(sqlite3)2336 PHP_MINIT_FUNCTION(sqlite3)
2337 {
2338 zend_class_entry ce;
2339
2340 #ifdef ZTS
2341 /* Refuse to load if this wasn't a threasafe library loaded */
2342 if (!sqlite3_threadsafe()) {
2343 php_error_docref(NULL, E_WARNING, "A thread safe version of SQLite is required when using a thread safe version of PHP.");
2344 return FAILURE;
2345 }
2346 #endif
2347
2348 memcpy(&sqlite3_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2349 memcpy(&sqlite3_stmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2350 memcpy(&sqlite3_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2351
2352 /* Register SQLite 3 Class */
2353 INIT_CLASS_ENTRY(ce, "SQLite3", class_SQLite3_methods);
2354 ce.create_object = php_sqlite3_object_new;
2355 sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo);
2356 sqlite3_object_handlers.clone_obj = NULL;
2357 sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage;
2358 php_sqlite3_sc_entry = zend_register_internal_class(&ce);
2359 php_sqlite3_sc_entry->serialize = zend_class_serialize_deny;
2360 php_sqlite3_sc_entry->unserialize = zend_class_unserialize_deny;
2361
2362 /* Register SQLite 3 Prepared Statement Class */
2363 INIT_CLASS_ENTRY(ce, "SQLite3Stmt", class_SQLite3Stmt_methods);
2364 ce.create_object = php_sqlite3_stmt_object_new;
2365 sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo);
2366 sqlite3_stmt_object_handlers.clone_obj = NULL;
2367 sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage;
2368 php_sqlite3_stmt_entry = zend_register_internal_class(&ce);
2369 php_sqlite3_stmt_entry->serialize = zend_class_serialize_deny;
2370 php_sqlite3_stmt_entry->unserialize = zend_class_unserialize_deny;
2371
2372 /* Register SQLite 3 Result Class */
2373 INIT_CLASS_ENTRY(ce, "SQLite3Result", class_SQLite3Result_methods);
2374 ce.create_object = php_sqlite3_result_object_new;
2375 sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo);
2376 sqlite3_result_object_handlers.clone_obj = NULL;
2377 sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage;
2378 php_sqlite3_result_entry = zend_register_internal_class(&ce);
2379 php_sqlite3_result_entry->serialize = zend_class_serialize_deny;
2380 php_sqlite3_result_entry->unserialize = zend_class_unserialize_deny;
2381
2382 REGISTER_INI_ENTRIES();
2383
2384 REGISTER_LONG_CONSTANT("SQLITE3_ASSOC", PHP_SQLITE3_ASSOC, CONST_CS | CONST_PERSISTENT);
2385 REGISTER_LONG_CONSTANT("SQLITE3_NUM", PHP_SQLITE3_NUM, CONST_CS | CONST_PERSISTENT);
2386 REGISTER_LONG_CONSTANT("SQLITE3_BOTH", PHP_SQLITE3_BOTH, CONST_CS | CONST_PERSISTENT);
2387
2388 REGISTER_LONG_CONSTANT("SQLITE3_INTEGER", SQLITE_INTEGER, CONST_CS | CONST_PERSISTENT);
2389 REGISTER_LONG_CONSTANT("SQLITE3_FLOAT", SQLITE_FLOAT, CONST_CS | CONST_PERSISTENT);
2390 REGISTER_LONG_CONSTANT("SQLITE3_TEXT", SQLITE3_TEXT, CONST_CS | CONST_PERSISTENT);
2391 REGISTER_LONG_CONSTANT("SQLITE3_BLOB", SQLITE_BLOB, CONST_CS | CONST_PERSISTENT);
2392 REGISTER_LONG_CONSTANT("SQLITE3_NULL", SQLITE_NULL, CONST_CS | CONST_PERSISTENT);
2393
2394 REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READONLY", SQLITE_OPEN_READONLY, CONST_CS | CONST_PERSISTENT);
2395 REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READWRITE", SQLITE_OPEN_READWRITE, CONST_CS | CONST_PERSISTENT);
2396 REGISTER_LONG_CONSTANT("SQLITE3_OPEN_CREATE", SQLITE_OPEN_CREATE, CONST_CS | CONST_PERSISTENT);
2397
2398 /* Class constants */
2399 zend_declare_class_constant_long(php_sqlite3_sc_entry, "OK", sizeof("OK") - 1, SQLITE_OK);
2400
2401 /* Constants for authorizer return */
2402 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DENY", sizeof("DENY") - 1, SQLITE_DENY);
2403 zend_declare_class_constant_long(php_sqlite3_sc_entry, "IGNORE", sizeof("IGNORE") - 1, SQLITE_IGNORE);
2404
2405 /* Constants for authorizer actions */
2406 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_INDEX", sizeof("CREATE_INDEX") - 1, SQLITE_CREATE_INDEX);
2407 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TABLE", sizeof("CREATE_TABLE") - 1, SQLITE_CREATE_TABLE);
2408 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_INDEX", sizeof("CREATE_TEMP_INDEX") - 1, SQLITE_CREATE_TEMP_INDEX);
2409 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_TABLE", sizeof("CREATE_TEMP_TABLE") - 1, SQLITE_CREATE_TEMP_TABLE);
2410 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_TRIGGER", sizeof("CREATE_TEMP_TRIGGER") - 1, SQLITE_CREATE_TEMP_TRIGGER);
2411 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_VIEW", sizeof("CREATE_TEMP_VIEW") - 1, SQLITE_CREATE_TEMP_VIEW);
2412 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TRIGGER", sizeof("CREATE_TRIGGER") - 1, SQLITE_CREATE_TRIGGER);
2413 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_VIEW", sizeof("CREATE_VIEW") - 1, SQLITE_CREATE_VIEW);
2414 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DELETE", sizeof("DELETE") - 1, SQLITE_DELETE);
2415 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_INDEX", sizeof("DROP_INDEX") - 1, SQLITE_DROP_INDEX);
2416 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TABLE", sizeof("DROP_TABLE") - 1, SQLITE_DROP_TABLE);
2417 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_INDEX", sizeof("DROP_TEMP_INDEX") - 1, SQLITE_DROP_TEMP_INDEX);
2418 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_TABLE", sizeof("DROP_TEMP_TABLE") - 1, SQLITE_DROP_TEMP_TABLE);
2419 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_TRIGGER", sizeof("DROP_TEMP_TRIGGER") - 1, SQLITE_DROP_TEMP_TRIGGER);
2420 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_VIEW", sizeof("DROP_TEMP_VIEW") - 1, SQLITE_DROP_TEMP_VIEW);
2421 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TRIGGER", sizeof("DROP_TRIGGER") - 1, SQLITE_DROP_TRIGGER);
2422 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_VIEW", sizeof("DROP_VIEW") - 1, SQLITE_DROP_VIEW);
2423 zend_declare_class_constant_long(php_sqlite3_sc_entry, "INSERT", sizeof("INSERT") - 1, SQLITE_INSERT);
2424 zend_declare_class_constant_long(php_sqlite3_sc_entry, "PRAGMA", sizeof("PRAGMA") - 1, SQLITE_PRAGMA);
2425 zend_declare_class_constant_long(php_sqlite3_sc_entry, "READ", sizeof("READ") - 1, SQLITE_READ);
2426 zend_declare_class_constant_long(php_sqlite3_sc_entry, "SELECT", sizeof("SELECT") - 1, SQLITE_SELECT);
2427 zend_declare_class_constant_long(php_sqlite3_sc_entry, "TRANSACTION", sizeof("TRANSACTION") - 1, SQLITE_TRANSACTION);
2428 zend_declare_class_constant_long(php_sqlite3_sc_entry, "UPDATE", sizeof("UPDATE") - 1, SQLITE_UPDATE);
2429 zend_declare_class_constant_long(php_sqlite3_sc_entry, "ATTACH", sizeof("ATTACH") - 1, SQLITE_ATTACH);
2430 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DETACH", sizeof("DETACH") - 1, SQLITE_DETACH);
2431 zend_declare_class_constant_long(php_sqlite3_sc_entry, "ALTER_TABLE", sizeof("ALTER_TABLE") - 1, SQLITE_ALTER_TABLE);
2432 zend_declare_class_constant_long(php_sqlite3_sc_entry, "REINDEX", sizeof("REINDEX") - 1, SQLITE_REINDEX);
2433 zend_declare_class_constant_long(php_sqlite3_sc_entry, "ANALYZE", sizeof("ANALYZE") - 1, SQLITE_ANALYZE);
2434 zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_VTABLE", sizeof("CREATE_VTABLE") - 1, SQLITE_CREATE_VTABLE);
2435 zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_VTABLE", sizeof("DROP_VTABLE") - 1, SQLITE_DROP_VTABLE);
2436 zend_declare_class_constant_long(php_sqlite3_sc_entry, "FUNCTION", sizeof("FUNCTION") - 1, SQLITE_FUNCTION);
2437 zend_declare_class_constant_long(php_sqlite3_sc_entry, "SAVEPOINT", sizeof("SAVEPOINT") - 1, SQLITE_SAVEPOINT);
2438 zend_declare_class_constant_long(php_sqlite3_sc_entry, "COPY", sizeof("COPY") - 1, SQLITE_COPY);
2439 #ifdef SQLITE_RECURSIVE
2440 zend_declare_class_constant_long(php_sqlite3_sc_entry, "RECURSIVE", sizeof("RECURSIVE") - 1, SQLITE_RECURSIVE);
2441 #endif
2442
2443 #ifdef SQLITE_DETERMINISTIC
2444 REGISTER_LONG_CONSTANT("SQLITE3_DETERMINISTIC", SQLITE_DETERMINISTIC, CONST_CS | CONST_PERSISTENT);
2445 #endif
2446
2447 return SUCCESS;
2448 }
2449 /* }}} */
2450
2451 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(sqlite3)2452 PHP_MSHUTDOWN_FUNCTION(sqlite3)
2453 {
2454 UNREGISTER_INI_ENTRIES();
2455
2456 return SUCCESS;
2457 }
2458 /* }}} */
2459
2460 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(sqlite3)2461 PHP_MINFO_FUNCTION(sqlite3)
2462 {
2463 php_info_print_table_start();
2464 php_info_print_table_header(2, "SQLite3 support", "enabled");
2465 php_info_print_table_row(2, "SQLite Library", sqlite3_libversion());
2466 php_info_print_table_end();
2467
2468 DISPLAY_INI_ENTRIES();
2469 }
2470 /* }}} */
2471
2472 /* {{{ PHP_GINIT_FUNCTION */
PHP_GINIT_FUNCTION(sqlite3)2473 static PHP_GINIT_FUNCTION(sqlite3)
2474 {
2475 #if defined(COMPILE_DL_SQLITE3) && defined(ZTS)
2476 ZEND_TSRMLS_CACHE_UPDATE();
2477 #endif
2478 memset(sqlite3_globals, 0, sizeof(*sqlite3_globals));
2479 }
2480 /* }}} */
2481
2482 /* {{{ sqlite3_module_entry */
2483 zend_module_entry sqlite3_module_entry = {
2484 STANDARD_MODULE_HEADER,
2485 "sqlite3",
2486 NULL,
2487 PHP_MINIT(sqlite3),
2488 PHP_MSHUTDOWN(sqlite3),
2489 NULL,
2490 NULL,
2491 PHP_MINFO(sqlite3),
2492 PHP_SQLITE3_VERSION,
2493 PHP_MODULE_GLOBALS(sqlite3),
2494 PHP_GINIT(sqlite3),
2495 NULL,
2496 NULL,
2497 STANDARD_MODULE_PROPERTIES_EX
2498 };
2499 /* }}} */
2500
2501 #ifdef COMPILE_DL_SQLITE3
2502 #ifdef ZTS
2503 ZEND_TSRMLS_CACHE_DEFINE()
2504 #endif
2505 ZEND_GET_MODULE(sqlite3)
2506 #endif
2507