diff --git a/composer.json b/composer.json index ed7615765c..7c41e2be5b 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,7 @@ "phpbench/phpbench": "^0.16.10 || ^1.0", "phpstan/phpstan": "1.4.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.6.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", diff --git a/tests/Doctrine/Tests/DbalExtensions/Connection.php b/tests/Doctrine/Tests/DbalExtensions/Connection.php new file mode 100644 index 0000000000..ce6d3982d2 --- /dev/null +++ b/tests/Doctrine/Tests/DbalExtensions/Connection.php @@ -0,0 +1,33 @@ +queryLog = new QueryLog(); + if (class_exists(LoggingMiddleware::class)) { + $logging = new LoggingMiddleware(new SqlLogger($this->queryLog)); + $driver = $logging->wrap($driver); + } else { + $config = $config ?? new Configuration(); + $config->setSQLLogger(new LegacySqlLogger($this->queryLog)); + } + + parent::__construct($params, $driver, $config, $eventManager); + } +} diff --git a/tests/Doctrine/Tests/DbalExtensions/LegacySqlLogger.php b/tests/Doctrine/Tests/DbalExtensions/LegacySqlLogger.php new file mode 100644 index 0000000000..b615b25f0a --- /dev/null +++ b/tests/Doctrine/Tests/DbalExtensions/LegacySqlLogger.php @@ -0,0 +1,27 @@ +queryLog = $queryLog; + } + + public function startQuery($sql, ?array $params = null, ?array $types = null): void + { + $this->queryLog->logQuery($sql, $params, $types); + } + + public function stopQuery(): void + { + } +} diff --git a/tests/Doctrine/Tests/DbalExtensions/QueryLog.php b/tests/Doctrine/Tests/DbalExtensions/QueryLog.php new file mode 100644 index 0000000000..906529c9c7 --- /dev/null +++ b/tests/Doctrine/Tests/DbalExtensions/QueryLog.php @@ -0,0 +1,58 @@ + */ + public $queries = []; + + public function logQuery(string $sql, ?array $params = null, ?array $types = null): void + { + if (! $this->enabled) { + return; + } + + $this->queries[] = [ + 'sql' => $sql, + 'params' => $params, + 'types' => $types, + ]; + } + + /** + * @return $this + */ + public function reset(): self + { + $this->enabled = false; + $this->queries = []; + + return $this; + } + + /** + * @return $this + */ + public function enable(): self + { + $this->enabled = true; + + return $this; + } + + /** + * @return $this + */ + public function disable(): self + { + $this->enabled = false; + + return $this; + } +} diff --git a/tests/Doctrine/Tests/DbalExtensions/SqlLogger.php b/tests/Doctrine/Tests/DbalExtensions/SqlLogger.php new file mode 100644 index 0000000000..3bbfd67b2d --- /dev/null +++ b/tests/Doctrine/Tests/DbalExtensions/SqlLogger.php @@ -0,0 +1,31 @@ +queryLog = $queryLog; + } + + public function log($level, $message, array $context = []): void + { + if (! isset($context['sql'])) { + return; + } + + $this->queryLog->logQuery( + $context['sql'], + $context['params'] ?? null, + $context['types'] ?? null + ); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php index 3d446de879..5aad10006a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\EntityNotFoundException; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\ORMInvalidArgumentException; @@ -113,7 +112,6 @@ public function testOneToManyAssociationModification(): void public function testBasicOneToOne(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $user = new CmsUser(); $user->name = 'Roman'; $user->username = 'romanb'; @@ -658,8 +656,6 @@ public function testFlushDoesNotIssueUnnecessaryUpdates(): void $this->_em->persist($article); $this->_em->persist($user); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $this->_em->flush(); $this->_em->clear(); @@ -669,14 +665,11 @@ public function testFlushDoesNotIssueUnnecessaryUpdates(): void self::assertCount(1, $user2->articles); self::assertInstanceOf(CmsAddress::class, $user2->address); - $oldLogger = $this->_em->getConnection()->getConfiguration()->getSQLLogger(); - $debugStack = new DebugStack(); - $this->_em->getConnection()->getConfiguration()->setSQLLogger($debugStack); - + $countBeforeFlush = $this->getCurrentQueryCount(); $this->_em->flush(); - self::assertCount(0, $debugStack->queries); + $countAfterFlush = $this->getCurrentQueryCount(); - $this->_em->getConnection()->getConfiguration()->setSQLLogger($oldLogger); + self::assertSame($countBeforeFlush, $countAfterFlush); } public function testRemoveEntityByReference(): void @@ -686,8 +679,6 @@ public function testRemoveEntityByReference(): void $user->username = 'gblanco'; $user->status = 'developer'; - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $this->_em->persist($user); $this->_em->flush(); $this->_em->clear(); @@ -698,8 +689,6 @@ public function testRemoveEntityByReference(): void $this->_em->clear(); self::assertEquals(0, $this->_em->getConnection()->fetchOne('select count(*) from cms_users')); - - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(null); } public function testQueryEntityByReference(): void @@ -721,8 +710,6 @@ public function testQueryEntityByReference(): void }); $this->_em->clear(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $userRef = $this->_em->getReference(CmsUser::class, $user->getId()); $address2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user') ->setParameter('user', $userRef) diff --git a/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php b/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php index fbfb37ec04..24e11e5b77 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php @@ -76,7 +76,6 @@ public function testOneToOneAssocToBaseTypeBidirectional(): void public function testManyToManyToCTIHierarchy(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger()); $mmrel = new CTIRelated2(); $child = new CTIChild(); $child->setData('child'); diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php index ea67489373..b792ba1efc 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php @@ -9,6 +9,8 @@ use Doctrine\Common\Collections\Criteria; use Doctrine\DBAL\Connection; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Logging\Middleware as LoggingMiddleware; +use Doctrine\DBAL\ParameterType; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Exception\InvalidEntityRepository; @@ -32,7 +34,9 @@ use Doctrine\Tests\Models\DDC753\DDC753InvalidRepository; use Doctrine\Tests\OrmFunctionalTestCase; -use function array_pop; +use function array_fill; +use function array_values; +use function class_exists; use function reset; class EntityRepositoryTest extends OrmFunctionalTestCase @@ -523,9 +527,9 @@ public function testIsNullCriteriaDoesNotGenerateAParameter(): void $repos = $this->_em->getRepository(CmsUser::class); $users = $repos->findBy(['status' => null, 'username' => 'romanb']); - $params = $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['params']; + $params = $this->getLastLoggedQuery()['params']; self::assertCount(1, $params, 'Should only execute with one parameter.'); - self::assertEquals(['romanb'], $params); + self::assertEquals(['romanb'], array_values($params)); } public function testIsNullCriteria(): void @@ -718,11 +722,28 @@ public function testInvalidOrientation(): void public function testFindByAssociationArray(): void { $repo = $this->_em->getRepository(CmsAddress::class); - $data = $repo->findBy(['user' => [1, 2, 3]]); - - $query = array_pop($this->_sqlLoggerStack->queries); - self::assertEquals([1, 2, 3], $query['params'][0]); - self::assertEquals(Connection::PARAM_INT_ARRAY, $query['types'][0]); + $repo->findBy(['user' => [1, 2, 3]]); + + if (! class_exists(LoggingMiddleware::class)) { + // DBAL 2 logs queries before resolving parameter positions + self::assertSame( + [ + 'sql' => 'SELECT t0.id AS id_1, t0.country AS country_2, t0.zip AS zip_3, t0.city AS city_4, t0.user_id AS user_id_5 FROM cms_addresses t0 WHERE t0.user_id IN (?)', + 'params' => [[1, 2, 3]], + 'types' => [Connection::PARAM_INT_ARRAY], + ], + $this->getLastLoggedQuery() + ); + } else { + self::assertSame( + [ + 'sql' => 'SELECT t0.id AS id_1, t0.country AS country_2, t0.zip AS zip_3, t0.city AS city_4, t0.user_id AS user_id_5 FROM cms_addresses t0 WHERE t0.user_id IN (?, ?, ?)', + 'params' => [1 => 1, 2 => 2, 3 => 3], + 'types' => array_fill(1, 3, ParameterType::INTEGER), + ], + $this->getLastLoggedQuery() + ); + } } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php b/tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php index f5ade88e8e..608a8ae851 100644 --- a/tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php @@ -25,7 +25,6 @@ protected function setUp(): void public function testPersistNewEntitiesOnPreFlush(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $this->_em->getEventManager()->addEventListener(Events::onFlush, new OnFlushListener()); $user = new CmsUser(); diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index b518b34483..415d28d8d0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -171,8 +171,6 @@ public function testPostLoadTriggeredOnRefresh(): void */ public function testCascadedEntitiesCallsPrePersist(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $e1 = new LifecycleCallbackTestEntity(); $e2 = new LifecycleCallbackTestEntity(); diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php b/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php index 98ce054309..4629d6a621 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php @@ -14,8 +14,6 @@ use Exception; use InvalidArgumentException; -use function array_pop; - /** * @group locking */ @@ -175,13 +173,15 @@ public function testLockPessimisticWrite(): void $this->_em->commit(); } catch (Exception $e) { $this->_em->rollback(); + } - throw $e; + $lastLoggedQuery = $this->getLastLoggedQuery()['sql']; + // DBAL 2 logs a commit as last query. + if ($lastLoggedQuery === '"COMMIT"') { + $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; } - $query = array_pop($this->_sqlLoggerStack->queries); - $query = array_pop($this->_sqlLoggerStack->queries); - self::assertStringContainsString($writeLockSql, $query['sql']); + self::assertStringContainsString($writeLockSql, $lastLoggedQuery); } /** @@ -209,14 +209,15 @@ public function testLockPessimisticRead(): void $this->_em->commit(); } catch (Exception $e) { $this->_em->rollback(); - - throw $e; } - array_pop($this->_sqlLoggerStack->queries); - $query = array_pop($this->_sqlLoggerStack->queries); + $lastLoggedQuery = $this->getLastLoggedQuery()['sql']; + // DBAL 2 logs a commit as last query. + if ($lastLoggedQuery === '"COMMIT"') { + $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; + } - self::assertStringContainsString($readLockSql, $query['sql']); + self::assertStringContainsString($readLockSql, $lastLoggedQuery); } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php index b1d4abc088..34ce3ad363 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php @@ -79,7 +79,6 @@ public function testRemovesAManyToManyAssociation(): void public function testEagerLoadFromInverseSideAndLazyLoadFromOwningSide(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $this->createLoadingFixture(); $categories = $this->findCategories(); $this->assertLazyLoadFromOwningSide($categories); @@ -87,7 +86,6 @@ public function testEagerLoadFromInverseSideAndLazyLoadFromOwningSide(): void public function testEagerLoadFromOwningSideAndLazyLoadFromInverseSide(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $this->createLoadingFixture(); $products = $this->findProducts(); $this->assertLazyLoadFromInverseSide($products); diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php b/tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php index 31185b518b..1ef346b307 100644 --- a/tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php @@ -6,17 +6,17 @@ use DateTime; use Doctrine\DBAL\DriverManager; -use Doctrine\DBAL\Logging\DebugStack; -use Doctrine\DBAL\Logging\SQLLogger; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Proxy\Proxy; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Tests\DbalExtensions\Connection; +use Doctrine\Tests\DbalExtensions\QueryLog; use Doctrine\Tests\Models\Generic\DateTimeModel; use Doctrine\Tests\OrmFunctionalTestCase; -use function count; +use function assert; use function realpath; use function serialize; use function unserialize; @@ -125,8 +125,8 @@ public function testMergeWithExistingUninitializedManagedProxy(): void */ public function testMergingProxyFromDifferentEntityManagerWithExistingManagedInstanceDoesNotReplaceInitializer(): void { - $em1 = $this->createEntityManager($logger1 = new DebugStack()); - $em2 = $this->createEntityManager($logger2 = new DebugStack()); + $em1 = $this->createEntityManager(); + $em2 = $this->createEntityManager(); $file1 = new DateTimeModel(); $file2 = new DateTimeModel(); @@ -138,8 +138,8 @@ public function testMergingProxyFromDifferentEntityManagerWithExistingManagedIns $em1->clear(); $em2->clear(); - $queryCount1 = count($logger1->queries); - $queryCount2 = count($logger2->queries); + $logger1 = $this->getResetQueryLogFromEntityManager($em1); + $logger2 = $this->getResetQueryLogFromEntityManager($em2); $proxy1 = $em1->getReference(DateTimeModel::class, $file1->id); $proxy2 = $em2->getReference(DateTimeModel::class, $file1->id); @@ -154,12 +154,12 @@ public function testMergingProxyFromDifferentEntityManagerWithExistingManagedIns $proxy1->__load(); self::assertCount( - $queryCount1 + 1, + 1, $logger1->queries, 'Loading the first proxy was done through the first entity manager' ); self::assertCount( - $queryCount2, + 0, $logger2->queries, 'No queries were executed on the second entity manager, as it is unrelated with the first proxy' ); @@ -167,12 +167,12 @@ public function testMergingProxyFromDifferentEntityManagerWithExistingManagedIns $proxy2->__load(); self::assertCount( - $queryCount1 + 1, + 1, $logger1->queries, 'Loading the second proxy does not affect the first entity manager' ); self::assertCount( - $queryCount2 + 1, + 1, $logger2->queries, 'Loading of the second proxy instance was done through the second entity manager' ); @@ -186,8 +186,8 @@ public function testMergingProxyFromDifferentEntityManagerWithExistingManagedIns */ public function testMergingUnInitializedProxyDoesNotInitializeIt(): void { - $em1 = $this->createEntityManager($logger1 = new DebugStack()); - $em2 = $this->createEntityManager($logger2 = new DebugStack()); + $em1 = $this->createEntityManager(); + $em2 = $this->createEntityManager(); $file1 = new DateTimeModel(); $file2 = new DateTimeModel(); @@ -199,8 +199,8 @@ public function testMergingUnInitializedProxyDoesNotInitializeIt(): void $em1->clear(); $em2->clear(); - $queryCount1 = count($logger1->queries); - $queryCount2 = count($logger1->queries); + $logger1 = $this->getResetQueryLogFromEntityManager($em1); + $logger2 = $this->getResetQueryLogFromEntityManager($em2); $unManagedProxy = $em1->getReference(DateTimeModel::class, $file1->id); $mergedInstance = $em2->merge($unManagedProxy); @@ -210,12 +210,12 @@ public function testMergingUnInitializedProxyDoesNotInitializeIt(): void self::assertFalse($unManagedProxy->__isInitialized()); self::assertCount( - $queryCount1, + 0, $logger1->queries, 'Loading the merged instance affected only the first entity manager' ); self::assertCount( - $queryCount1 + 1, + 1, $logger2->queries, 'Loading the merged instance was done via the second entity manager' ); @@ -223,18 +223,18 @@ public function testMergingUnInitializedProxyDoesNotInitializeIt(): void $unManagedProxy->__load(); self::assertCount( - $queryCount1 + 1, + 1, $logger1->queries, 'Loading the first proxy was done through the first entity manager' ); self::assertCount( - $queryCount2 + 1, + 1, $logger2->queries, 'No queries were executed on the second entity manager, as it is unrelated with the first proxy' ); } - private function createEntityManager(SQLLogger $logger): EntityManagerInterface + private function createEntityManager(): EntityManagerInterface { $config = new Configuration(); @@ -244,7 +244,6 @@ private function createEntityManager(SQLLogger $logger): EntityManagerInterface [realpath(__DIR__ . '/../../Models/Cache')], false )); - $config->setSQLLogger($logger); // always runs on sqlite to prevent multi-connection race-conditions with the test suite // multi-connection is not relevant for the purpose of checking locking here, but merely @@ -253,6 +252,7 @@ private function createEntityManager(SQLLogger $logger): EntityManagerInterface [ 'driver' => 'pdo_sqlite', 'memory' => true, + 'wrapperClass' => Connection::class, ], $config ); @@ -263,4 +263,12 @@ private function createEntityManager(SQLLogger $logger): EntityManagerInterface return $entityManager; } + + private function getResetQueryLogFromEntityManager(EntityManagerInterface $entityManager): QueryLog + { + $connection = $entityManager->getConnection(); + assert($connection instanceof Connection); + + return $connection->queryLog->reset()->enable(); + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php index 3faa6d2607..dc3dd0991b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php @@ -133,7 +133,6 @@ public function testLazyLoadsObjectsOnTheInverseSide(): void public function testLazyLoadsObjectsOnTheInverseSide2(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $this->createFixture(); $query = $this->_em->createQuery('select f,p from Doctrine\Tests\Models\ECommerce\ECommerceFeature f join f.product p'); @@ -150,8 +149,6 @@ public function testLazyLoadsObjectsOnTheInverseSide2(): void //$this->assertEquals(2, $product->getFeatures()->count()); //$this->assertTrue($product->getFeatures()->contains($features[0])); //$this->assertTrue($product->getFeatures()->contains($features[1])); - - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(null); } public function testJoinFromOwningSide(): void diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php b/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php index 90e3eb35e5..5ca4b36127 100644 --- a/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php @@ -19,7 +19,6 @@ use Doctrine\Tests\OrmFunctionalTestCase; use Exception; -use function count; use function get_class; /** @@ -61,13 +60,13 @@ public function testEagerLoadOneToOneOwningSide(): void $this->_em->flush(); $this->_em->clear(); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $train = $this->_em->find(get_class($train), $train->id); self::assertNotInstanceOf(Proxy::class, $train->driver); self::assertEquals('Benjamin', $train->driver->name); - self::assertCount($sqlCount + 1, $this->_sqlLoggerStack->queries); + self::assertSame($sqlCount + 1, $this->getCurrentQueryCount()); } /** @@ -81,13 +80,13 @@ public function testEagerLoadOneToOneNullOwningSide(): void $this->_em->flush(); $this->_em->clear(); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $train = $this->_em->find(get_class($train), $train->id); self::assertNotInstanceOf(Proxy::class, $train->driver); self::assertNull($train->driver); - self::assertCount($sqlCount + 1, $this->_sqlLoggerStack->queries); + self::assertSame($sqlCount + 1, $this->getCurrentQueryCount()); } /** @@ -102,13 +101,13 @@ public function testEagerLoadOneToOneInverseSide(): void $this->_em->flush(); $this->_em->clear(); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $driver = $this->_em->find(get_class($owner), $owner->id); self::assertNotInstanceOf(Proxy::class, $owner->train); self::assertNotNull($owner->train); - self::assertCount($sqlCount + 1, $this->_sqlLoggerStack->queries); + self::assertSame($sqlCount + 1, $this->getCurrentQueryCount()); } /** @@ -124,13 +123,13 @@ public function testEagerLoadOneToOneNullInverseSide(): void self::assertNull($driver->train); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $driver = $this->_em->find(get_class($driver), $driver->id); self::assertNotInstanceOf(Proxy::class, $driver->train); self::assertNull($driver->train); - self::assertCount($sqlCount + 1, $this->_sqlLoggerStack->queries); + self::assertSame($sqlCount + 1, $this->getCurrentQueryCount()); } public function testEagerLoadManyToOne(): void @@ -164,14 +163,14 @@ public function testEagerLoadWithNullableColumnsGeneratesLeftJoinOnBothSides(): $train = $this->_em->find(get_class($train), $train->id); $this->assertSQLEquals( 'SELECT t0.id AS id_1, t0.driver_id AS driver_id_2, t3.id AS id_4, t3.name AS name_5, t0.owner_id AS owner_id_6, t7.id AS id_8, t7.name AS name_9 FROM Train t0 LEFT JOIN TrainDriver t3 ON t0.driver_id = t3.id INNER JOIN TrainOwner t7 ON t0.owner_id = t7.id WHERE t0.id = ?', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql'] + $this->getLastLoggedQuery()['sql'] ); $this->_em->clear(); $driver = $this->_em->find(get_class($driver), $driver->id); $this->assertSQLEquals( 'SELECT t0.id AS id_1, t0.name AS name_2, t3.id AS id_4, t3.driver_id AS driver_id_5, t3.owner_id AS owner_id_6 FROM TrainOwner t0 LEFT JOIN Train t3 ON t3.owner_id = t0.id WHERE t0.id IN (?)', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql'] + $this->getLastLoggedQuery()['sql'] ); } @@ -195,13 +194,13 @@ public function testEagerLoadWithNonNullableColumnsGeneratesInnerJoinOnOwningSid // The last query is the eager loading of the owner of the train $this->assertSQLEquals( 'SELECT t0.id AS id_1, t0.name AS name_2, t3.id AS id_4, t3.driver_id AS driver_id_5, t3.owner_id AS owner_id_6 FROM TrainOwner t0 LEFT JOIN Train t3 ON t3.owner_id = t0.id WHERE t0.id IN (?)', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql'] + $this->getLastLoggedQuery()['sql'] ); // The one before is the fetching of the waggon and train $this->assertSQLEquals( 'SELECT t0.id AS id_1, t0.train_id AS train_id_2, t3.id AS id_4, t3.driver_id AS driver_id_5, t3.owner_id AS owner_id_6 FROM Waggon t0 INNER JOIN Train t3 ON t0.train_id = t3.id WHERE t0.id = ?', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery - 1]['sql'] + $this->getLastLoggedQuery(1)['sql'] ); } @@ -219,7 +218,7 @@ public function testEagerLoadWithNonNullableColumnsGeneratesLeftJoinOnNonOwningS $waggon = $this->_em->find(get_class($owner), $owner->id); $this->assertSQLEquals( 'SELECT t0.id AS id_1, t0.name AS name_2, t3.id AS id_4, t3.driver_id AS driver_id_5, t3.owner_id AS owner_id_6 FROM TrainOwner t0 LEFT JOIN Train t3 ON t3.owner_id = t0.id WHERE t0.id = ?', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql'] + $this->getLastLoggedQuery()['sql'] ); } diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php b/tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php index eb76a457cb..7b1fec871a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php @@ -61,12 +61,12 @@ public function testInverseSideOneToOneLoadedAfterDqlQuery(): void $this->assertSQLEquals( 'select o0_.id as id_0 from one_to_one_inverse_side_load_inverse o0_ where o0_.id = ?', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery - 1]['sql'] + $this->getLastLoggedQuery(1)['sql'] ); $this->assertSQLEquals( 'select t0.id as id_1, t0.inverse as inverse_2 from one_to_one_inverse_side_load_owning t0 WHERE t0.inverse = ?', - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql'] + $this->getLastLoggedQuery()['sql'] ); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php index d142a9760e..7d8f4b4892 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php @@ -15,7 +15,7 @@ class QueryBuilderParenthesisTest extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(QueryBuilderParenthesisEntity::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index a64de90a6a..885e6f2b2f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -5,6 +5,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\DBAL\Logging\Middleware as LoggingMiddleware; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\Proxy\Proxy; @@ -22,6 +23,7 @@ use Exception; use function array_values; +use function class_exists; use function count; use function iterator_to_array; @@ -237,14 +239,18 @@ public function testSetParameters(): void ->setParameters($parameters) ->getResult(); - $extractValue = static function (Parameter $parameter) { - return $parameter->getValue(); - }; - - self::assertSame( - $parameters->map($extractValue)->toArray(), - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['params'] - ); + if (! class_exists(LoggingMiddleware::class)) { + // DBAL 2 logs queries before resolving parameter positions + self::assertSame( + ['jwage', 'active'], + $this->getLastLoggedQuery()['params'] + ); + } else { + self::assertSame( + [1 => 'jwage', 2 => 'active'], + $this->getLastLoggedQuery()['params'] + ); + } } public function testSetParametersBackwardsCompatible(): void @@ -256,8 +262,8 @@ public function testSetParametersBackwardsCompatible(): void ->getResult(); self::assertSame( - array_values($parameters), - $this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['params'] + class_exists(LoggingMiddleware::class) ? $parameters : array_values($parameters), + $this->getLastLoggedQuery()['params'] ); } @@ -584,7 +590,7 @@ public function testEntityParameters(): void $this->_em->persist($article); $this->_em->flush(); $this->_em->clear(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $q = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a where a.topic = :topic and a.user = :user') ->setParameter('user', $this->_em->getReference(CmsUser::class, $author->id)) ->setParameter('topic', 'dr. dolittle'); diff --git a/tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php b/tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php index 6c81adbd9b..755b3f4a96 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php @@ -121,11 +121,11 @@ public function testUseResultCacheFalse(): void public function testUseResultCacheParams(): void { $cache = new ArrayAdapter(); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux WHERE ux.id = ?1'); $this->setResultCache($query, $cache); - $query->useResultCache(true); + $query->enableResultCache(); // these queries should result in cache miss: $query->setParameter(1, 1); @@ -133,9 +133,9 @@ public function testUseResultCacheParams(): void $query->setParameter(1, 2); $query->getResult(); - self::assertCount( + self::assertSame( $sqlCount + 2, - $this->_sqlLoggerStack->queries, + $this->getCurrentQueryCount(), 'Two non-cached queries.' ); @@ -145,9 +145,9 @@ public function testUseResultCacheParams(): void $query->setParameter(1, 2); $query->getResult(); - self::assertCount( + self::assertSame( $sqlCount + 2, - $this->_sqlLoggerStack->queries, + $this->getCurrentQueryCount(), 'The next two sql queries should have been cached, but were not.' ); } @@ -170,7 +170,7 @@ public function testEnableResultCache(): void public function testEnableResultCacheWithIterable(): void { $cache = new ArrayAdapter(); - $expectedSQLCount = count($this->_sqlLoggerStack->queries) + 1; + $expectedSQLCount = $this->getCurrentQueryCount() + 1; $query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux'); $query->enableResultCache(); @@ -180,9 +180,9 @@ public function testEnableResultCacheWithIterable(): void $this->_em->clear(); - self::assertCount( + self::assertSame( $expectedSQLCount, - $this->_sqlLoggerStack->queries + $this->getCurrentQueryCount() ); self::assertCacheHasItem('testing_iterable_result_cache_id', $cache); @@ -192,9 +192,9 @@ public function testEnableResultCacheWithIterable(): void $query->setResultCacheId('testing_iterable_result_cache_id'); iterator_to_array($query->toIterable()); - self::assertCount( + self::assertSame( $expectedSQLCount, - $this->_sqlLoggerStack->queries, + $this->getCurrentQueryCount(), 'Expected query to be cached' ); @@ -207,7 +207,7 @@ public function testEnableResultCacheWithIterable(): void public function testEnableResultCacheParams(): void { $cache = new ArrayAdapter(); - $sqlCount = count($this->_sqlLoggerStack->queries); + $sqlCount = $this->getCurrentQueryCount(); $query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux WHERE ux.id = ?1'); $this->setResultCache($query, $cache); @@ -219,9 +219,9 @@ public function testEnableResultCacheParams(): void $query->setParameter(1, 2); $query->getResult(); - self::assertCount( + self::assertSame( $sqlCount + 2, - $this->_sqlLoggerStack->queries, + $this->getCurrentQueryCount(), 'Two non-cached queries.' ); @@ -231,9 +231,9 @@ public function testEnableResultCacheParams(): void $query->setParameter(1, 2); $query->getResult(); - self::assertCount( + self::assertSame( $sqlCount + 2, - $this->_sqlLoggerStack->queries, + $this->getCurrentQueryCount(), 'The next two sql queries should have been cached, but were not.' ); } diff --git a/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php b/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php index 84c3a16bcb..c4ec569d29 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php @@ -519,7 +519,6 @@ public function testRepositoryFindOneByX(): void public function testToOneFilter(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $this->loadFixtureData(); $query = $this->_em->createQuery('select ux, ua from Doctrine\Tests\Models\CMS\CmsUser ux JOIN ux.address ua'); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php index bb8c6ca17c..a856df3935 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php @@ -29,7 +29,7 @@ class DDC1163Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC1163Product::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php index 62e1fa6534..e9e9b108f3 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php @@ -18,7 +18,7 @@ class DDC1193Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC1193Company::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php index 2b94720169..f4ab7b3394 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php @@ -5,7 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Common\Collections\Collection; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\DiscriminatorColumn; use Doctrine\ORM\Mapping\DiscriminatorMap; @@ -19,8 +18,6 @@ use Doctrine\ORM\Mapping\Table; use Doctrine\Tests\OrmFunctionalTestCase; -use function count; - /** * @group DDC-1595 * @group DDC-1596 @@ -32,8 +29,6 @@ protected function setUp(): void { parent::setUp(); - $this->_em->getConnection()->getConfiguration()->setSQLLogger(new DebugStack()); - $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC1595BaseInheritance::class), @@ -51,7 +46,6 @@ public function testIssue(): void $this->_em->flush(); $this->_em->clear(); - $sqlLogger = $this->_em->getConnection()->getConfiguration()->getSQLLogger(); $repository = $this->_em->getRepository(DDC1595InheritedEntity1::class); $entity1 = $repository->find($e1->id); @@ -59,14 +53,14 @@ public function testIssue(): void // DDC-1596 $this->assertSQLEquals( "SELECT t0.id AS id_1, t0.type FROM base t0 WHERE t0.id = ? AND t0.type IN ('Entity1')", - $sqlLogger->queries[count($sqlLogger->queries)]['sql'] + $this->getLastLoggedQuery()['sql'] ); $entities = $entity1->getEntities()->getValues(); self::assertEquals( "SELECT t0.id AS id_1, t0.type FROM base t0 INNER JOIN entity1_entity2 ON t0.id = entity1_entity2.item WHERE entity1_entity2.parent = ? AND t0.type IN ('Entity2')", - $sqlLogger->queries[count($sqlLogger->queries)]['sql'] + $this->getLastLoggedQuery()['sql'] ); $this->_em->clear(); @@ -76,7 +70,7 @@ public function testIssue(): void $this->assertSQLEquals( 'SELECT COUNT(*) FROM entity1_entity2 t WHERE t.parent = ?', - $sqlLogger->queries[count($sqlLogger->queries)]['sql'] + $this->getLastLoggedQuery()['sql'] ); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php index a8a279cf52..f9980c8cbe 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php @@ -38,8 +38,6 @@ public function tearDown(): void */ public function testJoinedSubclassPersisterRequiresSpecificOrderOfMetadataReflFieldsArray(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $spouse = new CompanyEmployee(); $spouse->setName('Blub'); $spouse->setDepartment('Accounting'); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php index b2a32e1cbe..e25094fca3 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php @@ -31,8 +31,6 @@ protected function setUp(): void public function testIssue(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $user = new DDC211User(); $user->setName('John Doe'); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php index 24f2d427f9..5ba1d389a5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php @@ -5,6 +5,8 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Logging\Middleware as LoggingMiddleware; +use Doctrine\DBAL\ParameterType; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; @@ -13,7 +15,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use function assert; -use function end; +use function class_exists; /** * Verifies that the type of parameters being bound to an SQL query is the same @@ -52,17 +54,18 @@ public function testIssue(): void assert($foo instanceof DDC2214Foo); $bar = $foo->bar; - $logger = $this->_em->getConnection()->getConfiguration()->getSQLLogger(); - $related = $this ->_em ->createQuery('SELECT b FROM ' . __NAMESPACE__ . '\DDC2214Bar b WHERE b.id IN(:ids)') ->setParameter('ids', [$bar]) ->getResult(); - $query = end($logger->queries); - - self::assertEquals(Connection::PARAM_INT_ARRAY, $query['types'][0]); + if (! class_exists(LoggingMiddleware::class)) { + // DBAL 2 logs queries before resolving parameter positions + self::assertEquals([Connection::PARAM_INT_ARRAY], $this->getLastLoggedQuery()['types']); + } else { + self::assertEquals([1 => ParameterType::INTEGER], $this->getLastLoggedQuery()['types']); + } } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php index 9b3402c0b1..3d1c7650ed 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php @@ -6,7 +6,6 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\DiscriminatorColumn; use Doctrine\ORM\Mapping\DiscriminatorMap; @@ -23,9 +22,6 @@ */ class DDC2346Test extends OrmFunctionalTestCase { - /** @var DebugStack */ - protected $logger; - protected function setUp(): void { parent::setUp(); @@ -37,8 +33,6 @@ protected function setUp(): void $this->_em->getClassMetadata(DDC2346Baz::class), ] ); - - $this->logger = new DebugStack(); } /** @@ -66,12 +60,12 @@ public function testIssue(): void $this->_em->flush(); $this->_em->clear(); - $this->_em->getConnection()->getConfiguration()->setSQLLogger($this->logger); + $this->getQueryLog()->reset()->enable(); $fetchedBazs = $this->_em->getRepository(DDC2346Baz::class)->findAll(); self::assertCount(2, $fetchedBazs); - self::assertCount(2, $this->logger->queries, 'The total number of executed queries is 2, and not n+1'); + self::assertSame(2, $this->getCurrentQueryCount(), 'The total number of executed queries is 2, and not n+1'); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php index dc82c4d2ba..f3760a86a5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php @@ -34,8 +34,6 @@ protected function setUp(): void */ public function testIssue(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $c1 = new DDC258Class1(); $c1->title = 'Foo'; $c1->description = 'Foo'; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php index 2a37cbfd40..8f4bb30875 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php @@ -26,7 +26,7 @@ class DDC345Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC345User::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php index dbdaf48cef..8f1792b6e7 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php @@ -25,7 +25,7 @@ class DDC371Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC371Parent::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php index ae37694dfa..849cd85602 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php @@ -26,7 +26,7 @@ class DDC422Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC422Guest::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php index 5125961f5e..d3e72ccff3 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php @@ -29,8 +29,6 @@ protected function setUp(): void */ public function testIssue(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $num = $this->_em->createQuery('DELETE ' . __NAMESPACE__ . '\DDC425Entity e WHERE e.someDatetimeField > ?1') ->setParameter(1, new DateTime(), Types::DATETIME_MUTABLE) ->getResult(); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php index cbea214cfa..8fec28cedc 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php @@ -19,7 +19,7 @@ class DDC444Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC444User::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php index ab586df9f7..6252574748 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php @@ -24,7 +24,7 @@ class DDC599Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + try { $this->_schemaTool->createSchema( [ diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php index c50910ed92..71dbf66510 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php @@ -23,7 +23,7 @@ class DDC719Test extends OrmFunctionalTestCase protected function setUp(): void { parent::setUp(); - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + $this->_schemaTool->createSchema( [ $this->_em->getClassMetadata(DDC719Group::class), diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php index 92a37be3f8..d927ff5b6b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php @@ -23,7 +23,6 @@ protected function setUp(): void */ public function testFetchJoinInitializesPreviouslyUninitializedCollectionOfManagedEntity(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); $article = new CmsArticle(); $article->topic = 'hello'; $article->text = 'talk talk talk'; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php index 8a2f785818..5b9fc04bae 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php @@ -36,8 +36,6 @@ protected function setUp(): void */ public function testIssue(): void { - //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); - $c1 = new DDC837Class1(); $c1->title = 'Foo'; $c1->description = 'Foo'; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php index 9042a92ec6..cb68215177 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php @@ -54,11 +54,15 @@ public function testUpdateEntityWithIdentifierAssociationWithQuotedJoinColumn(): self::assertNotEquals('name', $quotedColumn); self::assertNotEquals('user-id', $quotedIdentifier); - $queries = $this->_sqlLoggerStack->queries; + $lastLoggedQuery = $this->getLastLoggedQuery()['sql']; + // DBAL 2 logs a commit as last query. + if ($lastLoggedQuery === '"COMMIT"') { + $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; + } $this->assertSQLEquals( sprintf('UPDATE %s SET %s = ? WHERE %s = ?', $quotedTableName, $quotedColumn, $quotedIdentifier), - $queries[$this->_sqlLoggerStack->currentQuery - 1]['sql'] + $lastLoggedQuery ); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php index c7a5862fa6..0c4468f5ab 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\Tools\Pagination\Paginator; use Doctrine\Tests\Models\CMS\CmsArticle; use Doctrine\Tests\OrmFunctionalTestCase; @@ -14,9 +13,6 @@ */ final class GH7829Test extends OrmFunctionalTestCase { - /** @var DebugStack */ - private $logger; - protected function setUp(): void { $this->useModelSet('cms'); @@ -30,12 +26,12 @@ protected function setUp(): void $this->_em->persist($article); $this->_em->flush(); $this->_em->clear(); - - $this->_em->getConnection()->getConfiguration()->setSQLLogger($this->logger = new DebugStack()); } public function testPaginatorWithLimitSubquery(): void { + $this->getQueryLog()->reset()->enable(); + $query = $this->_em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a'); $query->setMaxResults(1); @@ -45,11 +41,13 @@ public function testPaginatorWithLimitSubquery(): void $paginator->count(); $paginator->getIterator(); - self::assertCount(3, $this->logger->queries); + self::assertSame(3, $this->getCurrentQueryCount()); } public function testPaginatorWithLimitSubquerySkipped(): void { + $this->getQueryLog()->reset()->enable(); + $query = $this->_em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a'); $paginator = new Paginator($query, true); @@ -58,6 +56,6 @@ public function testPaginatorWithLimitSubquerySkipped(): void $paginator->count(); $paginator->getIterator(); - self::assertCount(2, $this->logger->queries); + self::assertSame(2, $this->getCurrentQueryCount()); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php index 8b46448e15..cbba92b336 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php @@ -15,8 +15,6 @@ use Doctrine\ORM\Mapping\OneToMany; use Doctrine\Tests\OrmFunctionalTestCase; -use function count; - final class GH8217Test extends OrmFunctionalTestCase { protected function setUp(): void @@ -41,10 +39,9 @@ public function testNoQueriesAfterSecondFlush(): void $this->_em->persist($collection); $this->_em->flush(); - $logger = $this->_sqlLoggerStack; - $queriesNumberBeforeSecondFlush = count($logger->queries); + $queriesNumberBeforeSecondFlush = $this->getCurrentQueryCount(); $this->_em->flush(); - $queriesNumberAfterSecondFlush = count($logger->queries); + $queriesNumberAfterSecondFlush = $this->getCurrentQueryCount(); self::assertEquals($queriesNumberBeforeSecondFlush, $queriesNumberAfterSecondFlush); } } diff --git a/tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php b/tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php index db1e4a1aa0..85dac3d9ca 100644 --- a/tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\ORM\Performance; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Tests\Models\Cache\City; use Doctrine\Tests\Models\Cache\Country; @@ -32,100 +31,76 @@ protected function setUp(): void parent::setUp(); } - public function createEntityManager(): EntityManagerInterface - { - $logger = new DebugStack(); - $em = $this->getEntityManager(); - - $em->getConnection()->getConfiguration()->setSQLLogger($logger); - $em->getConfiguration()->setSQLLogger($logger); - - return $em; - } - - public function countQuery(EntityManagerInterface $em): int - { - return count($em->getConfiguration()->getSQLLogger()->queries); - } - public function testFindEntityWithoutCache(): void { - $em = $this->createEntityManager(); + $this->getQueryLog()->reset()->enable(); + $this->findEntity($this->_em, __FUNCTION__); - $this->findEntity($em, __FUNCTION__); - - self::assertEquals(6002, $this->countQuery($em)); + self::assertEquals(6002, $this->getCurrentQueryCount()); } public function testFindEntityWithCache(): void { parent::enableSecondLevelCache(false); - $em = $this->createEntityManager(); - - $this->findEntity($em, __FUNCTION__); + $this->getQueryLog()->reset()->enable(); + $this->findEntity($this->_em, __FUNCTION__); - self::assertEquals(502, $this->countQuery($em)); + self::assertEquals(502, $this->getCurrentQueryCount()); } public function testFindAllEntityWithoutCache(): void { - $em = $this->createEntityManager(); + $this->getQueryLog()->reset()->enable(); + $this->findAllEntity($this->_em, __FUNCTION__); - $this->findAllEntity($em, __FUNCTION__); - - self::assertEquals(153, $this->countQuery($em)); + self::assertEquals(153, $this->getCurrentQueryCount()); } public function testFindAllEntityWithCache(): void { parent::enableSecondLevelCache(false); - $em = $this->createEntityManager(); - - $this->findAllEntity($em, __FUNCTION__); + $this->getQueryLog()->reset()->enable(); + $this->findAllEntity($this->_em, __FUNCTION__); - self::assertEquals(53, $this->countQuery($em)); + self::assertEquals(53, $this->getCurrentQueryCount()); } public function testFindEntityOneToManyWithoutCache(): void { - $em = $this->createEntityManager(); + $this->getQueryLog()->reset()->enable(); + $this->findEntityOneToMany($this->_em, __FUNCTION__); - $this->findEntityOneToMany($em, __FUNCTION__); - - self::assertEquals(502, $this->countQuery($em)); + self::assertEquals(502, $this->getCurrentQueryCount()); } public function testFindEntityOneToManyWithCache(): void { parent::enableSecondLevelCache(false); - $em = $this->createEntityManager(); - - $this->findEntityOneToMany($em, __FUNCTION__); + $this->getQueryLog()->reset()->enable(); + $this->findEntityOneToMany($this->_em, __FUNCTION__); - self::assertEquals(472, $this->countQuery($em)); + self::assertEquals(472, $this->getCurrentQueryCount()); } public function testQueryEntityWithoutCache(): void { - $em = $this->createEntityManager(); + $this->getQueryLog()->reset()->enable(); + $this->queryEntity($this->_em, __FUNCTION__); - $this->queryEntity($em, __FUNCTION__); - - self::assertEquals(602, $this->countQuery($em)); + self::assertEquals(602, $this->getCurrentQueryCount()); } public function testQueryEntityWithCache(): void { parent::enableSecondLevelCache(false); - $em = $this->createEntityManager(); - - $this->queryEntity($em, __FUNCTION__); + $this->getQueryLog()->reset()->enable(); + $this->queryEntity($this->_em, __FUNCTION__); - self::assertEquals(503, $this->countQuery($em)); + self::assertEquals(503, $this->getCurrentQueryCount()); } private function queryEntity(EntityManagerInterface $em, string $label): void diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index fbaa297eb6..4e0cb7589c 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -6,7 +6,6 @@ use Doctrine\Common\Cache\Cache; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Logging\DebugStack; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; @@ -22,6 +21,7 @@ use Doctrine\ORM\Tools\DebugUnitOfWorkListener; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Tests\DbalExtensions\QueryLog; use Doctrine\Tests\DbalTypes\Rot13Type; use Doctrine\Tests\EventListener\CacheMetadataListener; use Exception; @@ -33,8 +33,10 @@ use Throwable; use function array_map; +use function array_pop; use function array_reverse; use function array_slice; +use function assert; use function count; use function explode; use function get_debug_type; @@ -72,7 +74,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase /** * Shared connection when a TestCase is run alone (outside of its functional suite). * - * @var Connection|null + * @var DbalExtensions\Connection|null */ protected static $sharedConn; @@ -82,9 +84,6 @@ abstract class OrmFunctionalTestCase extends OrmTestCase /** @var SchemaTool */ protected $_schemaTool; - /** @var DebugStack */ - protected $_sqlLoggerStack; - /** * The names of the model sets used in this testcase. * @@ -356,8 +355,8 @@ protected function tearDown(): void $platform = $conn->getDatabasePlatform(); - if ($this->_sqlLoggerStack instanceof DebugStack) { - $this->_sqlLoggerStack->enabled = false; + if ($this->isQueryLogAvailable()) { + $this->disableQueryLog(); } if (isset($this->_usedModelSets['cms'])) { @@ -696,7 +695,7 @@ protected function setUp(): void $this->_schemaTool->createSchema($classes); } - $this->_sqlLoggerStack->enabled = true; + $this->enableQueryLog(); } /** @@ -705,7 +704,7 @@ protected function setUp(): void * @throws ORMException */ protected function getEntityManager( - ?Connection $connection = null, + ?DbalExtensions\Connection $connection = null, ?MappingDriver $mappingDriver = null ): EntityManagerInterface { // NOTE: Functional tests use their own shared metadata cache, because @@ -723,9 +722,6 @@ protected function getEntityManager( self::$queryCache = new ArrayAdapter(); } - $this->_sqlLoggerStack = new DebugStack(); - $this->_sqlLoggerStack->enabled = false; - //FIXME: two different configs! $conn and the created entity manager have // different configs. $config = new Configuration(); @@ -777,7 +773,8 @@ protected function getEntityManager( ); $conn = $connection ?: static::$sharedConn; - $conn->getConfiguration()->setSQLLogger($this->_sqlLoggerStack); + assert($conn !== null); + $conn->queryLog->reset(); // get rid of more global state $evm = $conn->getEventManager(); @@ -821,9 +818,9 @@ protected function onNotSuccessfulTest(Throwable $e): void throw $e; } - if (isset($this->_sqlLoggerStack->queries) && count($this->_sqlLoggerStack->queries)) { + if ($this->isQueryLogAvailable() && $this->getCurrentQueryCount() > 0) { $queries = ''; - $last25queries = array_slice(array_reverse($this->_sqlLoggerStack->queries, true), 0, 25, true); + $last25queries = array_slice(array_reverse($this->getQueryLog()->queries, true), 0, 25, true); foreach ($last25queries as $i => $query) { $params = array_map(static function ($p) { return is_object($p) ? get_debug_type($p) : var_export($p, true); @@ -861,14 +858,6 @@ public function assertSQLEquals(string $expectedSql, string $actualSql): void ); } - /** - * Using the SQL Logger Stack this method retrieves the current query count executed in this test. - */ - protected function getCurrentQueryCount(): int - { - return count($this->_sqlLoggerStack->queries); - } - /** * Configures DBAL types required in tests */ @@ -880,4 +869,59 @@ protected function setUpDBALTypes(): void Type::addType('rot13', Rot13Type::class); } } + + final protected function isQueryLogAvailable(): bool + { + return $this->_em->getConnection() instanceof DbalExtensions\Connection; + } + + final protected function enableQueryLog(): void + { + $this->getQueryLog()->enabled = true; + } + + final protected function disableQueryLog(): void + { + $this->getQueryLog()->enabled = false; + } + + final protected function getQueryLog(): QueryLog + { + $connection = $this->_em->getConnection(); + if (! $connection instanceof DbalExtensions\Connection) { + throw new RuntimeException(sprintf( + 'The query log is only available if %s is used as wrapper class. Got %s.', + DbalExtensions\Connection::class, + get_debug_type($connection) + )); + } + + return $connection->queryLog; + } + + /** + * Using the SQL Logger Stack this method retrieves the current query count executed in this test. + */ + final protected function getCurrentQueryCount(): int + { + return count($this->getQueryLog()->queries); + } + + /** + * @psalm-return array{sql: string, params: array|null, types: array|null} + */ + final protected function getLastLoggedQuery(int $index = 0): array + { + $queries = $this->getQueryLog()->queries; + $lastQuery = null; + for ($i = $index; $i >= 0; $i--) { + $lastQuery = array_pop($queries); + } + + if ($lastQuery === null) { + throw new RuntimeException('The query log was empty.'); + } + + return $lastQuery; + } } diff --git a/tests/Doctrine/Tests/TestUtil.php b/tests/Doctrine/Tests/TestUtil.php index f3bb3a1c21..9abc09ac94 100644 --- a/tests/Doctrine/Tests/TestUtil.php +++ b/tests/Doctrine/Tests/TestUtil.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager; use UnexpectedValueException; +use function assert; use function explode; use function fwrite; use function get_debug_type; @@ -47,26 +48,28 @@ class TestUtil * IMPORTANT: * 1) Each invocation of this method returns a NEW database connection. * 2) The database is dropped and recreated to ensure it's clean. - * - * @return Connection The database connection instance. */ - public static function getConnection(): Connection + public static function getConnection(): DbalExtensions\Connection { if (! self::$initialized) { self::initializeDatabase(); self::$initialized = true; } - $conn = DriverManager::getConnection(self::getTestConnectionParameters()); + $connection = DriverManager::getConnection(self::getTestConnectionParameters()); + assert($connection instanceof DbalExtensions\Connection); - self::addDbEventSubscribers($conn); + self::addDbEventSubscribers($connection); - return $conn; + return $connection; } - public static function getPrivilegedConnection(): Connection + public static function getPrivilegedConnection(): DbalExtensions\Connection { - return DriverManager::getConnection(self::getPrivilegedConnectionParameters()); + $connection = DriverManager::getConnection(self::getPrivilegedConnectionParameters()); + assert($connection instanceof DbalExtensions\Connection); + + return $connection; } private static function initializeDatabase(): void @@ -194,6 +197,8 @@ private static function mapConnectionParameters(array $configuration, string $pr $parameters['driverOptions'][substr($param, strlen($prefix . 'driver_option_'))] = $value; } + $parameters['wrapperClass'] = DbalExtensions\Connection::class; + return $parameters; } }