Skip to content

Commit

Permalink
Connection parameters are cached hashed
Browse files Browse the repository at this point in the history
  • Loading branch information
fullbl authored and morozov committed Mar 29, 2018
1 parent 1693731 commit 017991a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 88 deletions.
27 changes: 13 additions & 14 deletions lib/Doctrine/DBAL/Cache/QueryCacheProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@
namespace Doctrine\DBAL\Cache;

use Doctrine\Common\Cache\Cache;
use function hash;
use function serialize;
use function sha1;

/**
* Query Cache Profile handles the data relevant for query caching.
*
* It is a value object, setter methods return NEW instances.
*
* @author Benjamin Eberlei <[email protected]>
*/
class QueryCacheProfile
{
/**
* @var \Doctrine\Common\Cache\Cache|null
* @var Cache|null
*/
private $resultCacheDriver;

Expand All @@ -46,19 +47,18 @@ class QueryCacheProfile
private $cacheKey;

/**
* @param int $lifetime
* @param string|null $cacheKey
* @param \Doctrine\Common\Cache\Cache|null $resultCache
* @param int $lifetime
* @param string|null $cacheKey
*/
public function __construct($lifetime = 0, $cacheKey = null, Cache $resultCache = null)
public function __construct($lifetime = 0, $cacheKey = null, ?Cache $resultCache = null)
{
$this->lifetime = $lifetime;
$this->cacheKey = $cacheKey;
$this->lifetime = $lifetime;
$this->cacheKey = $cacheKey;
$this->resultCacheDriver = $resultCache;
}

/**
* @return \Doctrine\Common\Cache\Cache|null
* @return Cache|null
*/
public function getResultCacheDriver()
{
Expand All @@ -76,7 +76,7 @@ public function getLifetime()
/**
* @return string
*
* @throws \Doctrine\DBAL\Cache\CacheException
* @throws CacheException
*/
public function getCacheKey()
{
Expand All @@ -102,7 +102,7 @@ public function generateCacheKeys($query, $params, $types, array $connectionPara
$realCacheKey = 'query=' . $query .
'&params=' . serialize($params) .
'&types=' . serialize($types) .
'&connectionParams=' . serialize($connectionParams);
'&connectionParams=' . hash('sha256', serialize($connectionParams));

// should the key be automatically generated using the inputs or is the cache key set?
if ($this->cacheKey === null) {
Expand All @@ -111,11 +111,10 @@ public function generateCacheKeys($query, $params, $types, array $connectionPara
$cacheKey = $this->cacheKey;
}

return array($cacheKey, $realCacheKey);
return [$cacheKey, $realCacheKey];
}

/**
* @param \Doctrine\Common\Cache\Cache $cache
*
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
Expand Down
150 changes: 76 additions & 74 deletions tests/Doctrine/Tests/DBAL/Cache/QueryCacheProfileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,70 @@
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\ParameterType;
use Doctrine\Tests\DbalTestCase;
use function parse_str;

class QueryCacheProfileTest extends DbalTestCase
{
const LIFETIME = 3600;
const CACHE_KEY = 'user_specified_cache_key';
private const LIFETIME = 3600;
private const CACHE_KEY = 'user_specified_cache_key';

/** @var QueryCacheProfile */
/**
* @var QueryCacheProfile
*/
private $queryCacheProfile;

/**
* @var string
*/
private $query = 'SELECT * FROM foo WHERE bar = ?';

/**
* @var int[]
*/
private $params = [666];

/**
* @var string[]
*/
private $types = [ParameterType::INTEGER];

/**
* @var string[]
*/
private $connectionParams = [
'dbname' => 'database_name',
'user' => 'database_user',
'password' => 'database_password',
'host' => 'database_host',
'driver' => 'database_driver',
];

protected function setUp()
{
$this->queryCacheProfile = new QueryCacheProfile(self::LIFETIME, self::CACHE_KEY);
}

public function testShouldUseTheGivenCacheKeyIfPresent()
{
$query = 'SELECT * FROM foo WHERE bar = ?';
$params = [666];
$types = [ParameterType::INTEGER];

$connectionParams = array(
'dbname' => 'database_name',
'user' => 'database_user',
'password' => 'database_password',
'host' => 'database_host',
'driver' => 'database_driver'
);

list($cacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

self::assertEquals(self::CACHE_KEY, $cacheKey, 'The returned cache key should match the given one');
}

public function testShouldGenerateAnAutomaticKeyIfNoKeyHasBeenGiven()
{
$query = 'SELECT * FROM foo WHERE bar = ?';
$params = [666];
$types = [ParameterType::INTEGER];

$connectionParams = array(
'dbname' => 'database_name',
'user' => 'database_user',
'password' => 'database_password',
'host' => 'database_host',
'driver' => 'database_driver'
);

$this->queryCacheProfile = $this->queryCacheProfile->setCacheKey(null);

list($cacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

self::assertNotEquals(
Expand All @@ -77,67 +82,64 @@ public function testShouldGenerateAnAutomaticKeyIfNoKeyHasBeenGiven()

public function testShouldGenerateDifferentKeysForSameQueryAndParamsAndDifferentConnections()
{
$query = 'SELECT * FROM foo WHERE bar = ?';
$params = [666];
$types = [ParameterType::INTEGER];

$connectionParams = array(
'dbname' => 'database_name',
'user' => 'database_user',
'password' => 'database_password',
'host' => 'database_host',
'driver' => 'database_driver'
);

$this->queryCacheProfile = $this->queryCacheProfile->setCacheKey(null);

list($firstCacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

$connectionParams['host'] = 'a_different_host';
$this->connectionParams['host'] = 'a_different_host';

list($secondCacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

self::assertNotEquals($firstCacheKey, $secondCacheKey, 'Cache keys should be different');
}

public function testShouldGenerateSameKeysIfNoneOfTheParamsChanges()
public function testConnectionParamsShouldBeHashed()
{
$query = 'SELECT * FROM foo WHERE bar = ?';
$params = [666];
$types = [ParameterType::INTEGER];
$this->queryCacheProfile = $this->queryCacheProfile->setCacheKey(null);

$connectionParams = array(
'dbname' => 'database_name',
'user' => 'database_user',
'password' => 'database_password',
'host' => 'database_host',
'driver' => 'database_driver'
list($cacheKey, $queryString) = $this->queryCacheProfile->generateCacheKeys(
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

$params = [];
parse_str($queryString, $params);

self::assertArrayHasKey('connectionParams', $params);

foreach ($this->connectionParams as $param) {
self::assertNotContains($param, $params['connectionParams']);
}
}

public function testShouldGenerateSameKeysIfNoneOfTheParamsChanges()
{
$this->queryCacheProfile = $this->queryCacheProfile->setCacheKey(null);

list($firstCacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

list($secondCacheKey) = $this->queryCacheProfile->generateCacheKeys(
$query,
$params,
$types,
$connectionParams
$this->query,
$this->params,
$this->types,
$this->connectionParams
);

self::assertEquals($firstCacheKey, $secondCacheKey, 'Cache keys should be the same');
Expand Down

0 comments on commit 017991a

Please sign in to comment.