Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / php / ext / pdo_sqlite / sqlite_driver.c
blob0f4a2456a1df30edc2e426a8454abf00ec584e5e
1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Wez Furlong <wez@php.net> |
16 +----------------------------------------------------------------------+
19 /* $Id$ */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "pdo/php_pdo.h"
29 #include "pdo/php_pdo_driver.h"
30 #include "php_pdo_sqlite.h"
31 #include "php_pdo_sqlite_int.h"
32 #include "zend_exceptions.h"
34 int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
36 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
37 pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
38 pdo_sqlite_error_info *einfo = &H->einfo;
40 einfo->errcode = sqlite3_errcode(H->db);
41 einfo->file = file;
42 einfo->line = line;
44 if (einfo->errcode != SQLITE_OK) {
45 if (einfo->errmsg) {
46 pefree(einfo->errmsg, dbh->is_persistent);
48 einfo->errmsg = pestrdup((char*)sqlite3_errmsg(H->db), dbh->is_persistent);
49 } else { /* no error */
50 strncpy(*pdo_err, PDO_ERR_NONE, sizeof(PDO_ERR_NONE));
51 return 0;
53 switch (einfo->errcode) {
54 case SQLITE_NOTFOUND:
55 strncpy(*pdo_err, "42S02", sizeof("42S02"));
56 break;
58 case SQLITE_INTERRUPT:
59 strncpy(*pdo_err, "01002", sizeof("01002"));
60 break;
62 case SQLITE_NOLFS:
63 strncpy(*pdo_err, "HYC00", sizeof("HYC00"));
64 break;
66 case SQLITE_TOOBIG:
67 strncpy(*pdo_err, "22001", sizeof("22001"));
68 break;
70 case SQLITE_CONSTRAINT:
71 strncpy(*pdo_err, "23000", sizeof("23000"));
72 break;
74 case SQLITE_ERROR:
75 default:
76 strncpy(*pdo_err, "HY000", sizeof("HY000"));
77 break;
80 if (!dbh->methods) {
81 zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
82 *pdo_err, einfo->errcode, einfo->errmsg);
85 return einfo->errcode;
87 /* }}} */
89 static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
91 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
92 pdo_sqlite_error_info *einfo = &H->einfo;
94 if (einfo->errcode) {
95 add_next_index_long(info, einfo->errcode);
96 add_next_index_string(info, einfo->errmsg, 1);
99 return 1;
102 static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H TSRMLS_DC)
104 struct pdo_sqlite_func *func;
106 while (H->funcs) {
107 func = H->funcs;
108 H->funcs = func->next;
110 if (H->db) {
111 /* delete the function from the handle */
112 sqlite3_create_function(H->db,
113 func->funcname,
114 func->argc,
115 SQLITE_UTF8,
116 func,
117 NULL, NULL, NULL);
120 efree((char*)func->funcname);
121 if (func->func) {
122 zval_ptr_dtor(&func->func);
124 if (func->step) {
125 zval_ptr_dtor(&func->step);
127 if (func->fini) {
128 zval_ptr_dtor(&func->fini);
130 efree(func);
133 while (H->collations) {
134 struct pdo_sqlite_collation *collation;
135 collation = H->collations;
136 H->collations = collation->next;
138 if (H->db) {
139 /* delete the collation from the handle */
140 sqlite3_create_collation(H->db,
141 collation->name,
142 SQLITE_UTF8,
143 collation,
144 NULL);
147 efree((char*)collation->name);
148 if (collation->callback) {
149 zval_ptr_dtor(&collation->callback);
151 efree(collation);
155 static int sqlite_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
157 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
159 if (H) {
160 pdo_sqlite_error_info *einfo = &H->einfo;
162 pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
163 if (H->db) {
164 sqlite3_close(H->db);
165 H->db = NULL;
167 if (einfo->errmsg) {
168 pefree(einfo->errmsg, dbh->is_persistent);
169 einfo->errmsg = NULL;
171 pefree(H, dbh->is_persistent);
172 dbh->driver_data = NULL;
174 return 0;
176 /* }}} */
178 static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
180 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
181 pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
182 int i;
183 const char *tail;
185 S->H = H;
186 stmt->driver_data = S;
187 stmt->methods = &sqlite_stmt_methods;
188 stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL|PDO_PLACEHOLDER_NAMED;
190 if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
191 H->einfo.errcode = SQLITE_ERROR;
192 pdo_sqlite_error(dbh);
193 return 0;
196 i = sqlite3_prepare(H->db, sql, sql_len, &S->stmt, &tail);
197 if (i == SQLITE_OK) {
198 return 1;
201 pdo_sqlite_error(dbh);
203 return 0;
206 static long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
208 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
209 char *errmsg = NULL;
211 if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
212 pdo_sqlite_error(dbh);
213 if (errmsg)
214 sqlite3_free(errmsg);
216 return -1;
217 } else {
218 return sqlite3_changes(H->db);
222 static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
224 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
225 char *id;
227 id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db) TSRMLS_CC);
228 *len = strlen(id);
229 return id;
232 /* NB: doesn't handle binary strings... use prepared stmts for that */
233 static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
235 *quoted = safe_emalloc(2, unquotedlen, 3);
236 sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
237 *quotedlen = strlen(*quoted);
238 return 1;
241 static int sqlite_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
243 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
244 char *errmsg = NULL;
246 if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
247 pdo_sqlite_error(dbh);
248 if (errmsg)
249 sqlite3_free(errmsg);
250 return 0;
252 return 1;
255 static int sqlite_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
257 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
258 char *errmsg = NULL;
260 if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
261 pdo_sqlite_error(dbh);
262 if (errmsg)
263 sqlite3_free(errmsg);
264 return 0;
266 return 1;
269 static int sqlite_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
271 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
272 char *errmsg = NULL;
274 if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
275 pdo_sqlite_error(dbh);
276 if (errmsg)
277 sqlite3_free(errmsg);
278 return 0;
280 return 1;
283 static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
285 switch (attr) {
286 case PDO_ATTR_CLIENT_VERSION:
287 case PDO_ATTR_SERVER_VERSION:
288 ZVAL_STRING(return_value, (char *)sqlite3_libversion(), 1);
289 break;
291 default:
292 return 0;
295 return 1;
298 static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
300 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
302 switch (attr) {
303 case PDO_ATTR_TIMEOUT:
304 convert_to_long(val);
305 sqlite3_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
306 return 1;
308 return 0;
311 static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
312 int argc, sqlite3_value **argv, sqlite3_context *context,
313 int is_agg TSRMLS_DC)
315 zval ***zargs = NULL;
316 zval *retval = NULL;
317 int i;
318 int ret;
319 int fake_argc;
320 zval **agg_context = NULL;
322 if (is_agg) {
323 is_agg = 2;
326 fake_argc = argc + is_agg;
328 fc->fci.size = sizeof(fc->fci);
329 fc->fci.function_table = EG(function_table);
330 fc->fci.function_name = cb;
331 fc->fci.symbol_table = NULL;
332 fc->fci.object_ptr = NULL;
333 fc->fci.retval_ptr_ptr = &retval;
334 fc->fci.param_count = fake_argc;
336 /* build up the params */
338 if (fake_argc) {
339 zargs = (zval ***)safe_emalloc(fake_argc, sizeof(zval **), 0);
342 if (is_agg) {
343 /* summon the aggregation context */
344 agg_context = (zval**)sqlite3_aggregate_context(context, sizeof(zval*));
345 if (!*agg_context) {
346 MAKE_STD_ZVAL(*agg_context);
347 ZVAL_NULL(*agg_context);
349 zargs[0] = agg_context;
351 zargs[1] = emalloc(sizeof(zval*));
352 MAKE_STD_ZVAL(*zargs[1]);
353 ZVAL_LONG(*zargs[1], sqlite3_aggregate_count(context));
356 for (i = 0; i < argc; i++) {
357 zargs[i + is_agg] = emalloc(sizeof(zval *));
358 MAKE_STD_ZVAL(*zargs[i + is_agg]);
360 /* get the value */
361 switch (sqlite3_value_type(argv[i])) {
362 case SQLITE_INTEGER:
363 ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int(argv[i]));
364 break;
366 case SQLITE_FLOAT:
367 ZVAL_DOUBLE(*zargs[i + is_agg], sqlite3_value_double(argv[i]));
368 break;
370 case SQLITE_NULL:
371 ZVAL_NULL(*zargs[i + is_agg]);
372 break;
374 case SQLITE_BLOB:
375 case SQLITE3_TEXT:
376 default:
377 ZVAL_STRINGL(*zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]),
378 sqlite3_value_bytes(argv[i]), 1);
379 break;
384 fc->fci.params = zargs;
387 if ((ret = zend_call_function(&fc->fci, &fc->fcc TSRMLS_CC)) == FAILURE) {
388 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the callback");
391 /* clean up the params */
392 if (zargs) {
393 for (i = is_agg; i < fake_argc; i++) {
394 zval_ptr_dtor(zargs[i]);
395 efree(zargs[i]);
397 if (is_agg) {
398 zval_ptr_dtor(zargs[1]);
399 efree(zargs[1]);
401 efree(zargs);
404 if (!is_agg || !argv) {
405 /* only set the sqlite return value if we are a scalar function,
406 * or if we are finalizing an aggregate */
407 if (retval) {
408 switch (Z_TYPE_P(retval)) {
409 case IS_LONG:
410 sqlite3_result_int(context, Z_LVAL_P(retval));
411 break;
413 case IS_NULL:
414 sqlite3_result_null(context);
415 break;
417 case IS_DOUBLE:
418 sqlite3_result_double(context, Z_DVAL_P(retval));
419 break;
421 default:
422 convert_to_string_ex(&retval);
423 sqlite3_result_text(context, Z_STRVAL_P(retval),
424 Z_STRLEN_P(retval), SQLITE_TRANSIENT);
425 break;
427 } else {
428 sqlite3_result_error(context, "failed to invoke callback", 0);
431 if (agg_context) {
432 zval_ptr_dtor(agg_context);
434 } else {
435 /* we're stepping in an aggregate; the return value goes into
436 * the context */
437 if (agg_context) {
438 zval_ptr_dtor(agg_context);
440 if (retval) {
441 *agg_context = retval;
442 retval = NULL;
443 } else {
444 *agg_context = NULL;
448 if (retval) {
449 zval_ptr_dtor(&retval);
452 return ret;
455 static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
456 sqlite3_value **argv)
458 struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
459 TSRMLS_FETCH();
461 do_callback(&func->afunc, func->func, argc, argv, context, 0 TSRMLS_CC);
464 static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
465 sqlite3_value **argv)
467 struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
468 TSRMLS_FETCH();
470 do_callback(&func->astep, func->step, argc, argv, context, 1 TSRMLS_CC);
473 static void php_sqlite3_func_final_callback(sqlite3_context *context)
475 struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
476 TSRMLS_FETCH();
478 do_callback(&func->afini, func->fini, 0, NULL, context, 1 TSRMLS_CC);
481 static int php_sqlite3_collation_callback(void *context,
482 int string1_len, const void *string1,
483 int string2_len, const void *string2)
485 int ret;
486 zval *zstring1, *zstring2;
487 zval **zargs[2];
488 zval *retval = NULL;
489 struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
490 TSRMLS_FETCH();
492 collation->fc.fci.size = sizeof(collation->fc.fci);
493 collation->fc.fci.function_table = EG(function_table);
494 collation->fc.fci.function_name = collation->callback;
495 collation->fc.fci.symbol_table = NULL;
496 collation->fc.fci.object_ptr = NULL;
497 collation->fc.fci.retval_ptr_ptr = &retval;
499 // Prepare the arguments.
500 MAKE_STD_ZVAL(zstring1);
501 ZVAL_STRINGL(zstring1, (char *) string1, string1_len, 1);
502 zargs[0] = &zstring1;
503 MAKE_STD_ZVAL(zstring2);
504 ZVAL_STRINGL(zstring2, (char *) string2, string2_len, 1);
505 zargs[1] = &zstring2;
506 collation->fc.fci.param_count = 2;
507 collation->fc.fci.params = zargs;
509 if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc TSRMLS_CC)) == FAILURE) {
510 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the callback");
512 else if (retval) {
513 if (Z_TYPE_P(retval) != IS_LONG) {
514 convert_to_long_ex(&retval);
516 ret = 0;
517 if (Z_LVAL_P(retval) > 0) {
518 ret = 1;
520 else if (Z_LVAL_P(retval) < 0) {
521 ret = -1;
523 zval_ptr_dtor(&retval);
526 zval_ptr_dtor(zargs[0]);
527 zval_ptr_dtor(zargs[1]);
529 return ret;
532 /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
533 Registers a UDF with the sqlite db handle */
534 static PHP_METHOD(SQLite, sqliteCreateFunction)
536 struct pdo_sqlite_func *func;
537 zval *callback;
538 char *func_name;
539 int func_name_len;
540 long argc = -1;
541 char *cbname = NULL;
542 pdo_dbh_t *dbh;
543 pdo_sqlite_db_handle *H;
544 int ret;
546 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l",
547 &func_name, &func_name_len, &callback, &argc)) {
548 RETURN_FALSE;
551 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
552 PDO_CONSTRUCT_CHECK;
554 if (!zend_is_callable(callback, 0, &cbname TSRMLS_CC)) {
555 php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
556 efree(cbname);
557 RETURN_FALSE;
559 efree(cbname);
561 H = (pdo_sqlite_db_handle *)dbh->driver_data;
563 func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
565 ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
566 func, php_sqlite3_func_callback, NULL, NULL);
567 if (ret == SQLITE_OK) {
568 func->funcname = estrdup(func_name);
570 MAKE_STD_ZVAL(func->func);
571 MAKE_COPY_ZVAL(&callback, func->func);
573 func->argc = argc;
575 func->next = H->funcs;
576 H->funcs = func;
578 RETURN_TRUE;
581 efree(func);
582 RETURN_FALSE;
584 /* }}} */
586 /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
587 Registers a UDF with the sqlite db handle */
589 /* The step function should have the prototype:
590 mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
592 $context will be null for the first row; on subsequent rows it will have
593 the value that was previously returned from the step function; you should
594 use this to maintain state for the aggregate.
596 The fini function should have the prototype:
597 mixed fini(mixed $context, int $rownumber)
599 $context will hold the return value from the very last call to the step function.
600 rownumber will hold the number of rows over which the aggregate was performed.
601 The return value of this function will be used as the return value for this
602 aggregate UDF.
605 static PHP_METHOD(SQLite, sqliteCreateAggregate)
607 struct pdo_sqlite_func *func;
608 zval *step_callback, *fini_callback;
609 char *func_name;
610 int func_name_len;
611 long argc = -1;
612 char *cbname = NULL;
613 pdo_dbh_t *dbh;
614 pdo_sqlite_db_handle *H;
615 int ret;
617 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l",
618 &func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
619 RETURN_FALSE;
622 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
623 PDO_CONSTRUCT_CHECK;
625 if (!zend_is_callable(step_callback, 0, &cbname TSRMLS_CC)) {
626 php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
627 efree(cbname);
628 RETURN_FALSE;
630 efree(cbname);
631 if (!zend_is_callable(fini_callback, 0, &cbname TSRMLS_CC)) {
632 php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
633 efree(cbname);
634 RETURN_FALSE;
636 efree(cbname);
638 H = (pdo_sqlite_db_handle *)dbh->driver_data;
640 func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
642 ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
643 func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
644 if (ret == SQLITE_OK) {
645 func->funcname = estrdup(func_name);
647 MAKE_STD_ZVAL(func->step);
648 MAKE_COPY_ZVAL(&step_callback, func->step);
650 MAKE_STD_ZVAL(func->fini);
651 MAKE_COPY_ZVAL(&fini_callback, func->fini);
653 func->argc = argc;
655 func->next = H->funcs;
656 H->funcs = func;
658 RETURN_TRUE;
661 efree(func);
662 RETURN_FALSE;
664 /* }}} */
666 /* {{{ bool SQLite::sqliteCreateCollation(string name, mixed callback)
667 Registers a collation with the sqlite db handle */
668 static PHP_METHOD(SQLite, sqliteCreateCollation)
670 struct pdo_sqlite_collation *collation;
671 zval *callback;
672 char *collation_name;
673 int collation_name_len;
674 char *cbname = NULL;
675 pdo_dbh_t *dbh;
676 pdo_sqlite_db_handle *H;
677 int ret;
679 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz",
680 &collation_name, &collation_name_len, &callback)) {
681 RETURN_FALSE;
684 dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
685 PDO_CONSTRUCT_CHECK;
687 if (!zend_is_callable(callback, 0, &cbname TSRMLS_CC)) {
688 php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
689 efree(cbname);
690 RETURN_FALSE;
692 efree(cbname);
694 H = (pdo_sqlite_db_handle *)dbh->driver_data;
696 collation = (struct pdo_sqlite_collation*)ecalloc(1, sizeof(*collation));
698 ret = sqlite3_create_collation(H->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_collation_callback);
699 if (ret == SQLITE_OK) {
700 collation->name = estrdup(collation_name);
702 MAKE_STD_ZVAL(collation->callback);
703 MAKE_COPY_ZVAL(&callback, collation->callback);
705 collation->next = H->collations;
706 H->collations = collation;
708 RETURN_TRUE;
711 efree(collation);
712 RETURN_FALSE;
714 /* }}} */
716 static const zend_function_entry dbh_methods[] = {
717 PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
718 PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
719 PHP_ME(SQLite, sqliteCreateCollation, NULL, ZEND_ACC_PUBLIC)
720 PHP_FE_END
723 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
725 switch (kind) {
726 case PDO_DBH_DRIVER_METHOD_KIND_DBH:
727 return dbh_methods;
729 default:
730 return NULL;
734 static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh TSRMLS_DC)
736 pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
737 /* unregister functions, so that they don't linger for the next
738 * request */
739 if (H) {
740 pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
744 static struct pdo_dbh_methods sqlite_methods = {
745 sqlite_handle_closer,
746 sqlite_handle_preparer,
747 sqlite_handle_doer,
748 sqlite_handle_quoter,
749 sqlite_handle_begin,
750 sqlite_handle_commit,
751 sqlite_handle_rollback,
752 pdo_sqlite_set_attr,
753 pdo_sqlite_last_insert_id,
754 pdo_sqlite_fetch_error_func,
755 pdo_sqlite_get_attribute,
756 NULL, /* check_liveness: not needed */
757 get_driver_methods,
758 pdo_sqlite_request_shutdown
761 static char *make_filename_safe(const char *filename TSRMLS_DC)
763 if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) {
764 char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
766 if (!fullpath) {
767 return NULL;
770 if (php_check_open_basedir(fullpath TSRMLS_CC)) {
771 efree(fullpath);
772 return NULL;
774 return fullpath;
776 return estrdup(filename);
779 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
780 const char *arg5, const char *arg6)
782 char *filename;
783 switch (access_type) {
784 case SQLITE_COPY: {
785 TSRMLS_FETCH();
786 filename = make_filename_safe(arg4 TSRMLS_CC);
787 if (!filename) {
788 return SQLITE_DENY;
790 efree(filename);
791 return SQLITE_OK;
794 case SQLITE_ATTACH: {
795 TSRMLS_FETCH();
796 filename = make_filename_safe(arg3 TSRMLS_CC);
797 if (!filename) {
798 return SQLITE_DENY;
800 efree(filename);
801 return SQLITE_OK;
804 default:
805 /* access allowed */
806 return SQLITE_OK;
810 static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
812 pdo_sqlite_db_handle *H;
813 int i, ret = 0;
814 long timeout = 60;
815 char *filename;
817 H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
819 H->einfo.errcode = 0;
820 H->einfo.errmsg = NULL;
821 dbh->driver_data = H;
823 filename = make_filename_safe(dbh->data_source TSRMLS_CC);
825 if (!filename) {
826 zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
827 "open_basedir prohibits opening %s",
828 dbh->data_source);
829 goto cleanup;
832 i = sqlite3_open(filename, &H->db);
833 efree(filename);
835 if (i != SQLITE_OK) {
836 pdo_sqlite_error(dbh);
837 goto cleanup;
840 if (PG(open_basedir) && *PG(open_basedir)) {
841 sqlite3_set_authorizer(H->db, authorizer, NULL);
844 if (driver_options) {
845 timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
847 sqlite3_busy_timeout(H->db, timeout * 1000);
849 dbh->alloc_own_columns = 1;
850 dbh->max_escaped_char_length = 2;
852 ret = 1;
854 cleanup:
855 dbh->methods = &sqlite_methods;
857 return ret;
859 /* }}} */
861 pdo_driver_t pdo_sqlite_driver = {
862 PDO_DRIVER_HEADER(sqlite),
863 pdo_sqlite_handle_factory
867 * Local variables:
868 * tab-width: 4
869 * c-basic-offset: 4
870 * End:
871 * vim600: noet sw=4 ts=4 fdm=marker
872 * vim<600: noet sw=4 ts=4