From 191938e874f623cec152292ba539e20b9cf83a35 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Wed, 11 Oct 2023 17:05:15 +0200 Subject: [PATCH] Enable establishing exclusive oci8 connections --- docs/en/reference/configuration.rst | 3 +++ src/Driver/OCI8/Driver.php | 12 ++++++++++- .../OCI8/Exception/InvalidConfiguration.php | 20 +++++++++++++++++++ tests/Driver/OCI8/DriverTest.php | 12 +++++++++++ tests/Functional/LockMode/NoneTest.php | 14 +++++++------ 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 src/Driver/OCI8/Exception/InvalidConfiguration.php diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst index 7d6bc9662a9..d9f1bf68983 100644 --- a/docs/en/reference/configuration.rst +++ b/docs/en/reference/configuration.rst @@ -319,6 +319,9 @@ pdo_oci / oci8 parameters will no longer be used. Note that when using this parameter, the ``getHost`` and ``getPort`` methods from ``Doctrine\DBAL\Connection`` will no longer function as expected. - ``persistent`` (boolean): Whether to establish a persistent connection. +- ``driverOptions`` (array): + - ``exclusive`` (boolean): Once specified for an ``oci8`` connection, forces the driver to always establish + a new connection instead of reusing an existing one from the connection pool. pdo_sqlsrv / sqlsrv ^^^^^^^^^^^^^^^^^^^ diff --git a/src/Driver/OCI8/Driver.php b/src/Driver/OCI8/Driver.php index 53e563c63c4..fe091bfa982 100644 --- a/src/Driver/OCI8/Driver.php +++ b/src/Driver/OCI8/Driver.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\Driver\AbstractOracleDriver; use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed; +use Doctrine\DBAL\Driver\OCI8\Exception\InvalidConfiguration; use SensitiveParameter; use function oci_connect; @@ -32,8 +33,17 @@ public function connect( $connectionString = $this->getEasyConnectString($params); - if (! empty($params['persistent'])) { + $persistent = ! empty($params['persistent']); + $exclusive = ! empty($params['driverOptions']['exclusive']); + + if ($persistent && $exclusive) { + throw InvalidConfiguration::forPersistentAndExclusive(); + } + + if ($persistent) { $connection = @oci_pconnect($username, $password, $connectionString, $charset, $sessionMode); + } elseif ($exclusive) { + $connection = @oci_new_connect($username, $password, $connectionString, $charset, $sessionMode); } else { $connection = @oci_connect($username, $password, $connectionString, $charset, $sessionMode); } diff --git a/src/Driver/OCI8/Exception/InvalidConfiguration.php b/src/Driver/OCI8/Exception/InvalidConfiguration.php new file mode 100644 index 00000000000..e9d2d0ebd79 --- /dev/null +++ b/src/Driver/OCI8/Exception/InvalidConfiguration.php @@ -0,0 +1,20 @@ +expectException(InvalidConfiguration::class); + + (new Driver())->connect([ + 'persistent' => true, + 'driverOptions' => ['exclusive' => true], + ]); + } + protected function createDriver(): DriverInterface { return new Driver(); diff --git a/tests/Functional/LockMode/NoneTest.php b/tests/Functional/LockMode/NoneTest.php index 39803a40e70..5cb5bcc6b21 100644 --- a/tests/Functional/LockMode/NoneTest.php +++ b/tests/Functional/LockMode/NoneTest.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Tests\Functional\LockMode; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Exception; use Doctrine\DBAL\LockMode; use Doctrine\DBAL\Platforms\SqlitePlatform; @@ -21,11 +22,6 @@ class NoneTest extends FunctionalTestCase public function setUp(): void { - if (TestUtil::isDriverOneOf('oci8')) { - // https://github.com/doctrine/dbal/issues/4417 - self::markTestSkipped('This test fails on OCI8 for a currently unknown reason'); - } - if ($this->connection->getDatabasePlatform() instanceof SQLServerPlatform) { // Use row versioning instead of locking on SQL Server (if we don't, the second connection will block when // attempting to read the row created by the first connection, instead of reading the previous version); @@ -43,7 +39,13 @@ public function setUp(): void $this->dropAndCreateTable($table); - $this->connection2 = TestUtil::getConnection(); + $params = TestUtil::getConnectionParams(); + + if (TestUtil::isDriverOneOf('oci8')) { + $params['driverOptions']['exclusive'] = true; + } + + $this->connection2 = DriverManager::getConnection($params); if ($this->connection2->getSchemaManager()->tablesExist('users')) { return;