This commit is contained in:
parent
ae342b43a2
commit
12788a4866
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id: Hydrate.php 1504 2007-05-28 19:03:57Z zYne $
|
* $Id: Hydrate.php 1564 2007-06-02 20:33:41Z romanb $
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
@ -29,7 +29,7 @@
|
|||||||
* @category Object Relational Mapping
|
* @category Object Relational Mapping
|
||||||
* @link www.phpdoctrine.com
|
* @link www.phpdoctrine.com
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
* @version $Revision: 1504 $
|
* @version $Revision: 1564 $
|
||||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
*/
|
*/
|
||||||
class Doctrine_Hydrate implements Serializable
|
class Doctrine_Hydrate implements Serializable
|
||||||
@ -578,10 +578,16 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
foreach ($row as $index => $value) {
|
foreach ($row as $index => $value) {
|
||||||
$agg = false;
|
$agg = false;
|
||||||
|
|
||||||
|
|
||||||
if (isset($this->_aliasMap[$alias]['agg'][$index])) {
|
if (isset($this->_aliasMap[$alias]['agg'][$index])) {
|
||||||
$agg = $this->_aliasMap[$alias]['agg'][$index];
|
$agg = $this->_aliasMap[$alias]['agg'][$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_array($record)) {
|
||||||
|
$record[$agg] = $value;
|
||||||
|
} else {
|
||||||
$record->mapValue($agg, $value);
|
$record->mapValue($agg, $value);
|
||||||
|
}
|
||||||
$found = true;
|
$found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,6 +766,12 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
* parseData
|
* parseData
|
||||||
* parses the data returned by statement object
|
* parses the data returned by statement object
|
||||||
*
|
*
|
||||||
|
* This is method defines the core of Doctrine 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
|
||||||
|
* within this massive loop.
|
||||||
|
*
|
||||||
* @param mixed $stmt
|
* @param mixed $stmt
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -782,9 +794,11 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
$array = $driver->getElementCollection($componentName);
|
$array = $driver->getElementCollection($componentName);
|
||||||
|
$identifiable = array();
|
||||||
|
|
||||||
while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
$parse = true;
|
$parse = true;
|
||||||
|
|
||||||
foreach ($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
if ( ! isset($cache[$key])) {
|
if ( ! isset($cache[$key])) {
|
||||||
$e = explode('__', $key);
|
$e = explode('__', $key);
|
||||||
@ -802,7 +816,6 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = array();
|
|
||||||
$alias = $cache[$key]['alias'];
|
$alias = $cache[$key]['alias'];
|
||||||
$component = $cache[$key]['component'];
|
$component = $cache[$key]['component'];
|
||||||
$componentName = $this->_aliasMap[$cache[$key]['alias']]['table']->getComponentName();
|
$componentName = $this->_aliasMap[$cache[$key]['alias']]['table']->getComponentName();
|
||||||
@ -812,75 +825,160 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
if ( ! isset($currData[$alias])) {
|
if ( ! isset($currData[$alias])) {
|
||||||
$currData[$alias] = array();
|
$currData[$alias] = array();
|
||||||
}
|
}
|
||||||
|
if ( ! isset($prevData[$alias])) {
|
||||||
|
$prevData[$alias] = array();
|
||||||
|
}
|
||||||
|
if ( ! isset($prevElement[$alias])) {
|
||||||
|
$prevElement[$alias] = array();
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! isset($prev[$alias])) {
|
if ( ! isset($prev[$alias])) {
|
||||||
$prev[$alias] = array();
|
$prev[$alias] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($alias !== $lastAlias || $parse) {
|
$skip = false;
|
||||||
|
if (($alias !== $lastAlias || $parse) && ! empty($currData[$alias])) {
|
||||||
|
|
||||||
// component changed
|
// component changed
|
||||||
if ( ! isset($prevData[$alias]) || (isset($currData[$alias]) && $currData[$alias] !== $prevData[$alias])) {
|
$element = $driver->getElement($currData[$alias], $componentName);
|
||||||
if ( ! empty($currData[$alias]) && $driver->isIdentifiable($currData[$alias], $table)) {
|
|
||||||
|
// map aggregate values (if any)
|
||||||
|
$this->mapAggregateValues($element, $currData[$alias], $alias);
|
||||||
|
|
||||||
|
if ($currData[$alias] !== $prevData[$alias] || $element !== $prevElement[$alias]) {
|
||||||
|
|
||||||
if ($alias === $rootAlias) {
|
if ($alias === $rootAlias) {
|
||||||
// dealing with root component
|
// dealing with root component
|
||||||
|
|
||||||
$array[$index] = $driver->getElement($currData[$alias], $componentName);
|
$index = $driver->search($element, $array);
|
||||||
$prev[$alias] =& $array[$index];
|
if ($index === false) {
|
||||||
|
$array[] = $element;
|
||||||
|
}
|
||||||
|
|
||||||
$index++;
|
$coll =& $array;
|
||||||
} else {
|
} else {
|
||||||
$parent = $cache[$key]['parent'];
|
$parent = $cache[$key]['parent'];
|
||||||
$relation = $this->_aliasMap[$cache[$key]['alias']]['relation'];
|
$relation = $this->_aliasMap[$cache[$key]['alias']]['relation'];
|
||||||
// check the type of the relation
|
// check the type of the relation
|
||||||
if ( ! $relation->isOneToOne()) {
|
if ( ! $relation->isOneToOne()) {
|
||||||
|
// initialize the collection
|
||||||
|
$driver->initRelated($prev[$parent], $component);
|
||||||
|
|
||||||
$prev[$parent][$component][] = $driver->getElement($currData[$alias], $componentName);
|
// append element
|
||||||
|
if (isset($identifiable[$alias])) {
|
||||||
|
$index = $driver->search($element, $prev[$parent][$component]);
|
||||||
|
|
||||||
|
if ($index === false) {
|
||||||
|
$prev[$parent][$component][] = $element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// register collection for later snapshots
|
||||||
$driver->registerCollection($prev[$parent][$component]);
|
$driver->registerCollection($prev[$parent][$component]);
|
||||||
} else {
|
} else {
|
||||||
$prev[$parent][$component] = $driver->getElement($currData[$alias], $componentName);
|
$prev[$parent][$component] = $element;
|
||||||
}
|
}
|
||||||
|
$coll =& $prev[$parent][$component];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($index !== false) {
|
||||||
|
$prev[$alias] =& $coll[$index];
|
||||||
|
} else {
|
||||||
|
// first check the count (we do not want to get the last element
|
||||||
|
// of an empty collection/array)
|
||||||
|
if (count($coll) > 0) {
|
||||||
|
// check the type
|
||||||
|
if (is_array($coll)) {
|
||||||
|
end($coll);
|
||||||
|
$prev[$alias] =& $coll[key($coll)];
|
||||||
|
} else {
|
||||||
|
$prev[$alias] = $coll->getLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($currData[$alias])) {
|
if (isset($currData[$alias])) {
|
||||||
$prevData[$alias] = $currData[$alias];
|
$prevData[$alias] = $currData[$alias];
|
||||||
} else {
|
} else {
|
||||||
$prevData[$alias] = array();
|
$prevData[$alias] = array();
|
||||||
}
|
}
|
||||||
$currData[$alias] = array();
|
$currData[$alias] = array();
|
||||||
|
$identifiable[$alias] = null;
|
||||||
|
|
||||||
|
$prevElement[$alias] =& $element;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$field = $cache[$key]['field'];
|
$field = $cache[$key]['field'];
|
||||||
|
|
||||||
$currData[$alias][$field] = $value;
|
$currData[$alias][$field] = $value;
|
||||||
|
|
||||||
|
if ($value !== null) {
|
||||||
|
$identifiable[$alias] = true;
|
||||||
|
}
|
||||||
$lastAlias = $alias;
|
$lastAlias = $alias;
|
||||||
$parse = false;
|
$parse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
$identifiable = array();
|
||||||
foreach ($currData as $alias => $data) {
|
foreach ($currData as $alias => $data) {
|
||||||
$componentName = $this->_aliasMap[$alias]['table']->getComponentName();
|
$table = $this->_aliasMap[$alias]['table'];
|
||||||
if ( ! isset($prevData[$alias]) || (isset($currData[$alias]) && $currData[$alias] !== $prevData[$alias])) {
|
$componentName = $table->getComponentName();
|
||||||
if ( ! empty($currData[$alias]) && $driver->isIdentifiable($currData[$alias], $table)) {
|
// component changed
|
||||||
|
|
||||||
|
$element = $driver->getElement($currData[$alias], $componentName);
|
||||||
|
|
||||||
|
// map aggregate values (if any)
|
||||||
|
$this->mapAggregateValues($element, $currData[$alias], $alias);
|
||||||
|
|
||||||
|
if ( ! isset($prevData[$alias]) || (isset($currData[$alias]) && $currData[$alias] !== $prevData[$alias])
|
||||||
|
|| $element !== $prevElement[$alias]) {
|
||||||
|
|
||||||
|
|
||||||
if ($alias === $rootAlias) {
|
if ($alias === $rootAlias) {
|
||||||
// dealing with root component
|
// dealing with root component
|
||||||
$array[$index] = $driver->getElement($currData[$alias], $componentName);
|
$index = $driver->search($element, $array);
|
||||||
$prev[$alias] =& $array[$index];
|
if ($index === false) {
|
||||||
$index++;
|
$array[] = $element;
|
||||||
|
}
|
||||||
|
$coll =& $array;
|
||||||
} else {
|
} else {
|
||||||
$parent = $this->_aliasMap[$alias]['parent'];
|
$parent = $this->_aliasMap[$alias]['parent'];
|
||||||
$relation = $this->_aliasMap[$alias]['relation'];
|
$relation = $this->_aliasMap[$alias]['relation'];
|
||||||
$componentAlias = $relation->getAlias();
|
$componentAlias = $relation->getAlias();
|
||||||
|
|
||||||
// check the type of the relation
|
// check the type of the relation
|
||||||
if ( ! $relation->isOneToOne()) {
|
if ( ! $relation->isOneToOne()) {
|
||||||
$prev[$parent][$component][] = $driver->getElement($currData[$alias], $componentName);
|
// initialize the collection
|
||||||
$driver->registerCollection($prev[$parent][$component]);
|
$driver->initRelated($prev[$parent], $componentAlias);
|
||||||
|
|
||||||
|
// append element
|
||||||
|
if (isset($identifiable[$alias])) {
|
||||||
|
$index = $driver->search($element, $prev[$parent][$component]);
|
||||||
|
|
||||||
|
if ($index === false) {
|
||||||
|
$prev[$parent][$componentAlias][] = $element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// register collection for later snapshots
|
||||||
|
$driver->registerCollection($prev[$parent][$componentAlias]);
|
||||||
} else {
|
} else {
|
||||||
$prev[$parent][$component] = $driver->getElement($currData[$alias], $componentName);
|
$prev[$parent][$componentAlias] = $element;
|
||||||
|
}
|
||||||
|
$coll =& $prev[$parent][$componentAlias];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($index !== false) {
|
||||||
|
$prev[$alias] =& $coll[$index];
|
||||||
|
} else {
|
||||||
|
// first check the count (we do not want to get the last element
|
||||||
|
// of an empty collection/array)
|
||||||
|
if (count($coll) > 0) {
|
||||||
|
if (is_array($coll)) {
|
||||||
|
end($coll);
|
||||||
|
$prev[$alias] =& $coll[key($coll)];
|
||||||
|
} else {
|
||||||
|
$prev[$alias] = $coll->getLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -891,6 +989,9 @@ class Doctrine_Hydrate implements Serializable
|
|||||||
$prevData[$alias] = array();
|
$prevData[$alias] = array();
|
||||||
}
|
}
|
||||||
$currData[$alias] = array();
|
$currData[$alias] = array();
|
||||||
|
unset($identifiable[$alias]);
|
||||||
|
|
||||||
|
$prevElement[$alias] = $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
$driver->flush();
|
$driver->flush();
|
||||||
|
Loading…
Reference in New Issue
Block a user