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);
}
/* }}} */
+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;
/* Cancel any pending results */
dbcancel(H->link);
+
+ pdo_dblib_err_dtor(&H->err);
return 1;
}
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ pdo_dblib_err_dtor(&S->err);
+
efree(S);
return 1;
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;
}
ZEND_EXTERN_MODULE_GLOBALS(dblib)
+enum {
+ PDO_DBLIB_ATTR_CONNECTION_TIMEOUT = PDO_ATTR_DRIVER_SPECIFIC,
+ PDO_DBLIB_ATTR_QUERY_TIMEOUT
+};
+
#endif
--- /dev/null
+--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