xref: /PHP-5.3/ext/sqlite/pdo_sqlite2.c (revision a2045ff3)
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   +----------------------------------------------------------------------+
17 */
18 
19 /* $Id$ */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include "php.h"
24 
25 #ifdef PHP_SQLITE2_HAVE_PDO
26 #include "sqlite.h"
27 #include "pdo/php_pdo.h"
28 #include "pdo/php_pdo_driver.h"
29 #include "zend_exceptions.h"
30 
31 #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
32 #define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
33 
34 
35 typedef struct {
36 	const char *file;
37 	int line;
38 	unsigned int errcode;
39 	char *errmsg;
40 } pdo_sqlite2_error_info;
41 
42 typedef struct {
43 	sqlite *db;
44 	pdo_sqlite2_error_info einfo;
45 } pdo_sqlite2_db_handle;
46 
47 typedef struct {
48 	pdo_sqlite2_db_handle 	*H;
49 	sqlite_vm *vm;
50 	const char **rowdata, **colnames;
51 	int ncols;
52 	unsigned pre_fetched:1;
53 	unsigned done:1;
54 	pdo_sqlite2_error_info einfo;
55 } pdo_sqlite2_stmt;
56 
57 extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
58 #define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
59 #define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
60 
61 extern struct pdo_stmt_methods sqlite2_stmt_methods;
62 
pdo_sqlite2_stmt_dtor(pdo_stmt_t * stmt TSRMLS_DC)63 static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
64 {
65 	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
66 
67 	if (S->vm) {
68 		char *errmsg = NULL;
69 		sqlite_finalize(S->vm, &errmsg);
70 		if (errmsg) {
71 			sqlite_freemem(errmsg);
72 		}
73 		S->vm = NULL;
74 	}
75 	if (S->einfo.errmsg) {
76 		pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
77 	}
78 	efree(S);
79 	return 1;
80 }
81 
pdo_sqlite2_stmt_execute(pdo_stmt_t * stmt TSRMLS_DC)82 static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
83 {
84 	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
85 	char *errmsg = NULL;
86 	const char *tail;
87 
88 	if (stmt->executed && !S->done) {
89 		sqlite_finalize(S->vm, &errmsg);
90 		pdo_sqlite2_error_stmt(errmsg, stmt);
91 		errmsg = NULL;
92 		S->vm = NULL;
93 	}
94 
95 	S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
96 	if (S->einfo.errcode != SQLITE_OK) {
97 		pdo_sqlite2_error_stmt(errmsg, stmt);
98 		return 0;
99 	}
100 
101 	S->done = 0;
102 	S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
103 	switch (S->einfo.errcode) {
104 		case SQLITE_ROW:
105 			S->pre_fetched = 1;
106 			stmt->column_count = S->ncols;
107 			return 1;
108 
109 		case SQLITE_DONE:
110 			stmt->column_count = S->ncols;
111 			stmt->row_count = sqlite_changes(S->H->db);
112 			S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
113 			if (S->einfo.errcode != SQLITE_OK) {
114 				pdo_sqlite2_error_stmt(errmsg, stmt);
115 			}
116 			S->done = 1;
117 			return 1;
118 
119 		case SQLITE_ERROR:
120 		case SQLITE_MISUSE:
121 		case SQLITE_BUSY:
122 		default:
123 			pdo_sqlite2_error_stmt(errmsg, stmt);
124 			return 0;
125 	}
126 }
127 
pdo_sqlite2_stmt_param_hook(pdo_stmt_t * stmt,struct pdo_bound_param_data * param,enum pdo_param_event event_type TSRMLS_DC)128 static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
129 		enum pdo_param_event event_type TSRMLS_DC)
130 {
131 	return 1;
132 }
133 
pdo_sqlite2_stmt_fetch(pdo_stmt_t * stmt,enum pdo_fetch_orientation ori,long offset TSRMLS_DC)134 static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
135 	enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
136 {
137 	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
138 	char *errmsg = NULL;
139 
140 	if (!S->vm) {
141 		return 0;
142 	}
143 	if (S->pre_fetched) {
144 		S->pre_fetched = 0;
145 		return 1;
146 	}
147 	if (S->done) {
148 		return 0;
149 	}
150 
151 	S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
152 	switch (S->einfo.errcode) {
153 		case SQLITE_ROW:
154 			return 1;
155 
156 		case SQLITE_DONE:
157 			S->done = 1;
158 			S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
159 			if (S->einfo.errcode != SQLITE_OK) {
160 				pdo_sqlite2_error_stmt(errmsg, stmt);
161 				errmsg = NULL;
162 			}
163 			return 0;
164 
165 		default:
166 			pdo_sqlite2_error_stmt(errmsg, stmt);
167 			return 0;
168 	}
169 }
170 
pdo_sqlite2_stmt_describe(pdo_stmt_t * stmt,int colno TSRMLS_DC)171 static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
172 {
173 	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
174 
175 	if(colno >= S->ncols) {
176 		/* error invalid column */
177 		pdo_sqlite2_error_stmt(NULL, stmt);
178 		return 0;
179 	}
180 
181 	stmt->columns[colno].name = estrdup(S->colnames[colno]);
182 	stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
183 	stmt->columns[colno].maxlen = 0xffffffff;
184 	stmt->columns[colno].precision = 0;
185 	stmt->columns[colno].param_type = PDO_PARAM_STR;
186 
187 	return 1;
188 }
189 
pdo_sqlite2_stmt_get_col(pdo_stmt_t * stmt,int colno,char ** ptr,unsigned long * len,int * caller_frees TSRMLS_DC)190 static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
191 {
192 	pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
193 	if (!S->vm) {
194 		return 0;
195 	}
196 	if(colno >= S->ncols) {
197 		/* error invalid column */
198 		pdo_sqlite2_error_stmt(NULL, stmt);
199 		return 0;
200 	}
201 	if (S->rowdata[colno]) {
202 		if (S->rowdata[colno][0] == '\x01') {
203 			/* encoded */
204 			*caller_frees = 1;
205 			*ptr = emalloc(strlen(S->rowdata[colno]));
206 			*len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
207 			(*(char**)ptr)[*len] = '\0';
208 		} else {
209 			*ptr = (char*)S->rowdata[colno];
210 			*len = strlen(*ptr);
211 		}
212 	} else {
213 		*ptr = NULL;
214 		*len = 0;
215 	}
216 	return 1;
217 }
218 
219 struct pdo_stmt_methods sqlite2_stmt_methods = {
220 	pdo_sqlite2_stmt_dtor,
221 	pdo_sqlite2_stmt_execute,
222 	pdo_sqlite2_stmt_fetch,
223 	pdo_sqlite2_stmt_describe,
224 	pdo_sqlite2_stmt_get_col,
225 	pdo_sqlite2_stmt_param_hook,
226 	NULL, /* set_attr */
227 	NULL, /* get_attr */
228 	NULL
229 };
230 
231 
_pdo_sqlite2_error(pdo_dbh_t * dbh,pdo_stmt_t * stmt,char * errmsg,const char * file,int line TSRMLS_DC)232 int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
233 {
234 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
235 	pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
236 	pdo_sqlite2_error_info *einfo = &H->einfo;
237 	pdo_sqlite2_stmt *S;
238 
239 	if (stmt) {
240 		S = stmt->driver_data;
241 		einfo = &S->einfo;
242 	}
243 
244 	einfo->file = file;
245 	einfo->line = line;
246 
247 	if (einfo->errmsg) {
248 		pefree(einfo->errmsg, dbh->is_persistent);
249 		einfo->errmsg = NULL;
250 	}
251 
252 	if (einfo->errcode != SQLITE_OK) {
253 		if (errmsg) {
254 			einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
255 			sqlite_freemem(errmsg);
256 		} else {
257 			einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
258 		}
259 	} else { /* no error */
260 		strcpy(*pdo_err, PDO_ERR_NONE);
261 		return 0;
262 	}
263 	switch (einfo->errcode) {
264 		case SQLITE_NOTFOUND:
265 			strcpy(*pdo_err, "42S02");
266 			break;
267 
268 		case SQLITE_INTERRUPT:
269 			strcpy(*pdo_err, "01002");
270 			break;
271 
272 		case SQLITE_NOLFS:
273 			strcpy(*pdo_err, "HYC00");
274 			break;
275 
276 		case SQLITE_TOOBIG:
277 			strcpy(*pdo_err, "22001");
278 			break;
279 
280 		case SQLITE_CONSTRAINT:
281 			strcpy(*pdo_err, "23000");
282 			break;
283 
284 		case SQLITE_ERROR:
285 		default:
286 			strcpy(*pdo_err, "HY000");
287 			break;
288 	}
289 
290 	if (!dbh->methods) {
291 		zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
292 				*pdo_err, einfo->errcode, einfo->errmsg);
293 	}
294 
295 	return einfo->errcode;
296 }
297 /* }}} */
298 
pdo_sqlite2_fetch_error_func(pdo_dbh_t * dbh,pdo_stmt_t * stmt,zval * info TSRMLS_DC)299 static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
300 {
301 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
302 	pdo_sqlite2_error_info *einfo = &H->einfo;
303 	pdo_sqlite2_stmt *S;
304 
305 	if (stmt) {
306 		S = stmt->driver_data;
307 		einfo = &S->einfo;
308 	}
309 
310 	if (einfo->errcode) {
311 		add_next_index_long(info, einfo->errcode);
312 		if (einfo->errmsg) {
313 			add_next_index_string(info, einfo->errmsg, 1);
314 		}
315 	}
316 
317 	return 1;
318 }
319 
sqlite2_handle_closer(pdo_dbh_t * dbh TSRMLS_DC)320 static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
321 {
322 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
323 
324 	if (H) {
325 		if (H->db) {
326 			sqlite_close(H->db);
327 			H->db = NULL;
328 		}
329 		if (H->einfo.errmsg) {
330 			pefree(H->einfo.errmsg, dbh->is_persistent);
331 			H->einfo.errmsg = NULL;
332 		}
333 		pefree(H, dbh->is_persistent);
334 		dbh->driver_data = NULL;
335 	}
336 	return 0;
337 }
338 /* }}} */
339 
sqlite2_handle_preparer(pdo_dbh_t * dbh,const char * sql,long sql_len,pdo_stmt_t * stmt,zval * driver_options TSRMLS_DC)340 static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
341 {
342 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
343 	pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
344 
345 	S->H = H;
346 	stmt->driver_data = S;
347 	stmt->methods = &sqlite2_stmt_methods;
348 	stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
349 
350 	if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
351 		H->einfo.errcode = SQLITE_ERROR;
352 		pdo_sqlite2_error(NULL, dbh);
353 		return 0;
354 	}
355 
356 	return 1;
357 }
358 
sqlite2_handle_doer(pdo_dbh_t * dbh,const char * sql,long sql_len TSRMLS_DC)359 static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
360 {
361 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
362 	char *errmsg = NULL;
363 
364 	if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
365 		pdo_sqlite2_error(errmsg, dbh);
366 		return -1;
367 	} else {
368 		return sqlite_changes(H->db);
369 	}
370 }
371 
pdo_sqlite2_last_insert_id(pdo_dbh_t * dbh,const char * name,unsigned int * len TSRMLS_DC)372 static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
373 {
374 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
375 	char *id;
376 
377 	id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
378 	*len = strlen(id);
379 	return id;
380 }
381 
sqlite2_handle_quoter(pdo_dbh_t * dbh,const char * unquoted,int unquotedlen,char ** quoted,int * quotedlen,enum pdo_param_type paramtype TSRMLS_DC)382 static int sqlite2_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
383 {
384 	char *ret;
385 
386 	if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
387 		/* binary string */
388 		int len;
389 		ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
390 		ret[0] = '\'';
391 		ret[1] = '\x01';
392 		len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
393 		ret[len + 2] = '\'';
394 		ret[len + 3] = '\0';
395 		*quoted = ret;
396 		*quotedlen = len + 3;
397 		/* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
398 		return 1;
399 	} else if (unquotedlen) {
400 		ret = sqlite_mprintf("'%q'", unquoted);
401 		if (ret) {
402 			*quoted = estrdup(ret);
403 			*quotedlen = strlen(ret);
404 			sqlite_freemem(ret);
405 			return 1;
406 		}
407 		return 0;
408 	} else {
409 		*quoted = estrdup("''");
410 		*quotedlen = 2;
411 		return 1;
412 	}
413 }
414 
sqlite2_handle_begin(pdo_dbh_t * dbh TSRMLS_DC)415 static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
416 {
417 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
418 	char *errmsg = NULL;
419 
420 	if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
421 		pdo_sqlite2_error(errmsg, dbh);
422 		return 0;
423 	}
424 	return 1;
425 }
426 
sqlite2_handle_commit(pdo_dbh_t * dbh TSRMLS_DC)427 static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
428 {
429 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
430 	char *errmsg = NULL;
431 
432 	if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
433 		pdo_sqlite2_error(errmsg, dbh);
434 		return 0;
435 	}
436 	return 1;
437 }
438 
sqlite2_handle_rollback(pdo_dbh_t * dbh TSRMLS_DC)439 static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
440 {
441 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
442 	char *errmsg = NULL;
443 
444 	if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
445 		pdo_sqlite2_error(errmsg, dbh);
446 		return 0;
447 	}
448 	return 1;
449 }
450 
pdo_sqlite2_get_attribute(pdo_dbh_t * dbh,long attr,zval * return_value TSRMLS_DC)451 static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
452 {
453 	switch (attr) {
454 		case PDO_ATTR_CLIENT_VERSION:
455 		case PDO_ATTR_SERVER_VERSION:
456 			ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
457 			break;
458 
459 		default:
460 			return 0;
461 	}
462 
463 	return 1;
464 }
465 
pdo_sqlite2_set_attr(pdo_dbh_t * dbh,long attr,zval * val TSRMLS_DC)466 static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
467 {
468 	pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
469 
470 	switch (attr) {
471 		case PDO_ATTR_TIMEOUT:
472 			convert_to_long(val);
473 			sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
474 			return 1;
475 	}
476 	return 0;
477 }
478 
PHP_FUNCTION(sqlite2_create_function)479 static PHP_FUNCTION(sqlite2_create_function)
480 {
481 	/* TODO: implement this stuff */
482 }
483 
484 static const zend_function_entry dbh_methods[] = {
485 	PHP_FE(sqlite2_create_function, NULL)
486 	{NULL, NULL, NULL}
487 };
488 
get_driver_methods(pdo_dbh_t * dbh,int kind TSRMLS_DC)489 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
490 {
491 	switch (kind) {
492 		case PDO_DBH_DRIVER_METHOD_KIND_DBH:
493 			return dbh_methods;
494 
495 		default:
496 			return NULL;
497 	}
498 }
499 
500 static struct pdo_dbh_methods sqlite2_methods = {
501 	sqlite2_handle_closer,
502 	sqlite2_handle_preparer,
503 	sqlite2_handle_doer,
504 	sqlite2_handle_quoter,
505 	sqlite2_handle_begin,
506 	sqlite2_handle_commit,
507 	sqlite2_handle_rollback,
508 	pdo_sqlite2_set_attr,
509 	pdo_sqlite2_last_insert_id,
510 	pdo_sqlite2_fetch_error_func,
511 	pdo_sqlite2_get_attribute,
512 	NULL,	/* check_liveness: not needed */
513 	get_driver_methods
514 };
515 
make_filename_safe(const char * filename TSRMLS_DC)516 static char *make_filename_safe(const char *filename TSRMLS_DC)
517 {
518 	if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
519 		char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
520 
521 		if (!fullpath) {
522 			return NULL;
523 		}
524 
525 		if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
526 			efree(fullpath);
527 			return NULL;
528 		}
529 
530 		if (php_check_open_basedir(fullpath TSRMLS_CC)) {
531 			efree(fullpath);
532 			return NULL;
533 		}
534 		return fullpath;
535 	}
536 	return estrdup(filename);
537 }
538 
authorizer(void * autharg,int access_type,const char * arg3,const char * arg4,const char * arg5,const char * arg6)539 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
540 		const char *arg5, const char *arg6)
541 {
542 	char *filename;
543 	switch (access_type) {
544 		case SQLITE_COPY: {
545 			TSRMLS_FETCH();
546 			filename = make_filename_safe(arg4 TSRMLS_CC);
547 			if (!filename) {
548 				return SQLITE_DENY;
549 			}
550 			efree(filename);
551 			return SQLITE_OK;
552 		}
553 
554 		case SQLITE_ATTACH: {
555 			TSRMLS_FETCH();
556 			filename = make_filename_safe(arg3 TSRMLS_CC);
557 			if (!filename) {
558 				return SQLITE_DENY;
559 			}
560 			efree(filename);
561 			return SQLITE_OK;
562 		}
563 
564 		default:
565 			/* access allowed */
566 			return SQLITE_OK;
567 	}
568 }
569 
pdo_sqlite2_handle_factory(pdo_dbh_t * dbh,zval * driver_options TSRMLS_DC)570 static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
571 {
572 	pdo_sqlite2_db_handle *H;
573 	int ret = 0;
574 	long timeout = 60;
575 	char *filename;
576 	char *errmsg = NULL;
577 
578 	H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
579 
580 	H->einfo.errcode = 0;
581 	H->einfo.errmsg = NULL;
582 	dbh->driver_data = H;
583 
584 	filename = make_filename_safe(dbh->data_source TSRMLS_CC);
585 
586 	if (!filename) {
587 		zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
588 				"safe_mode/open_basedir prohibits opening %s",
589 				dbh->data_source);
590 		goto cleanup;
591 	}
592 
593 	H->db = sqlite_open(filename, 0666, &errmsg);
594 	efree(filename);
595 
596 	if (!H->db) {
597 		H->einfo.errcode = SQLITE_ERROR;
598 		pdo_sqlite2_error(errmsg, dbh);
599 		goto cleanup;
600 	}
601 
602 	sqlite_set_authorizer(H->db, authorizer, NULL);
603 
604 	if (driver_options) {
605 		timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
606 	}
607 	sqlite_busy_timeout(H->db, timeout * 1000);
608 
609 	dbh->alloc_own_columns = 1;
610 	dbh->max_escaped_char_length = 2;
611 
612 	ret = 1;
613 
614 cleanup:
615 	dbh->methods = &sqlite2_methods;
616 
617 	return ret;
618 }
619 /* }}} */
620 
621 pdo_driver_t pdo_sqlite2_driver = {
622 	PDO_DRIVER_HEADER(sqlite2),
623 	pdo_sqlite2_handle_factory
624 };
625 
626 
627 
628 #endif
629 
630 
631 /*
632  * Local variables:
633  * tab-width: 4
634  * c-basic-offset: 4
635  * End:
636  * vim600: noet sw=4 ts=4 fdm=marker
637  * vim<600: noet sw=4 ts=4
638  */
639