summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/pdo_dblib/dblib_driver.c14
-rw-r--r--ext/pdo_dblib/dblib_stmt.c20
-rw-r--r--ext/pdo_dblib/pdo_dblib.c3
-rw-r--r--ext/pdo_dblib/php_pdo_dblib_int.h5
-rw-r--r--ext/pdo_dblib/tests/timeout.phpt50
5 files changed, 90 insertions, 2 deletions
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--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$sql = 'WAITFOR DELAY \'00:00:02\'';
+
+// querying without a timeout will succeed
+$stmt = $db->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