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