From b05e48a745f722801f55408d0dbd8003b403dbbd Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 25 Apr 2024 09:04:44 +0200 Subject: [PATCH] Connection::setNestTransactionsWithSavepoints() should not break lazy connection (#6362) | Q | A |------------- | ----------- | Type | bug | Fixed issues | N/A #### Summary When calling `Connection::setNestTransactionsWithSavepoints()`, the platform is fetched to check if savepoints are actually supported. This is a problem because it might cause the connection to be opened. I've removed the check which will postpone the exception to the first time we attempt to create a savepoint. --- src/Connection.php | 4 --- tests/ConnectionTest.php | 42 +++++++++++++++++++++++++++++ tests/Functional/ConnectionTest.php | 12 --------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/Connection.php b/src/Connection.php index 76b427b5b38..b9756706061 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -1317,10 +1317,6 @@ public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoint throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); } - if (! $this->getDatabasePlatform()->supportsSavepoints()) { - throw ConnectionException::savepointsNotSupported(); - } - $this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints; } diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index d8bfd8f722d..0a94a129b45 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -2,12 +2,14 @@ namespace Doctrine\DBAL\Tests; +use BadMethodCallException; use Doctrine\Common\EventManager; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Connection; use Doctrine\DBAL\ConnectionException; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\API\ExceptionConverter; use Doctrine\DBAL\Driver\Connection as DriverConnection; use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\DriverManager; @@ -81,6 +83,46 @@ public function testNoTransactionActiveByDefault(): void self::assertFalse($this->connection->isTransactionActive()); } + public function testSetNestTransactionsWithSavepointsDoesNotConnect(): void + { + $this->expectNotToPerformAssertions(); + + $connection = new Connection( + [], + new class implements VersionAwarePlatformDriver { + /** {@inheritDoc} */ + public function connect(array $params): DriverConnection + { + throw new BadMethodCallException('The connection must not be opened'); + } + + public function getDatabasePlatform(): AbstractPlatform + { + throw new BadMethodCallException('The connection must not be opened'); + } + + public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager + { + throw new BadMethodCallException('The connection must not be opened'); + } + + public function getExceptionConverter(): ExceptionConverter + { + throw new BadMethodCallException('The connection must not be opened'); + } + + /** {@inheritDoc} */ + public function createDatabasePlatformForVersion($version): AbstractPlatform + { + throw new BadMethodCallException('The connection must not be opened'); + } + }, + new Configuration(), + ); + + $connection->setNestTransactionsWithSavepoints(true); + } + public function testCommitWithNoActiveTransactionThrowsException(): void { $this->expectException(ConnectionException::class); diff --git a/tests/Functional/ConnectionTest.php b/tests/Functional/ConnectionTest.php index 567f7bcddb4..33f77385c95 100644 --- a/tests/Functional/ConnectionTest.php +++ b/tests/Functional/ConnectionTest.php @@ -195,18 +195,6 @@ public function testTransactionIsInactiveAfterConnectionClose(): void self::assertFalse($this->connection->isTransactionActive()); } - public function testSetNestedTransactionsThroughSavepointsNotSupportedThrowsException(): void - { - if ($this->connection->getDatabasePlatform()->supportsSavepoints()) { - self::markTestSkipped('This test requires the platform not to support savepoints.'); - } - - $this->expectException(ConnectionException::class); - $this->expectExceptionMessage('Savepoints are not supported by this driver.'); - - $this->connection->setNestTransactionsWithSavepoints(true); - } - public function testCreateSavepointsNotSupportedThrowsException(): void { if ($this->connection->getDatabasePlatform()->supportsSavepoints()) {