diff --git a/lib/Doctrine/Hydrate/Array.php b/lib/Doctrine/Hydrate/Array.php deleted file mode 100644 index 6c9465fca..000000000 --- a/lib/Doctrine/Hydrate/Array.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ - -/** - * Doctrine_Hydrate_Array - * defines an array fetching strategy for Doctrine_Hydrate - * - * @package Doctrine - * @subpackage Hydrate - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.com - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - */ -class Doctrine_Hydrate_Array -{ - public function getElementCollection($component) - { - return array(); - } - public function getElement(array $data, $component) - { - return $data; - } - public function isIdentifiable(array $data, Doctrine_Table $table) - { - return ( ! empty($data)); - } - public function registerCollection($coll) - { - - } - public function initRelated(array &$data, $name) - { - if ( ! isset($data[$name])) { - $data[$name] = array(); - } - return true; - } - public function getNullPointer() - { - return null; - } - public function getLastKey(&$data) - { - end($data); - return key($data); - } - - public function flush() - { - - } -} diff --git a/lib/Doctrine/Hydrate/Record.php b/lib/Doctrine/Hydrate/Record.php deleted file mode 100644 index d8e15fc0c..000000000 --- a/lib/Doctrine/Hydrate/Record.php +++ /dev/null @@ -1,132 +0,0 @@ -. - */ - -/** - * Doctrine_Hydrate_Record - * defines a record fetching strategy for Doctrine_Hydrate - * - * @package Doctrine - * @subpackage Hydrate - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.com - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - */ -class Doctrine_Hydrate_Record extends Doctrine_Locator_Injectable -{ - protected $_collections = array(); - - protected $_records = array(); - - protected $_tables = array(); - - public function getElementCollection($component) - { - $coll = new Doctrine_Collection($component); - $this->_collections[] = $coll; - - return $coll; - } - - public function getLastKey($coll) - { - $coll->end(); - - return $coll->key(); - } - - public function initRelated($record, $name) - { - if ( ! is_array($record)) { - $record[$name]; - - return true; - } - return false; - } - - public function registerCollection(Doctrine_Collection $coll) - { - $this->_collections[] = $coll; - } - - /** - * isIdentifiable - * returns whether or not a given data row is identifiable (it contains - * all primary key fields specified in the second argument) - * - * @param array $row - * @param Doctrine_Table $table - * @return boolean - */ - public function isIdentifiable(array $row, Doctrine_Table $table) - { - $primaryKeys = $table->getIdentifierColumnNames(); - - if (is_array($primaryKeys)) { - foreach ($primaryKeys as $id) { - if ( ! isset($row[$id])) { - return false; - } - } - } else { - if ( ! isset($row[$primaryKeys])) { - return false; - } - } - return true; - } - - public function getNullPointer() - { - return self::$_null; - } - - public function getElement(array $data, $component) - { - if ( ! isset($this->_tables[$component])) { - $this->_tables[$component] = Doctrine_Manager::getInstance()->getTable($component); - $this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false); - } - - $this->_tables[$component]->setData($data); - $record = $this->_tables[$component]->getRecord(); - - if ( ! isset($this->_records[$record->getOid()]) ) { - $record->clearRelated(); - $this->_records[$record->getOid()] = $record; - } - - return $record; - } - - public function flush() - { - // take snapshots from all initialized collections - foreach ($this->_collections as $key => $coll) { - $coll->takeSnapshot(); - } - foreach ($this->_tables as $table) { - $table->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true); - } - } -} diff --git a/lib/Doctrine/Hydrator/Abstract.php b/lib/Doctrine/Hydrator/Abstract.php index 2cfb4a326..479c58d3c 100644 --- a/lib/Doctrine/Hydrator/Abstract.php +++ b/lib/Doctrine/Hydrator/Abstract.php @@ -47,7 +47,7 @@ abstract class Doctrine_Hydrator_Abstract extends Doctrine_Locator_Injectable * map the name of the column / aggregate value this * component is mapped to a collection */ - protected $_aliasMap = array(); + protected $_queryComponents = array(); /** * The current hydration mode. @@ -59,10 +59,7 @@ abstract class Doctrine_Hydrator_Abstract extends Doctrine_Locator_Injectable * * @param Doctrine_Connection|null $connection */ - public function __construct() - { - - } + public function __construct() {} /** * Sets the fetchmode. @@ -81,10 +78,9 @@ abstract class Doctrine_Hydrator_Abstract extends Doctrine_Locator_Injectable * @param array $map alias map * @return Doctrine_Hydrate this object */ - public function setAliasMap(array $map) + public function setQueryComponents(array $queryComponents) { - $this->_aliasMap = $map; - return $this; + $this->_queryComponents = $queryComponents; } /** @@ -93,9 +89,9 @@ abstract class Doctrine_Hydrator_Abstract extends Doctrine_Locator_Injectable * * @return array component alias map */ - public function getAliasMap() + public function getQueryComponents() { - return $this->_aliasMap; + return $this->_queryComponents; } /** @@ -114,6 +110,6 @@ abstract class Doctrine_Hydrator_Abstract extends Doctrine_Locator_Injectable * @param mixed $stmt * @return array */ - abstract public function hydrateResultSet($stmt, $aliasMap, $tableAliases, $hydrationMode = null); + abstract public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null); } diff --git a/lib/Doctrine/Hydrator/Default.php b/lib/Doctrine/Hydrator/Default.php index 544383016..94cd19e67 100644 --- a/lib/Doctrine/Hydrator/Default.php +++ b/lib/Doctrine/Hydrator/Default.php @@ -38,7 +38,7 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract * hydrateResultSet * parses the data returned by statement object * - * This is method defines the core of Doctrine object population algorithm + * This is method defines the core of Doctrine's object population algorithm * hence this method strives to be as fast as possible * * The key idea is the loop over the rowset only once doing all the needed operations @@ -49,31 +49,20 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract * @param mixed $stmt * @param array $tableAliases Array that maps table aliases (SQL alias => DQL alias) * @param array $aliasMap Array that maps DQL aliases to their components - * (DQL alias => array('table' => Table object, - * 'parent' => Parent DQL alias (if any), - * 'relation' => Relation object (if any), - * 'map' => ??? (if any) - * ) + * (DQL alias => array( + * 'table' => Table object, + * 'parent' => Parent DQL alias (if any), + * 'relation' => Relation object (if any), + * 'map' => ??? (if any) + * ) * ) * @return array */ - public function hydrateResultSet($stmt, $aliasMap, $tableAliases, $hydrationMode = null) + public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null) { //$s = microtime(true); - $this->_aliasMap = $aliasMap; $this->_tableAliases = $tableAliases; - /*echo "aliasmap:
"; - foreach ($this->_aliasMap as $map) { - if ( ! empty($map['map'])) { - Doctrine::dump($map['map']); - } - }*/ - //Doctrine::dump($this->_aliasMap); - //echo "
"; - //echo "tableAliases:
"; - //Doctrine::dump($tableAliases); - //echo "

"; if ($hydrationMode == Doctrine::HYDRATE_NONE) { return $stmt->fetchAll(PDO::FETCH_NUM); @@ -84,56 +73,57 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract } if ($hydrationMode === Doctrine::HYDRATE_ARRAY) { - $driver = new Doctrine_Hydrator_Default_FetchModeDriver_Array(); + $driver = new Doctrine_Hydrator_Default_ArrayDriver(); } else { - $driver = new Doctrine_Hydrator_Default_FetchModeDriver_Record(); + $driver = new Doctrine_Hydrator_Default_RecordDriver(); } $event = new Doctrine_Event(null, Doctrine_Event::HYDRATE, null); // Used variables during hydration - $rootMap = reset($this->_aliasMap); - $rootAlias = key($this->_aliasMap); - $componentName = $rootMap['table']->getComponentName(); - $isSimpleQuery = count($this->_aliasMap) <= 1; - $result = array(); // Holds the resulting hydrated data structure - $listeners = array(); // Holds hydration listeners that get called during hydration - $identifierMap = array(); // Lookup map to quickly discover/lookup existing records in the result - $prev = array(); // Holds for each component the last previously seen element in the result set - $id = array(); // holds the values of the identifier/primary key columns of components, - // separated by a pipe '|' and grouped by component alias (r, u, i, ... whatever) + reset($this->_queryComponents); + $rootAlias = key($this->_queryComponents); + $rootComponentName = $this->_queryComponents[$rootAlias]['table']->getComponentName(); + // if only one component is involved we can make our lives easier + $isSimpleQuery = count($this->_queryComponents) <= 1; + // Holds the resulting hydrated data structure + $result = array(); + // Holds hydration listeners that get called during hydration + $listeners = array(); + // Lookup map to quickly discover/lookup existing records in the result + $identifierMap = array(); + // Holds for each component the last previously seen element in the result set + $prev = array(); + // holds the values of the identifier/primary key fields of components, + // separated by a pipe '|' and grouped by component alias (r, u, i, ... whatever) + $id = array(); - $result = $driver->getElementCollection($componentName); + $result = $driver->getElementCollection($rootComponentName); if ($stmt === false || $stmt === 0) { return $result; } - // Initialize the variables - foreach ($this->_aliasMap as $alias => $data) { + // Initialize + foreach ($this->_queryComponents as $dqlAlias => $data) { $componentName = $data['table']->getComponentName(); $listeners[$componentName] = $data['table']->getRecordListener(); - $identifierMap[$alias] = array(); - $prev[$alias] = array(); - $id[$alias] = ''; + $identifierMap[$dqlAlias] = array(); + $prev[$dqlAlias] = array(); + $id[$dqlAlias] = ''; } // Process result set $cache = array(); while ($data = $stmt->fetch(Doctrine::FETCH_ASSOC)) { - $identifiable = array(); - - $rowData = $this->_gatherRowData($data, $cache, $id, $identifiable); - - //echo "rowData of row:
"; - //Doctrine::dump($rowData); - //echo "

"; + $nonemptyComponents = array(); + $rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents); // // hydrate the data of the root component from the current row // - $table = $this->_aliasMap[$rootAlias]['table']; + $table = $this->_queryComponents[$rootAlias]['table']; $componentName = $table->getComponentName(); $event->set('data', $rowData[$rootAlias]); $listeners[$componentName]->preHydrate($event); @@ -148,9 +138,9 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract // do we need to index by a custom field? if ($field = $this->_getCustomIndexField($rootAlias)) { if (isset($result[$field])) { - throw new Doctrine_Hydrate_Exception("Couldn't hydrate. Found non-unique key mapping."); + throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found non-unique key mapping."); } else if ( ! isset($element[$field])) { - throw new Doctrine_Hydrate_Exception("Couldn't hydrate. Found a non-existent key."); + throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found a non-existent key."); } $result[$element[$field]] = $element; } else { @@ -166,17 +156,16 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract unset($rowData[$rootAlias]); // end hydrate data of the root component for the current row - //echo "\$result after root element hydration:
"; - //Doctrine::dump($result); - //echo "

"; + + // $prev[$rootAlias] now points to the last element in $result. // now hydrate the rest of the data found in the current row, that belongs to other - // (related) components + // (related) components. $oneToOne = false; - foreach ($rowData as $alias => $data) { + foreach ($rowData as $dqlAlias => $data) { $index = false; - $map = $this->_aliasMap[$alias]; - $table = $this->_aliasMap[$alias]['table']; + $map = $this->_queryComponents[$dqlAlias]; + $table = $map['table']; $componentName = $table->getComponentName(); $event->set('data', $data); $listeners[$componentName]->preHydrate($event); @@ -185,67 +174,63 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract $parent = $map['parent']; $relation = $map['relation']; - $componentAlias = $map['relation']->getAlias(); + $relationAlias = $map['relation']->getAlias(); - $path = $parent . '.' . $alias; + $path = $parent . '.' . $dqlAlias; if ( ! isset($prev[$parent])) { break; } // check the type of the relation - if ( ! $relation->isOneToOne() && $driver->initRelated($prev[$parent], $componentAlias)) { + if ( ! $relation->isOneToOne() && $driver->initRelated($prev[$parent], $relationAlias)) { // append element - if (isset($identifiable[$alias])) { - if ($isSimpleQuery || ! isset($identifierMap[$path][$id[$parent]][$id[$alias]])) { - //$index = false; + if (isset($nonemptyComponents[$dqlAlias])) { + if ($isSimpleQuery || ! isset($identifierMap[$path][$id[$parent]][$id[$dqlAlias]])) { $event->set('data', $element); $listeners[$componentName]->postHydrate($event); - if ($field = $this->_getCustomIndexField($alias)) { - if (isset($prev[$parent][$componentAlias][$field])) { - throw new Doctrine_Hydrate_Exception("Couldn't hydrate. Found non-unique key mapping."); + if ($field = $this->_getCustomIndexField($dqlAlias)) { + if (isset($prev[$parent][$relationAlias][$field])) { + throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found non-unique key mapping."); } else if ( ! isset($element[$field])) { - throw new Doctrine_Hydrate_Exception("Couldn't hydrate. Found a non-existent key."); + throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found a non-existent key."); } - $prev[$parent][$componentAlias][$element[$field]] = $element; + $prev[$parent][$relationAlias][$element[$field]] = $element; } else { - $prev[$parent][$componentAlias][] = $element; + $prev[$parent][$relationAlias][] = $element; } - $identifierMap[$path][$id[$parent]][$id[$alias]] = $driver->getLastKey($prev[$parent][$componentAlias]); + $identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = $driver->getLastKey($prev[$parent][$relationAlias]); } else { - $index = $identifierMap[$path][$id[$parent]][$id[$alias]]; + $index = $identifierMap[$path][$id[$parent]][$id[$dqlAlias]]; } } // register collection for later snapshots - $driver->registerCollection($prev[$parent][$componentAlias]); + $driver->registerCollection($prev[$parent][$relationAlias]); } else { - if ( ! isset($identifiable[$alias])) { - $prev[$parent][$componentAlias] = $driver->getNullPointer(); - } else { - $prev[$parent][$componentAlias] = $element; - } + // 1-1 relation $oneToOne = true; + if ( ! isset($nonemptyComponents[$dqlAlias])) { + $prev[$parent][$relationAlias] = $driver->getNullPointer(); + } else { + $prev[$parent][$relationAlias] = $element; + } } - $coll =& $prev[$parent][$componentAlias]; - $this->_setLastElement($prev, $coll, $index, $alias, $oneToOne); - $id[$alias] = ''; + $coll =& $prev[$parent][$relationAlias]; + $this->_setLastElement($prev, $coll, $index, $dqlAlias, $oneToOne); + $id[$dqlAlias] = ''; } - //echo "\$result after related element hydration:
"; - //Doctrine::dump($result); - //echo "

"; $id[$rootAlias] = ''; } - $driver->flush(); - $stmt->closeCursor(); - //$e = microtime(true); - - //echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records
'; + $driver->flush(); + //$e = microtime(true); + //echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records
'; + return $result; } @@ -259,30 +244,30 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract * @return void * @todo Detailed documentation */ - protected function _setLastElement(&$prev, &$coll, $index, $alias, $oneToOne) + protected function _setLastElement(&$prev, &$coll, $index, $dqlAlias, $oneToOne) { if ($coll === self::$_null) { return false; } if ($index !== false) { - // Set lement at $index as previous element for the component + // Link element at $index to previous element for the component // identified by the DQL alias $alias - $prev[$alias] =& $coll[$index]; + $prev[$dqlAlias] =& $coll[$index]; return; } if (is_array($coll) && $coll) { if ($oneToOne) { - $prev[$alias] =& $coll; + $prev[$dqlAlias] =& $coll; } else { end($coll); - $prev[$alias] =& $coll[key($coll)]; + $prev[$dqlAlias] =& $coll[key($coll)]; } } else if (count($coll) > 0) { - $prev[$alias] = $coll->getLast(); - } else if (isset($prev[$alias])) { - unset($prev[$alias]); + $prev[$dqlAlias] = $coll->getLast(); + } else if (isset($prev[$dqlAlias])) { + unset($prev[$dqlAlias]); } } @@ -294,7 +279,7 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract * @return array An array with all the fields (name => value) of the data row, * grouped by their component (alias). */ - protected function _gatherRowData(&$data, &$cache, &$id, &$identifiable) + protected function _gatherRowData(&$data, &$cache, &$id, &$nonemptyComponents) { $rowData = array(); @@ -302,29 +287,29 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract // Parse each column name only once. Cache the results. if ( ! isset($cache[$key])) { $e = explode('__', $key); - $last = strtolower(array_pop($e)); - $cache[$key]['alias'] = $this->_tableAliases[strtolower(implode('__', $e))]; - $fieldName = $this->_aliasMap[$cache[$key]['alias']]['table']->getFieldName($last); + $last = strtolower(array_pop($e)); + $cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))]; + $fieldName = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']->getFieldName($last); $cache[$key]['fieldName'] = $fieldName; } - $map = $this->_aliasMap[$cache[$key]['alias']]; + $map = $this->_queryComponents[$cache[$key]['dqlAlias']]; $table = $map['table']; - $alias = $cache[$key]['alias']; + $dqlAlias = $cache[$key]['dqlAlias']; $fieldName = $cache[$key]['fieldName']; - if (isset($this->_aliasMap[$alias]['agg'][$fieldName])) { - $fieldName = $this->_aliasMap[$alias]['agg'][$fieldName]; + if (isset($this->_queryComponents[$dqlAlias]['agg'][$fieldName])) { + $fieldName = $this->_queryComponents[$dqlAlias]['agg'][$fieldName]; } if ($table->isIdentifier($fieldName)) { - $id[$alias] .= '|' . $value; + $id[$dqlAlias] .= '|' . $value; } - $rowData[$alias][$fieldName] = $table->prepareValue($fieldName, $value); + $rowData[$dqlAlias][$fieldName] = $table->prepareValue($fieldName, $value); - if ($value !== null) { - $identifiable[$alias] = true; + if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) { + $nonemptyComponents[$dqlAlias] = true; } } @@ -339,7 +324,7 @@ class Doctrine_Hydrator_Default extends Doctrine_Hydrator_Abstract */ protected function _getCustomIndexField($alias) { - return isset($this->_aliasMap[$alias]['map']) ? $this->_aliasMap[$alias]['map'] : null; + return isset($this->_queryComponents[$alias]['map']) ? $this->_queryComponents[$alias]['map'] : null; } } diff --git a/lib/Doctrine/Hydrator/Default/FetchModeDriver/Array.php b/lib/Doctrine/Hydrator/Default/ArrayDriver.php similarity index 97% rename from lib/Doctrine/Hydrator/Default/FetchModeDriver/Array.php rename to lib/Doctrine/Hydrator/Default/ArrayDriver.php index 299e294d0..7d1800a61 100644 --- a/lib/Doctrine/Hydrator/Default/FetchModeDriver/Array.php +++ b/lib/Doctrine/Hydrator/Default/ArrayDriver.php @@ -31,7 +31,7 @@ * @version $Revision$ * @author Konsta Vesterinen */ -class Doctrine_Hydrator_Default_FetchModeDriver_Array +class Doctrine_Hydrator_Default_ArrayDriver { public function getElementCollection($component) { diff --git a/lib/Doctrine/Hydrator/Default/FetchModeDriver/Record.php b/lib/Doctrine/Hydrator/Default/RecordDriver.php similarity index 96% rename from lib/Doctrine/Hydrator/Default/FetchModeDriver/Record.php rename to lib/Doctrine/Hydrator/Default/RecordDriver.php index dcb4b0016..f4f7d7bb3 100644 --- a/lib/Doctrine/Hydrator/Default/FetchModeDriver/Record.php +++ b/lib/Doctrine/Hydrator/Default/RecordDriver.php @@ -31,7 +31,7 @@ * @version $Revision$ * @author Konsta Vesterinen */ -class Doctrine_Hydrator_Default_FetchModeDriver_Record extends Doctrine_Locator_Injectable +class Doctrine_Hydrator_Default_RecordDriver extends Doctrine_Locator_Injectable { protected $_collections = array(); @@ -56,12 +56,14 @@ class Doctrine_Hydrator_Default_FetchModeDriver_Record extends Doctrine_Locator_ public function initRelated($record, $name) { + return true; + /* if ( ! is_array($record)) { $record[$name]; - return true; } return false; + */ } public function registerCollection(Doctrine_Collection $coll) diff --git a/lib/Doctrine/Hydrate/Exception.php b/lib/Doctrine/Hydrator/Exception.php similarity index 91% rename from lib/Doctrine/Hydrate/Exception.php rename to lib/Doctrine/Hydrator/Exception.php index ce6333427..430ee26c5 100644 --- a/lib/Doctrine/Hydrate/Exception.php +++ b/lib/Doctrine/Hydrator/Exception.php @@ -1,34 +1,34 @@ -. - */ -Doctrine::autoload('Doctrine_Exception'); -/** - * Doctrine_Hydrate_Exception - * - * @package Doctrine - * @subpackage Hydrate - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.com - * @since 1.0 - * @version $Revision: 1080 $ - * @author Konsta Vesterinen - */ -class Doctrine_Hydrate_Exception extends Doctrine_Exception +. + */ +Doctrine::autoload('Doctrine_Exception'); +/** + * Doctrine_Hydrator_Exception + * + * @package Doctrine + * @subpackage Hydrate + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision: 1080 $ + * @author Konsta Vesterinen + */ +class Doctrine_Hydrator_Exception extends Doctrine_Exception { } \ No newline at end of file diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index d143fb0ba..aefe47ea4 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -208,31 +208,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria $this->_params = $params; } - /** - * getCachedForm - * returns the cached form of this query for given resultSet - * - * @param array $resultSet - * @return string serialized string representation of this query - */ - 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())); - } - /** * fetchArray * Convenience method to execute using array fetching as hydration mode. @@ -950,8 +925,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria } if (count($tableAliases) !== 1) { - $componentAlias = reset($this->tableAliases); - $tableAlias = key($this->tableAliases); + $componentAlias = reset($this->_tableAliases); + $tableAlias = key($this->_tableAliases); } $index = count($this->aggregateMap); @@ -1405,7 +1380,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria { $e = Doctrine_Tokenizer::sqlExplode($query, ' '); - foreach ($e as $k=>$part) { + foreach ($e as $k => $part) { $part = trim($part); switch (strtolower($part)) { case 'delete': @@ -1752,7 +1727,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria $queryPart .= ' ' . $this->_conn->quoteIdentifier($tableAlias); } - $this->tableAliases[$tableAlias] = $componentAlias; + $this->_tableAliases[$tableAlias] = $componentAlias; $queryPart .= $this->buildInheritanceJoinSql($name, $componentAlias); diff --git a/lib/Doctrine/Query/Abstract.php b/lib/Doctrine/Query/Abstract.php index f6b39af6d..dc27dce73 100644 --- a/lib/Doctrine/Query/Abstract.php +++ b/lib/Doctrine/Query/Abstract.php @@ -752,8 +752,9 @@ abstract class Doctrine_Query_Abstract if ($cached === false) { // cache miss $stmt = $this->_execute($params); - $array = $this->_hydrator->hydrateResultSet($stmt, $this->_aliasMap, - $this->_tableAliases, Doctrine::HYDRATE_ARRAY); + $this->_hydrator->setQueryComponents($this->_aliasMap); + $array = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliases, + Doctrine::HYDRATE_ARRAY); $cached = $this->getCachedForm($array); @@ -786,12 +787,36 @@ abstract class Doctrine_Query_Abstract return $stmt; } - $array = $this->_hydrator->hydrateResultSet($stmt, $this->_aliasMap, - $this->_tableAliases, $hydrationMode); + $this->_hydrator->setQueryComponents($this->_aliasMap); + $array = $this->_hydrator->hydrateResultSet($stmt, $this->_tableAliases, $hydrationMode); } return $array; } + /** + * getCachedForm + * returns the cached form of this query for given resultSet + * + * @param array $resultSet + * @return string serialized string representation of this query + */ + public function getCachedForm(array $resultSet) + { + $map = array(); + + 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())); + } /** * addSelect diff --git a/tests/HydrateTestCase.php b/tests/HydrateTestCase.php index 14614a431..04e66ab73 100644 --- a/tests/HydrateTestCase.php +++ b/tests/HydrateTestCase.php @@ -98,7 +98,7 @@ class Doctrine_Hydrate_Mock extends Doctrine_Hydrator_Abstract $this->data = $data; } - public function hydrateResultSet($stmt, $aliasMap, $tableAliases, $hydrationMode = null) + public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null) { return true; }