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