Last active
April 16, 2020 08:47
-
-
Save dmaicher/e282c59d81dedde89bacb3bb9bb360cb 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 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']); |
This file contains 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; | |
/** | |
* @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]; | |
} | |
/** | |
* {@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 string $query | |
* @param array $params | |
* @param array $types | |
* @param array $tags | |
* | |
* @return $this | |
*/ | |
public function setQueryCacheTags($query, array $params, array $types, array $tags) | |
{ | |
$this->queryTags[$this->getDoctrineQueryCacheKey($query, $params, $types)] = $tags; | |
return $this; | |
} | |
/** | |
* @return TagAwareAdapterInterface | |
*/ | |
public function getTagAwareAdapter() | |
{ | |
return $this->tagAwareAdapter; | |
} | |
} |
@shubaivan in my case it works, because I pass null
as a cacheKey
to the QueryCacheProfile
constructor.
If one passes some string it will indeed not work properly 👍
@dmaicher I understand, you are right, if did not use $cacheKey
for QueryCacheProfile
constructor it will be null and in \Doctrine\DBAL\Cache\QueryCacheProfile::generateCacheKeys
cache key will be the same $cacheKey = sha1($realCacheKey);
. Thank you
@dmaicher but in your case used two separate object QueryCacheProfile
one in TagAwareQueryResultCache
and one for executeCacheQuery
. Perhaps better use one like in my revision
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@dmaicher Hi, I just tested you case and cache not invalidated, because need use the same
QueryCacheProfile
when callexecuteCacheQuery
and when callsetQueryCacheTags
.Could you look please my changes ? It's works correctly, cache creaetd with tag and when called
invalidateTags
, cache invalidatedhttps://gist.github.com/shubaivan/5e8217f3b5b0afbd302a5a93506bb26e/revisions