summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite_driver.c')
-rw-r--r--ext/pdo_sqlite/sqlite_driver.c110
1 files changed, 71 insertions, 39 deletions
diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
index 26fa1c00eb..b7c20b1eae 100644
--- a/ext/pdo_sqlite/sqlite_driver.c
+++ b/ext/pdo_sqlite/sqlite_driver.c
@@ -82,7 +82,7 @@ int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int li
}
/* }}} */
-static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
+static void pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
pdo_sqlite_error_info *einfo = &H->einfo;
@@ -91,8 +91,6 @@ static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *i
add_next_index_long(info, einfo->errcode);
add_next_index_string(info, einfo->errmsg);
}
-
- return 1;
}
static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
@@ -148,7 +146,7 @@ static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
}
}
-static int sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */
+static void sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
@@ -171,11 +169,10 @@ static int sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */
pefree(H, dbh->is_persistent);
dbh->driver_data = NULL;
}
- return 0;
}
/* }}} */
-static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options)
+static bool sqlite_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
@@ -190,25 +187,25 @@ static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_le
if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY)) {
H->einfo.errcode = SQLITE_ERROR;
pdo_sqlite_error(dbh);
- return 0;
+ return false;
}
- i = sqlite3_prepare_v2(H->db, sql, sql_len, &S->stmt, &tail);
+ i = sqlite3_prepare_v2(H->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &S->stmt, &tail);
if (i == SQLITE_OK) {
- return 1;
+ return true;
}
pdo_sqlite_error(dbh);
- return 0;
+ return false;
}
-static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
+static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
char *errmsg = NULL;
- if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
+ if (sqlite3_exec(H->db, ZSTR_VAL(sql), NULL, NULL, &errmsg) != SQLITE_OK) {
pdo_sqlite_error(dbh);
if (errmsg)
sqlite3_free(errmsg);
@@ -219,26 +216,25 @@ static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_
}
}
-static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
- char *id;
- id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
- *len = strlen(id);
- return id;
+ return php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
}
/* NB: doesn't handle binary strings... use prepared stmts for that */
-static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
+static zend_string* sqlite_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype)
{
- *quoted = safe_emalloc(2, unquotedlen, 3);
- sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
- *quotedlen = strlen(*quoted);
- return 1;
+ char *quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3);
+ /* TODO use %Q format? */
+ sqlite3_snprintf(2*ZSTR_LEN(unquoted) + 3, quoted, "'%q'", ZSTR_VAL(unquoted));
+ zend_string *quoted_str = zend_string_init(quoted, strlen(quoted), 0);
+ efree(quoted);
+ return quoted_str;
}
-static int sqlite_handle_begin(pdo_dbh_t *dbh)
+static bool sqlite_handle_begin(pdo_dbh_t *dbh)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
char *errmsg = NULL;
@@ -247,12 +243,12 @@ static int sqlite_handle_begin(pdo_dbh_t *dbh)
pdo_sqlite_error(dbh);
if (errmsg)
sqlite3_free(errmsg);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int sqlite_handle_commit(pdo_dbh_t *dbh)
+static bool sqlite_handle_commit(pdo_dbh_t *dbh)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
char *errmsg = NULL;
@@ -261,12 +257,12 @@ static int sqlite_handle_commit(pdo_dbh_t *dbh)
pdo_sqlite_error(dbh);
if (errmsg)
sqlite3_free(errmsg);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int sqlite_handle_rollback(pdo_dbh_t *dbh)
+static bool sqlite_handle_rollback(pdo_dbh_t *dbh)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
char *errmsg = NULL;
@@ -275,9 +271,9 @@ static int sqlite_handle_rollback(pdo_dbh_t *dbh)
pdo_sqlite_error(dbh);
if (errmsg)
sqlite3_free(errmsg);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
@@ -295,19 +291,26 @@ static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return
return 1;
}
-static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
+static bool pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
+ zend_long lval;
switch (attr) {
case PDO_ATTR_TIMEOUT:
- sqlite3_busy_timeout(H->db, zval_get_long(val) * 1000);
- return 1;
+ if (!pdo_get_long_param(&lval, val)) {
+ return false;
+ }
+ sqlite3_busy_timeout(H->db, lval * 1000);
+ return true;
case PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES:
- sqlite3_extended_result_codes(H->db, zval_get_long(val));
- return 1;
+ if (!pdo_get_long_param(&lval, val)) {
+ return false;
+ }
+ sqlite3_extended_result_codes(H->db, lval);
+ return true;
}
- return 0;
+ return false;
}
typedef struct {
@@ -497,7 +500,7 @@ static int php_sqlite3_collation_callback(void *context,
php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
} else if (!Z_ISUNDEF(retval)) {
if (Z_TYPE(retval) != IS_LONG) {
- convert_to_long_ex(&retval);
+ convert_to_long(&retval);
}
ret = 0;
if (Z_LVAL(retval) > 0) {
@@ -695,6 +698,25 @@ static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)
}
}
+static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
+{
+ pdo_sqlite_db_handle *H = dbh->driver_data;
+
+ struct pdo_sqlite_func *func = H->funcs;
+ while (func) {
+ zend_get_gc_buffer_add_zval(gc_buffer, &func->func);
+ zend_get_gc_buffer_add_zval(gc_buffer, &func->step);
+ zend_get_gc_buffer_add_zval(gc_buffer, &func->fini);
+ func = func->next;
+ }
+
+ struct pdo_sqlite_collation *collation = H->collations;
+ while (collation) {
+ zend_get_gc_buffer_add_zval(gc_buffer, &collation->callback);
+ collation = collation->next;
+ }
+}
+
static const struct pdo_dbh_methods sqlite_methods = {
sqlite_handle_closer,
sqlite_handle_preparer,
@@ -710,11 +732,18 @@ static const struct pdo_dbh_methods sqlite_methods = {
NULL, /* check_liveness: not needed */
get_driver_methods,
pdo_sqlite_request_shutdown,
- NULL
+ NULL, /* in transaction, use PDO's internal tracking mechanism */
+ pdo_sqlite_get_gc
};
static char *make_filename_safe(const char *filename)
{
+ if (*filename && strncasecmp(filename, "file:", 5) == 0) {
+ if (PG(open_basedir) && *PG(open_basedir)) {
+ return NULL;
+ }
+ return estrdup(filename);
+ }
if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) {
char *fullpath = expand_filepath(filename, NULL);
@@ -787,6 +816,9 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{
flags = pdo_attr_lval(driver_options, PDO_SQLITE_ATTR_OPEN_FLAGS, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
+ if (!(PG(open_basedir) && *PG(open_basedir))) {
+ flags |= SQLITE_OPEN_URI;
+ }
i = sqlite3_open_v2(filename, &H->db, flags, NULL);
efree(filename);