summaryrefslogtreecommitdiff
path: root/ext/sqlite/sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/sqlite/sqlite.c')
-rw-r--r--ext/sqlite/sqlite.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c
index 84d5307aaa..f104167b92 100644
--- a/ext/sqlite/sqlite.c
+++ b/ext/sqlite/sqlite.c
@@ -118,6 +118,7 @@ function_entry sqlite_functions[] = {
PHP_FE(sqlite_popen, arg3_force_ref)
PHP_FE(sqlite_close, NULL)
PHP_FE(sqlite_query, NULL)
+ PHP_FE(sqlite_array_query, NULL)
PHP_FE(sqlite_fetch_array, NULL)
PHP_FE(sqlite_fetch_string, NULL)
PHP_FE(sqlite_fetch_all, NULL)
@@ -939,9 +940,9 @@ next_row:
/* }}} */
/* {{{ sqlite_query */
-void sqlite_query(struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value TSRMLS_DC)
+void sqlite_query(struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result *rres TSRMLS_DC)
{
- struct php_sqlite_result res, *rres;
+ struct php_sqlite_result res;
int ret;
char *errtext = NULL;
const char *tail;
@@ -960,7 +961,9 @@ void sqlite_query(struct php_sqlite_db *db, char *sql, long sql_len, int mode, i
RETURN_FALSE;
}
- rres = (struct php_sqlite_result*)emalloc(sizeof(*rres));
+ if (!rres) {
+ rres = (struct php_sqlite_result*)emalloc(sizeof(*rres));
+ }
memcpy(rres, &res, sizeof(*rres));
rres->db = db;
zend_list_addref(db->rsrc_id);
@@ -974,7 +977,9 @@ void sqlite_query(struct php_sqlite_db *db, char *sql, long sql_len, int mode, i
rres->curr_row = 0;
- ZEND_REGISTER_RESOURCE(return_value, rres, le_sqlite_result);
+ if (return_value) {
+ ZEND_REGISTER_RESOURCE(return_value, rres, le_sqlite_result);
+ }
}
/* }}} */
@@ -1008,7 +1013,7 @@ PHP_FUNCTION(sqlite_unbuffered_query)
return;
}
- sqlite_query(db, sql, sql_len, mode, 0, return_value TSRMLS_CC);
+ sqlite_query(db, sql, sql_len, mode, 0, return_value, NULL TSRMLS_CC);
}
/* }}} */
@@ -1041,14 +1046,14 @@ PHP_FUNCTION(sqlite_query)
return;
}
- sqlite_query(db, sql, sql_len, mode, 1, return_value TSRMLS_CC);
+ sqlite_query(db, sql, sql_len, mode, 1, return_value, NULL TSRMLS_CC);
}
/* }}} */
/* {{{ php_sqlite_fetch_array */
static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
{
- int j;
+ int j, buffered = res->buffered;
const char **rowdata, **colnames;
/* check range of the row */
@@ -1070,17 +1075,22 @@ static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend
zval *decoded;
MAKE_STD_ZVAL(decoded);
- if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
+ if (rowdata[j] == NULL) {
+ ZVAL_NULL(decoded);
+ } else if (decode_binary && rowdata[j][0] == '\x01') {
int l = strlen(rowdata[j]);
Z_STRVAL_P(decoded) = emalloc(l);
Z_STRLEN_P(decoded) = l = sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
Z_STRVAL_P(decoded)[l] = '\0';
Z_TYPE_P(decoded) = IS_STRING;
+ if (!buffered) {
+ efree((char*)rowdata[j]);
+ rowdata[j] = NULL;
+ }
} else {
- if ((char*)rowdata[j]) {
- ZVAL_STRING(decoded, (char*)rowdata[j], 1);
- } else {
- ZVAL_NULL(decoded);
+ ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
+ if (!buffered) {
+ rowdata[j] = NULL;
}
}
@@ -1111,8 +1121,6 @@ static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which,
{
int j;
const char **rowdata, **colnames;
- char *decoded = NULL;
- int decoded_len;
/* check range of the row */
if (res->curr_row >= res->nrows) {
@@ -1120,11 +1128,6 @@ static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which,
RETURN_FALSE;
}
colnames = (const char**)res->col_names;
- if (res->buffered) {
- rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
- } else {
- rowdata = (const char**)res->table;
- }
if (Z_TYPE_P(which) == IS_LONG) {
j = Z_LVAL_P(which);
@@ -1141,27 +1144,29 @@ static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which,
RETURN_FALSE;
}
- if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
- int l = strlen(rowdata[j]);
- decoded = do_alloca(l);
- decoded_len = sqlite_decode_binary(rowdata[j]+1, decoded);
+ if (res->buffered) {
+ rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
} else {
- decoded = (char*)rowdata[j];
- if (decoded) {
- decoded_len = strlen(decoded);
- } else {
- decoded_len = 0;
- }
+ rowdata = (const char**)res->table;
}
-
- if (decoded == NULL) {
+
+ if (rowdata[j] == NULL) {
RETURN_NULL();
+ } else if (decode_binary && rowdata[j][0] == '\x01') {
+ int l = strlen(rowdata[j]);
+ char *decoded = emalloc(l);
+ l = sqlite_decode_binary(rowdata[j]+1, decoded);
+ decoded[l] = '\0';
+ RETVAL_STRINGL(decoded, l, 0);
+ if (!res->buffered) {
+ efree((char*)rowdata[j]);
+ rowdata[j] = NULL;
+ }
} else {
- RETURN_STRINGL(decoded, decoded_len, 1);
- }
-
- if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
- free_alloca(decoded);
+ RETVAL_STRING((char*)rowdata[j], res->buffered);
+ if (!res->buffered) {
+ rowdata[j] = NULL;
+ }
}
}
/* }}} */
@@ -1222,6 +1227,51 @@ PHP_FUNCTION(sqlite_fetch_array)
}
/* }}} */
+/* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type, bool decode_binary ])
+ Executes a query against a given database and returns an array */
+PHP_FUNCTION(sqlite_array_query)
+{
+ zval *zdb, *ent;
+ struct php_sqlite_db *db;
+ struct php_sqlite_result *rres;
+ char *sql;
+ long sql_len;
+ int mode = PHPSQLITE_BOTH;
+ char *errtext = NULL;
+ zend_bool decode_binary = 1;
+
+ if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+ ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
+ FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
+ return;
+ }
+ DB_FROM_ZVAL(db, &zdb);
+
+ /* avoid doing work if we can */
+ if (!return_value_used) {
+ db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
+
+ if (db->last_err_code != SQLITE_OK) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
+ sqlite_freemem(errtext);
+ }
+ return;
+ }
+
+ rres = (struct php_sqlite_result *)emalloc(sizeof(*rres));
+ sqlite_query(db, sql, sql_len, mode, 0, NULL, rres TSRMLS_CC);
+
+ array_init(return_value);
+
+ while (rres->curr_row < rres->nrows) {
+ MAKE_STD_ZVAL(ent);
+ php_sqlite_fetch_array(rres, mode, decode_binary, 1, ent TSRMLS_CC);
+ add_next_index_zval(return_value, ent);
+ }
+ real_result_dtor(rres TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ proto string sqlite_fetch_array(resource result [, bool decode_binary])
Fetches first column of a result set as a string */
PHP_FUNCTION(sqlite_fetch_string)