Forked from dmaicher/TagAwareQueryResultCache.php
Last active
April 16, 2020 07:44
-
-
Save shubaivan/5e8217f3b5b0afbd302a5a93506bb26e to your computer and use it in GitHub Desktop.
use symfony/cache 3.2 tag aware cache as Doctrine DBAL query result cache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$sql = 'some query'; | |
$parameters = []; | |
$types = []; | |
$queryCacheProfile = new QueryCacheProfile(7200, null, $tagAwareResultCache); | |
// use 'foo' as tag for query cache item | |
$tagAwareResultCache->setQueryCacheTags($sql, $parameters, $types, ['foo']); | |
// perform query and write it into our cache | |
$connection->executeCacheQuery($sql, $parameters, $types, $queryCacheProfile); | |
// invalidate previously stored cache item | |
$tagAwareResultCache->getTagAwareAdapter()->invalidateTags(['foo']); | |
// another using | |
$connection = $this->getEntityManager()->getConnection(); | |
$query = ' | |
select | |
DISTINCT e.key, | |
jsonb_agg(DISTINCT e.value) as fields | |
from products AS p | |
join jsonb_each_text(p.extras) e on true | |
WHERE e.key != :exclude_key | |
GROUP BY e.key | |
'; | |
$this->getTagAwareQueryResultCacheCommon()->setQueryCacheTags( | |
$query, | |
[':exclude_key' => 'ALTERNATIVE_IMAGE'], | |
[':exclude_key' => ParameterType::STRING], | |
['fetchAllExtrasFieldsWithCache'], | |
0, "extras_fields" | |
); | |
[$query, $params, $types, $queryCacheProfile] = $this->getTagAwareQueryResultCacheCommon() | |
->prepareParamsForExecuteCacheQuery(); | |
/** @var ResultCacheStatement $statement */ | |
$statement = $connection->executeCacheQuery( | |
$query, $params, $types, $queryCacheProfile | |
); | |
$fetchAll = $statement->fetchAll(\PDO::FETCH_ASSOC); | |
$statement->closeCursor(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Doctrine\DBAL\Cache\QueryCacheProfile; | |
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface; | |
use Symfony\Component\Cache\CacheItem; | |
use Symfony\Component\Cache\DoctrineProvider; | |
class TagAwareQueryResultCache extends DoctrineProvider | |
{ | |
/** | |
* @var TagAwareAdapterInterface | |
*/ | |
private $tagAwareAdapter; | |
/** | |
* @var array | |
*/ | |
private $queryTags = []; | |
/** | |
* @var string | |
*/ | |
private $currentIdWithoutNamespace; | |
/** | |
* @var QueryCacheProfile | |
*/ | |
private $queryCacheProfile; | |
/** | |
* @var string | |
*/ | |
private $query; | |
/** | |
* @var array | |
*/ | |
private $params; | |
/** | |
* @var array | |
*/ | |
private $types; | |
/** | |
* @param TagAwareAdapterInterface $tagAwareAdapter | |
*/ | |
public function __construct(TagAwareAdapterInterface $tagAwareAdapter) | |
{ | |
parent::__construct($tagAwareAdapter); | |
$this->tagAwareAdapter = $tagAwareAdapter; | |
} | |
/** | |
* @param $query | |
* @param array $params | |
* @param array $types | |
* | |
* @return string | |
*/ | |
private function getDoctrineQueryCacheKey($query, array $params, array $types) | |
{ | |
// return (new QueryCacheProfile())->generateCacheKeys($query, $params, $types)[0]; | |
return $this->getQueryCacheProfile()->generateCacheKeys($query, $params, $types)[0]; | |
} | |
/** | |
* @return QueryCacheProfile | |
*/ | |
public function getQueryCacheProfile() | |
{ | |
return $this->queryCacheProfile; | |
} | |
/** | |
* @param int $lifetime | |
* @param string $cacheKey | |
* @return $this | |
*/ | |
public function setQueryCacheProfile(int $lifetime = 0, string $cacheKey = '') | |
{ | |
$this->queryCacheProfile = new QueryCacheProfile($lifetime, $cacheKey, $this); | |
return $this; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function save($id, $data, $lifeTime = 0) | |
{ | |
$this->currentIdWithoutNamespace = $id; | |
return parent::save($id, $data, $lifeTime); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
protected function doSave($id, $data, $lifeTime = 0) | |
{ | |
/** @var CacheItem $item */ | |
$item = $this->tagAwareAdapter->getItem(rawurlencode($id)); | |
if (isset($this->queryTags[$this->currentIdWithoutNamespace])) { | |
$item->tag($this->queryTags[$this->currentIdWithoutNamespace]); | |
} | |
if (0 < $lifeTime) { | |
$item->expiresAfter($lifeTime); | |
} | |
$this->currentIdWithoutNamespace = null; | |
return $this->tagAwareAdapter->save($item->set($data)); | |
} | |
/** | |
* @param $query | |
* @param array $params | |
* @param array $types | |
* @param array $tags | |
* @param int $lifetime | |
* @param string $cacheKey | |
* @return $this | |
*/ | |
public function setQueryCacheTags( | |
$query, | |
array $params, | |
array $types, | |
array $tags, | |
int $lifetime = 0, | |
string $cacheKey = '') | |
{ | |
$this->setQueryCacheProfile($lifetime, $cacheKey); | |
$this->query = $query; | |
$this->params = $params; | |
$this->types = $types; | |
$this->queryTags[$this->getDoctrineQueryCacheKey($query, $params, $types)] = $tags; | |
return $this; | |
} | |
/** | |
* @return array | |
*/ | |
public function prepareParamsForExecuteCacheQuery() | |
{ | |
return [$this->query, $this->params, $this->types, $this->getQueryCacheProfile()]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment