Chris@0: . Chris@0: */ Chris@0: Chris@0: namespace Doctrine\Common\Cache; Chris@0: Chris@0: /** Chris@0: * Base class for cache provider implementations. Chris@0: * Chris@0: * @since 2.2 Chris@0: * @author Benjamin Eberlei Chris@0: * @author Guilherme Blanco Chris@0: * @author Jonathan Wage Chris@0: * @author Roman Borschel Chris@0: * @author Fabio B. Silva Chris@0: */ Chris@0: abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache Chris@0: { Chris@0: const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; Chris@0: Chris@0: /** Chris@0: * The namespace to prefix all cache ids with. Chris@0: * Chris@0: * @var string Chris@0: */ Chris@0: private $namespace = ''; Chris@0: Chris@0: /** Chris@0: * The namespace version. Chris@0: * Chris@0: * @var integer|null Chris@0: */ Chris@0: private $namespaceVersion; Chris@0: Chris@0: /** Chris@0: * Sets the namespace to prefix all cache ids with. Chris@0: * Chris@0: * @param string $namespace Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: public function setNamespace($namespace) Chris@0: { Chris@0: $this->namespace = (string) $namespace; Chris@0: $this->namespaceVersion = null; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieves the namespace that prefixes all cache ids. Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getNamespace() Chris@0: { Chris@0: return $this->namespace; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function fetch($id) Chris@0: { Chris@0: return $this->doFetch($this->getNamespacedId($id)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function fetchMultiple(array $keys) Chris@0: { Chris@0: if (empty($keys)) { Chris@0: return array(); Chris@0: } Chris@0: Chris@0: // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys Chris@0: $namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys)); Chris@0: $items = $this->doFetchMultiple($namespacedKeys); Chris@0: $foundItems = array(); Chris@0: Chris@0: // no internal array function supports this sort of mapping: needs to be iterative Chris@0: // this filters and combines keys in one pass Chris@0: foreach ($namespacedKeys as $requestedKey => $namespacedKey) { Chris@0: if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) { Chris@0: $foundItems[$requestedKey] = $items[$namespacedKey]; Chris@0: } Chris@0: } Chris@0: Chris@0: return $foundItems; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function saveMultiple(array $keysAndValues, $lifetime = 0) Chris@0: { Chris@0: $namespacedKeysAndValues = array(); Chris@0: foreach ($keysAndValues as $key => $value) { Chris@0: $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value; Chris@0: } Chris@0: Chris@0: return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function contains($id) Chris@0: { Chris@0: return $this->doContains($this->getNamespacedId($id)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function save($id, $data, $lifeTime = 0) Chris@0: { Chris@0: return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function delete($id) Chris@0: { Chris@0: return $this->doDelete($this->getNamespacedId($id)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getStats() Chris@0: { Chris@0: return $this->doGetStats(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function flushAll() Chris@0: { Chris@0: return $this->doFlush(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function deleteAll() Chris@0: { Chris@0: $namespaceCacheKey = $this->getNamespaceCacheKey(); Chris@0: $namespaceVersion = $this->getNamespaceVersion() + 1; Chris@0: Chris@0: if ($this->doSave($namespaceCacheKey, $namespaceVersion)) { Chris@0: $this->namespaceVersion = $namespaceVersion; Chris@0: Chris@0: return true; Chris@0: } Chris@0: Chris@0: return false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Prefixes the passed id with the configured namespace value. Chris@0: * Chris@0: * @param string $id The id to namespace. Chris@0: * Chris@0: * @return string The namespaced id. Chris@0: */ Chris@0: private function getNamespacedId($id) Chris@0: { Chris@0: $namespaceVersion = $this->getNamespaceVersion(); Chris@0: Chris@0: return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the namespace cache key. Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: private function getNamespaceCacheKey() Chris@0: { Chris@0: return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the namespace version. Chris@0: * Chris@0: * @return integer Chris@0: */ Chris@0: private function getNamespaceVersion() Chris@0: { Chris@0: if (null !== $this->namespaceVersion) { Chris@0: return $this->namespaceVersion; Chris@0: } Chris@0: Chris@0: $namespaceCacheKey = $this->getNamespaceCacheKey(); Chris@0: $this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1; Chris@0: Chris@0: return $this->namespaceVersion; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. Chris@0: * Chris@0: * @param array $keys Array of keys to retrieve from cache Chris@0: * @return array Array of values retrieved for the given keys. Chris@0: */ Chris@0: protected function doFetchMultiple(array $keys) Chris@0: { Chris@0: $returnValues = array(); Chris@0: Chris@0: foreach ($keys as $key) { Chris@0: if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) { Chris@0: $returnValues[$key] = $item; Chris@0: } Chris@0: } Chris@0: Chris@0: return $returnValues; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Fetches an entry from the cache. Chris@0: * Chris@0: * @param string $id The id of the cache entry to fetch. Chris@0: * Chris@0: * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id. Chris@0: */ Chris@0: abstract protected function doFetch($id); Chris@0: Chris@0: /** Chris@0: * Tests if an entry exists in the cache. Chris@0: * Chris@0: * @param string $id The cache id of the entry to check for. Chris@0: * Chris@0: * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. Chris@0: */ Chris@0: abstract protected function doContains($id); Chris@0: Chris@0: /** Chris@0: * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it. Chris@0: * Chris@0: * @param array $keysAndValues Array of keys and values to save in cache Chris@0: * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these Chris@0: * cache entries (0 => infinite lifeTime). Chris@0: * Chris@0: * @return bool TRUE if the operation was successful, FALSE if it wasn't. Chris@0: */ Chris@0: protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) Chris@0: { Chris@0: $success = true; Chris@0: Chris@0: foreach ($keysAndValues as $key => $value) { Chris@0: if (!$this->doSave($key, $value, $lifetime)) { Chris@0: $success = false; Chris@0: } Chris@0: } Chris@0: Chris@0: return $success; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Puts data into the cache. Chris@0: * Chris@0: * @param string $id The cache id. Chris@0: * @param string $data The cache entry/data. Chris@0: * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this Chris@0: * cache entry (0 => infinite lifeTime). Chris@0: * Chris@0: * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. Chris@0: */ Chris@0: abstract protected function doSave($id, $data, $lifeTime = 0); Chris@0: Chris@0: /** Chris@0: * Deletes a cache entry. Chris@0: * Chris@0: * @param string $id The cache id. Chris@0: * Chris@0: * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise. Chris@0: */ Chris@0: abstract protected function doDelete($id); Chris@0: Chris@0: /** Chris@0: * Flushes all cache entries. Chris@0: * Chris@0: * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise. Chris@0: */ Chris@0: abstract protected function doFlush(); Chris@0: Chris@0: /** Chris@0: * Retrieves cached information from the data store. Chris@0: * Chris@0: * @since 2.2 Chris@0: * Chris@0: * @return array|null An associative array with server's statistics if available, NULL otherwise. Chris@0: */ Chris@0: abstract protected function doGetStats(); Chris@0: }