From 02025a95211a706f6461e63250264f7aa942f9e4 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Wed, 11 Oct 2023 09:35:00 -0700 Subject: [PATCH 1/2] Enable establishing exclusive oci8 connections (#6182) --- 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; From e8479d1e5ddbc2583b0f1a8e60f99932f3036e68 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Fri, 13 Oct 2023 22:41:38 -0500 Subject: [PATCH 2/2] Add `QueryBuilder::resetOrderBy()` (#6190) --- src/Query/QueryBuilder.php | 14 ++++++++++++++ tests/Query/QueryBuilderTest.php | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Query/QueryBuilder.php b/src/Query/QueryBuilder.php index ba6598c44c2..c0d18d5f2ff 100644 --- a/src/Query/QueryBuilder.php +++ b/src/Query/QueryBuilder.php @@ -1366,6 +1366,20 @@ public function resetQueryPart($queryPartName) return $this; } + /** + * Resets the ordering for the query. + * + * @return $this This QueryBuilder instance. + */ + public function resetOrderBy(): self + { + $this->sqlParts['orderBy'] = self::SQL_PARTS_DEFAULTS['orderBy']; + + $this->state = self::STATE_DIRTY; + + return $this; + } + /** @throws QueryException */ private function getSQLForSelect(): string { diff --git a/tests/Query/QueryBuilderTest.php b/tests/Query/QueryBuilderTest.php index 78c420a6a51..76fe76bdb7f 100644 --- a/tests/Query/QueryBuilderTest.php +++ b/tests/Query/QueryBuilderTest.php @@ -631,6 +631,17 @@ public function testResetQueryParts(): void self::assertEquals('SELECT u.* FROM users u', (string) $qb); } + public function testResetOrderBy(): void + { + $qb = new QueryBuilder($this->conn); + + $qb->select('u.*')->from('users', 'u')->orderBy('u.name'); + + self::assertEquals('SELECT u.* FROM users u ORDER BY u.name ASC', (string) $qb); + $qb->resetOrderBy(); + self::assertEquals('SELECT u.* FROM users u', (string) $qb); + } + public function testCreateNamedParameter(): void { $qb = new QueryBuilder($this->conn);