|
|
|
|
@@ -38,28 +38,6 @@ static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, c
|
|
|
|
|
static void sqlite3_param_dtor(zval *data);
|
|
|
|
|
static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
|
|
|
|
|
|
|
|
|
|
/* {{{ Error Handler */
|
|
|
|
|
static void php_sqlite3_error(php_sqlite3_db_object *db_obj, const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list arg;
|
|
|
|
|
char *message;
|
|
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
|
vspprintf(&message, 0, format, arg);
|
|
|
|
|
va_end(arg);
|
|
|
|
|
|
|
|
|
|
if (db_obj && db_obj->exception) {
|
|
|
|
|
zend_throw_exception(zend_ce_exception, message, 0);
|
|
|
|
|
} else {
|
|
|
|
|
php_error_docref(NULL, E_WARNING, "%s", message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (message) {
|
|
|
|
|
efree(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
|
#define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
|
|
|
|
|
if (!(db_obj) || !(member)) { \
|
|
|
|
|
zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \
|
|
|
|
|
@@ -87,10 +65,33 @@ static zend_object_handlers sqlite3_stmt_object_handlers;
|
|
|
|
|
static zend_object_handlers sqlite3_result_object_handlers;
|
|
|
|
|
|
|
|
|
|
/* Class entries */
|
|
|
|
|
zend_class_entry *php_sqlite3_exception_ce;
|
|
|
|
|
zend_class_entry *php_sqlite3_sc_entry;
|
|
|
|
|
zend_class_entry *php_sqlite3_stmt_entry;
|
|
|
|
|
zend_class_entry *php_sqlite3_result_entry;
|
|
|
|
|
|
|
|
|
|
/* {{{ Error Handler */
|
|
|
|
|
static void php_sqlite3_error(php_sqlite3_db_object *db_obj, int errcode, const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list arg;
|
|
|
|
|
char *message;
|
|
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
|
vspprintf(&message, 0, format, arg);
|
|
|
|
|
va_end(arg);
|
|
|
|
|
|
|
|
|
|
if (db_obj && db_obj->exception) {
|
|
|
|
|
zend_throw_exception(php_sqlite3_exception_ce, message, errcode);
|
|
|
|
|
} else {
|
|
|
|
|
php_error_docref(NULL, E_WARNING, "%s", message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (message) {
|
|
|
|
|
efree(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
|
/* {{{ Opens a SQLite 3 Database, if the build includes encryption then it will attempt to use the key. */
|
|
|
|
|
PHP_METHOD(SQLite3, open)
|
|
|
|
|
{
|
|
|
|
|
@@ -188,7 +189,7 @@ PHP_METHOD(SQLite3, close)
|
|
|
|
|
if(db_obj->db) {
|
|
|
|
|
errcode = sqlite3_close(db_obj->db);
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to close database: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "Unable to close database: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -204,6 +205,7 @@ PHP_METHOD(SQLite3, exec)
|
|
|
|
|
{
|
|
|
|
|
php_sqlite3_db_object *db_obj;
|
|
|
|
|
zval *object = ZEND_THIS;
|
|
|
|
|
int errcode;
|
|
|
|
|
zend_string *sql;
|
|
|
|
|
char *errtext = NULL;
|
|
|
|
|
db_obj = Z_SQLITE3_DB_P(object);
|
|
|
|
|
@@ -214,8 +216,10 @@ PHP_METHOD(SQLite3, exec)
|
|
|
|
|
|
|
|
|
|
SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
|
|
|
|
|
|
|
|
|
|
if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "%s", errtext);
|
|
|
|
|
errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
|
|
|
|
|
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "%s", errtext);
|
|
|
|
|
sqlite3_free(errtext);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -367,7 +371,7 @@ PHP_METHOD(SQLite3, busyTimeout)
|
|
|
|
|
#ifdef SQLITE_ENABLE_API_ARMOR
|
|
|
|
|
return_code = sqlite3_busy_timeout(db_obj->db, ms);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to set busy timeout: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to set busy timeout: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
@@ -400,18 +404,18 @@ PHP_METHOD(SQLite3, loadExtension)
|
|
|
|
|
if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
|
|
|
|
|
(strcmp(sapi_module.name, "cli") != 0) &&
|
|
|
|
|
(strncmp(sapi_module.name, "embed", 5) != 0)
|
|
|
|
|
) { php_sqlite3_error(db_obj, "Not supported in multithreaded Web servers");
|
|
|
|
|
) { php_sqlite3_error(db_obj, 0, "Not supported in multithreaded Web servers");
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (!SQLITE3G(extension_dir)) {
|
|
|
|
|
php_sqlite3_error(db_obj, "SQLite Extension are disabled");
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "SQLite Extensions are disabled");
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (extension_len == 0) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Empty string as an extension");
|
|
|
|
|
zend_argument_value_error(1, "cannot be empty");
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -425,7 +429,7 @@ PHP_METHOD(SQLite3, loadExtension)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!VCWD_REALPATH(lib_path, fullpath)) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to load extension at '%s'", lib_path);
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "Unable to load extension at '%s'", lib_path);
|
|
|
|
|
efree(lib_path);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -433,14 +437,14 @@ PHP_METHOD(SQLite3, loadExtension)
|
|
|
|
|
efree(lib_path);
|
|
|
|
|
|
|
|
|
|
if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to open extensions outside the defined directory");
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "Unable to open extensions outside the defined directory");
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Extension loading should only be enabled for when we attempt to load */
|
|
|
|
|
sqlite3_enable_load_extension(db_obj->db, 1);
|
|
|
|
|
if (sqlite3_load_extension(db_obj->db, fullpath, 0, &errtext) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "%s", errtext);
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "%s", errtext);
|
|
|
|
|
sqlite3_free(errtext);
|
|
|
|
|
sqlite3_enable_load_extension(db_obj->db, 0);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
@@ -520,7 +524,7 @@ PHP_METHOD(SQLite3, prepare)
|
|
|
|
|
|
|
|
|
|
errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
zval_ptr_dtor(return_value);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -560,8 +564,10 @@ PHP_METHOD(SQLite3, query)
|
|
|
|
|
|
|
|
|
|
/* If there was no return value then just execute the query */
|
|
|
|
|
if (!USED_RET()) {
|
|
|
|
|
if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "%s", errtext);
|
|
|
|
|
int errcode;
|
|
|
|
|
errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "%s", errtext);
|
|
|
|
|
sqlite3_free(errtext);
|
|
|
|
|
}
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
@@ -574,7 +580,7 @@ PHP_METHOD(SQLite3, query)
|
|
|
|
|
|
|
|
|
|
return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, return_code, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
zval_ptr_dtor(&stmt);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -605,7 +611,7 @@ PHP_METHOD(SQLite3, query)
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
if (!EG(exception)) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
}
|
|
|
|
|
sqlite3_finalize(stmt_obj->stmt);
|
|
|
|
|
stmt_obj->initialised = 0;
|
|
|
|
|
@@ -676,8 +682,10 @@ PHP_METHOD(SQLite3, querySingle)
|
|
|
|
|
|
|
|
|
|
/* If there was no return value then just execute the query */
|
|
|
|
|
if (!USED_RET()) {
|
|
|
|
|
if (sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "%s", errtext);
|
|
|
|
|
int errcode;
|
|
|
|
|
errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "%s", errtext);
|
|
|
|
|
sqlite3_free(errtext);
|
|
|
|
|
}
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
@@ -685,7 +693,7 @@ PHP_METHOD(SQLite3, querySingle)
|
|
|
|
|
|
|
|
|
|
return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &stmt, NULL);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, return_code, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -718,7 +726,7 @@ PHP_METHOD(SQLite3, querySingle)
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
if (!EG(exception)) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
}
|
|
|
|
|
RETVAL_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -909,7 +917,7 @@ static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, in
|
|
|
|
|
//retval ought to contain a ZVAL_LONG by now
|
|
|
|
|
// (the result of a comparison, i.e. most likely -1, 0, or 1)
|
|
|
|
|
//I suppose we could accept any scalar return type, though.
|
|
|
|
|
php_error_docref(NULL, E_WARNING, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined.");
|
|
|
|
|
php_sqlite3_error(NULL, 0, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined.");
|
|
|
|
|
} else {
|
|
|
|
|
ret = Z_LVAL(retval);
|
|
|
|
|
}
|
|
|
|
|
@@ -1081,12 +1089,12 @@ static ssize_t php_sqlite3_stream_write(php_stream *stream, const char *buf, siz
|
|
|
|
|
php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
|
|
|
|
|
|
|
|
|
|
if (sqlite3_stream->flags & SQLITE_OPEN_READONLY) {
|
|
|
|
|
php_error_docref(NULL, E_WARNING, "Can't write to blob stream: is open as read only");
|
|
|
|
|
php_sqlite3_error(NULL, 0, "Can't write to blob stream: is open as read only");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sqlite3_stream->position + count > sqlite3_stream->size) {
|
|
|
|
|
php_error_docref(NULL, E_WARNING, "It is not possible to increase the size of a BLOB");
|
|
|
|
|
php_sqlite3_error(NULL, 0, "It is not possible to increase the size of a BLOB");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1252,7 +1260,7 @@ PHP_METHOD(SQLite3, openBlob)
|
|
|
|
|
sqlite_flags = (flags & SQLITE_OPEN_READWRITE) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
if (sqlite3_blob_open(db_obj->db, dbname, table, column, rowid, sqlite_flags, &blob) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to open blob: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to open blob: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1291,6 +1299,10 @@ PHP_METHOD(SQLite3, enableExceptions)
|
|
|
|
|
|
|
|
|
|
RETVAL_BOOL(db_obj->exception);
|
|
|
|
|
|
|
|
|
|
if (!enableExceptions) {
|
|
|
|
|
php_error_docref("ref.sqlite3", E_DEPRECATED, "Use of warnings for SQLite3 is deprecated");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db_obj->exception = enableExceptions;
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
@@ -1372,13 +1384,13 @@ PHP_METHOD(SQLite3, backup)
|
|
|
|
|
|
|
|
|
|
if (rc != SQLITE_OK) {
|
|
|
|
|
if (rc == SQLITE_BUSY) {
|
|
|
|
|
php_sqlite3_error(source_obj, "Backup failed: source database is busy");
|
|
|
|
|
php_sqlite3_error(source_obj, rc, "Backup failed: source database is busy");
|
|
|
|
|
}
|
|
|
|
|
else if (rc == SQLITE_LOCKED) {
|
|
|
|
|
php_sqlite3_error(source_obj, "Backup failed: source database is locked");
|
|
|
|
|
php_sqlite3_error(source_obj, rc, "Backup failed: source database is locked");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
php_sqlite3_error(source_obj, "Backup failed: %d, %s", rc, sqlite3_errmsg(source_obj->db));
|
|
|
|
|
php_sqlite3_error(source_obj, rc, "Backup failed: %s", sqlite3_errmsg(source_obj->db));
|
|
|
|
|
}
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -1436,7 +1448,7 @@ PHP_METHOD(SQLite3Stmt, reset)
|
|
|
|
|
SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
|
|
|
|
|
|
|
|
|
|
if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
RETURN_TRUE;
|
|
|
|
|
@@ -1456,7 +1468,7 @@ PHP_METHOD(SQLite3Stmt, clear)
|
|
|
|
|
SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
|
|
|
|
|
|
|
|
|
|
if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1509,7 +1521,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
if (Z_TYPE_P(parameter) == IS_NULL) {
|
|
|
|
|
return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
@@ -1523,7 +1535,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
|
|
|
|
|
#endif
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
@@ -1531,7 +1543,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
convert_to_double(parameter);
|
|
|
|
|
return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter));
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
@@ -1542,7 +1554,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
if (Z_TYPE_P(parameter) == IS_RESOURCE) {
|
|
|
|
|
php_stream_from_zval_no_verify(stream, parameter);
|
|
|
|
|
if (stream == NULL) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, 0, "Unable to read stream for parameter %ld", param->param_number);
|
|
|
|
|
return FAILURE;
|
|
|
|
|
}
|
|
|
|
|
buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
|
|
|
|
|
@@ -1554,12 +1566,12 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT);
|
|
|
|
|
zend_string_release_ex(buffer, 0);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@@ -1572,7 +1584,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
}
|
|
|
|
|
return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
zend_string_release(str);
|
|
|
|
|
break;
|
|
|
|
|
@@ -1581,12 +1593,12 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
|
|
|
|
|
case SQLITE_NULL:
|
|
|
|
|
return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
|
|
|
|
|
if (return_code != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, 0, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
|
|
|
|
|
return FAILURE;
|
|
|
|
|
}
|
|
|
|
|
} ZEND_HASH_FOREACH_END();
|
|
|
|
|
@@ -1626,7 +1638,7 @@ PHP_METHOD(SQLite3Stmt, getSQL)
|
|
|
|
|
RETVAL_STRING(sql);
|
|
|
|
|
sqlite3_free(sql);
|
|
|
|
|
#else
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, 0, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
@@ -1808,7 +1820,7 @@ PHP_METHOD(SQLite3Stmt, execute)
|
|
|
|
|
ZEND_FALLTHROUGH;
|
|
|
|
|
default:
|
|
|
|
|
if (!EG(exception)) {
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
|
|
|
|
|
}
|
|
|
|
|
zval_ptr_dtor(return_value);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
@@ -1851,7 +1863,7 @@ PHP_METHOD(SQLite3Stmt, __construct)
|
|
|
|
|
|
|
|
|
|
errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
|
|
|
|
|
if (errcode != SQLITE_OK) {
|
|
|
|
|
php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db));
|
|
|
|
|
php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
|
|
|
|
|
zval_ptr_dtor(return_value);
|
|
|
|
|
RETURN_FALSE;
|
|
|
|
|
}
|
|
|
|
|
@@ -1997,7 +2009,7 @@ PHP_METHOD(SQLite3Result, fetchArray)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
php_sqlite3_error(result_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt)));
|
|
|
|
|
php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
@@ -2127,15 +2139,15 @@ static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, c
|
|
|
|
|
|
|
|
|
|
zend_call_known_fcc(&db_obj->authorizer_fcc, &retval, /* argc */ 5, argv, /* named_params */ NULL);
|
|
|
|
|
if (Z_ISUNDEF(retval)) {
|
|
|
|
|
php_sqlite3_error(db_obj, "An error occurred while invoking the authorizer callback");
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "An error occurred while invoking the authorizer callback");
|
|
|
|
|
} else {
|
|
|
|
|
if (Z_TYPE(retval) != IS_LONG) {
|
|
|
|
|
php_sqlite3_error(db_obj, "The authorizer callback returned an invalid type: expected int");
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid type: expected int");
|
|
|
|
|
} else {
|
|
|
|
|
authreturn = Z_LVAL(retval);
|
|
|
|
|
|
|
|
|
|
if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY) {
|
|
|
|
|
php_sqlite3_error(db_obj, "The authorizer callback returned an invalid value");
|
|
|
|
|
php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid value: %d", authreturn);
|
|
|
|
|
authreturn = SQLITE_DENY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -2349,6 +2361,9 @@ static void sqlite3_param_dtor(zval *data) /* {{{ */
|
|
|
|
|
/* {{{ PHP_MINIT_FUNCTION */
|
|
|
|
|
PHP_MINIT_FUNCTION(sqlite3)
|
|
|
|
|
{
|
|
|
|
|
/* Register SQLite3Exception class */
|
|
|
|
|
php_sqlite3_exception_ce = register_class_SQLite3Exception(zend_ce_exception);
|
|
|
|
|
|
|
|
|
|
#ifdef ZTS
|
|
|
|
|
/* Refuse to load if this wasn't a threasafe library loaded */
|
|
|
|
|
if (!sqlite3_threadsafe()) {
|
|
|
|
|
|