Refactor PDO doer handler to use zend_string

This commit is contained in:
George Peter Banyard 2021-01-18 16:07:24 +00:00
parent 9be0ee4309
commit 94ea8e247b
10 changed files with 42 additions and 34 deletions

View File

@ -56,3 +56,5 @@ PHP 8.1 INTERNALS UPGRADE NOTES
of returning a boolean, and the quoted string as a pair of out params.
Similarly the unquoted string is now a zend_string* instead of a pair of
char* and size_t length.
- The doer handler now accepts a zend_string* instead of char* + size_t
pair for the SQL statement.

View File

@ -913,23 +913,22 @@ PHP_METHOD(PDO, getAttribute)
PHP_METHOD(PDO, exec)
{
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
char *statement;
size_t statement_len;
zend_string *statement;
zend_long ret;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(statement, statement_len)
Z_PARAM_STR(statement)
ZEND_PARSE_PARAMETERS_END();
if (statement_len == 0) {
if (ZSTR_LEN(statement) == 0) {
zend_argument_value_error(1, "cannot be empty");
RETURN_THROWS();
}
PDO_DBH_CLEAR_ERR();
PDO_CONSTRUCT_CHECK;
ret = dbh->methods->doer(dbh, statement, statement_len);
if(ret == -1) {
ret = dbh->methods->doer(dbh, statement);
if (ret == -1) {
PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
} else {

View File

@ -232,8 +232,9 @@ typedef void (*pdo_dbh_close_func)(pdo_dbh_t *dbh);
* return true on success, false otherwise */
typedef bool (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options);
/* execute a statement (that does not return a result set) */
typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len);
/* execute a statement (that does not return a result set)
* Return -1 on failure, otherwise the number of affected rows */
typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const zend_string *sql);
/* quote a string */
typedef zend_string* (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype);

View File

@ -106,14 +106,14 @@ static bool dblib_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *
return true;
}
static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
RETCODE ret, resret;
dbsetuserdata(H->link, (BYTE*)&H->err);
if (FAIL == dbcmd(H->link, sql)) {
if (FAIL == dbcmd(H->link, ZSTR_VAL(sql))) {
return -1;
}

View File

@ -29,7 +29,7 @@
#include "php_pdo_firebird.h"
#include "php_pdo_firebird_int.h"
static int firebird_alloc_prepare_stmt(pdo_dbh_t*, const char*, size_t, XSQLDA*, isc_stmt_handle*,
static int firebird_alloc_prepare_stmt(pdo_dbh_t*, const zend_string*, XSQLDA*, isc_stmt_handle*,
HashTable*);
const char CHR_LETTER = 1;
@ -291,13 +291,13 @@ static FbTokenType getToken(const char** begin, const char* end)
return ret;
}
int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_params)
int preprocess(const zend_string* sql, char* sql_out, HashTable* named_params)
{
bool passAsIs = 1, execBlock = 0;
zend_long pindex = -1;
char pname[254], ident[253], ident2[253];
unsigned int l;
const char* p = sql, * end = sql + sql_len;
const char* p = ZSTR_VAL(sql), * end = ZSTR_VAL(sql) + ZSTR_LEN(sql);
const char* start = p;
FbTokenType tok = getToken(&p, end);
@ -363,7 +363,7 @@ int preprocess(const char* sql, int sql_len, char* sql_out, HashTable* named_par
if (passAsIs)
{
strcpy(sql_out, sql);
strcpy(sql_out, ZSTR_VAL(sql));
return 1;
}
@ -522,7 +522,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
zend_hash_init(np, 8, NULL, NULL, 0);
/* allocate and prepare statement */
if (!firebird_alloc_prepare_stmt(dbh, ZSTR_VAL(sql), ZSTR_LEN(sql), &num_sqlda, &s, np)) {
if (!firebird_alloc_prepare_stmt(dbh, sql, &num_sqlda, &s, np)) {
break;
}
@ -587,7 +587,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
/* }}} */
/* called by PDO to execute a statement that doesn't produce a result set */
static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len) /* {{{ */
static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* {{{ */
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
isc_stmt_handle stmt = PDO_FIREBIRD_HANDLE_INITIALIZER;
@ -602,7 +602,7 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sq
out_sqlda.sqln = 1;
/* allocate and prepare statement */
if (!firebird_alloc_prepare_stmt(dbh, sql, sql_len, &out_sqlda, &stmt, 0)) {
if (!firebird_alloc_prepare_stmt(dbh, sql, &out_sqlda, &stmt, 0)) {
return -1;
}
@ -767,14 +767,14 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
/* }}} */
/* used by prepare and exec to allocate a statement handle and prepare the SQL */
static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t sql_len, /* {{{ */
static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
XSQLDA *out_sqlda, isc_stmt_handle *s, HashTable *named_params)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
char *new_sql;
/* Firebird allows SQL statements up to 64k, so bail if it doesn't fit */
if (sql_len > 65536) {
if (ZSTR_LEN(sql) > 65536) {
strcpy(dbh->error_code, "01004");
return 0;
}
@ -797,9 +797,9 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t s
/* in order to support named params, which Firebird itself doesn't,
we need to replace :foo by ?, and store the name we just replaced */
new_sql = emalloc(sql_len+1);
new_sql = emalloc(ZSTR_LEN(sql)+1);
new_sql[0] = '\0';
if (!preprocess(sql, sql_len, new_sql, named_params)) {
if (!preprocess(sql, new_sql, named_params)) {
strcpy(dbh->error_code, "07000");
efree(new_sql);
return 0;
@ -815,7 +815,6 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t s
efree(new_sql);
return 1;
}
/* }}} */
/* called by PDO to set a driver-specific dbh attribute */
static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) /* {{{ */

View File

@ -249,14 +249,14 @@ end:
/* }}} */
/* {{{ mysql_handle_doer */
static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
PDO_DBG_ENTER("mysql_handle_doer");
PDO_DBG_INF_FMT("dbh=%p", dbh);
PDO_DBG_INF_FMT("sql=%.*s", (int)sql_len, sql);
PDO_DBG_INF_FMT("sql=%.*s", (int)ZSTR_LEN(sql), ZSTR_VAL(sql));
if (mysql_real_query(H->server, sql, sql_len)) {
if (mysql_real_query(H->server, ZSTR_VAL(sql), ZSTR_LEN(sql))) {
pdo_mysql_error(dbh);
PDO_DBG_RETURN(-1);
} else {
@ -348,9 +348,16 @@ static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
/* {{{ mysql_handle_begin */
static bool mysql_handle_begin(pdo_dbh_t *dbh)
{
zend_long return_value;
zend_string *command;
PDO_DBG_ENTER("mysql_handle_quoter");
PDO_DBG_INF_FMT("dbh=%p", dbh);
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("START TRANSACTION")));
command = zend_string_init("START TRANSACTION", strlen("START TRANSACTION"), 0);
return_value = mysql_handle_doer(dbh, command);
zend_string_release_ex(command, 0);
PDO_DBG_RETURN(0 <= return_value);
}
/* }}} */

View File

@ -306,7 +306,7 @@ static bool oci_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *st
}
/* }}} */
static zend_long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len) /* {{{ */
static zend_long oci_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* {{{ */
{
pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data;
OCIStmt *stmt;
@ -316,7 +316,7 @@ static zend_long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
OCIHandleAlloc(H->env, (dvoid*)&stmt, OCI_HTYPE_STMT, 0, NULL);
H->last_err = OCIStmtPrepare(stmt, H->err, (text*)sql, (ub4) sql_len, OCI_NTV_SYNTAX, OCI_DEFAULT);
H->last_err = OCIStmtPrepare(stmt, H->err, (text*)ZSTR_VAL(sql), (ub4) ZSTR_LEN(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
if (H->last_err) {
H->last_err = oci_drv_error("OCIStmtPrepare");
OCIHandleFree(stmt, OCI_HTYPE_STMT);

View File

@ -212,7 +212,7 @@ static bool odbc_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *s
return true;
}
static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
RETCODE rc;
@ -225,7 +225,7 @@ static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_le
return -1;
}
rc = SQLExecDirect(stmt, (SQLCHAR *) sql, sql_len);
rc = SQLExecDirect(stmt, (SQLCHAR *) ZSTR_VAL(sql), ZSTR_LEN(sql));
if (rc == SQL_NO_DATA) {
/* If SQLExecDirect executes a searched update or delete statement that

View File

@ -288,14 +288,14 @@ static bool pgsql_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *
return true;
}
static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
PGresult *res;
zend_long ret = 1;
ExecStatusType qs;
if (!(res = PQexec(H->server, sql))) {
if (!(res = PQexec(H->server, ZSTR_VAL(sql)))) {
/* fatal error */
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
return -1;

View File

@ -200,12 +200,12 @@ static bool sqlite_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t
return false;
}
static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
char *errmsg = NULL;
if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
if (sqlite3_exec(H->db, ZSTR_VAL(sql), NULL, NULL, &errmsg) != SQLITE_OK) {
pdo_sqlite_error(dbh);
if (errmsg)
sqlite3_free(errmsg);