1
0
mirror of synced 2025-01-18 22:41:43 +03:00

dql resultSet cache, first draft

This commit is contained in:
zYne 2007-05-27 11:38:16 +00:00
parent 01f5436bdd
commit 6673186970
2 changed files with 164 additions and 72 deletions

View File

@ -32,7 +32,7 @@
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Hydrate
class Doctrine_Hydrate implements Serializable
{
/**
* QUERY TYPE CONSTANTS
@ -94,6 +94,14 @@ class Doctrine_Hydrate
* and values as sql aliases
*/
protected $aggregateMap = array();
/**
* @var array $_options an array of options
*/
protected $_options = array(
'fetchMode' => Doctrine::FETCH_RECORD,
'parserCache' => false,
'resultSetCache' => false,
);
/**
* @var array $parts SQL query string parts
*/
@ -137,6 +145,33 @@ class Doctrine_Hydrate
}
$this->_conn = $connection;
}
public function getSql()
{
return $this->getQuery();
}
/**
* serialize
* this method is automatically called when this Doctrine_Hydrate is serialized
*
* @return array an array of serialized properties
*/
public function serialize()
{
$vars = get_object_vars($this);
}
/**
* unseralize
* this method is automatically called everytime a Doctrine_Hydrate object is unserialized
*
* @param string $serialized Doctrine_Record as serialized string
* @return void
*/
public function unserialize($serialized)
{
}
/**
* generateNewTableAlias
* generates a new alias from given table alias
@ -228,12 +263,12 @@ class Doctrine_Hydrate
return $alias;
}
/**
* getAliases
* returns all aliases
* getTableAliases
* returns all table aliases
*
* @return array
* @return array table aliases as an array
*/
public function getAliases()
public function getTableAliases()
{
return $this->_tableAliases;
}
@ -296,19 +331,42 @@ class Doctrine_Hydrate
return $this;
}
/**
* getAliasDeclaration
* get the declaration for given component alias
* setQueryPart
* sets a query part in the query part array
*
* @param string $componentAlias the component alias the retrieve the declaration from
* @return array the alias declaration
* @param string $name the name of the query part to be set
* @param string $part query part string
* @throws Doctrine_Hydrate_Exception if trying to set unknown query part
* @return Doctrine_Hydrate this object
*/
public function getAliasDeclaration($componentAlias)
public function getQueryPart($part)
{
if ( ! isset($this->_aliasMap[$componentAlias])) {
throw new Doctrine_Hydrate_Exception('Unknown component alias ' . $componentAlias);
if ( ! isset($this->parts[$part])) {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $part);
}
return $this->_aliasMap[$componentAlias];
return $this->parts[$part];
}
/**
* removeQueryPart
* removes a query part from the query part array
*
* @param string $name the name of the query part to be removed
* @throws Doctrine_Hydrate_Exception if trying to remove unknown query part
* @return Doctrine_Hydrate this object
*/
public function removeQueryPart($name)
{
if (isset($this->parts[$name])) {
if ($name == 'limit' || $name == 'offset') {
$this->parts[$name] = false;
} else {
$this->parts[$name] = array();
}
} else {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $part);
}
return $this;
}
/**
* setQueryPart
@ -333,6 +391,21 @@ class Doctrine_Hydrate
return $this;
}
/**
* getAliasDeclaration
* get the declaration for given component alias
*
* @param string $componentAlias the component alias the retrieve the declaration from
* @return array the alias declaration
*/
public function getAliasDeclaration($componentAlias)
{
if ( ! isset($this->_aliasMap[$componentAlias])) {
throw new Doctrine_Hydrate_Exception('Unknown component alias ' . $componentAlias);
}
return $this->_aliasMap[$componentAlias];
}
/**
* copyAliases
* copy aliases from another Hydrate object
@ -379,44 +452,6 @@ class Doctrine_Hydrate
{
return false;
}
/**
* setQueryPart
* sets a query part in the query part array
*
* @param string $name the name of the query part to be set
* @param string $part query part string
* @throws Doctrine_Hydrate_Exception if trying to set unknown query part
* @return Doctrine_Hydrate this object
*/
public function getQueryPart($part)
{
if ( ! isset($this->parts[$part])) {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $part);
}
return $this->parts[$part];
}
/**
* removeQueryPart
* removes a query part from the query part array
*
* @param string $name the name of the query part to be removed
* @throws Doctrine_Hydrate_Exception if trying to remove unknown query part
* @return Doctrine_Hydrate this object
*/
public function removeQueryPart($name)
{
if (isset($this->parts[$name])) {
if ($name == 'limit' || $name == 'offset') {
$this->parts[$name] = false;
} else {
$this->parts[$name] = array();
}
} else {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $part);
}
return $this;
}
/**
* clear
* resets all the variables
@ -542,14 +577,24 @@ class Doctrine_Hydrate
}
return $found;
}
/**
* execute
* executes the dql query and populates all collections
*
* @param string $params
* @return Doctrine_Collection the root collection
*/
public function execute($params = array(), $return = Doctrine::FETCH_RECORD)
public function getCachedForm(array $resultSet)
{
$map = '';
foreach ($this->getAliasMap() as $k => $v) {
if ( ! isset($v['parent'])) {
$map[$k][] = $v['table']->getComponentName();
} else {
$map[$k][] = $v['parent'] . '.' . $v['relation']->getAlias();
}
if (isset($v['agg'])) {
$map[$k][] = $v['agg'];
}
}
return serialize(array($resultSet, $map, $this->getTableAliases()));
}
public function _execute($params, $return = Doctrine::FETCH_RECORD)
{
$params = $this->_conn->convertBooleans(array_merge($this->_params, $params));
$params = $this->convertEnums($params);
@ -571,7 +616,60 @@ class Doctrine_Hydrate
}
$stmt = $this->_conn->execute($query, $params);
$array = (array) $this->parseData($stmt);
return (array) $this->parseData($stmt);
}
/**
* execute
* executes the query and populates the data set
*
* @param string $params
* @return Doctrine_Collection the root collection
*/
public function execute($params = array(), $return = Doctrine::FETCH_RECORD)
{
if ($this->_options['resultSetCache']) {
$dql = $this->getDql();
// calculate hash for dql query
$hash = strlen($dql) . md5($dql);
$cached = $this->_options['resultSetCache']->fetch($hash);
if ($cached === null) {
// cache miss
$array = $this->_execute($params, $return);
$cached = $this->getCachedForm($array);
$this->_options['resultSetCache']->save($hash, $cached);
} else {
$cached = unserialize($cached);
$this->_tableAliases = $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->_aliasMap = $map;
}
} else {
$array = $this->_execute($params, $return);
}
if ($return === Doctrine::FETCH_ARRAY) {
return $array;
}
if (empty($this->_aliasMap)) {
throw new Doctrine_Hydrate_Exception("Couldn't execute query. Component alias map was empty.");
}

View File

@ -65,14 +65,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* @var array $_enumParams an array containing the keys of the parameters that should be enumerated
*/
protected $_enumParams = array();
/**
* @var array $_options an array of options
*/
protected $_options = array(
'fetchMode' => Doctrine::FETCH_RECORD,
'parserCache' => false,
'resultSetCache' => false,
);
/**
* @var array $_dqlParts an array containing all DQL query parts
*/
@ -626,20 +619,21 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
public function getQuery($params = array())
{
// check if parser cache is on
if ($this->_options['parserCache'] !== false) {
if ($this->_options['resultSetCache'] !== false) {
/**
$dql = $this->getDql();
// calculate hash for dql query
$hash = strlen($dql) . md5($dql);
// check if cache has sql equivalent for given hash
$sql = $this->_options['parserCache']->fetch($hash, true);
if ($sql !== null) {
return $sql;
}
*/
// cache miss, build sql query from dql parts
foreach ($this->_dqlParts as $queryPartName => $queryParts) {
if (is_array($queryParts)) {
if (is_array($queryParts) && ! empty($queryParts)) {
foreach ($queryParts as $queryPart) {
$this->getParser($queryPartName)->parse($queryPart);
}