Add driver-specific attributes for controlling calls to dbsetlogintime() and dbsettime()

This commit is contained in:
Adam Baratz 2016-04-05 18:14:03 +02:00 committed by Anatol Belski
parent 32d6ac4ddf
commit a5e21665ee
5 changed files with 90 additions and 2 deletions

View 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);

View 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;

View 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;
}

View 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

View File

@ -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