[Cache] Implement PSR-16 SimpleCache v1.0
This commit is contained in:
parent
60d7d437b5
commit
848a33ed3e
@ -21,6 +21,7 @@
|
|||||||
"twig/twig": "~1.28|~2.0",
|
"twig/twig": "~1.28|~2.0",
|
||||||
"psr/cache": "~1.0",
|
"psr/cache": "~1.0",
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
|
"psr/simple-cache": "^1.0",
|
||||||
"symfony/polyfill-intl-icu": "~1.0",
|
"symfony/polyfill-intl-icu": "~1.0",
|
||||||
"symfony/polyfill-mbstring": "~1.0",
|
"symfony/polyfill-mbstring": "~1.0",
|
||||||
"symfony/polyfill-php56": "~1.0",
|
"symfony/polyfill-php56": "~1.0",
|
||||||
@ -79,7 +80,7 @@
|
|||||||
"symfony/yaml": "self.version"
|
"symfony/yaml": "self.version"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"cache/integration-tests": "dev-master",
|
"cache/integration-tests": "^0.15.0",
|
||||||
"doctrine/cache": "~1.6",
|
"doctrine/cache": "~1.6",
|
||||||
"doctrine/data-fixtures": "1.0.*",
|
"doctrine/data-fixtures": "1.0.*",
|
||||||
"doctrine/dbal": "~2.4",
|
"doctrine/dbal": "~2.4",
|
||||||
@ -99,7 +100,8 @@
|
|||||||
"phpdocumentor/type-resolver": "<0.2.0"
|
"phpdocumentor/type-resolver": "<0.2.0"
|
||||||
},
|
},
|
||||||
"provide": {
|
"provide": {
|
||||||
"psr/cache-implementation": "1.0"
|
"psr/cache-implementation": "1.0",
|
||||||
|
"psr/simple-cache-implementation": "1.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -62,6 +62,8 @@
|
|||||||
<array>
|
<array>
|
||||||
<element><string>Cache\IntegrationTests</string></element>
|
<element><string>Cache\IntegrationTests</string></element>
|
||||||
<element><string>Doctrine\Common\Cache</string></element>
|
<element><string>Doctrine\Common\Cache</string></element>
|
||||||
|
<element><string>Symfony\Component\Cache</string></element>
|
||||||
|
<element><string>Symfony\Component\Cache\Traits</string></element>
|
||||||
<element><string>Symfony\Component\Console</string></element>
|
<element><string>Symfony\Component\Console</string></element>
|
||||||
<element><string>Symfony\Component\HttpFoundation</string></element>
|
<element><string>Symfony\Component\HttpFoundation</string></element>
|
||||||
</array>
|
</array>
|
||||||
|
75
src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php
Normal file
75
src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Cache\Adapter;
|
||||||
|
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
class SimpleCacheAdapter extends AbstractAdapter
|
||||||
|
{
|
||||||
|
private $pool;
|
||||||
|
private $miss;
|
||||||
|
|
||||||
|
public function __construct(CacheInterface $pool, $namespace = '', $defaultLifetime = 0)
|
||||||
|
{
|
||||||
|
parent::__construct($namespace, $defaultLifetime);
|
||||||
|
|
||||||
|
$this->pool = $pool;
|
||||||
|
$this->miss = new \stdClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function doFetch(array $ids)
|
||||||
|
{
|
||||||
|
foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
|
||||||
|
if ($this->miss !== $value) {
|
||||||
|
yield $key => $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function doHave($id)
|
||||||
|
{
|
||||||
|
return $this->pool->has($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function doClear($namespace)
|
||||||
|
{
|
||||||
|
return $this->pool->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function doDelete(array $ids)
|
||||||
|
{
|
||||||
|
return $this->pool->deleteMultiple($ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function doSave(array $values, $lifetime)
|
||||||
|
{
|
||||||
|
return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Exception;
|
namespace Symfony\Component\Cache\Exception;
|
||||||
|
|
||||||
use Psr\Cache\CacheException as CacheExceptionInterface;
|
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||||
|
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
||||||
|
|
||||||
class CacheException extends \Exception implements CacheExceptionInterface
|
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Exception;
|
namespace Symfony\Component\Cache\Exception;
|
||||||
|
|
||||||
use Psr\Cache\InvalidArgumentException as InvalidArgumentExceptionInterface;
|
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
|
||||||
|
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
|
||||||
|
|
||||||
class InvalidArgumentException extends \InvalidArgumentException implements InvalidArgumentExceptionInterface
|
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
225
src/Symfony/Component/Cache/Simple/Psr6Cache.php
Normal file
225
src/Symfony/Component/Cache/Simple/Psr6Cache.php
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Cache\Simple;
|
||||||
|
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
use Psr\Cache\CacheException as Psr6CacheException;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use Psr\SimpleCache\CacheException as SimpleCacheException;
|
||||||
|
use Symfony\Component\Cache\CacheItem;
|
||||||
|
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
class Psr6Cache implements CacheInterface
|
||||||
|
{
|
||||||
|
private $pool;
|
||||||
|
private $createCacheItem;
|
||||||
|
|
||||||
|
public function __construct(CacheItemPoolInterface $pool)
|
||||||
|
{
|
||||||
|
$this->pool = $pool;
|
||||||
|
|
||||||
|
if ($pool instanceof Adapter\AdapterInterface) {
|
||||||
|
$this->createCacheItem = \Closure::bind(
|
||||||
|
function ($key, $value, $allowInt = false) {
|
||||||
|
if ($allowInt && is_int($key)) {
|
||||||
|
$key = (string) $key;
|
||||||
|
} else {
|
||||||
|
CacheItem::validateKey($key);
|
||||||
|
}
|
||||||
|
$item = new CacheItem();
|
||||||
|
$item->key = $key;
|
||||||
|
$item->value = $value;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
CacheItem::class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function get($key, $default = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$item = $this->pool->getItem($key);
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $item->isHit() ? $item->get() : $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function set($key, $value, $ttl = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (null !== $f = $this->createCacheItem) {
|
||||||
|
$item = $f($key, $value);
|
||||||
|
} else {
|
||||||
|
$item = $this->pool->getItem($key)->set($value);
|
||||||
|
}
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
if (null !== $ttl) {
|
||||||
|
$item->expiresAfter($ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->pool->save($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function delete($key)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->pool->deleteItem($key);
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
return $this->pool->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMultiple($keys, $default = null)
|
||||||
|
{
|
||||||
|
if ($keys instanceof \Traversable) {
|
||||||
|
$keys = iterator_to_array($keys, false);
|
||||||
|
} elseif (!is_array($keys)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$items = $this->pool->getItems($keys);
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
$values = array();
|
||||||
|
|
||||||
|
foreach ($items as $key => $item) {
|
||||||
|
$values[$key] = $item->isHit() ? $item->get() : $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setMultiple($values, $ttl = null)
|
||||||
|
{
|
||||||
|
$valuesIsArray = is_array($values);
|
||||||
|
if (!$valuesIsArray && !$values instanceof \Traversable) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values)));
|
||||||
|
}
|
||||||
|
$items = array();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (null !== $f = $this->createCacheItem) {
|
||||||
|
$valuesIsArray = false;
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$items[$key] = $f($key, $value, true);
|
||||||
|
}
|
||||||
|
} elseif ($valuesIsArray) {
|
||||||
|
$items = array();
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$items[] = (string) $key;
|
||||||
|
}
|
||||||
|
$items = $this->pool->getItems($items);
|
||||||
|
} else {
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
if (is_int($key)) {
|
||||||
|
$key = (string) $key;
|
||||||
|
}
|
||||||
|
$items[$key] = $this->pool->getItem($key)->set($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
$ok = true;
|
||||||
|
|
||||||
|
foreach ($items as $key => $item) {
|
||||||
|
if ($valuesIsArray) {
|
||||||
|
$item->set($values[$key]);
|
||||||
|
}
|
||||||
|
if (null !== $ttl) {
|
||||||
|
$item->expiresAfter($ttl);
|
||||||
|
}
|
||||||
|
$ok = $this->pool->saveDeferred($item) && $ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->pool->commit() && $ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function deleteMultiple($keys)
|
||||||
|
{
|
||||||
|
if ($keys instanceof \Traversable) {
|
||||||
|
$keys = iterator_to_array($keys, false);
|
||||||
|
} elseif (!is_array($keys)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->pool->deleteItems($keys);
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function has($key)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->pool->hasItem($key);
|
||||||
|
} catch (SimpleCacheException $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (Psr6CacheException $e) {
|
||||||
|
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||||
|
use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
|
||||||
|
use Symfony\Component\Cache\Simple\Psr6Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group time-sensitive
|
||||||
|
*/
|
||||||
|
class SimpleCacheAdapterTest extends AdapterTestCase
|
||||||
|
{
|
||||||
|
public function createCachePool($defaultLifetime = 0)
|
||||||
|
{
|
||||||
|
return new SimpleCacheAdapter(new Psr6Cache(new FilesystemAdapter()), '', $defaultLifetime);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "symfony/cache",
|
"name": "symfony/cache",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"description": "Symfony implementation of PSR-6",
|
"description": "Symfony Cache component with PSR-6, PSR-16, and tags",
|
||||||
"keywords": ["caching", "psr6"],
|
"keywords": ["caching", "psr6"],
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -16,15 +16,17 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"provide": {
|
"provide": {
|
||||||
"psr/cache-implementation": "1.0"
|
"psr/cache-implementation": "1.0",
|
||||||
|
"psr/simple-cache-implementation": "1.0"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.9",
|
"php": ">=5.5.9",
|
||||||
"psr/cache": "~1.0",
|
"psr/cache": "~1.0",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0",
|
||||||
|
"psr/simple-cache": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"cache/integration-tests": "dev-master",
|
"cache/integration-tests": "^0.15.0",
|
||||||
"doctrine/cache": "~1.6",
|
"doctrine/cache": "~1.6",
|
||||||
"doctrine/dbal": "~2.4",
|
"doctrine/dbal": "~2.4",
|
||||||
"predis/predis": "~1.0"
|
"predis/predis": "~1.0"
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
<array>
|
<array>
|
||||||
<element><string>Cache\IntegrationTests</string></element>
|
<element><string>Cache\IntegrationTests</string></element>
|
||||||
<element><string>Doctrine\Common\Cache</string></element>
|
<element><string>Doctrine\Common\Cache</string></element>
|
||||||
|
<element><string>Symfony\Component\Cache</string></element>
|
||||||
|
<element><string>Symfony\Component\Cache\Traits</string></element>
|
||||||
</array>
|
</array>
|
||||||
</arguments>
|
</arguments>
|
||||||
</listener>
|
</listener>
|
||||||
|
Reference in New Issue
Block a user