/** * @covers validateTags * * @dataProvider validateTagsProvider */ public function testValidateTags(array $tags, $expected_exception_message) { if ($expected_exception_message !== FALSE) { $this->setExpectedException('LogicException', $expected_exception_message); } Cache::validateTags($tags); }
/** * @covers ::validateTags * * @dataProvider validateTagsProvider */ public function testValidateTags(array $tags, $expected_exception_message) { if ($expected_exception_message !== FALSE) { $this->setExpectedException('LogicException', $expected_exception_message); } // If it doesn't throw an exception, validateTags() returns NULL. $this->assertNull(Cache::validateTags($tags)); }
/** * {@inheritdoc} */ public function invalidateTags(array $tags) { // Validate the tags. Cache::validateTags($tags); // Notify all added cache tags invalidators. foreach ($this->invalidators as $invalidator) { $invalidator->invalidateTags($tags); } // Additionally, notify each cache bin if it implements the service. foreach ($this->getInvalidatorCacheBins() as $bin) { $bin->invalidateTags($tags); } }
/** * Initialize the cache backend. * * Plugin definitions are cached using the provided cache backend. The * interface language is added as a suffix to the cache key. * * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. * @param string $cache_key * Cache key prefix to use, the language code will be appended * automatically. * @param array $cache_tags * (optional) When providing a list of cache tags, the cached plugin * definitions are tagged with the provided cache tags. These cache tags can * then be used to clear the corresponding cached plugin definitions. Note * that this should be used with care! For clearing all cached plugin * definitions of a plugin manager, call that plugin manager's * clearCachedDefinitions() method. Only use cache tags when cached plugin * definitions should be cleared along with other, related cache entries. */ public function setCacheBackend(CacheBackendInterface $cache_backend, $cache_key, array $cache_tags = array()) { Cache::validateTags($cache_tags); $this->cacheBackend = $cache_backend; $this->cacheKey = $cache_key; $this->cacheTags = $cache_tags; }
/** * {@inheritdoc} */ public function setMultiple(array $items) { $values = array(); foreach ($items as $cid => $item) { $item += array('expire' => CacheBackendInterface::CACHE_PERMANENT, 'tags' => array()); Cache::validateTags($item['tags']); $item['tags'] = array_unique($item['tags']); // Sort the cache tags so that they are stored consistently in the DB. sort($item['tags']); $fields = array('cid' => $cid, 'expire' => $item['expire'], 'created' => round(microtime(TRUE), 3), 'tags' => implode(' ', $item['tags']), 'checksum' => $this->checksumProvider->getCurrentChecksum($item['tags'])); if (!is_string($item['data'])) { $fields['data'] = serialize($item['data']); $fields['serialized'] = 1; } else { $fields['data'] = $item['data']; $fields['serialized'] = 0; } $values[] = $fields; } // Use a transaction so that the database can write the changes in a single // commit. The transaction is started after calculating the tag checksums // since that can create a table and this causes an exception when using // PostgreSQL. $transaction = $this->connection->startTransaction(); try { // Delete all items first so we can do one insert. Rather than multiple // merge queries. $this->deleteMultiple(array_keys($items)); $query = $this->connection->insert($this->bin)->fields(array('cid', 'expire', 'created', 'tags', 'checksum', 'data', 'serialized')); foreach ($values as $fields) { // Only pass the values since the order of $fields matches the order of // the insert fields. This is a performance optimization to avoid // unnecessary loops within the method. $query->values(array_values($fields)); } $query->execute(); } catch (\Exception $e) { $transaction->rollback(); // @todo Log something here or just re throw? throw $e; } }
/** * Constructs a CacheCollector object. * * @param string $cid * The cid for the array being cached. * @param \Drupal\Core\Cache\CacheBackendInterface $cache * The cache backend. * @param \Drupal\Core\Lock\LockBackendInterface $lock * The lock backend. * @param array $tags * (optional) The tags to specify for the cache item. */ public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, array $tags = array()) { Cache::validateTags($tags); $this->cid = $cid; $this->cache = $cache; $this->tags = $tags; $this->lock = $lock; }
/** * Stores multiple items in the persistent cache. * * @param array $items * An array of cache items, keyed by cid. * * @see \Drupal\Core\Cache\CacheBackendInterface::setMultiple() */ protected function doSetMultiple(array $items) { $values = array(); foreach ($items as $cid => $item) { $item += array('expire' => CacheBackendInterface::CACHE_PERMANENT, 'tags' => array()); Cache::validateTags($item['tags']); $item['tags'] = array_unique($item['tags']); // Sort the cache tags so that they are stored consistently in the DB. sort($item['tags']); $fields = array('cid' => $this->normalizeCid($cid), 'expire' => $item['expire'], 'created' => round(microtime(TRUE), 3), 'tags' => implode(' ', $item['tags']), 'checksum' => $this->checksumProvider->getCurrentChecksum($item['tags'])); if (!is_string($item['data'])) { $fields['data'] = serialize($item['data']); $fields['serialized'] = 1; } else { $fields['data'] = $item['data']; $fields['serialized'] = 0; } $values[] = $fields; } // Use an upsert query which is atomic and optimized for multiple-row // merges. $query = $this->connection->upsert($this->bin)->key('cid')->fields(array('cid', 'expire', 'created', 'tags', 'checksum', 'data', 'serialized')); foreach ($values as $fields) { // Only pass the values since the order of $fields matches the order of // the insert fields. This is a performance optimization to avoid // unnecessary loops within the method. $query->values(array_values($fields)); } $query->execute(); }
/** * {@inheritdoc} */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { Cache::validateTags($tags); $item = (object) array('cid' => $cid, 'data' => $data, 'created' => round(microtime(TRUE), 3), 'expire' => $expire, 'tags' => array_unique($tags), 'checksum' => $this->checksumProvider->getCurrentChecksum($tags)); $this->writeItem($this->normalizeCid($cid), $item); }
/** * {@inheritdoc} */ public function setMultiple(array $items) { $deleted_tags =& drupal_static('Drupal\\Core\\Cache\\DatabaseBackend::deletedTags', array()); $invalidated_tags =& drupal_static('Drupal\\Core\\Cache\\DatabaseBackend::invalidatedTags', array()); // Use a transaction so that the database can write the changes in a single // commit. $transaction = $this->connection->startTransaction(); try { // Delete all items first so we can do one insert. Rather than multiple // merge queries. $this->deleteMultiple(array_keys($items)); $query = $this->connection->insert($this->bin)->fields(array('cid', 'data', 'expire', 'created', 'serialized', 'tags', 'checksum_invalidations', 'checksum_deletions')); foreach ($items as $cid => $item) { $item += array('expire' => CacheBackendInterface::CACHE_PERMANENT, 'tags' => array()); Cache::validateTags($item['tags']); $item['tags'] = array_unique($item['tags']); // Sort the cache tags so that they are stored consistently in the DB. sort($item['tags']); // Remove tags that were already deleted or invalidated during this // request from the static caches so that another deletion or // invalidation can occur. foreach ($item['tags'] as $tag) { if (isset($deleted_tags[$tag])) { unset($deleted_tags[$tag]); } if (isset($invalidated_tags[$tag])) { unset($invalidated_tags[$tag]); } } $checksum = $this->checksumTags($item['tags']); $fields = array('cid' => $cid, 'expire' => $item['expire'], 'created' => round(microtime(TRUE), 3), 'tags' => implode(' ', $item['tags']), 'checksum_invalidations' => $checksum['invalidations'], 'checksum_deletions' => $checksum['deletions']); if (!is_string($item['data'])) { $fields['data'] = serialize($item['data']); $fields['serialized'] = 1; } else { $fields['data'] = $item['data']; $fields['serialized'] = 0; } $query->values($fields); } $query->execute(); } catch (\Exception $e) { $transaction->rollback(); // @todo Log something here or just re throw? throw $e; } }
/** * {@inheritdoc} */ public function setMultiple(array $items) { // Use a transaction so that the database can write the changes in a single // commit. $transaction = $this->connection->startTransaction(); try { // Delete all items first so we can do one insert. Rather than multiple // merge queries. $this->deleteMultiple(array_keys($items)); $query = $this->connection->insert($this->bin)->fields(array('cid', 'data', 'expire', 'created', 'serialized', 'tags', 'checksum')); foreach ($items as $cid => $item) { $item += array('expire' => CacheBackendInterface::CACHE_PERMANENT, 'tags' => array()); Cache::validateTags($item['tags']); $item['tags'] = array_unique($item['tags']); // Sort the cache tags so that they are stored consistently in the DB. sort($item['tags']); $fields = array('cid' => $cid, 'expire' => $item['expire'], 'created' => round(microtime(TRUE), 3), 'tags' => implode(' ', $item['tags']), 'checksum' => $this->checksumProvider->getCurrentChecksum($item['tags'])); if (!is_string($item['data'])) { $fields['data'] = serialize($item['data']); $fields['serialized'] = 1; } else { $fields['data'] = $item['data']; $fields['serialized'] = 0; } $query->values($fields); } $query->execute(); } catch (\Exception $e) { $transaction->rollback(); // @todo Log something here or just re throw? throw $e; } }