summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Peter Banyard <girgias@php.net>2021-01-18 16:29:32 +0000
committerGeorge Peter Banyard <girgias@php.net>2021-01-19 11:54:25 +0000
commita78aea8948255718952471db9f96d882aa28dc7d (patch)
tree9e4e1d64ce737137fd868526ea1de71424ebe670
parent94ea8e247bb8103e346666dd33de08905b3e67ab (diff)
downloadphp-git-a78aea8948255718952471db9f96d882aa28dc7d.tar.gz
Refactor PDO's last inserted ID handler to use and return zend_string
Closes GH-6617
-rw-r--r--UPGRADING.INTERNALS3
-rw-r--r--ext/pdo/pdo.c15
-rw-r--r--ext/pdo/pdo_dbh.c24
-rw-r--r--ext/pdo/php_pdo_driver.h8
-rw-r--r--ext/pdo_dblib/dblib_driver.c12
-rw-r--r--ext/pdo_mysql/mysql_driver.c6
-rw-r--r--ext/pdo_oci/oci_driver.c2
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c9
-rw-r--r--ext/pdo_sqlite/sqlite_driver.c7
9 files changed, 40 insertions, 46 deletions
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index fcd5773fe5..39b26f3dae 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -58,3 +58,6 @@ PHP 8.1 INTERNALS UPGRADE NOTES
char* and size_t length.
- The doer handler now accepts a zend_string* instead of char* + size_t
pair for the SQL statement.
+ - The last_id handler now returns a zend_string* instead of returning a
+ char* and the length as an out param, and accepts a zend_string* instead
+ of char* for the optional sequence/table name.
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c
index a66596ee54..8ab9003fa8 100644
--- a/ext/pdo/pdo.c
+++ b/ext/pdo/pdo.c
@@ -248,8 +248,9 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s
}
/* }}} */
+/* TODO Refactor */
static const char digit_vec[] = "0123456789";
-PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
+PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
{
char buffer[65];
char outbuf[65] = "";
@@ -257,17 +258,15 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
zend_long long_val;
char *dst = outbuf;
+ if (i64 == 0) {
+ return ZSTR_CHAR('0');
+ }
+
if (i64 < 0) {
i64 = -i64;
*dst++ = '-';
}
- if (i64 == 0) {
- *dst++ = '0';
- *dst++ = '\0';
- return estrdup(outbuf);
- }
-
p = &buffer[sizeof(buffer)-1];
*p = '\0';
@@ -286,7 +285,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
while ((*dst++ = *p++) != 0)
;
*dst = '\0';
- return estrdup(outbuf);
+ return zend_string_init(outbuf, strlen(outbuf), 0);
}
/* }}} */
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index 2b1e7eab6b..c1b3495a1b 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -941,12 +941,12 @@ PHP_METHOD(PDO, exec)
PHP_METHOD(PDO, lastInsertId)
{
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
- char *name = NULL;
- size_t namelen;
+ zend_string *name = NULL;
+ zend_string *last_id = NULL;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
- Z_PARAM_STRING_OR_NULL(name, namelen)
+ Z_PARAM_STR_OR_NULL(name)
ZEND_PARSE_PARAMETERS_END();
PDO_CONSTRUCT_CHECK;
@@ -956,19 +956,13 @@ PHP_METHOD(PDO, lastInsertId)
if (!dbh->methods->last_id) {
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()");
RETURN_FALSE;
- } else {
- size_t id_len;
- char *id;
- id = dbh->methods->last_id(dbh, name, &id_len);
- if (!id) {
- PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
- } else {
- //??? use zend_string ?
- RETVAL_STRINGL(id, id_len);
- efree(id);
- }
}
+ last_id = dbh->methods->last_id(dbh, name);
+ if (!last_id) {
+ PDO_HANDLE_DBH_ERR();
+ RETURN_FALSE;
+ }
+ RETURN_STR(last_id);
}
/* }}} */
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index f29749c4ac..775ffd240f 100644
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -33,7 +33,7 @@ typedef unsigned __int64 pdo_uint64_t;
typedef long long int pdo_int64_t;
typedef unsigned long long int pdo_uint64_t;
#endif
-PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64);
+PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64);
#ifndef TRUE
# define TRUE 1
@@ -247,9 +247,9 @@ typedef bool (*pdo_dbh_txn_func)(pdo_dbh_t *dbh);
* Return true on success and false in case of failure */
typedef bool (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, zend_long attr, zval *val);
-/* return last insert id. NULL indicates error condition, otherwise, the return value
- * MUST be an emalloc'd NULL terminated string. */
-typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, size_t *len);
+/* return last insert id. NULL indicates error condition.
+ * name MIGHT be NULL */
+typedef zend_string *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const zend_string *name);
/* Fetch error information.
* If stmt is not null, fetch information pertaining to the statement,
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index f66ade482e..ae45da6beb 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -222,12 +222,14 @@ static bool dblib_handle_rollback(pdo_dbh_t *dbh)
return pdo_dblib_transaction_cmd("ROLLBACK TRANSACTION", dbh);
}
-char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name)
{
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
RETCODE ret;
char *id = NULL;
+ size_t len;
+ zend_string *ret_id;
/*
* Would use scope_identity() but it's not implemented on Sybase
@@ -260,10 +262,12 @@ char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len)
}
id = emalloc(32);
- *len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
-
+ len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
dbcancel(H->link);
- return id;
+
+ ret_id = zend_string_init(id, len, 0);
+ efree(id);
+ return ret_id;
}
static bool dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index cc70af6990..6b42335878 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -285,13 +285,11 @@ static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
/* }}} */
/* {{{ pdo_mysql_last_insert_id */
-static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
- char *id = php_pdo_int64_to_str(mysql_insert_id(H->server));
PDO_DBG_ENTER("pdo_mysql_last_insert_id");
- *len = strlen(id);
- PDO_DBG_RETURN(id);
+ PDO_DBG_RETURN(php_pdo_int64_to_str(mysql_insert_id(H->server)));
}
/* }}} */
diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c
index 8fae3ccd05..dd4a7bb171 100644
--- a/ext/pdo_oci/oci_driver.c
+++ b/ext/pdo_oci/oci_driver.c
@@ -696,7 +696,7 @@ static const struct pdo_dbh_methods oci_methods = {
oci_handle_commit,
oci_handle_rollback,
oci_handle_set_attribute,
- NULL,
+ NULL, /* last_id not supported */
pdo_oci_fetch_error_func,
oci_handle_get_attribute,
pdo_oci_check_liveness, /* check_liveness */
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 606623d708..5f2827334a 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -352,10 +352,10 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
return quoted_str;
}
-static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
- char *id = NULL;
+ zend_string *id = NULL;
PGresult *res;
ExecStatusType status;
@@ -363,15 +363,14 @@ static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *
res = PQexec(H->server, "SELECT LASTVAL()");
} else {
const char *q[1];
- q[0] = name;
+ q[0] = ZSTR_VAL(name);
res = PQexecParams(H->server, "SELECT CURRVAL($1)", 1, NULL, q, NULL, NULL, 0);
}
status = PQresultStatus(res);
if (res && (status == PGRES_TUPLES_OK)) {
- id = estrdup((char *)PQgetvalue(res, 0, 0));
- *len = PQgetlength(res, 0, 0);
+ id = zend_string_init((char *)PQgetvalue(res, 0, 0), PQgetlength(res, 0, 0), 0);
} else {
pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
}
diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
index abf2e2253f..a48c77f9e8 100644
--- a/ext/pdo_sqlite/sqlite_driver.c
+++ b/ext/pdo_sqlite/sqlite_driver.c
@@ -216,14 +216,11 @@ static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
}
}
-static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
- char *id;
- id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
- *len = strlen(id);
- return id;
+ return php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
}
/* NB: doesn't handle binary strings... use prepared stmts for that */