From 9e262e18f97ddd2acd56436b271a40406ca7296a Mon Sep 17 00:00:00 2001 From: twosee Date: Tue, 10 Dec 2019 14:55:10 +0800 Subject: [PATCH] Better PDO::inTransaction --- ext/mysqlnd/mysqlnd_libmysql_compat.h | 2 + ext/pdo_mysql/mysql_driver.c | 11 ++- .../tests/pdo_mysql_inTransaction.phpt | 68 +++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 ext/pdo_mysql/tests/pdo_mysql_inTransaction.phpt diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h index df4b96eec32f5..53121204604c0 100644 --- a/ext/mysqlnd/mysqlnd_libmysql_compat.h +++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h @@ -57,6 +57,7 @@ #define mysql_field_tell(r) mysqlnd_field_tell((r)) #define mysql_init(a) mysqlnd_connection_init((a), false) #define mysql_insert_id(r) mysqlnd_insert_id((r)) +#define mysql_get_server_status(r) mysqlnd_get_server_status((r)) #define mysql_kill(r,n) mysqlnd_kill((r), (n)) #define mysql_list_dbs(c, wild) mysqlnd_list_dbs((c), (wild)) #define mysql_list_processes(c) mysqlnd_list_processes((c)) @@ -80,6 +81,7 @@ #define mysql_stmt_param_count(s) mysqlnd_stmt_param_count((s)) #define mysql_stmt_num_rows(s) mysqlnd_stmt_num_rows((s)) #define mysql_stmt_insert_id(s) mysqlnd_stmt_insert_id((s)) +#define mysql_stmt_server_status(s) mysqlnd_stmt_server_status((s)) #define mysql_stmt_close(s) mysqlnd_stmt_close((s)) #define mysql_stmt_bind_param(s,b) mysqlnd_stmt_bind_param((s), (b)) #define mysql_stmt_bind_result(s,b) mysqlnd_stmt_bind_result((s), (b)) diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 0b5ef64b22dee..19b754b0f54d0 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -528,6 +528,15 @@ static void pdo_mysql_request_shutdown(pdo_dbh_t *dbh) } /* }}} */ +/* {{{ pdo_mysql_in_transaction */ +static int pdo_mysql_in_transaction(pdo_dbh_t *dbh) +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + PDO_DBG_ENTER("pdo_mysql_in_transaction"); + PDO_DBG_RETURN(!!(mysql_get_server_status(H->server) & SERVER_STATUS_IN_TRANS)); +} +/* }}} */ + /* {{{ mysql_methods */ static const struct pdo_dbh_methods mysql_methods = { mysql_handle_closer, @@ -544,7 +553,7 @@ static const struct pdo_dbh_methods mysql_methods = { pdo_mysql_check_liveness, NULL, pdo_mysql_request_shutdown, - NULL + pdo_mysql_in_transaction }; /* }}} */ diff --git a/ext/pdo_mysql/tests/pdo_mysql_inTransaction.phpt b/ext/pdo_mysql/tests/pdo_mysql_inTransaction.phpt new file mode 100644 index 0000000000000..58c921f44a423 --- /dev/null +++ b/ext/pdo_mysql/tests/pdo_mysql_inTransaction.phpt @@ -0,0 +1,68 @@ +--TEST-- +MySQL PDO class inTransaction +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // mysql does not support +for ($b = 0; $b < count(BEGIN); $b++) { + for ($e = 0; $e < count(END); $e++) { + foreach (['exec', 'query', 'execute'] as $w) { + foreach ([BEGIN[$b], END[$e]] as $command) { + switch ($w) { + case 'exec': + $db->exec($command); + break; + case'query': + $db->query($command)->execute(); + break; + case 'execute': + /* EMULATE_PREPARES = QUERY */ + $db->prepare($command)->execute(); + break; + default: + assert(0); + } + var_dump($db->inTransaction()); + } + } + } +} + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false)