SQLite3: Separating parameters binding in a function

This commit is contained in:
BohwaZ 2018-12-07 14:06:03 +01:00 committed by Christoph M. Becker
parent 8f46f6dd6f
commit abd9f08752

View File

@ -1393,6 +1393,108 @@ PHP_METHOD(sqlite3stmt, readOnly)
}
/* }}} */
/* bind parameters to a statement before execution */
static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
{
struct php_sqlite3_bound_param *param;
int return_code;
if (stmt_obj->bound_params) {
ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
zval *parameter;
/* parameter must be a reference? */
if (Z_ISREF(param->parameter)) {
parameter = Z_REFVAL(param->parameter);
} else {
parameter = &param->parameter;
}
/* If the ZVAL is null then it should be bound as that */
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);
}
continue;
}
switch (param->type) {
case SQLITE_INTEGER:
convert_to_long(parameter);
#if ZEND_LONG_MAX > 2147483647
return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
#else
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);
}
break;
case SQLITE_FLOAT:
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);
}
break;
case SQLITE_BLOB:
{
php_stream *stream = NULL;
zend_string *buffer = NULL;
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);
return FAILURE;
}
buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
} else {
buffer = zval_get_string(parameter);
}
if (buffer) {
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);
}
} 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);
}
}
break;
}
case SQLITE3_TEXT:
convert_to_string(parameter);
return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), SQLITE_STATIC);
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);
}
break;
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);
}
break;
default:
php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
return FAILURE;
}
} ZEND_HASH_FOREACH_END();
}
return SUCCESS;
}
/* }}} */
static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
{
HashTable *hash;
@ -1548,7 +1650,7 @@ PHP_METHOD(sqlite3stmt, execute)
php_sqlite3_result *result;
zval *object = ZEND_THIS;
int return_code = 0;
struct php_sqlite3_bound_param *param;
int bind_rc = 0;
stmt_obj = Z_SQLITE3_STMT_P(object);
@ -1561,96 +1663,11 @@ PHP_METHOD(sqlite3stmt, execute)
/* Always reset statement before execution, see bug #77051 */
sqlite3_reset(stmt_obj->stmt);
if (stmt_obj->bound_params) {
ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
zval *parameter;
/* parameter must be a reference? */
if (Z_ISREF(param->parameter)) {
parameter = Z_REFVAL(param->parameter);
} else {
parameter = &param->parameter;
}
/* Bind parameters to the statement */
bind_rc = php_sqlite3_bind_params(stmt_obj);
/* If the ZVAL is null then it should be bound as that */
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);
}
continue;
}
switch (param->type) {
case SQLITE_INTEGER:
convert_to_long(parameter);
#if ZEND_LONG_MAX > 2147483647
return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
#else
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);
}
break;
case SQLITE_FLOAT:
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);
}
break;
case SQLITE_BLOB:
{
php_stream *stream = NULL;
zend_string *buffer = NULL;
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);
RETURN_FALSE;
}
buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
} else {
buffer = zval_get_string(parameter);
}
if (buffer) {
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);
}
} 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);
}
}
break;
}
case SQLITE3_TEXT:
convert_to_string(parameter);
return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), SQLITE_STATIC);
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);
}
break;
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);
}
break;
default:
php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
RETURN_FALSE;
}
} ZEND_HASH_FOREACH_END();
if (bind_rc == FAILURE) {
RETURN_FALSE;
}
return_code = sqlite3_step(stmt_obj->stmt);