Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
14 changes: 3 additions & 11 deletions ext/sqlite3/php_sqlite3_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ typedef struct _php_sqlite3_collation {

/* Structure for SQLite Database object. */
typedef struct _php_sqlite3_db_object {
int initialised;
bool initialised;
sqlite3 *db;
php_sqlite3_func *funcs;
php_sqlite3_collation *collations;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you move this next to the exception field to back it? As there are going to be 7 bytes of padding, and then again a bunch of padding after the exception field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do it originally because it seemed better to keep db and initialised in the same cacheline, but I see now that I can just move exception up and it will result in the same struct size while keeping db and initialised together.

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