Merge pull request #9750 from tersmitten/make-it-possible-to-configure-cachemethodhashalgo-in-dbosource

Make it possible to configure the cacheMethod hashing algorithm in DboSource
This commit is contained in:
Mark Story 2016-11-14 12:00:33 -05:00 committed by GitHub
commit 5f1463f45b
2 changed files with 69 additions and 7 deletions

View file

@ -51,17 +51,19 @@ class DboSource extends DataSource {
public $alias = 'AS ';
/**
* Caches result from query parsing operations. Cached results for both DboSource::name() and
* DboSource::conditions() will be stored here. Method caching uses `md5()`. If you have
* problems with collisions, set DboSource::$cacheMethods to false.
* Caches result from query parsing operations. Cached results for both DboSource::name() and DboSource::fields()
* will be stored here.
*
* Method caching uses `md5` (by default) to construct cache keys. If you have problems with collisions,
* try a different hashing algorithm by overriding DboSource::cacheMethodHasher or set DboSource::$cacheMethods to false.
*
* @var array
*/
public static $methodCache = array();
/**
* Whether or not to cache the results of DboSource::name() and DboSource::conditions()
* into the memory cache. Set to false to disable the use of the memory cache.
* Whether or not to cache the results of DboSource::name() and DboSource::fields() into the memory cache.
* Set to false to disable the use of the memory cache.
*
* @var bool
*/
@ -837,6 +839,21 @@ class DboSource extends DataSource {
return true;
}
/**
* Hashes a given value.
*
* Method caching uses `md5` (by default) to construct cache keys. If you have problems with collisions,
* try a different hashing algorithm or set DboSource::$cacheMethods to false.
*
* @param string $value Value to hash
* @return string Hashed value
* @see http://php.net/manual/en/function.hash-algos.php
* @see http://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
*/
public function cacheMethodHasher($value) {
return md5($value);
}
/**
* Returns a quoted name of $data for use in an SQL statement.
* Strips fields out of SQL functions before quoting.
@ -862,7 +879,7 @@ class DboSource extends DataSource {
}
return $data;
}
$cacheKey = md5($this->startQuote . $data . $this->endQuote);
$cacheKey = $this->cacheMethodHasher($this->startQuote . $data . $this->endQuote);
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
return $return;
}
@ -2580,7 +2597,7 @@ class DboSource extends DataSource {
$Model->schemaName,
$Model->table
);
$cacheKey = md5(serialize($cacheKey));
$cacheKey = $this->cacheMethodHasher(serialize($cacheKey));
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
return $return;
}

View file

@ -109,6 +109,23 @@ class DboSecondTestSource extends DboSource {
}
/**
* DboThirdTestSource
*
* @package Cake.Test.Case.Model.Datasource
*/
class DboThirdTestSource extends DboSource {
public function connect($config = array()) {
$this->connected = true;
}
public function cacheMethodHasher($value) {
return hash('sha1', $value);
}
}
/**
* DboFourthTestSource
*
@ -838,6 +855,34 @@ class DboSourceTest extends CakeTestCase {
$this->assertTrue($actual);
}
/**
* Test that cacheMethodHasher uses md5 by default.
*
* @return void
*/
public function testCacheMethodHasher() {
$name = 'Model.fieldlbqndkezcoapfgirmjsh';
$actual = $this->testDb->cacheMethodHasher($name);
$expected = '4a45dc9ed52f98c393d04ac424ee5078';
$this->assertEquals($expected, $actual);
}
/**
* Test that cacheMethodHasher can be overridden to use a different hashing algorithm.
*
* @return void
*/
public function testCacheMethodHasherOverridden() {
$testDb = new DboThirdTestSource();
$name = 'Model.fieldlbqndkezcoapfgirmjsh';
$actual = $testDb->cacheMethodHasher($name);
$expected = 'beb8b6469359285b7c2865dce0ef743feb16cb71';
$this->assertEquals($expected, $actual);
}
/**
* Test that rare collisions do not happen with method caching
*