From 92c9d05d3f6b52d557095c6f46e749fd1388f38c Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 9 Jul 2019 21:30:21 +0200 Subject: [PATCH] Respect schema asset filters from DBAL 2.9+ --- .../Common/DataFixtures/Purger/ORMPurger.php | 31 +++++++++++++++---- .../Purger/ORMPurgerExcludeTest.php | 22 +++++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php index af393f0f..16eca488 100644 --- a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php +++ b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php @@ -7,6 +7,9 @@ use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use function array_search; +use function is_callable; +use function preg_match; /** * Class responsible for purging databases of data before reloading data fixtures. @@ -126,13 +129,29 @@ public function purge() $connection = $this->em->getConnection(); $filterExpr = $connection->getConfiguration()->getFilterSchemaAssetsExpression(); $emptyFilterExpression = empty($filterExpr); + + $schemaAssetsFilter = method_exists($connection->getConfiguration(), 'getSchemaAssetsFilter') ? $connection->getConfiguration()->getSchemaAssetsFilter() : null; + foreach($orderedTables as $tbl) { - if(($emptyFilterExpression||preg_match($filterExpr, $tbl)) && array_search($tbl, $this->excluded) === false){ - if ($this->purgeMode === self::PURGE_MODE_DELETE) { - $connection->executeUpdate("DELETE FROM " . $tbl); - } else { - $connection->executeUpdate($platform->getTruncateTableSQL($tbl, true)); - } + // If we have a filter expression, check it and skip if necessary + if (!$emptyFilterExpression && !preg_match($filterExpr, $tbl)) { + continue; + } + + // If the table is excluded, skip it as well + if (array_search($tbl, $this->excluded) !== false) { + continue; + } + + // Support schema asset filters as presented in + if (is_callable($schemaAssetsFilter) && !$schemaAssetsFilter($tbl)) { + continue; + } + + if ($this->purgeMode === self::PURGE_MODE_DELETE) { + $connection->executeUpdate("DELETE FROM " . $tbl); + } else { + $connection->executeUpdate($platform->getTruncateTableSQL($tbl, true)); } } } diff --git a/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerExcludeTest.php b/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerExcludeTest.php index 41452a10..b68de4b8 100644 --- a/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerExcludeTest.php +++ b/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerExcludeTest.php @@ -9,6 +9,7 @@ use Doctrine\ORM\Tools\Setup; use Doctrine\Tests\Common\DataFixtures\TestPurgeEntity\ExcludedEntity; use Doctrine\Tests\Common\DataFixtures\TestPurgeEntity\IncludedEntity; +use function method_exists; class ORMPurgerExcludeTest extends BaseTest { @@ -59,7 +60,7 @@ protected function loadTestData(){ * @param string|null $expression * @param array $list */ - public function executeTestPurge($expression, array $list){ + public function executeTestPurge($expression, array $list, ?callable $filter = null){ $em = $this->loadTestData(); $excludedRepository = $em->getRepository(self::TEST_ENTITY_EXCLUDED); $includedRepository = $em->getRepository(self::TEST_ENTITY_INCLUDED); @@ -74,6 +75,14 @@ public function executeTestPurge($expression, array $list){ $configuration = $connection->getConfiguration(); $configuration->setFilterSchemaAssetsExpression($expression); + if ($filter !== null) { + if (!method_exists($configuration, 'setSchemaAssetsFilter')) { + $this->markTestSkipped('DBAL 2.9 or newer is required to test schema assets filters'); + } + + $configuration->setSchemaAssetsFilter($filter); + } + $purger = new ORMPurger($em,$list); $purger->purge(); @@ -88,13 +97,20 @@ public function executeTestPurge($expression, array $list){ * Test for purge exclusion usig dbal filter expression regexp. */ public function testPurgeExcludeUsingFilterExpression(){ - $this->executeTestPurge('~^(?!ExcludedEntity)~', []); + $this->executeTestPurge('~^(?!ExcludedEntity)~', [], null); } /** * Test for purge exclusion usig explicit exclution list. */ public function testPurgeExcludeUsingList(){ - $this->executeTestPurge(null, ['ExcludedEntity']); + $this->executeTestPurge(null, ['ExcludedEntity'], null); + } + + public function testPurgeExcludeUsingFilterCallable() : void + { + $this->executeTestPurge(null, [], static function (string $table) : bool { + return preg_match('~^(?!ExcludedEntity)~', $table); + }); } }