Skip to content

Commit f332e68

Browse files
committed
make pdo (adapter|simple) implement PruneableInterface
1 parent f0d0c5f commit f332e68

File tree

8 files changed

+128
-5
lines changed

8 files changed

+128
-5
lines changed

src/Symfony/Component/Cache/Adapter/PdoAdapter.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
namespace Symfony\Component\Cache\Adapter;
1313

14+
use Symfony\Component\Cache\PruneableInterface;
1415
use Symfony\Component\Cache\Traits\PdoTrait;
1516

16-
class PdoAdapter extends AbstractAdapter
17+
class PdoAdapter extends AbstractAdapter implements PruneableInterface
1718
{
1819
use PdoTrait;
1920

src/Symfony/Component/Cache/CHANGELOG.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ CHANGELOG
55
-----
66

77
* added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning
8-
* added FilesystemTrait::prune() and PhpFilesTrait::prune() implementations
9-
* now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, and PhpFilesCache implement PruneableInterface and support
10-
manual stale cache pruning
8+
* added FilesystemTrait::prune(), PhpFilesTrait::prune(), and PdoTrait::prune() implementations
9+
* now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, PhpFilesCache, PdoAdapter, and PdoCache implement
10+
PruneableInterface and support manual stale cache pruning
1111

1212
3.3.0
1313
-----

src/Symfony/Component/Cache/Simple/PdoCache.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
namespace Symfony\Component\Cache\Simple;
1313

14+
use Symfony\Component\Cache\PruneableInterface;
1415
use Symfony\Component\Cache\Traits\PdoTrait;
1516

16-
class PdoCache extends AbstractCache
17+
class PdoCache extends AbstractCache implements PruneableInterface
1718
{
1819
use PdoTrait;
1920

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

+23
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

14+
use Psr\Cache\CacheItemPoolInterface;
1415
use Symfony\Component\Cache\Adapter\PdoAdapter;
1516

1617
/**
@@ -67,4 +68,26 @@ public function testCleanupExpiredItems()
6768
$this->assertFalse($newItem->isHit());
6869
$this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items');
6970
}
71+
72+
protected function isPruned(CacheItemPoolInterface $cache, $name)
73+
{
74+
$cacheObject = new \ReflectionObject($cache);
75+
$getConnectionMethod = $cacheObject->getMethod('getConnection');
76+
$getConnectionMethod->setAccessible(true);
77+
78+
$tableProperty = $cacheObject->getProperty('table');
79+
$tableProperty->setAccessible(true);
80+
81+
$idColProperty = $cacheObject->getProperty('idCol');
82+
$idColProperty->setAccessible(true);
83+
84+
$selectSql = "SELECT 1 FROM {$tableProperty->getValue($cache)} WHERE {$idColProperty->getValue($cache)} LIKE :id";
85+
86+
/** @var \Doctrine\DBAL\Statement $select */
87+
$select = $getConnectionMethod->invoke($cache)->prepare($selectSql);
88+
$select->bindValue(':id', sprintf('%%:%s', $name));
89+
$select->execute();
90+
91+
return $select->rowCount() !== 0;
92+
}
7093
}

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

+23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use Doctrine\DBAL\DriverManager;
15+
use Psr\Cache\CacheItemPoolInterface;
1516
use Symfony\Component\Cache\Adapter\PdoAdapter;
1617

1718
/**
@@ -42,4 +43,26 @@ public function createCachePool($defaultLifetime = 0)
4243
{
4344
return new PdoAdapter(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile)), '', $defaultLifetime);
4445
}
46+
47+
protected function isPruned(CacheItemPoolInterface $cache, $name)
48+
{
49+
$cacheObject = new \ReflectionObject($cache);
50+
$getConnectionMethod = $cacheObject->getMethod('getConnection');
51+
$getConnectionMethod->setAccessible(true);
52+
53+
$tableProperty = $cacheObject->getProperty('table');
54+
$tableProperty->setAccessible(true);
55+
56+
$idColProperty = $cacheObject->getProperty('idCol');
57+
$idColProperty->setAccessible(true);
58+
59+
$selectSql = "SELECT 1 FROM {$tableProperty->getValue($cache)} WHERE {$idColProperty->getValue($cache)} = :id";
60+
61+
/** @var \Doctrine\DBAL\Statement $select */
62+
$select = $getConnectionMethod->invoke($cache)->prepare($selectSql);
63+
$select->bindValue(':id', $name);
64+
$select->execute();
65+
66+
return $select->rowCount() !== 0;
67+
}
4568
}

src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Cache\Tests\Simple;
1313

14+
use Psr\SimpleCache\CacheInterface;
1415
use Symfony\Component\Cache\Simple\PdoCache;
1516

1617
/**
@@ -41,4 +42,26 @@ public function createSimpleCache($defaultLifetime = 0)
4142
{
4243
return new PdoCache('sqlite:'.self::$dbFile, 'ns', $defaultLifetime);
4344
}
45+
46+
protected function isPruned(CacheInterface $cache, $name)
47+
{
48+
$cacheObject = new \ReflectionObject($cache);
49+
$getConnectionMethod = $cacheObject->getMethod('getConnection');
50+
$getConnectionMethod->setAccessible(true);
51+
52+
$tableProperty = $cacheObject->getProperty('table');
53+
$tableProperty->setAccessible(true);
54+
55+
$idColProperty = $cacheObject->getProperty('idCol');
56+
$idColProperty->setAccessible(true);
57+
58+
$selectSql = "SELECT 1 FROM {$tableProperty->getValue($cache)} WHERE {$idColProperty->getValue($cache)} LIKE :id";
59+
60+
/** @var \Doctrine\DBAL\Statement $select */
61+
$select = $getConnectionMethod->invoke($cache)->prepare($selectSql);
62+
$select->bindValue(':id', sprintf('%%:%s', $name));
63+
$select->execute();
64+
65+
return $select->rowCount() !== 0;
66+
}
4467
}

src/Symfony/Component/Cache/Tests/Simple/PdoDbalCacheTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Cache\Tests\Simple;
1313

1414
use Doctrine\DBAL\DriverManager;
15+
use Psr\SimpleCache\CacheInterface;
1516
use Symfony\Component\Cache\Simple\PdoCache;
1617

1718
/**
@@ -42,4 +43,26 @@ public function createSimpleCache($defaultLifetime = 0)
4243
{
4344
return new PdoCache(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile)), '', $defaultLifetime);
4445
}
46+
47+
protected function isPruned(CacheInterface $cache, $name)
48+
{
49+
$cacheObject = new \ReflectionObject($cache);
50+
$getConnectionMethod = $cacheObject->getMethod('getConnection');
51+
$getConnectionMethod->setAccessible(true);
52+
53+
$tableProperty = $cacheObject->getProperty('table');
54+
$tableProperty->setAccessible(true);
55+
56+
$idColProperty = $cacheObject->getProperty('idCol');
57+
$idColProperty->setAccessible(true);
58+
59+
$selectSql = "SELECT 1 FROM {$tableProperty->getValue($cache)} WHERE {$idColProperty->getValue($cache)} = :id";
60+
61+
/** @var \Doctrine\DBAL\Statement $select */
62+
$select = $getConnectionMethod->invoke($cache)->prepare($selectSql);
63+
$select->bindValue(':id', $name);
64+
$select->execute();
65+
66+
return $select->rowCount() !== 0;
67+
}
4568
}

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

+29
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,35 @@ public function createTable()
137137
$conn->exec($sql);
138138
}
139139

140+
public function prune()
141+
{
142+
$pruned = true;
143+
144+
$selectSql = "SELECT $this->idCol FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= :time";
145+
$select = $this->getConnection()->prepare($selectSql);
146+
$select->bindValue(':time', time(), \PDO::PARAM_INT);
147+
$select->execute();
148+
149+
$expired = array();
150+
while ($row = $select->fetch()) {
151+
$expired[] = $row[$this->idCol];
152+
}
153+
154+
if (0 !== count($expired)) {
155+
$deleteSql = sprintf("DELETE FROM $this->table WHERE $this->idCol IN (%s)", str_pad('', (count($expired) << 1) - 1, '?,'));
156+
$delete = $this->getConnection()->prepare($deleteSql);
157+
158+
$i = 0;
159+
foreach ($expired as $id) {
160+
$delete->bindValue(++$i, $id);
161+
}
162+
163+
$pruned = $delete->execute() && $delete->rowCount() === count($expired);
164+
}
165+
166+
return $pruned;
167+
}
168+
140169
/**
141170
* {@inheritdoc}
142171
*/

0 commit comments

Comments
 (0)