renamed the default hydrator. started to implement a query cache.
This commit is contained in:
parent
896b991545
commit
352ab0de40
@ -32,7 +32,7 @@
|
||||
* @version $Revision: 3192 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
*/
|
||||
class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract
|
||||
class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
{
|
||||
/**
|
||||
* hydrateResultSet
|
||||
@ -73,9 +73,9 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract
|
||||
}
|
||||
|
||||
if ($hydrationMode === Doctrine::HYDRATE_ARRAY) {
|
||||
$driver = new Doctrine_Hydrator_Default_ArrayDriver();
|
||||
$driver = new Doctrine_Hydrator_ArrayDriver();
|
||||
} else {
|
||||
$driver = new Doctrine_Hydrator_Default_RecordDriver();
|
||||
$driver = new Doctrine_Hydrator_RecordDriver();
|
||||
}
|
||||
|
||||
$event = new Doctrine_Event(null, Doctrine_Event::HYDRATE, null);
|
@ -31,7 +31,7 @@
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
*/
|
||||
class Doctrine_Hydrator_Default_ArrayDriver
|
||||
class Doctrine_Hydrator_ArrayDriver
|
||||
{
|
||||
public function getElementCollection($component)
|
||||
{
|
@ -31,7 +31,7 @@
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
*/
|
||||
class Doctrine_Hydrator_Default_RecordDriver extends Doctrine_Locator_Injectable
|
||||
class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
|
||||
{
|
||||
protected $_collections = array();
|
||||
|
@ -1018,14 +1018,14 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
|
||||
}
|
||||
|
||||
/**
|
||||
* _getSqlQueryBase
|
||||
* _buildSqlQueryBase
|
||||
* returns the base of the generated sql query
|
||||
* On mysql driver special strategy has to be used for DELETE statements
|
||||
* (where is this special strategy??)
|
||||
*
|
||||
* @return string the base of the generated sql query
|
||||
*/
|
||||
protected function _getSqlQueryBase()
|
||||
protected function _buildSqlQueryBase()
|
||||
{
|
||||
switch ($this->_type) {
|
||||
case self::DELETE:
|
||||
@ -1169,7 +1169,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
|
||||
|
||||
$needsSubQuery = false;
|
||||
$subquery = '';
|
||||
$map = reset($this->_queryComponents);
|
||||
$map = reset($this->_queryComponents);
|
||||
$table = $map['table'];
|
||||
$rootAlias = key($this->_queryComponents);
|
||||
|
||||
@ -1193,7 +1193,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
|
||||
$this->_pendingFields = array();
|
||||
|
||||
// build the basic query
|
||||
$q = $this->_getSqlQueryBase();
|
||||
$q = $this->_buildSqlQueryBase();
|
||||
$q .= $this->_buildSqlFromPart();
|
||||
|
||||
if ( ! empty($this->_sqlParts['set'])) {
|
||||
@ -1355,8 +1355,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
|
||||
|
||||
$part = trim($part, "\"'`");
|
||||
|
||||
if ($this->hasTableAlias($part)) {
|
||||
$parts[$k] = $this->_conn->quoteIdentifier($this->generateNewTableAlias($part));
|
||||
if ($this->hasSqlTableAlias($part)) {
|
||||
$parts[$k] = $this->_conn->quoteIdentifier($this->generateNewSqlTableAlias($part));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1367,7 +1367,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
|
||||
|
||||
foreach ($m[0] as $match) {
|
||||
$e = explode('.', $match);
|
||||
$e[0] = $this->generateNewTableAlias($e[0]);
|
||||
$e[0] = $this->generateNewSqlTableAlias($e[0]);
|
||||
|
||||
$parts[$k] = str_replace($match, implode('.', $e), $parts[$k]);
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ abstract class Doctrine_Query_Abstract
|
||||
$connection = Doctrine_Manager::getInstance()->getCurrentConnection();
|
||||
}
|
||||
if ($hydrator === null) {
|
||||
$hydrator = new Doctrine_Hydrator_Default();
|
||||
$hydrator = new Doctrine_Hydrator();
|
||||
}
|
||||
$this->_conn = $connection;
|
||||
$this->_hydrator = $hydrator;
|
||||
@ -862,14 +862,29 @@ abstract class Doctrine_Query_Abstract
|
||||
* _execute
|
||||
*
|
||||
* @param array $params
|
||||
* @return void
|
||||
* @return PDOStatement The executed PDOStatement.
|
||||
*/
|
||||
protected function _execute($params)
|
||||
{
|
||||
$params = $this->_conn->convertBooleans($params);
|
||||
|
||||
if ( ! $this->_view) {
|
||||
$query = $this->getSqlQuery($params);
|
||||
if ($this->_queryCache) {
|
||||
$queryCacheDriver = $this->getQueryCacheDriver();
|
||||
// calculate hash for dql query
|
||||
$dql = $this->getDql();
|
||||
$hash = md5($dql);
|
||||
$cached = $queryCacheDriver->fetch($hash);
|
||||
if ($cached) {
|
||||
$query = $this->_constructQueryFromCache($cached);
|
||||
} else {
|
||||
$query = $this->getSqlQuery($params);
|
||||
$serializedQuery = $this->getCachedForm($query);
|
||||
$queryCacheDriver->save($hash, $serializedQuery, $this->_queryCacheTTL);
|
||||
}
|
||||
} else {
|
||||
$query = $this->getSqlQuery($params);
|
||||
}
|
||||
} else {
|
||||
$query = $this->_view->getSelectSql();
|
||||
}
|
||||
@ -884,7 +899,7 @@ abstract class Doctrine_Query_Abstract
|
||||
if ($this->_type !== self::SELECT) {
|
||||
return $this->_conn->exec($query, $params);
|
||||
}
|
||||
//echo $query . "<br /><br />";
|
||||
|
||||
$stmt = $this->_conn->execute($query, $params);
|
||||
return $stmt;
|
||||
}
|
||||
@ -916,32 +931,14 @@ abstract class Doctrine_Query_Abstract
|
||||
// cache miss
|
||||
$stmt = $this->_execute($params);
|
||||
$this->_hydrator->setQueryComponents($this->_queryComponents);
|
||||
$array = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliasMap,
|
||||
$result = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliasMap,
|
||||
Doctrine::HYDRATE_ARRAY);
|
||||
|
||||
$cached = $this->getCachedForm($array);
|
||||
|
||||
$cached = $this->getCachedForm($result);
|
||||
$cacheDriver->save($hash, $cached, $this->_resultCacheTTL);
|
||||
return $result;
|
||||
} else {
|
||||
$cached = unserialize($cached);
|
||||
$this->_tableAliasMap = $cached[2];
|
||||
$array = $cached[0];
|
||||
|
||||
$map = array();
|
||||
foreach ($cached[1] as $k => $v) {
|
||||
$e = explode('.', $v[0]);
|
||||
if (count($e) === 1) {
|
||||
$map[$k]['table'] = $this->_conn->getTable($e[0]);
|
||||
} else {
|
||||
$map[$k]['parent'] = $e[0];
|
||||
$map[$k]['relation'] = $map[$e[0]]['table']->getRelation($e[1]);
|
||||
$map[$k]['table'] = $map[$k]['relation']->getTable();
|
||||
}
|
||||
if (isset($v[1])) {
|
||||
$map[$k]['agg'] = $v[1];
|
||||
}
|
||||
}
|
||||
$this->_queryComponents = $map;
|
||||
return $this->_constructQueryFromCache($cached);
|
||||
}
|
||||
} else {
|
||||
$stmt = $this->_execute($params);
|
||||
@ -951,9 +948,45 @@ abstract class Doctrine_Query_Abstract
|
||||
}
|
||||
|
||||
$this->_hydrator->setQueryComponents($this->_queryComponents);
|
||||
$array = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliasMap, $hydrationMode);
|
||||
return $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliasMap, $hydrationMode);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the query from the cached form.
|
||||
*
|
||||
* @param string The cached query, in a serialized form.
|
||||
* @return array The custom component that was cached together with the essential
|
||||
* query data. This can be either a result set (result caching)
|
||||
* or an SQL query string (query caching).
|
||||
*/
|
||||
protected function _constructQueryFromCache($cached)
|
||||
{
|
||||
$cached = unserialize($cached);
|
||||
$this->_tableAliasMap = $cached[2];
|
||||
$customComponent = $cached[0];
|
||||
|
||||
$queryComponents = array();
|
||||
$cachedComponents = $cached[1];
|
||||
foreach ($cachedComponents as $alias => $components) {
|
||||
$e = explode('.', $components[0]);
|
||||
if (count($e) === 1) {
|
||||
$queryComponents[$alias]['table'] = $this->_conn->getTable($e[0]);
|
||||
} else {
|
||||
$queryComponents[$alias]['parent'] = $e[0];
|
||||
$queryComponents[$alias]['relation'] = $queryComponents[$e[0]]['table']->getRelation($e[1]);
|
||||
$queryComponents[$alias]['table'] = $queryComponents[$alias]['relation']->getTable();
|
||||
}
|
||||
if (isset($v[1])) {
|
||||
$queryComponents[$alias]['agg'] = $components[1];
|
||||
}
|
||||
if (isset($v[2])) {
|
||||
$queryComponents[$alias]['map'] = $components[2];
|
||||
}
|
||||
}
|
||||
$this->_queryComponents = $queryComponents;
|
||||
|
||||
return $customComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -963,22 +996,25 @@ abstract class Doctrine_Query_Abstract
|
||||
* @param array $resultSet
|
||||
* @return string serialized string representation of this query
|
||||
*/
|
||||
public function getCachedForm(array $resultSet)
|
||||
public function getCachedForm($customComponent = null)
|
||||
{
|
||||
$map = array();
|
||||
$componentInfo = array();
|
||||
|
||||
foreach ($this->getAliasMap() as $k => $v) {
|
||||
if ( ! isset($v['parent'])) {
|
||||
$map[$k][] = $v['table']->getComponentName();
|
||||
foreach ($this->getQueryComponents() as $alias => $components) {
|
||||
if ( ! isset($components['parent'])) {
|
||||
$componentInfo[$alias][] = $components['table']->getComponentName();
|
||||
} else {
|
||||
$map[$k][] = $v['parent'] . '.' . $v['relation']->getAlias();
|
||||
$componentInfo[$alias][] = $components['parent'] . '.' . $components['relation']->getAlias();
|
||||
}
|
||||
if (isset($v['agg'])) {
|
||||
$map[$k][] = $v['agg'];
|
||||
if (isset($components['agg'])) {
|
||||
$componentInfo[$alias][] = $components['agg'];
|
||||
}
|
||||
if (isset($components['map'])) {
|
||||
$componentInfo[$alias][] = $components['map'];
|
||||
}
|
||||
}
|
||||
|
||||
return serialize(array($resultSet, $map, $this->getTableAliasMap()));
|
||||
|
||||
return serialize(array($customComponent, $componentInfo, $this->getTableAliasMap()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1468,7 +1504,7 @@ abstract class Doctrine_Query_Abstract
|
||||
*/
|
||||
public function useResultCache($driver = true, $timeToLive = null)
|
||||
{
|
||||
if($driver !== null && $driver !== true && ! ($driver instanceOf Doctrine_Cache_Interface)){
|
||||
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);
|
||||
}
|
||||
@ -1484,9 +1520,15 @@ abstract class Doctrine_Query_Abstract
|
||||
* @param integer $timeToLive how long the cache entry is valid
|
||||
* @return Doctrine_Hydrate this object
|
||||
*/
|
||||
public function useQueryCache($driver = null, $timeToLive = null)
|
||||
public function useQueryCache($driver = true, $timeToLive = null)
|
||||
{
|
||||
throw new Doctrine_Query_Exception("Not yet implemented.");
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,24 @@
|
||||
class Doctrine_Query_Cache_TestCase extends Doctrine_UnitTestCase
|
||||
{
|
||||
|
||||
public function testQueryCacheAddsQueryIntoCache()
|
||||
{
|
||||
$cache = new Doctrine_Cache_Array();
|
||||
$q = new Doctrine_Query();
|
||||
$q->select('u.name')->from('User u')->leftJoin('u.Phonenumber p')
|
||||
->useQueryCache($cache);
|
||||
|
||||
$coll = $q->execute();
|
||||
|
||||
$this->assertEqual($cache->count(), 1);
|
||||
$this->assertEqual(count($coll), 8);
|
||||
|
||||
$coll = $q->execute();
|
||||
|
||||
$this->assertEqual($cache->count(), 1);
|
||||
$this->assertEqual(count($coll), 8);
|
||||
}
|
||||
|
||||
public function testResultSetCacheAddsResultSetsIntoCache()
|
||||
{
|
||||
$q = new Doctrine_Query();
|
||||
@ -86,7 +104,8 @@ class Doctrine_Query_Cache_TestCase extends Doctrine_UnitTestCase
|
||||
|
||||
$this->assertEqual($cache->count(), 1);
|
||||
$this->assertEqual(count($coll), 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function testUseCacheSupportsBooleanTrueAsParameter()
|
||||
{
|
||||
$q = new Doctrine_Query();
|
||||
|
Loading…
x
Reference in New Issue
Block a user