8000 [FrameworkBundle][Cache] Allow configuring PDO-based cache pools, wit… · symfony/symfony@583eca6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 583eca6

Browse files
[FrameworkBundle][Cache] Allow configuring PDO-based cache pools, with table auto-creation on first use
1 parent 5fe78a3 commit 583eca6

File tree

9 files changed

+53
-10
lines changed

9 files changed

+53
-10
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* Allowed configuring taggable cache pools via a new `framework.cache.pools.tags` option (bool|service-id)
8+
* Allowed configuring PDO-based cache pools via a new `cache.adapter.pdo` abstract service
89
* Deprecated auto-injection of the container in AbstractController instances, register them as service subscribers instead
910
* Deprecated processing of services tagged `security.expression_language_provider` in favor of a new `AddExpressionLanguageProvidersPass` in SecurityBundle.
1011

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ private function addCacheSection(ArrayNodeDefinition $rootNode)
866866
->scalarNode('default_psr6_provider')->end()
867867
->scalarNode('default_redis_provider')->defaultValue('redis://localhost')->end()
868868
->scalarNode('default_memcached_provider')->defaultValue('memcached://localhost')->end()
869+
->scalarNode('default_pdo_provider')->defaultValue('doctrine.dbal.default_connection')->end()
869870
->arrayNode('pools')
870871
->useAttributeAsKey('name')
871872
->prototype('array')

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
15471547
// Inline any env vars referenced in the parameter
15481548
$container->setParameter('cache.prefix.seed', $container->resolveEnvPlaceholders($container->getParameter('cache.prefix.seed'), true));
15491549
}
1550-
foreach (array('doctrine', 'psr6', 'redis', 'memcached') as $name) {
1550+
foreach (array('doctrine', 'psr6', 'redis', 'memcached', 'pdo') as $name) {
15511551
if (isset($config[$name = 'default_'.$name.'_provider'])) {
15521552
$container->setAlias('cache.'.$name, new Alias(Compiler\CachePoolPass::getServiceProvider($container, $config[$name]), false));
15531553
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@
109109
</call>
110110
</service>
111111

112+
<service id="cache.adapter.pdo" class="Symfony\Component\Cache\Adapter\PdoAdapter" abstract="true">
113+
<tag name="cache.pool" provider="cache.default_pdo_provider" clearer="cache.default_clearer" reset="reset" />
114+
<tag name="monolog.logger" channel="cache" />
115+
<argument /> <!-- PDO connection service -->
116+
<argument /> <!-- namespace -->
117+
<argument>0</argument> <!-- default lifetime -->
118+
<argument type="collection" /> <!-- table options -->
119+
<argument type="service" id="cache.default_marshaller" on-invalid="ignore" />
120+
<call method="setLogger">
121+
<argument type="service" id="logger" on-invalid="ignore" />
122+
</call>
123+
</service>
124+
112125
<service id="cache.adapter.array" class="Symfony\Component\Cache\Adapter\ArrayAdapter" abstract="true">
113126
<tag name="cache.pool" clearer="cache.default_clearer" />
114127
<tag name="monolog.logger" channel="cache" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ protected static function getBundleDefaultConfig()
266266
'directory' => '%kernel.cache_dir%/pools',
267267
'default_redis_provider' => 'redis://localhost',
268268
'default_memcached_provider' => 'memcached://localhost',
269+
'default_pdo_provider' => 'doctrine.dbal.default_connection',
269270
),
270271
'workflows' => array(
271272
'enabled' => false,

src/Symfony/Component/Cache/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* added `CacheInterface`, which provides stampede protection via probabilistic early expiration and should become the preferred way to use a cache
88
* added sub-second expiry accuracy for backends that support it
99
* added support for phpredis 4 `compression` and `tcp_keepalive` options
10+
* added automatic table creation when using Doctrine DBAL with PDO-based backends
1011
* throw `LogicException` when `CacheItem::tag()` is called on an item coming from a non tag-aware pool
1112
* deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead
1213
* deprecated the `AbstractAdapter::createSystemCache()` method

src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public static function setupBeforeClass()
3333
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
3434

3535
$pool = new PdoAdapter(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile)));
36-
$pool->createTable();
3736
}
3837

3938
public static function tearDownAfterClass()

src/Symfony/Component/Cache/Traits/PdoTrait.php

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Doctrine\DBAL\Connection;
1515
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
1616
use Doctrine\DBAL\DBALException;
17+
use Doctrine\DBAL\Exception\TableNotFoundException;
1718
use Doctrine\DBAL\Schema\Schema;
1819
use Symfony\Component\Cache\Exception\InvalidArgumentException;
1920

@@ -150,7 +151,11 @@ public function prune()
150151
$deleteSql .= " AND $this->idCol LIKE :namespace";
151152
}
152153

153-
$delete = $this->getConnection()->prepare($deleteSql);
154+
try {
155+
$delete = $this->getConnection()->prepare($deleteSql);
156+
} catch (TableNotFoundException $e) {
157+
return true;
158+
}
154159
$delete->bindValue(':time', time(), \PDO::PARAM_INT);
155160

156161
if ('' !== $this->namespace) {
@@ -170,7 +175,11 @@ protected function doFetch(array $ids)
170175

171176
$sql = str_pad('', (count($ids) << 1) - 1, '?,');
172177
$sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN ($sql)";
173-
$stmt = $this->getConnection()->prepare($sql);
178+
try {
179+
$stmt = $this->getConnection()->prepare($sql);
180+
} catch (TableNotFoundException $e) {
181+
return;
182+
}
174183
$stmt->bindValue($i = 1, $now, \PDO::PARAM_INT);
175184
foreach ($ids as $id) {
176185
$stmt->bindValue(++$i, $id);
@@ -203,7 +212,11 @@ protected function doFetch(array $ids)
203212
protected function doHave($id)
204213
{
205214
$sql = "SELECT 1 FROM $this->table WHERE $this->idCol = :id AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > :time)";
206-
$stmt = $this->getConnection()->prepare($sql);
215+
try {
216+
$stmt = $this->getConnection()->prepare($sql);
217+
} catch (TableNotFoundException $e) {
218+
return false;
219+
}
207220

208221
$stmt->bindValue(':id', $id);
209222
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
@@ -229,7 +242,10 @@ protected function doClear($namespace)
229242
$sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'";
230243
}
231244

232-
$conn->exec($sql);
245+
try {
246+
$conn->exec($sql);
247+
} catch (TableNotFoundException $e) {
248+
}
233249

234250
return true;
235251
}
@@ -241,8 +257,11 @@ protected function doDelete(array $ids)
241257
{
242258
$sql = str_pad('', (count($ids) << 1) - 1, '?,');
243259
$sql = "DELETE FROM $this->table WHERE $this->idCol IN ($sql)";
244-
$stmt = $this->getConnection()->prepare($sql);
245-
$stmt->execute(array_values($ids));
260+
try {
261+
$stmt = $this->getConnection()->prepare($sql);
262+
$stmt->execute(array_values($ids));
263+
} catch (TableNotFoundException $e) {
264+
}
246265

247266
return true;
248267
}
@@ -302,7 +321,14 @@ protected function doSave(array $values, $lifetime)
302321

303322
$now = time();
304323
$lifetime = $lifetime ?: null;
305-
$stmt = $conn->prepare($sql);
324+
try {
325+
$stmt = $conn->prepare($sql);
326+
} catch (TableNotFoundException $e) {
327+
if (!$conn->isTransactionActive() || \in_array($this->driver, array('pgsql', 'sqlite', 'sqlsrv'), true)) {
328+
$this->createTable();
329+
}
330+
$stmt = $conn->prepare($sql);
331+
}
306332

307333
if ('sqlsrv' === $driver || 'oci' === $driver) {
308334
$stmt->bindParam(1, $id);

src/Symfony/Component/Cache/composer.json

Lines changed: 2 additions &am 9BF7 p; 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@
2828
"require-dev": {
2929
"cache/integration-tests": "dev-master",
3030
"doctrine/cache": "~1.6",
31-
"doctrine/dbal": "~2.4",
31+
"doctrine/dbal": "~2.5",
3232
"predis/predis": "~1.0",
3333
"symfony/var-dumper": "^4.1.1"
3434
},
3535
"conflict": {
36+
"doctrine/dbal": "<2.5",
3637
"symfony/var-dumper": "<3.4"
3738
},
3839
"autoload": {

0 commit comments

Comments
 (0)
0