]> granicus.if.org Git - php/commitdiff
Add driver-specific attributes for controlling calls to dbsetlogintime() and dbsettime()
authorAdam Baratz <adam.baratz@gmail.com>
Tue, 5 Apr 2016 16:14:03 +0000 (18:14 +0200)
committerAnatol Belski <ab@php.net>
Tue, 5 Apr 2016 16:24:15 +0000 (18:24 +0200)
ext/pdo_dblib/dblib_driver.c
ext/pdo_dblib/dblib_stmt.c
ext/pdo_dblib/pdo_dblib.c
ext/pdo_dblib/php_pdo_dblib_int.h
ext/pdo_dblib/tests/timeout.phpt [new file with mode: 0644]

index 993746656116f2c235c4daa43ca17805eb643050..9d9424a8b20521a4234643257a74ec98df133407 100644 (file)
@@ -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);
index 8d7762ad8d62a9593ce0ddf347a6f7d0c474db51..49b75ee2bb4826cca726c54c2e8bbf4353aa60b4 100644 (file)
@@ -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;
index 0b64bce8a732c06095bf75ea1d54400bd677dc49..dd64cbe882c7eb81c412eb076aa3c595e58e7c27 100644 (file)
@@ -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;
        }
index 86ff43bb09ca599c39a714e2d1c222aebed80c3c..5b47922abefcf8ba184af46c7a8dd6a98b77a4db 100644 (file)
@@ -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 (file)
index 0000000..d650462
--- /dev/null
@@ -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