Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save shubaivan/5e8217f3b5b0afbd302a5a93506bb26e to your computer and use it in GitHub Desktop.
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
<?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();
<?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