Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions ext/sqlite3/php_sqlite3_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ typedef struct _php_sqlite3_collation {

/* Structure for SQLite Database object. */
typedef struct _php_sqlite3_db_object {
int initialised;
bool initialised;
bool exception;

sqlite3 *db;
php_sqlite3_func *funcs;
php_sqlite3_collation *collations;
zend_fcall_info_cache authorizer_fcc;

bool exception;

zend_llist free_list;
zend_object zo;
} php_sqlite3_db_object;
Expand All @@ -89,24 +89,17 @@ typedef struct _php_sqlite3_agg_context {
typedef struct _php_sqlite3_stmt_object php_sqlite3_stmt;
typedef struct _php_sqlite3_result_object php_sqlite3_result;

/* sqlite3 objects to be destroyed */
typedef struct _php_sqlite3_free_list {
zval stmt_obj_zval;
php_sqlite3_stmt *stmt_obj;
} php_sqlite3_free_list;

/* Structure for SQLite Result object. */
struct _php_sqlite3_result_object {
php_sqlite3_db_object *db_obj;
php_sqlite3_stmt *stmt_obj;
zval stmt_obj_zval;

bool is_prepared_statement;
/* Cache of column names to speed up repeated fetchArray(SQLITE3_ASSOC) calls.
* Cache is cleared on reset() and finalize() calls. */
int column_count;
zend_string **column_names;

int is_prepared_statement;
zend_object zo;
};

Expand All @@ -120,9 +113,8 @@ static inline php_sqlite3_result *php_sqlite3_result_from_obj(zend_object *obj)
struct _php_sqlite3_stmt_object {
sqlite3_stmt *stmt;
php_sqlite3_db_object *db_obj;
zval db_obj_zval;

int initialised;
bool initialised;

/* Keep track of the zvals for bound parameters */
HashTable *bound_params;
Expand Down
111 changes: 39 additions & 72 deletions ext/sqlite3/sqlite3.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
static PHP_GINIT_FUNCTION(sqlite3);
static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4);
static void sqlite3_param_dtor(zval *data);
static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement);

#define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
if (!(db_obj) || !(member)) { \
Expand Down Expand Up @@ -161,7 +161,7 @@ PHP_METHOD(SQLite3, open)
}
#endif

db_obj->initialised = 1;
db_obj->initialised = true;
db_obj->authorizer_fcc = empty_fcall_info_cache;

sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, db_obj);
Expand Down Expand Up @@ -199,7 +199,7 @@ PHP_METHOD(SQLite3, close)
RETURN_FALSE;
}
}
db_obj->initialised = 0;
db_obj->initialised = false;
}

RETURN_TRUE;
Expand Down Expand Up @@ -509,7 +509,6 @@ PHP_METHOD(SQLite3, prepare)
zval *object = ZEND_THIS;
zend_string *sql;
int errcode;
php_sqlite3_free_list *free_item;

db_obj = Z_SQLITE3_DB_P(object);

Expand All @@ -526,7 +525,7 @@ PHP_METHOD(SQLite3, prepare)
object_init_ex(return_value, php_sqlite3_stmt_entry);
stmt_obj = Z_SQLITE3_STMT_P(return_value);
stmt_obj->db_obj = db_obj;
ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
Z_ADDREF_P(object);

errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
if (errcode != SQLITE_OK) {
Expand All @@ -535,13 +534,9 @@ PHP_METHOD(SQLite3, prepare)
RETURN_FALSE;
}

stmt_obj->initialised = 1;
stmt_obj->initialised = true;

free_item = emalloc(sizeof(php_sqlite3_free_list));
free_item->stmt_obj = stmt_obj;
ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(return_value));

zend_llist_add_element(&(db_obj->free_list), &free_item);
zend_llist_add_element(&(db_obj->free_list), &stmt_obj);
}
/* }}} */

Expand Down Expand Up @@ -582,7 +577,7 @@ PHP_METHOD(SQLite3, query)
object_init_ex(&stmt, php_sqlite3_stmt_entry);
stmt_obj = Z_SQLITE3_STMT_P(&stmt);
stmt_obj->db_obj = db_obj;
ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
Z_ADDREF_P(object);

return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
if (return_code != SQLITE_OK) {
Expand All @@ -591,27 +586,22 @@ PHP_METHOD(SQLite3, query)
RETURN_FALSE;
}

stmt_obj->initialised = 1;
stmt_obj->initialised = true;

object_init_ex(return_value, php_sqlite3_result_entry);
result = Z_SQLITE3_RESULT_P(return_value);
result->db_obj = db_obj;
result->stmt_obj = stmt_obj;
result->column_names = NULL;
result->column_count = -1;
ZVAL_OBJ(&result->stmt_obj_zval, Z_OBJ(stmt));

return_code = sqlite3_step(result->stmt_obj->stmt);

switch (return_code) {
case SQLITE_ROW: /* Valid Row */
case SQLITE_DONE: /* Valid but no results */
{
php_sqlite3_free_list *free_item;
free_item = emalloc(sizeof(php_sqlite3_free_list));
free_item->stmt_obj = stmt_obj;
free_item->stmt_obj_zval = stmt;
zend_llist_add_element(&(db_obj->free_list), &free_item);
zend_llist_add_element(&(db_obj->free_list), &stmt_obj);
sqlite3_reset(result->stmt_obj->stmt);
break;
}
Expand All @@ -620,7 +610,7 @@ PHP_METHOD(SQLite3, query)
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;
stmt_obj->initialised = false;
zval_ptr_dtor(return_value);
RETURN_FALSE;
}
Expand Down Expand Up @@ -833,13 +823,14 @@ static int sqlite3_do_callback(zend_fcall_info_cache *fcc, uint32_t argc, sqlite
break;

default: {
zend_string *str = zval_try_get_string(&retval);
zend_string *tmp;
zend_string *str = zval_try_get_tmp_string(&retval, &tmp);
if (UNEXPECTED(!str)) {
ret = FAILURE;
break;
}
sqlite3_result_text(context, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
zend_string_release(str);
zend_tmp_string_release(tmp);
break;
}
}
Expand Down Expand Up @@ -1415,7 +1406,7 @@ PHP_METHOD(SQLite3Stmt, close)

SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);

zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
zend_llist_del_element(&(stmt_obj->db_obj->free_list), stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);

RETURN_TRUE;
}
Expand Down Expand Up @@ -1564,15 +1555,16 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
}

case SQLITE3_TEXT: {
zend_string *str = zval_try_get_string(parameter);
zend_string *tmp;
zend_string *str = zval_try_get_tmp_string(parameter, &tmp);
if (UNEXPECTED(!str)) {
return FAILURE;
}
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, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
}
zend_string_release(str);
zend_tmp_string_release(tmp);
break;
}

Expand Down Expand Up @@ -1790,12 +1782,12 @@ PHP_METHOD(SQLite3Stmt, execute)
object_init_ex(return_value, php_sqlite3_result_entry);
result = Z_SQLITE3_RESULT_P(return_value);

result->is_prepared_statement = 1;
result->is_prepared_statement = true;
result->db_obj = stmt_obj->db_obj;
result->stmt_obj = stmt_obj;
result->column_names = NULL;
result->column_count = -1;
ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object));
Z_ADDREF_P(object);

break;
}
Expand Down Expand Up @@ -1823,7 +1815,6 @@ PHP_METHOD(SQLite3Stmt, __construct)
zval *db_zval;
zend_string *sql;
int errcode;
php_sqlite3_free_list *free_item;

stmt_obj = Z_SQLITE3_STMT_P(object);

Expand All @@ -1840,22 +1831,17 @@ PHP_METHOD(SQLite3Stmt, __construct)
}

stmt_obj->db_obj = db_obj;
ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval));
Z_ADDREF_P(db_zval);

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, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
zval_ptr_dtor(return_value);
RETURN_FALSE;
}
stmt_obj->initialised = 1;

free_item = emalloc(sizeof(php_sqlite3_free_list));
free_item->stmt_obj = stmt_obj;
//?? free_item->stmt_obj_zval = ZEND_THIS;
ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(object));
stmt_obj->initialised = true;

zend_llist_add_element(&(db_obj->free_list), &free_item);
zend_llist_add_element(&(db_obj->free_list), &stmt_obj);
}
/* }}} */

Expand Down Expand Up @@ -1998,7 +1984,7 @@ PHP_METHOD(SQLite3Result, fetchArray)
static void sqlite3result_clear_column_names_cache(php_sqlite3_result *result) {
if (result->column_names) {
for (int i = 0; i < result->column_count; i++) {
zend_string_release(result->column_names[i]);
zend_string_release_ex(result->column_names[i], false);
}
efree(result->column_names);
}
Expand Down Expand Up @@ -2041,9 +2027,9 @@ PHP_METHOD(SQLite3Result, finalize)
sqlite3result_clear_column_names_cache(result_obj);

/* We need to finalize an internal statement */
if (result_obj->is_prepared_statement == 0) {
zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
(int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
if (!result_obj->is_prepared_statement) {
zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj,
(int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
} else {
sqlite3_reset(result_obj->stmt_obj->stmt);
}
Expand Down Expand Up @@ -2149,25 +2135,18 @@ static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, c
/* {{{ php_sqlite3_free_list_dtor */
static void php_sqlite3_free_list_dtor(void **item)
{
php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item;
php_sqlite3_stmt *stmt_obj = *item;

if (free_item->stmt_obj && free_item->stmt_obj->initialised) {
sqlite3_finalize(free_item->stmt_obj->stmt);
free_item->stmt_obj->initialised = 0;
if (stmt_obj && stmt_obj->initialised) {
sqlite3_finalize(stmt_obj->stmt);
stmt_obj->initialised = false;
}
efree(*item);
}
/* }}} */

static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
{
return ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));
}
/* }}} */

static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */
static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement ) /* {{{ */
{
return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);
return ((*stmt_obj_ptr)->initialised && statement == (*stmt_obj_ptr)->stmt);
}
/* }}} */

Expand All @@ -2177,10 +2156,6 @@ static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
php_sqlite3_func *func;
php_sqlite3_collation *collation;

if (!intern) {
return;
}

/* Release function_name from authorizer */
if (ZEND_FCC_INITIALIZED(intern->authorizer_fcc)) {
zend_fcc_dtor(&intern->authorizer_fcc);
Expand Down Expand Up @@ -2222,7 +2197,7 @@ static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */

if (intern->initialised && intern->db) {
sqlite3_close(intern->db);
intern->initialised = 0;
intern->initialised = false;
}

zend_object_std_dtor(&intern->zo);
Expand Down Expand Up @@ -2276,10 +2251,6 @@ static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
{
php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);

if (!intern) {
return;
}

if (intern->bound_params) {
zend_hash_destroy(intern->bound_params);
FREE_HASHTABLE(intern->bound_params);
Expand All @@ -2291,8 +2262,8 @@ static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
(int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
}

if (!Z_ISUNDEF(intern->db_obj_zval)) {
zval_ptr_dtor(&intern->db_obj_zval);
if (intern->db_obj) {
OBJ_RELEASE(&intern->db_obj->zo);
}

zend_object_std_dtor(&intern->zo);
Expand All @@ -2303,18 +2274,14 @@ static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ *
{
php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);

if (!intern) {
return;
}

sqlite3result_clear_column_names_cache(intern);

if (!Z_ISNULL(intern->stmt_obj_zval)) {
if (intern->stmt_obj && intern->stmt_obj->initialised) {
if (intern->stmt_obj) {
if (intern->stmt_obj->initialised) {
sqlite3_reset(intern->stmt_obj->stmt);
}

zval_ptr_dtor(&intern->stmt_obj_zval);
OBJ_RELEASE(&intern->stmt_obj->zo);
}

zend_object_std_dtor(&intern->zo);
Expand All @@ -2329,7 +2296,7 @@ static zend_object *php_sqlite3_object_new(zend_class_entry *class_type) /* {{{
intern = zend_object_alloc(sizeof(php_sqlite3_db_object), class_type);

/* Need to keep track of things to free */
zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_stmt *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);

zend_object_std_init(&intern->zo, class_type);
object_properties_init(&intern->zo, class_type);
Expand Down