From 5e69f599960d4324b73f3e36442fc57ca29b0d87 Mon Sep 17 00:00:00 2001 From: Allison Guilhem Date: Mon, 16 Jan 2023 19:45:57 +0100 Subject: [PATCH] [Lock] create migration for lock table when DoctrineDbalStore is used --- .../LockStoreSchemaSubscriber.php | 39 +++++++++++++++++++ .../FrameworkExtension.php | 6 ++- src/Symfony/Component/Lock/CHANGELOG.md | 5 +++ .../Lock/Store/DoctrineDbalStore.php | 10 ++++- .../Tests/Store/DoctrineDbalStoreTest.php | 36 +++++++++++++++++ .../Lock/Tests/Store/PdoStoreTest.php | 1 + 6 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/SchemaListener/LockStoreSchemaSubscriber.php diff --git a/src/Symfony/Bridge/Doctrine/SchemaListener/LockStoreSchemaSubscriber.php b/src/Symfony/Bridge/Doctrine/SchemaListener/LockStoreSchemaSubscriber.php new file mode 100644 index 0000000000000..cbd76fe1d10e2 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/SchemaListener/LockStoreSchemaSubscriber.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\SchemaListener; + +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; +use Symfony\Component\Lock\PersistingStoreInterface; +use Symfony\Component\Lock\Store\DoctrineDbalStore; + +final class LockStoreSchemaSubscriber extends AbstractSchemaSubscriber +{ + /** + * @param iterable $stores + */ + public function __construct(private iterable $stores) + { + } + + public function postGenerateSchema(GenerateSchemaEventArgs $event): void + { + $connection = $event->getEntityManager()->getConnection(); + + foreach ($this->stores as $store) { + if (!$store instanceof DoctrineDbalStore) { + continue; + } + + $store->configureSchema($event->getSchema(), $this->getIsSameDatabaseChecker($connection)); + } + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 1a80c9ca9cfa5..551f02dc66299 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1898,8 +1898,10 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont foreach ($resourceStores as $resourceStore) { $storeDsn = $container->resolveEnvPlaceholders($resourceStore, null, $usedEnvs); $storeDefinition = new Definition(PersistingStoreInterface::class); - $storeDefinition->setFactory([StoreFactory::class, 'createStore']); - $storeDefinition->setArguments([$resourceStore]); + $storeDefinition + ->setFactory([StoreFactory::class, 'createStore']) + ->setArguments([$resourceStore]) + ->addTag('lock.store'); $container->setDefinition($storeDefinitionId = '.lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition); diff --git a/src/Symfony/Component/Lock/CHANGELOG.md b/src/Symfony/Component/Lock/CHANGELOG.md index 45d08d29f36ba..cc5528ffe188a 100644 --- a/src/Symfony/Component/Lock/CHANGELOG.md +++ b/src/Symfony/Component/Lock/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.3 +--- + + * Create migration for lock table when DoctrineDbalStore is used + 6.0 --- diff --git a/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php b/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php index 9ea46a25ff9a2..dcdcc557881fe 100644 --- a/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php +++ b/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php @@ -181,13 +181,21 @@ public function createTable(): void /** * Adds the Table to the Schema if it doesn't exist. + * + * @param \Closure $isSameDatabase */ - public function configureSchema(Schema $schema): void + public function configureSchema(Schema $schema/* , \Closure $isSameDatabase */): void { if ($schema->hasTable($this->table)) { return; } + $isSameDatabase = 1 < \func_num_args() ? func_get_arg(1) : static fn () => true; + + if (!$isSameDatabase($this->conn->executeStatement(...))) { + return; + } + $table = $schema->createTable($this->table); $table->addColumn($this->idCol, 'string', ['length' => 64]); $table->addColumn($this->tokenCol, 'string', ['length' => 44]); diff --git a/src/Symfony/Component/Lock/Tests/Store/DoctrineDbalStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/DoctrineDbalStoreTest.php index cf414926ff3ca..63e4cf8572d76 100644 --- a/src/Symfony/Component/Lock/Tests/Store/DoctrineDbalStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/DoctrineDbalStoreTest.php @@ -15,6 +15,7 @@ use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Schema\Schema; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\PersistingStoreInterface; use Symfony\Component\Lock\Store\DoctrineDbalStore; @@ -208,4 +209,39 @@ public function testCreatesTableOutsideTransaction() $store->save($key); } + + public function testConfigureSchemaDifferentDatabase() + { + $conn = $this->createMock(Connection::class); + $someFunction = function () { return false; }; + $schema = new Schema(); + + $dbalStore = new DoctrineDbalStore($conn); + $dbalStore->configureSchema($schema, $someFunction); + $this->assertFalse($schema->hasTable('lock_keys')); + } + + public function testConfigureSchemaSameDatabase() + { + $conn = $this->createMock(Connection::class); + $someFunction = function () { return true; }; + $schema = new Schema(); + + $dbalStore = new DoctrineDbalStore($conn); + $dbalStore->configureSchema($schema, $someFunction); + $this->assertTrue($schema->hasTable('lock_keys')); + } + + public function testConfigureSchemaTableExists() + { + $conn = $this->createMock(Connection::class); + $schema = new Schema(); + $schema->createTable('lock_keys'); + + $dbalStore = new DoctrineDbalStore($conn); + $someFunction = function () { return true; }; + $dbalStore->configureSchema($schema, $someFunction); + $table = $schema->getTable('lock_keys'); + $this->assertEmpty($table->getColumns(), 'The table was not overwritten'); + } } diff --git a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php index 35a605385f4e6..3f19e91487e01 100644 --- a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php @@ -20,6 +20,7 @@ * @author Jérémy Derussé * * @requires extension pdo_sqlite + * * @group integration */ class PdoStoreTest extends AbstractStoreTest