From 05147fbeb65139a2bcf764d544956dc5d8d5c8a4 Mon Sep 17 00:00:00 2001 From: romanb Date: Sun, 25 Nov 2007 19:07:30 +0000 Subject: [PATCH] Completed implementation of the query cache. --- lib/Doctrine.php | 4 ++++ lib/Doctrine/Configurable.php | 2 ++ lib/Doctrine/Connection.php | 18 ++++++++++++++++-- lib/Doctrine/Hydrator.php | 2 +- lib/Doctrine/Manager.php | 2 ++ lib/Doctrine/Query/Abstract.php | 11 +++-------- tests/Query/CacheTestCase.php | 21 ++++++++++++++++++++- 7 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/Doctrine.php b/lib/Doctrine.php index e29f89d9e..cd94dfe36 100644 --- a/lib/Doctrine.php +++ b/lib/Doctrine.php @@ -182,11 +182,15 @@ final class Doctrine const ATTR_COLL_LIMIT = 123; const ATTR_CACHE = 150; + const ATTR_RESULT_CACHE = 150; const ATTR_CACHE_LIFESPAN = 151; + const ATTR_RESULT_CACHE_LIFESPAN = 151; const ATTR_LOAD_REFERENCES = 153; const ATTR_RECORD_LISTENER = 154; const ATTR_THROW_EXCEPTIONS = 155; const ATTR_DEFAULT_PARAM_NAMESPACE = 156; + const ATTR_QUERY_CACHE = 157; + const ATTR_QUERY_CACHE_LIFESPAN = 158; /** * LIMIT CONSTANTS diff --git a/lib/Doctrine/Configurable.php b/lib/Doctrine/Configurable.php index 94170dd67..5cb14c411 100644 --- a/lib/Doctrine/Configurable.php +++ b/lib/Doctrine/Configurable.php @@ -102,6 +102,8 @@ abstract class Doctrine_Configurable extends Doctrine_Locator_Injectable } break; case Doctrine::ATTR_CACHE: + case Doctrine::ATTR_RESULT_CACHE: + case Doctrine::ATTR_QUERY_CACHE: if ($value !== null) { if ( ! ($value instanceof Doctrine_Cache_Interface)) { throw new Doctrine_Exception('Cache driver should implement Doctrine_Cache_Interface'); diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php index 39703deba..842071ab1 100644 --- a/lib/Doctrine/Connection.php +++ b/lib/Doctrine/Connection.php @@ -1218,11 +1218,25 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun */ public function getResultCacheDriver() { - if ( ! isset($this->attributes[Doctrine::ATTR_CACHE])) { + if ( ! $this->getAttribute(Doctrine::ATTR_RESULT_CACHE)) { throw new Doctrine_Exception('Result Cache driver not initialized.'); } - return $this->attributes[Doctrine::ATTR_CACHE]; + return $this->getAttribute(Doctrine::ATTR_RESULT_CACHE); + } + + /** + * getQueryCacheDriver + * + * @return Doctrine_Cache_Interface + */ + public function getQueryCacheDriver() + { + if ( ! $this->getAttribute(Doctrine::ATTR_QUERY_CACHE)) { + throw new Doctrine_Exception('Query Cache driver not initialized.'); + } + + return $this->getAttribute(Doctrine::ATTR_QUERY_CACHE); } /** diff --git a/lib/Doctrine/Hydrator.php b/lib/Doctrine/Hydrator.php index f57183038..36e521565 100644 --- a/lib/Doctrine/Hydrator.php +++ b/lib/Doctrine/Hydrator.php @@ -53,7 +53,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract * 'table' => Table object, * 'parent' => Parent DQL alias (if any), * 'relation' => Relation object (if any), - * 'map' => ??? (if any) + * 'map' => Custom index to use as the key in the result (if any) * ) * ) * @return array diff --git a/lib/Doctrine/Manager.php b/lib/Doctrine/Manager.php index 388faabe2..30d52420a 100644 --- a/lib/Doctrine/Manager.php +++ b/lib/Doctrine/Manager.php @@ -92,6 +92,8 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera $init = true; $attributes = array( Doctrine::ATTR_CACHE => null, + Doctrine::ATTR_RESULT_CACHE => null, + Doctrine::ATTR_QUERY_CACHE => null, Doctrine::ATTR_LOAD_REFERENCES => true, Doctrine::ATTR_LISTENER => new Doctrine_EventListener(), Doctrine::ATTR_RECORD_LISTENER => new Doctrine_Record_Listener(), diff --git a/lib/Doctrine/Query/Abstract.php b/lib/Doctrine/Query/Abstract.php index e1f7029f2..6c5950936 100644 --- a/lib/Doctrine/Query/Abstract.php +++ b/lib/Doctrine/Query/Abstract.php @@ -869,11 +869,11 @@ abstract class Doctrine_Query_Abstract $params = $this->_conn->convertBooleans($params); if ( ! $this->_view) { - if ($this->_queryCache) { + if ($this->_queryCache || $this->_conn->getAttribute(Doctrine::ATTR_QUERY_CACHE)) { $queryCacheDriver = $this->getQueryCacheDriver(); // calculate hash for dql query $dql = $this->getDql(); - $hash = md5($dql); + $hash = md5($dql . 'DOCTRINE_QUERY_CACHE_SALT'); $cached = $queryCacheDriver->fetch($hash); if ($cached) { $query = $this->_constructQueryFromCache($cached); @@ -1520,14 +1520,9 @@ abstract class Doctrine_Query_Abstract * @param integer $timeToLive how long the cache entry is valid * @return Doctrine_Hydrate this object */ - public function useQueryCache($driver = true, $timeToLive = null) + public function useQueryCache(Doctrine_Cache_Interface $driver, $timeToLive = null) { - if ($driver !== null && $driver !== true && ! ($driver instanceof Doctrine_Cache_Interface)){ - $msg = 'First argument should be instance of Doctrine_Cache_Interface or null.'; - throw new Doctrine_Query_Exception($msg); - } $this->_queryCache = $driver; - return $this->setQueryCacheLifeSpan($timeToLive); } diff --git a/tests/Query/CacheTestCase.php b/tests/Query/CacheTestCase.php index 0e13b5dad..3eee3e849 100644 --- a/tests/Query/CacheTestCase.php +++ b/tests/Query/CacheTestCase.php @@ -37,11 +37,30 @@ class Doctrine_Query_Cache_TestCase extends Doctrine_UnitTestCase { $cache = new Doctrine_Cache_Array(); $q = new Doctrine_Query(); - $q->select('u.name')->from('User u')->leftJoin('u.Phonenumber p') + $q->select('u.name')->from('User u')->leftJoin('u.Phonenumber p')->where('u.name = ?', 'walhala') ->useQueryCache($cache); $coll = $q->execute(); + $this->assertEqual($cache->count(), 1); + $this->assertEqual(count($coll), 0); + + $coll = $q->execute(); + + $this->assertEqual($cache->count(), 1); + $this->assertEqual(count($coll), 0); + } + + public function testQueryCacheWorksWithGlobalConfiguration() + { + $cache = new Doctrine_Cache_Array(); + Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cache); + + $q = new Doctrine_Query(); + $q->select('u.name')->from('User u')->leftJoin('u.Phonenumber p'); + + $coll = $q->execute(); + $this->assertEqual($cache->count(), 1); $this->assertEqual(count($coll), 8);