diff --git a/Dbal/BlacklistSchemaAssetFilter.php b/Dbal/BlacklistSchemaAssetFilter.php
new file mode 100644
index 000000000..493e5fb42
--- /dev/null
+++ b/Dbal/BlacklistSchemaAssetFilter.php
@@ -0,0 +1,29 @@
+blacklist = $blacklist;
+ }
+
+ public function __invoke($assetName) : bool
+ {
+ if ($assetName instanceof AbstractAsset) {
+ $assetName = $assetName->getName();
+ }
+
+ return ! in_array($assetName, $this->blacklist, true);
+ }
+}
diff --git a/DependencyInjection/Compiler/WellKnownSchemaFilterPass.php b/DependencyInjection/Compiler/WellKnownSchemaFilterPass.php
new file mode 100644
index 000000000..e83678421
--- /dev/null
+++ b/DependencyInjection/Compiler/WellKnownSchemaFilterPass.php
@@ -0,0 +1,65 @@
+getDefinitions() as $definition) {
+ if ($definition->isAbstract() || $definition->isSynthetic()) {
+ continue;
+ }
+
+ switch ($definition->getClass()) {
+ case PdoAdapter::class:
+ $blacklist[] = $definition->getArguments()[3]['db_table'] ?? 'cache_items';
+ break;
+
+ case PdoSessionHandler::class:
+ $blacklist[] = $definition->getArguments()[1]['db_table'] ?? 'lock_keys';
+ break;
+
+ case PdoStore::class:
+ $blacklist[] = $definition->getArguments()[1]['db_table'] ?? 'sessions';
+ break;
+
+ case Connection::class:
+ $blacklist[] = $definition->getArguments()[0]['table_name'] ?? 'messenger_messages';
+ break;
+ }
+ }
+
+ if (! $blacklist) {
+ return;
+ }
+
+ $definition = $container->getDefinition('doctrine.dbal.well_known_schema_asset_filter');
+ $definition->replaceArgument(0, $blacklist);
+
+ foreach (array_keys($container->getParameter('doctrine.connections')) as $name) {
+ $definition->addTag('doctrine.dbal.schema_filter', ['connection' => $name]);
+ }
+ }
+}
diff --git a/DoctrineBundle.php b/DoctrineBundle.php
index e8111b0a6..f19a1e527 100644
--- a/DoctrineBundle.php
+++ b/DoctrineBundle.php
@@ -5,6 +5,7 @@
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
+use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Proxy\Autoloader;
@@ -37,6 +38,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new DoctrineValidationPass('orm'));
$container->addCompilerPass(new EntityListenerPass());
$container->addCompilerPass(new ServiceRepositoryCompilerPass());
+ $container->addCompilerPass(new WellKnownSchemaFilterPass());
$container->addCompilerPass(new DbalSchemaFilterPass());
}
diff --git a/Resources/config/dbal.xml b/Resources/config/dbal.xml
index 6755891d7..917d7df53 100644
--- a/Resources/config/dbal.xml
+++ b/Resources/config/dbal.xml
@@ -75,6 +75,10 @@
+
+
+
+
diff --git a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
index 42511b5c6..92f910683 100644
--- a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
+++ b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
@@ -4,6 +4,7 @@
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
+use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Schema\AbstractAsset;
@@ -804,6 +805,7 @@ public function testDbalSchemaFilterNewConfig()
$container = $this->getContainer([]);
$loader = new DoctrineExtension();
$container->registerExtension($loader);
+ $container->addCompilerPass(new WellKnownSchemaFilterPass());
$container->addCompilerPass(new DbalSchemaFilterPass());
// ignore table1 table on "default" connection
@@ -841,6 +843,68 @@ public function testDbalSchemaFilterNewConfig()
$this->assertNull($connConfig = $getConfiguration('connection3')->getSchemaAssetsFilter());
}
+ public function testWellKnownSchemaFilterDefaultTables()
+ {
+ if (! method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
+ $this->markTestSkipped('Test requires doctrine/dbal 2.9 or higher');
+ }
+
+ $container = $this->getContainer([]);
+ $loader = new DoctrineExtension();
+ $container->registerExtension($loader);
+ $container->addCompilerPass(new WellKnownSchemaFilterPass());
+ $container->addCompilerPass(new DbalSchemaFilterPass());
+
+ $this->loadFromFile($container, 'well_known_schema_filter_default_tables');
+
+ $this->compileContainer($container);
+
+ $definition = $container->getDefinition('doctrine.dbal.well_known_schema_asset_filter');
+
+ $this->assertSame([['cache_items', 'lock_keys', 'sessions', 'messenger_messages']], $definition->getArguments());
+ $this->assertSame([['connection' => 'connection1'], ['connection' => 'connection2'], ['connection' => 'connection3']], $definition->getTag('doctrine.dbal.schema_filter'));
+
+ $definition = $container->getDefinition('doctrine.dbal.connection1_schema_asset_filter_manager');
+
+ $this->assertEquals([new Reference('doctrine.dbal.well_known_schema_asset_filter'), new Reference('doctrine.dbal.connection1_regex_schema_filter')], $definition->getArgument(0));
+
+ $filter = $container->get('well_known_filter');
+
+ $this->assertFalse($filter('sessions'));
+ $this->assertFalse($filter('cache_items'));
+ $this->assertFalse($filter('lock_keys'));
+ $this->assertFalse($filter('messenger_messages'));
+ $this->assertTrue($filter('anything_else'));
+ }
+
+ public function testWellKnownSchemaFilterOverriddenTables()
+ {
+ if (! method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
+ $this->markTestSkipped('Test requires doctrine/dbal 2.9 or higher');
+ }
+
+ $container = $this->getContainer([]);
+ $loader = new DoctrineExtension();
+ $container->registerExtension($loader);
+ $container->addCompilerPass(new WellKnownSchemaFilterPass());
+ $container->addCompilerPass(new DbalSchemaFilterPass());
+
+ $this->loadFromFile($container, 'well_known_schema_filter_overridden_tables');
+
+ $this->compileContainer($container);
+
+ $filter = $container->get('well_known_filter');
+
+ $this->assertFalse($filter('app_session'));
+ $this->assertFalse($filter('app_cache'));
+ $this->assertFalse($filter('app_locks'));
+ $this->assertFalse($filter('app_messages'));
+ $this->assertTrue($filter('sessions'));
+ $this->assertTrue($filter('cache_items'));
+ $this->assertTrue($filter('lock_keys'));
+ $this->assertTrue($filter('messenger_messages'));
+ }
+
public function testEntityListenerResolver()
{
$container = $this->loadContainer('orm_entity_listener_resolver', ['YamlBundle'], new EntityListenerPass());
diff --git a/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_default_tables.xml b/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_default_tables.xml
new file mode 100644
index 000000000..a63c484d1
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_default_tables.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_overridden_tables.xml b/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_overridden_tables.xml
new file mode 100644
index 000000000..99b2d51cd
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/config/xml/well_known_schema_filter_overridden_tables.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app_cache
+
+
+
+
+
+ app_session
+
+
+
+
+
+ app_locks
+
+
+
+
+ app_messages
+
+
+
+
diff --git a/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_default_tables.yml b/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_default_tables.yml
new file mode 100644
index 000000000..c99dd8d7c
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_default_tables.yml
@@ -0,0 +1,25 @@
+doctrine:
+ dbal:
+ default_connection: connection1
+ connections:
+ connection1:
+ schema_filter: ~^(?!t_)~
+ connection2: []
+ connection3: []
+
+services:
+ well_known_filter:
+ alias: 'doctrine.dbal.well_known_schema_asset_filter'
+ public: true
+
+ symfony.cache:
+ class: 'Symfony\Component\Cache\Adapter\PdoAdapter'
+
+ symfony.session:
+ class: 'Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler'
+
+ symfony.lock:
+ class: 'Symfony\Component\Lock\Store\PdoStore'
+
+ symfony.messenger:
+ class: 'Symfony\Component\Messenger\Transport\Doctrine\Connection'
diff --git a/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_overridden_tables.yml b/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_overridden_tables.yml
new file mode 100644
index 000000000..7058ae8b1
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/config/yml/well_known_schema_filter_overridden_tables.yml
@@ -0,0 +1,38 @@
+doctrine:
+ dbal:
+ default_connection: connection1
+ connections:
+ connection1:
+ schema_filter: ~^(?!t_)~
+ connection2: []
+ connection3: []
+
+services:
+ well_known_filter:
+ alias: 'doctrine.dbal.well_known_schema_asset_filter'
+ public: true
+
+ symfony.cache:
+ class: 'Symfony\Component\Cache\Adapter\PdoAdapter'
+ arguments:
+ - ~
+ - ~
+ - ~
+ - db_table: app_cache
+
+ symfony.session:
+ class: 'Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler'
+ arguments:
+ - ~
+ - db_table: app_session
+
+ symfony.lock:
+ class: 'Symfony\Component\Lock\Store\PdoStore'
+ arguments:
+ - ~
+ - db_table: app_locks
+
+ symfony.messenger:
+ class: 'Symfony\Component\Messenger\Transport\Doctrine\Connection'
+ arguments:
+ - table_name: app_messages