-
Notifications
You must be signed in to change notification settings - Fork 6
caching
Parsing and building of queries is not a fast operation so it is highly recommended to use cache in production. Package classes like Node
and NativeStatement
are designed with serialization in mind and implement the magic __sleep()
and __wakeup()
methods.
Parser
can automatically cache AST of everything that goes through its parseSomething()
methods (these are overloaded via __call()
that contains caching code). You only need to provide an instance of class implementing CacheItemPoolInterface
from PSR-6 to Parser
constructor
$parser = new Parser(new Lexer(), new CacheImplementation());
ASTs will be stored in cache under keys having parsetree-
prefix.
You can also cache the results of query building process represented by NativeStatement
. This should be done manually along the following lines
// You need to know the structure of query beforehand to create a cache key
$queryParts = [
'base' => 'baseQueryId'
'foo' => '...',
'bar' => '...'
];
$cacheKey = 'query-' . md5(serialize($queryParts));
$cacheItem = $cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
$query = $cacheItem->get();
} else {
$ast = createBaseQuery($queryParts['base']);
if (!empty($queryParts['foo'])) {
$ast->list[] = 'foo.*'
$ast->from[0]->join('foo')->using = ['foo_id'];
}
if (!empty($queryParts['bar'])) {
// ...
}
// ...
$query = $factory->createFromAST($ast);
$cache->save($cacheItem->set($query);
}
Note: caching of whole statements makes sense if you use parameters. If you just build query with constants caching won't help much
// This is OK:
$ast->where->and('foo_id = any(:id::integer[])');
// ...sometime later...
$query->executeParams($connection, ['id' => $id]);
// This is not OK:
$ast->where->and('foo_id in (' . implode(', ', $id) . ')');