mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Refactor PDO's last inserted ID handler to use and return zend_string
Closes GH-6617
This commit is contained in:
parent
94ea8e247b
commit
a78aea8948
9 changed files with 40 additions and 46 deletions
|
@ -58,3 +58,6 @@ PHP 8.1 INTERNALS UPGRADE NOTES
|
||||||
char* and size_t length.
|
char* and size_t length.
|
||||||
- The doer handler now accepts a zend_string* instead of char* + size_t
|
- The doer handler now accepts a zend_string* instead of char* + size_t
|
||||||
pair for the SQL statement.
|
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.
|
||||||
|
|
|
@ -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";
|
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 buffer[65];
|
||||||
char outbuf[65] = "";
|
char outbuf[65] = "";
|
||||||
|
@ -257,17 +258,15 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
|
||||||
zend_long long_val;
|
zend_long long_val;
|
||||||
char *dst = outbuf;
|
char *dst = outbuf;
|
||||||
|
|
||||||
|
if (i64 == 0) {
|
||||||
|
return ZSTR_CHAR('0');
|
||||||
|
}
|
||||||
|
|
||||||
if (i64 < 0) {
|
if (i64 < 0) {
|
||||||
i64 = -i64;
|
i64 = -i64;
|
||||||
*dst++ = '-';
|
*dst++ = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i64 == 0) {
|
|
||||||
*dst++ = '0';
|
|
||||||
*dst++ = '\0';
|
|
||||||
return estrdup(outbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
p = &buffer[sizeof(buffer)-1];
|
p = &buffer[sizeof(buffer)-1];
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
|
||||||
while ((*dst++ = *p++) != 0)
|
while ((*dst++ = *p++) != 0)
|
||||||
;
|
;
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
return estrdup(outbuf);
|
return zend_string_init(outbuf, strlen(outbuf), 0);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -941,12 +941,12 @@ PHP_METHOD(PDO, exec)
|
||||||
PHP_METHOD(PDO, lastInsertId)
|
PHP_METHOD(PDO, lastInsertId)
|
||||||
{
|
{
|
||||||
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
|
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
|
||||||
char *name = NULL;
|
zend_string *name = NULL;
|
||||||
size_t namelen;
|
zend_string *last_id = NULL;
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||||
Z_PARAM_OPTIONAL
|
Z_PARAM_OPTIONAL
|
||||||
Z_PARAM_STRING_OR_NULL(name, namelen)
|
Z_PARAM_STR_OR_NULL(name)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
|
||||||
PDO_CONSTRUCT_CHECK;
|
PDO_CONSTRUCT_CHECK;
|
||||||
|
@ -956,19 +956,13 @@ PHP_METHOD(PDO, lastInsertId)
|
||||||
if (!dbh->methods->last_id) {
|
if (!dbh->methods->last_id) {
|
||||||
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()");
|
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()");
|
||||||
RETURN_FALSE;
|
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);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ typedef unsigned __int64 pdo_uint64_t;
|
||||||
typedef long long int pdo_int64_t;
|
typedef long long int pdo_int64_t;
|
||||||
typedef unsigned long long int pdo_uint64_t;
|
typedef unsigned long long int pdo_uint64_t;
|
||||||
#endif
|
#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
|
#ifndef TRUE
|
||||||
# define TRUE 1
|
# 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 */
|
* 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);
|
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
|
/* return last insert id. NULL indicates error condition.
|
||||||
* MUST be an emalloc'd NULL terminated string. */
|
* name MIGHT be NULL */
|
||||||
typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, size_t *len);
|
typedef zend_string *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const zend_string *name);
|
||||||
|
|
||||||
/* Fetch error information.
|
/* Fetch error information.
|
||||||
* If stmt is not null, fetch information pertaining to the statement,
|
* If stmt is not null, fetch information pertaining to the statement,
|
||||||
|
|
|
@ -222,12 +222,14 @@ static bool dblib_handle_rollback(pdo_dbh_t *dbh)
|
||||||
return pdo_dblib_transaction_cmd("ROLLBACK TRANSACTION", 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;
|
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
|
||||||
|
|
||||||
RETCODE ret;
|
RETCODE ret;
|
||||||
char *id = NULL;
|
char *id = NULL;
|
||||||
|
size_t len;
|
||||||
|
zend_string *ret_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Would use scope_identity() but it's not implemented on Sybase
|
* 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);
|
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);
|
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)
|
static bool dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
||||||
|
|
|
@ -285,13 +285,11 @@ static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ pdo_mysql_last_insert_id */
|
/* {{{ 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;
|
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");
|
PDO_DBG_ENTER("pdo_mysql_last_insert_id");
|
||||||
*len = strlen(id);
|
PDO_DBG_RETURN(php_pdo_int64_to_str(mysql_insert_id(H->server)));
|
||||||
PDO_DBG_RETURN(id);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -696,7 +696,7 @@ static const struct pdo_dbh_methods oci_methods = {
|
||||||
oci_handle_commit,
|
oci_handle_commit,
|
||||||
oci_handle_rollback,
|
oci_handle_rollback,
|
||||||
oci_handle_set_attribute,
|
oci_handle_set_attribute,
|
||||||
NULL,
|
NULL, /* last_id not supported */
|
||||||
pdo_oci_fetch_error_func,
|
pdo_oci_fetch_error_func,
|
||||||
oci_handle_get_attribute,
|
oci_handle_get_attribute,
|
||||||
pdo_oci_check_liveness, /* check_liveness */
|
pdo_oci_check_liveness, /* check_liveness */
|
||||||
|
|
|
@ -352,10 +352,10 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
|
||||||
return quoted_str;
|
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;
|
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||||
char *id = NULL;
|
zend_string *id = NULL;
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
ExecStatusType status;
|
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()");
|
res = PQexec(H->server, "SELECT LASTVAL()");
|
||||||
} else {
|
} else {
|
||||||
const char *q[1];
|
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);
|
res = PQexecParams(H->server, "SELECT CURRVAL($1)", 1, NULL, q, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
status = PQresultStatus(res);
|
status = PQresultStatus(res);
|
||||||
|
|
||||||
if (res && (status == PGRES_TUPLES_OK)) {
|
if (res && (status == PGRES_TUPLES_OK)) {
|
||||||
id = estrdup((char *)PQgetvalue(res, 0, 0));
|
id = zend_string_init((char *)PQgetvalue(res, 0, 0), PQgetlength(res, 0, 0), 0);
|
||||||
*len = PQgetlength(res, 0, 0);
|
|
||||||
} else {
|
} else {
|
||||||
pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
|
pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
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));
|
return php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
|
||||||
*len = strlen(id);
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB: doesn't handle binary strings... use prepared stmts for that */
|
/* NB: doesn't handle binary strings... use prepared stmts for that */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue