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