Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 133d715

Browse files
committed
[Lock] create migration for lock table when PdoStore or DoctrineDbalStore is used
1 parent 1f7bc10 commit 133d715

File tree

8 files changed

+175
-3
lines changed

8 files changed

+175
-3
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\SchemaListener;
13+
14+
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
15+
use Symfony\Component\Lock\PersistingStoreInterface;
16+
use Symfony\Component\Lock\Store\DoctrineDbalStore;
17+
use Symfony\Component\Lock\Store\PdoStore;
18+
19+
final class LockStoreSchemaSubscriber extends AbstractSchemaSubscriber
20+
{
21+
/**
22+
* @param iterable<mixed, PersistingStoreInterface> $stores
23+
*/
24+
public function __construct(private iterable $stores)
25+
{
26+
}
27+
28+
public function postGenerateSchema(GenerateSchemaEventArgs $event): void
29+
{
30+
$connection = $event->getEntityManager()->getConnection();
31+
32+
foreach ($this->stores as $store) {
33+
if (!$store instanceof PdoStore && !$store instanceof DoctrineDbalStore) {
34+
continue;
35+
}
36+
37+
$store->configureSchema($event->getSchema(), $this->getIsSameDatabaseChecker($connection));
38+
}
39+
}
40+
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class UnusedTagsPass implements CompilerPassInterface
6161
'kernel.locale_aware',
6262
'kernel.reset',
6363
'ldap',
64+
'lock.store',
6465
'mailer.transport_factory',
6566
'messenger.bus',
6667
'messenger.message_handler',

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,8 +1898,10 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
18981898
foreach ($resourceStores as $resourceStore) {
18991899
$storeDsn = $container->resolveEnvPlaceholders($resourceStore, null, $usedEnvs);
19001900
$storeDefinition = new Definition(PersistingStoreInterface::class);
1901-
$storeDefinition->setFactory([StoreFactory::class, 'createStore']);
1902-
$storeDefinition->setArguments([$resourceStore]);
1901+
$storeDefinition
1902+
->setFactory([StoreFactory::class, 'createStore'])
1903+
->setArguments([$resourceStore])
1904+
->addTag('lock.store');
19031905

19041906
$container->setDefinition($storeDefinitionId = '.lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
19051907

src/Symfony/Component/Lock/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Create migration for lock table when PdoStore or DoctrineDbalStore is used
8+
49
6.0
510
---
611

src/Symfony/Component/Lock/Store/DoctrineDbalStore.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,21 @@ public function createTable(): void
181181

182182
/**
183183
* Adds the Table to the Schema if it doesn't exist.
184+
*
185+
* @param \Closure $isSameDatabase
184186
*/
185-
public function configureSchema(Schema $schema): void
187+
public function configureSchema(Schema $schema/* , \Closure $isSameDatabase */): void
186188
{
187189
if ($schema->hasTable($this->table)) {
188190
return;
189191
}
190192

193+
$isSameDatabase = 1 < \func_num_args() ? func_get_arg(1) : static fn () => true;
194+
195+
if (!$isSameDatabase($this->conn->executeStatement(...))) {
196+
return;
197+
}
198+
191199
$table = $schema->createTable($this->table);
192200
$table->addColumn($this->idCol, 'string', ['length' => 64]);
193201
$table->addColumn($this->tokenCol, 'string', ['length' => 44]);

src/Symfony/Component/Lock/Store/PdoStore.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Lock\Store;
1313

14+
use Doctrine\DBAL\Schema\Schema;
15+
use Doctrine\DBAL\Types\Types;
1416
use Symfony\Component\Lock\Exception\InvalidArgumentException;
1517
use Symfony\Component\Lock\Exception\InvalidTtlException;
1618
use Symfony\Component\Lock\Exception\LockConflictedException;
@@ -193,6 +195,47 @@ public function createTable(): void
193195
$conn->exec($sql);
194196
}
195197

198+
public function configureSchema(Schema $schema, \Closure $isSameDatabase): void
199+
{
200+
if ($schema->hasTable($this->table) || !$isSameDatabase($this->getConnection()->exec(...))) {
201+
return;
202+
}
203+
204+
$table = $schema->createTable($this->table);
205+
switch ($this->getDriver()) {
206+
case 'mysql':
207+
$table->addColumn($this->idCol, Types::STRING)->setLength(64)->setNotnull(true);
208+
$table->addColumn($this->tokenCol, Types::STRING)->setLength(44)->setNotnull(true);
209+
$table->addColumn($this->expirationCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
210+
$table->addOption('collate', 'utf8mb4_bin');
211+
$table->addOption('engine', 'InnoDB');
212+
break;
213+
case 'sqlite':
214+
$table->addColumn($this->idCol, Types::STRING)->setNotnull(true);
215+
$table->addColumn($this->tokenCol, Types::STRING)->setNotnull(true);
216+
$table->addColumn($this->expirationCol, Types::INTEGER);
217+
break;
218+
case 'pgsql':
219+
$table->addColumn($this->idCol, Types::STRING)->setLength(64)->setNotnull(true);
220+
$table->addColumn($this->tokenCol, Types::STRING)->setLength(64)->setNotnull(true);
221+
$table->addColumn($this->expirationCol, Types::INTEGER);
222+
break;
223+
case 'oci':
224+
$table->addColumn($this->idCol, Types::STRING)->setLength(64)->setNotnull(true);
225+
$table->addColumn($this->tokenCol, Types::STRING)->setNotnull(true);
226+
$table->addColumn($this->expirationCol, Types::INTEGER);
227+
break;
228+
case 'sqlsrv':
229+
$table->addColumn($this->idCol, Types::TEXT)->setLength(64)->setNotnull(true);
230+
$table->addColumn($this->tokenCol, Types::TEXT)->setNotnull(true);
231+
$table->addColumn($this->expirationCol, Types::INTEGER);
232+
break;
233+
default:
234+
throw new \DomainException(sprintf('Creating the lock pdo table is currently not implemented for PDO driver "%s".', $this->driver));
235+
}
236+
$table->setPrimaryKey([$this->idCol]);
237+
}
238+
196239
/**
197240
* Cleans up the table by removing all expired locks.
198241
*/

src/Symfony/Component/Lock/Tests/Store/DoctrineDbalStoreTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\DBAL\DriverManager;
1616
use Doctrine\DBAL\Exception\TableNotFoundException;
1717
use Doctrine\DBAL\Platforms\AbstractPlatform;
18+
use Doctrine\DBAL\Schema\Schema;
1819
use Symfony\Component\Lock\Key;
1920
use Symfony\Component\Lock\PersistingStoreInterface;
2021
use Symfony\Component\Lock\Store\DoctrineDbalStore;
@@ -208,4 +209,39 @@ public function testCreatesTableOutsideTransaction()
208209

209210
$store->save($key);
210211
}
212+
213+
public function testConfigureSchemaDifferentDatabase()
214+
{
215+
$conn = $this->createMock(Connection::class);
216+
$someFunction = function () { return false; };
217+
$schema = new Schema();
218+
219+
$dbalStore = new DoctrineDbalStore($conn);
220+
$dbalStore->configureSchema($schema, $someFunction);
221+
$this->assertFalse($schema->hasTable('lock_keys'));
222+
}
223+
224+
public function testConfigureSchemaSameDatabase()
225+
{
226+
$conn = $this->createMock(Connection::class);
227+
$someFunction = function () { return true; };
228+
$schema = new Schema();
229+
230+
$dbalStore = new DoctrineDbalStore($conn);
231+
$dbalStore->configureSchema($schema, $someFunction);
232+
$this->assertTrue($schema->hasTable('lock_keys'));
233+
}
234+
235+
public function testConfigureSchemaTableExists()
236+
{
237+
$conn = $this->createMock(Connection::class);
238+
$schema = new Schema();
239+
$schema->createTable('lock_keys');
240+
241+
$dbalStore = new DoctrineDbalStore($conn);
242+
$someFunction = function () { return true; };
243+
$dbalStore->configureSchema($schema, $someFunction);
244+
$table = $schema->getTable('lock_keys');
245+
$this->assertEmpty($table->getColumns(), 'The table was not overwritten');
246+
}
211247
}

src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Lock\Tests\Store;
1313

14+
use Doctrine\DBAL\Schema\Schema;
1415
use Symfony\Component\Lock\Exception\InvalidTtlException;
1516
use Symfony\Component\Lock\Key;
1617
use Symfony\Component\Lock\PersistingStoreInterface;
@@ -20,6 +21,7 @@
2021
* @author Jérémy Derussé <[email protected]>
2122
*
2223
* @requires extension pdo_sqlite
24+
*
2325
* @group integration
2426
*/
2527
class PdoStoreTest extends AbstractStoreTest
@@ -89,6 +91,41 @@ public function testDsn(string $dsn, string $file = null)
8991
}
9092
}
9193

94+
public function testConfigureSchemaDifferentDatabase()
95+
{
96+
$someFunction = function () { return false; };
97+
$schema = new Schema();
98+
99+
/** @var PdoStore $pdoStore */
100+
$pdoStore = $this->getStore();
101+
$pdoStore->configureSchema($schema, $someFunction);
102+
$this->assertFalse($schema->hasTable('lock_keys'));
103+
}
104+
105+
public function testConfigureSchemaSameDatabase()
106+
{
107+
$someFunction = function () { return true; };
108+
$schema = new Schema();
109+
110+
/** @var PdoStore $pdoStore */
111+
$pdoStore = $this->getStore();
112+
$pdoStore->configureSchema($schema, $someFunction);
113+
$this->assertTrue($schema->hasTable('lock_keys'));
114+
}
115+
116+
public function testConfigureSchemaTableExists()
117+
{
118+
$schema = new Schema();
119+
$schema->createTable('lock_keys');
120+
121+
/** @var PdoStore $pdoStore */
122+
$pdoStore = $this->getStore();
123+
$someFunction = function () { return true; };
124+
$pdoStore->configureSchema($schema, $someFunction);
125+
$table = $schema->getTable('lock_keys');
126+
$this->assertEmpty($table->getColumns(), 'The table was not overwritten');
127+
}
128+
92129
public function provideDsn()
93130
{
94131
$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');

0 commit comments

Comments
 (0)