Patch bug45259_sqlite-bind-params-autodetect for PDO related Bug #45259
Patch version 2010-12-19 12:46 UTC
Return to Bug #45259 |
Download this patch
Patch Revisions:
Developer: sl9@gmx.net
Index: ext/pdo_sqlite/sqlite_statement.c
===================================================================
--- ext/pdo_sqlite/sqlite_statement.c (revision 306430)
+++ ext/pdo_sqlite/sqlite_statement.c (working copy)
@@ -78,6 +78,8 @@
static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
enum pdo_param_event event_type TSRMLS_DC)
{
+ int hookResult = 0; // failure
+
pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
switch (event_type) {
@@ -86,39 +88,97 @@
sqlite3_reset(S->stmt);
S->done = 1;
}
-
+
if (param->is_param) {
-
if (param->paramno == -1) {
param->paramno = sqlite3_bind_parameter_index(S->stmt, param->name) - 1;
}
+ if(PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_ZVAL){
+ // XXX: User didn't specify a PDO_PARAM_* value, so let's do autodetect using the ZVAL type
+ switch(Z_TYPE_P(param->parameter)){
+ case IS_STRING:
+ param->param_type = PDO_PARAM_STR;
+ break;
+ case IS_LONG:
+ param->param_type = PDO_PARAM_INT;
+ break;
+ case IS_NULL:
+ param->param_type = PDO_PARAM_NULL;
+ break;
+ case IS_BOOL:
+ param->param_type = PDO_PARAM_BOOL;
+ break;
+ case IS_DOUBLE:
+ param->param_type = PDO_PARAM_INT;
+ break;
+ case IS_RESOURCE:
+ param->param_type = PDO_PARAM_LOB;
+ break;
+ default:
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Invalid parameter type" TSRMLS_CC);
+ }
+ }
+
switch (PDO_PARAM_TYPE(param->param_type)) {
case PDO_PARAM_STMT:
- return 0;
-
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Invalid parameter type" TSRMLS_CC);
+ break;
case PDO_PARAM_NULL:
- if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
- return 1;
+ if(sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
- pdo_sqlite_error_stmt(stmt);
- return 0;
-
+ break;
case PDO_PARAM_INT:
- case PDO_PARAM_BOOL:
- if (Z_TYPE_P(param->parameter) == IS_NULL) {
+ if (Z_TYPE_P(param->parameter) == IS_LONG) {
+ // no conversion
+ }else if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
+ if (sqlite3_bind_double(S->stmt, param->paramno + 1, Z_DVAL_P(param->parameter)) == SQLITE_OK) {
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
+ }
+ }else if (Z_TYPE_P(param->parameter) == IS_NULL) {
if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
- return 1;
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
- } else {
+ }else{
convert_to_long(param->parameter);
- if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter))) {
- return 1;
+ }
+
+ if (Z_TYPE_P(param->parameter) == IS_LONG) {
+ if (sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter)) == SQLITE_OK) {
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
}
- pdo_sqlite_error_stmt(stmt);
- return 0;
-
+ break;
+ case PDO_PARAM_BOOL:
+ if (Z_TYPE_P(param->parameter) == IS_BOOL) {
+ // no conversion
+ }else if (Z_TYPE_P(param->parameter) == IS_NULL) {
+ if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
+ }
+ }else{
+ convert_to_boolean(param->parameter);
+ }
+
+ if (Z_TYPE_P(param->parameter) == IS_BOOL) {
+ if (sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter)) == SQLITE_OK) {
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
+ }
+ }
+ break;
case PDO_PARAM_LOB:
if (Z_TYPE_P(param->parameter) == IS_RESOURCE) {
php_stream *stm;
@@ -128,54 +188,70 @@
Z_TYPE_P(param->parameter) = IS_STRING;
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
- } else {
+ }else{
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
- return 0;
}
} else if (Z_TYPE_P(param->parameter) == IS_NULL) {
if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
- return 1;
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
- pdo_sqlite_error_stmt(stmt);
- return 0;
} else {
convert_to_string(param->parameter);
+ if(
+ sqlite3_bind_blob(
+ S->stmt, param->paramno + 1,
+ Z_STRVAL_P(param->parameter),
+ Z_STRLEN_P(param->parameter),
+ SQLITE_STATIC
+ ) == SQLITE_OK
+ ){
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
+ }
}
-
- if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
- Z_STRVAL_P(param->parameter),
- Z_STRLEN_P(param->parameter),
- SQLITE_STATIC)) {
- return 1;
- }
- pdo_sqlite_error_stmt(stmt);
- return 0;
-
+ break;
+
case PDO_PARAM_STR:
default:
- if (Z_TYPE_P(param->parameter) == IS_NULL) {
+ if (Z_TYPE_P(param->parameter) == IS_STRING) {
+ // no conversion
+ } else if (Z_TYPE_P(param->parameter) == IS_NULL) {
if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
- return 1;
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
} else {
convert_to_string(param->parameter);
- if(SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
+ }
+
+ if(Z_TYPE_P(param->parameter) == IS_STRING){
+ if(
+ sqlite3_bind_text(
+ S->stmt, param->paramno + 1,
Z_STRVAL_P(param->parameter),
Z_STRLEN_P(param->parameter),
- SQLITE_STATIC)) {
- return 1;
+ SQLITE_STATIC
+ ) == SQLITE_OK
+ ){
+ hookResult = 1; // success
+ }else{
+ pdo_sqlite_error_stmt(stmt);
}
}
- pdo_sqlite_error_stmt(stmt);
- return 0;
+ break;
}
+ }else{
+ hookResult = 1; // success
}
- break;
-
+ break;
default:
- ;
+ hookResult = 1; // success
}
- return 1;
+ return hookResult;
}
static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
Index: ext/pdo/pdo_stmt.c
===================================================================
--- ext/pdo/pdo_stmt.c (revision 306430)
+++ ext/pdo/pdo_stmt.c (working copy)
@@ -468,6 +468,13 @@
}
param.param_type = PDO_PARAM_STR;
+ if(strcmp(stmt->dbh->driver->driver_name, "sqlite") == 0){
+ // Sqlite does own mapping of zvals to pdo params now.
+ // Setting param type to a constant to signal that no explicit type was set
+ // gives the driver the opportunity to autodetect the type from the zval itself
+ param.param_type = PDO_PARAM_ZVAL;
+ }
+
MAKE_STD_ZVAL(param.parameter);
MAKE_COPY_ZVAL(tmp, param.parameter);
|