From a5e21665ee001e54d827e703ec6f0a3c7053be85 Mon Sep 17 00:00:00 2001 From: Adam Baratz Date: Tue, 5 Apr 2016 18:14:03 +0200 Subject: [PATCH] Add driver-specific attributes for controlling calls to dbsetlogintime() and dbsettime() --- ext/pdo_dblib/dblib_driver.c | 14 +++++++-- ext/pdo_dblib/dblib_stmt.c | 20 +++++++++++++ ext/pdo_dblib/pdo_dblib.c | 3 ++ ext/pdo_dblib/php_pdo_dblib_int.h | 5 ++++ ext/pdo_dblib/tests/timeout.phpt | 50 +++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 ext/pdo_dblib/tests/timeout.phpt diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 9937466561..9d9424a8b2 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -347,9 +347,19 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars); if (driver_options) { + int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1); + int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1); int timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30); - dbsetlogintime(timeout); /* Connection/Login Timeout */ - dbsettime(timeout); /* Statement Timeout */ + + if (connect_timeout == -1) { + connect_timeout = timeout; + } + if (query_timeout == -1) { + query_timeout = timeout; + } + + dbsetlogintime(connect_timeout); /* Connection/Login Timeout */ + dbsettime(query_timeout); /* Statement Timeout */ } H = pecalloc(1, sizeof(*H), dbh->is_persistent); diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index 8d7762ad8d..49b75ee2bb 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -95,6 +95,22 @@ static char *pdo_dblib_get_field_name(int type) } /* }}} */ +static void pdo_dblib_err_dtor(pdo_dblib_err *err) +{ + if (err->dberrstr) { + efree(err->dberrstr); + err->dberrstr = NULL; + } + if (err->lastmsg) { + efree(err->lastmsg); + err->lastmsg = NULL; + } + if (err->oserrstr) { + efree(err->oserrstr); + err->oserrstr = NULL; + } +} + static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; @@ -102,6 +118,8 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt) /* Cancel any pending results */ dbcancel(H->link); + + pdo_dblib_err_dtor(&H->err); return 1; } @@ -110,6 +128,8 @@ static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; + pdo_dblib_err_dtor(&S->err); + efree(S); return 1; diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index 0b64bce8a7..dd64cbe882 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -171,6 +171,9 @@ PHP_RSHUTDOWN_FUNCTION(pdo_dblib) PHP_MINIT_FUNCTION(pdo_dblib) { + REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); + REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT); + if (FAIL == dbinit()) { return FAILURE; } diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index 86ff43bb09..5b47922abe 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -139,5 +139,10 @@ ZEND_END_MODULE_GLOBALS(dblib) ZEND_EXTERN_MODULE_GLOBALS(dblib) +enum { + PDO_DBLIB_ATTR_CONNECTION_TIMEOUT = PDO_ATTR_DRIVER_SPECIFIC, + PDO_DBLIB_ATTR_QUERY_TIMEOUT +}; + #endif diff --git a/ext/pdo_dblib/tests/timeout.phpt b/ext/pdo_dblib/tests/timeout.phpt new file mode 100644 index 0000000000..d65046262e --- /dev/null +++ b/ext/pdo_dblib/tests/timeout.phpt @@ -0,0 +1,50 @@ +--TEST-- +PDO_DBLIB: Set query timeouts +--SKIPIF-- + +--FILE-- +prepare($sql); +if ($stmt->execute()) { + echo "OK\n"; +} + +// regular timeout attribute will affect query timeout, causing this query to fail +$db = new PDO($dsn, $user, $pass, [PDO::ATTR_TIMEOUT => 1]); +$stmt = $db->prepare($sql); +if (!$stmt->execute()) { + echo "OK\n"; + + // expect some kind of error code + if ($stmt->errorCode() != '00000') { + echo "OK\n"; + } +} + +// pdo_dblib-specific timeout attribute will control query timeout, causing this query to fail +$db = new PDO($dsn, $user, $pass, [PDO::DBLIB_ATTR_QUERY_TIMEOUT => 1]); +$stmt = $db->prepare($sql); +if (!$stmt->execute()) { + echo "OK\n"; + + // expect some kind of error code + if ($stmt->errorCode() != '00000') { + echo "OK\n"; + } +} + +?> +--EXPECT-- +OK +OK +OK +OK +OK -- 2.50.1