]> granicus.if.org Git - php/commitdiff
pdo_oci: Add support for setting and getting the oracle OCI 18c call timeout value.
authorCameron Porter <porterca@us.ibm.com>
Fri, 25 Oct 2019 06:32:12 +0000 (08:32 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Fri, 1 Nov 2019 09:36:55 +0000 (10:36 +0100)
NEWS
ext/pdo/tests/bug_69356.phpt
ext/pdo_oci/oci_driver.c
ext/pdo_oci/pdo_oci.c
ext/pdo_oci/php_pdo_oci_int.h
ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt [new file with mode: 0644]
ext/pdo_oci/tests/pdo_oci_class_constants.phpt
ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index f914d9d264fbf4e0c799f323d72a0f0ecab94716..102295dd7d1cf222f29c136480190036a7961fe6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,10 @@ PHP                                                                        NEWS
   . Fixed bug #77849 (Disable cloning of PDO handle/connection objects).
     (camporter)
 
+- PDO_OCI:
+  . Added support for setting and getting the oracle OCI 18c call timeout.
+    (camporter)
+
 - phpdbg:
   . Fixed bug #76596 (phpdbg support for display_errors=stderr). (kabel)
   . Fixed bug #76801 (too many open files). (alekitto)
index 4fca242a9171e02957c5da2970e0e3b2a8216504..0885a8264faab9f8ea8ec986348bea42e8a76959 100644 (file)
@@ -5,6 +5,7 @@ PDO Common: Bug #69356 (PDOStatement::debugDumpParams() truncates query)
 if (!extension_loaded('pdo')) die('skip');
 $dir = getenv('REDIR_TEST_DIR');
 if (false == $dir) die('skip no driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip query not supported');
 require_once $dir . 'pdo_test.inc';
 PDOTest::skip();
 ?>
index 58a63f58cb1552202cb228784a7f19bbccfbb9a0..3d9267ba853f48b65fb971c9b55fd3721bc3f802 100644 (file)
@@ -537,6 +537,24 @@ static int oci_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) /
 #else
                        oci_drv_error("Unsupported attribute type");
                        return 0;
+#endif
+               }
+               case PDO_OCI_ATTR_CALL_TIMEOUT:
+               {
+#if (OCI_MAJOR_VERSION >= 18)
+                       ub4 timeout = (ub4) lval;
+
+                       H->last_err = OCIAttrSet(H->svc, OCI_HTYPE_SVCCTX,
+                               (dvoid *) &timeout, (ub4) 0,
+                               OCI_ATTR_CALL_TIMEOUT, H->err);
+                       if (H->last_err) {
+                               oci_drv_error("OCIAttrSet: OCI_ATTR_CALL_TIMEOUT");
+                               return 0;
+                       }
+                       return 1;
+#else
+                       oci_drv_error("Unsupported attribute type");
+                       return 0;
 #endif
                }
                default:
@@ -606,6 +624,26 @@ static int oci_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return
                case PDO_ATTR_PREFETCH:
                        ZVAL_LONG(return_value, H->prefetch);
                        return TRUE;
+               case PDO_OCI_ATTR_CALL_TIMEOUT:
+               {
+#if (OCI_MAJOR_VERSION >= 18)
+                       ub4 timeout;
+
+                       H->last_err = OCIAttrGet(H->svc, OCI_HTYPE_SVCCTX,
+                               (dvoid *) &timeout, NULL,
+                               OCI_ATTR_CALL_TIMEOUT, H->err);
+                       if (H->last_err) {
+                               oci_drv_error("OCIAttrGet: OCI_ATTR_CALL_TIMEOUT");
+                               return FALSE;
+                       }
+
+                       ZVAL_LONG(return_value, (zend_long) timeout);
+                       return TRUE;
+#else
+                       oci_drv_error("Unsupported attribute type");
+                       return FALSE;
+#endif
+               }
                default:
                        return FALSE;
 
index e9be6cd0a6d35024cda1ce9b1cf9546a2443d7d2..121378492a675dc28c7a25f9e36500cf3884e851 100644 (file)
@@ -92,6 +92,7 @@ PHP_MINIT_FUNCTION(pdo_oci)
        REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CLIENT_INFO", (zend_long)PDO_OCI_ATTR_CLIENT_INFO);
        REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CLIENT_IDENTIFIER", (zend_long)PDO_OCI_ATTR_CLIENT_IDENTIFIER);
        REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_MODULE", (zend_long)PDO_OCI_ATTR_MODULE);
+       REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CALL_TIMEOUT", (zend_long)PDO_OCI_ATTR_CALL_TIMEOUT);
 
        php_pdo_register_driver(&pdo_oci_driver);
 
index ee56720e19e42663067e30a7d9feecdb9c03599e..488daf54e5d122835417fc485a44d9dcfa0492f1 100644 (file)
@@ -102,5 +102,6 @@ enum {
        PDO_OCI_ATTR_ACTION = PDO_ATTR_DRIVER_SPECIFIC,
        PDO_OCI_ATTR_CLIENT_INFO,
        PDO_OCI_ATTR_CLIENT_IDENTIFIER,
-       PDO_OCI_ATTR_MODULE
+       PDO_OCI_ATTR_MODULE,
+       PDO_OCI_ATTR_CALL_TIMEOUT
 };
diff --git a/ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt b/ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt
new file mode 100644 (file)
index 0000000..31df153
--- /dev/null
@@ -0,0 +1,66 @@
+--TEST--
+PDO_OCI: Attribute: Setting and using call timeout
+--SKIPIF--
+<?php
+if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request');
+if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
+require(__DIR__.'/../../pdo/tests/pdo_test.inc');
+PDOTest::skip();
+if (strcasecmp(getenv('PDOTEST_USER'), "system") && strcasecmp(getenv('PDOTEST_USER'), "sys")) {
+    die("skip needs to be run as a user with access to DBMS_LOCK");
+}
+
+$dbh = PDOTest::factory();
+preg_match('/^[[:digit:]]+/', $dbh->getAttribute(PDO::ATTR_CLIENT_VERSION), $matches);
+if (!(isset($matches[0]) && $matches[0] >= 18)) {
+    die("skip works only with Oracle 18c or greater version of Oracle client libraries");
+}
+
+?>
+--FILE--
+<?php
+
+require(__DIR__ . '/../../pdo/tests/pdo_test.inc');
+
+function mysleep($dbh, $t)
+{
+    $stmt = $dbh->prepare("begin dbms_lock.sleep(:t); end;");
+
+    if (!$stmt) {
+        $error = $dbh->errorInfo();
+        echo "Prepare error was ", $error[2], "\n";
+        return;
+    }
+    $stmt->bindParam(":t", $t, PDO::PARAM_INT);
+
+    $r = $stmt->execute();
+    if ($r) {
+        echo "Execute succeeded\n";
+    } else {
+        $error = $dbh->errorInfo();
+        echo "Execute error was ", $error[2], "\n";
+    }
+}
+
+$dbh = PDOTest::factory();
+$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
+
+echo "Test 1\n";
+
+$dbh->setAttribute(PDO::OCI_ATTR_CALL_TIMEOUT, 4000); // milliseconds
+
+echo "call timeout:\n";
+var_dump($dbh->getAttribute(PDO::OCI_ATTR_CALL_TIMEOUT));
+
+$r = mysleep($dbh, 8); // seconds
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Test 1
+call timeout:
+int(4000)
+Execute error was OCIStmtExecute: ORA-%r(03136|03156)%r: %s
+ (%s:%d)
+===DONE===
index 265e84b9bae4285472c8e9da09b6fc5a134ce864..0946b3f89b79e44e26a8de47f7d8d6c61d0f028c 100644 (file)
@@ -16,6 +16,7 @@ $expected = [
        'OCI_ATTR_ACTION'             => true,
        'OCI_ATTR_CLIENT_IDENTIFIER'  => true,
        'OCI_ATTR_MODULE'             => true,
+       'OCI_ATTR_CALL_TIMEOUT'       => true,
 ];
 
 $ref = new ReflectionClass('PDO');
diff --git a/ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt b/ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt
new file mode 100644 (file)
index 0000000..6f743c2
--- /dev/null
@@ -0,0 +1,37 @@
+--TEST--
+PDO_OCI: Bug #69356 (PDOStatement::debugDumpParams() truncates query)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
+require(__DIR__.'/../../pdo/tests/pdo_test.inc');
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require(__DIR__ . '/../../pdo/tests/pdo_test.inc');
+
+$db = PDOTest::factory();
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+$stmt = $db->query("
+    SELECT '
+        Dumps the informations contained by a prepared statement directly on the output. It will provide the SQL query in use, the number of parameters used (Params), the list of parameters, with their name, type (paramtype) as an integer, their key name or position, and the position in the query (if this is supported by the PDO driver, otherwise, it will be -1).
+        This is a debug function, which dump directly the data on the normal output.
+        Tip:
+        As with anything that outputs its result directly to the browser, the output-control functions can be used to capture the output of this function, and save it in a string (for example).
+        This will only dumps the parameters in the statement at the moment of the dump. Extra parameters are not stored in the statement, and not displayed.
+    ' FROM DUAL
+");
+var_dump($stmt->debugDumpParams());
+?>
+--EXPECT--
+SQL: [845] 
+    SELECT '
+        Dumps the informations contained by a prepared statement directly on the output. It will provide the SQL query in use, the number of parameters used (Params), the list of parameters, with their name, type (paramtype) as an integer, their key name or position, and the position in the query (if this is supported by the PDO driver, otherwise, it will be -1).
+        This is a debug function, which dump directly the data on the normal output.
+        Tip:
+        As with anything that outputs its result directly to the browser, the output-control functions can be used to capture the output of this function, and save it in a string (for example).
+        This will only dumps the parameters in the statement at the moment of the dump. Extra parameters are not stored in the statement, and not displayed.
+    ' FROM DUAL
+
+Params:  0
+NULL