From 16a2370e27caf8fd24234e87cde91240274351cb Mon Sep 17 00:00:00 2001 From: zYne Date: Fri, 11 May 2007 00:19:46 +0000 Subject: [PATCH] --- draft/new-core/Collection.php | 52 +++------ draft/new-core/Hydrate.php | 204 ++++++++++------------------------ 2 files changed, 79 insertions(+), 177 deletions(-) diff --git a/draft/new-core/Collection.php b/draft/new-core/Collection.php index 3a8713ae9..636eaeea9 100644 --- a/draft/new-core/Collection.php +++ b/draft/new-core/Collection.php @@ -31,7 +31,7 @@ Doctrine::autoload("Doctrine_Access"); * @version $Revision: 1207 $ * @author Konsta Vesterinen */ -class Doctrine_Collection2 extends Doctrine_Access implements Countable, IteratorAggregate, Serializable +class Doctrine_Collection2 extends Doctrine_Collection implements Countable, IteratorAggregate, Serializable { /** * @var array $data an array containing the data access objects of this collection @@ -40,7 +40,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato /** * @var Doctrine_Table $table each collection has only records of specified table */ - protected $table; + protected $_table; /** * @var Doctrine_Record $reference collection can belong to a record */ @@ -75,7 +75,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato $table = Doctrine_Manager::getInstance() ->getTable($table); } - $this->table = $table; + $this->_table = $table; $name = $table->getAttribute(Doctrine::ATTR_COLL_KEY); if ($name !== null) { @@ -100,7 +100,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato */ public function getTable() { - return $this->table; + return $this->_table; } /** * this method is automatically called when this Doctrine_Collection is serialized @@ -139,12 +139,12 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato $this->$name = $values; } - $this->table = $connection->getTable($this->table); + $this->_table = $connection->getTable($this->_table); $this->expanded = array(); $this->expandable = true; - $name = $this->table->getAttribute(Doctrine::ATTR_COLL_KEY); + $name = $this->_table->getAttribute(Doctrine::ATTR_COLL_KEY); if ($name !== null) { $this->keyColumn = $name; } @@ -294,8 +294,8 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato */ public function get($key) { - if ($key === null) { - $record = $this->table->create(); + if ($key === null || ! isset($this->data[$key])) { + $record = $this->_table->create(); if (isset($this->referenceField)) { $record->set($this->referenceField, $this->reference, false); @@ -306,22 +306,6 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato return $record; } - - if ( ! isset($this->data[$key])) { - if ( ! isset($this->data[$key])) { - $this->data[$key] = $this->table->create(); - } - if (isset($this->referenceField)) { - $value = $this->reference->get($this->relation->getLocal()); - - if ($value !== null) { - $this->data[$key]->set($this->referenceField, $value, false); - } else { - $this->data[$key]->set($this->referenceField, $this->reference, false); - } - } - } - return $this->data[$key]; } @@ -331,7 +315,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato public function getPrimaryKeys() { $list = array(); - $name = $this->table->getIdentifier(); + $name = $this->_table->getIdentifier(); foreach ($this->data as $record) { if (is_array($record) && isset($record[$name])) { @@ -380,7 +364,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato * @param string $key optional key for the record * @return boolean */ - public function add(Doctrine_Record $record,$key = null) + public function add(Doctrine_Record $record, $key = null) { if (isset($this->referenceField)) { $record->set($this->referenceField, $this->reference, false); @@ -424,7 +408,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato public function loadRelated($name = null) { $list = array(); - $query = new Doctrine_Query($this->table->getConnection()); + $query = new Doctrine_Query($this->_table->getConnection()); if ( ! isset($name)) { foreach ($this->data as $record) { @@ -433,13 +417,13 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato $list[] = $value; } }; - $query->from($this->table->getComponentName() . '(' . implode(", ",$this->table->getPrimaryKeys()) . ')'); - $query->where($this->table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')'); + $query->from($this->_table->getComponentName() . '(' . implode(", ",$this->_table->getPrimaryKeys()) . ')'); + $query->where($this->_table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')'); return $query; } - $rel = $this->table->getRelation($name); + $rel = $this->_table->getRelation($name); if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) { foreach ($this->data as $record) { @@ -469,7 +453,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato */ public function populateRelated($name, Doctrine_Collection $coll) { - $rel = $this->table->getRelation($name); + $rel = $this->_table->getRelation($name); $table = $rel->getTable(); $foreign = $rel->getForeign(); $local = $rel->getLocal(); @@ -501,7 +485,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato $this->data[$key]->setRelated($name, $sub); } } elseif ($rel instanceof Doctrine_Relation_Association) { - $identifier = $this->table->getIdentifier(); + $identifier = $this->_table->getIdentifier(); $asf = $rel->getAssociationFactory(); $name = $table->getComponentName(); @@ -541,7 +525,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato public function save(Doctrine_Connection $conn = null) { if ($conn == null) { - $conn = $this->table->getConnection(); + $conn = $this->_table->getConnection(); } $conn->beginTransaction(); @@ -561,7 +545,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato public function delete(Doctrine_Connection $conn = null) { if ($conn == null) { - $conn = $this->table->getConnection(); + $conn = $this->_table->getConnection(); } $conn->beginTransaction(); diff --git a/draft/new-core/Hydrate.php b/draft/new-core/Hydrate.php index 3d0b624df..6c463ed1b 100644 --- a/draft/new-core/Hydrate.php +++ b/draft/new-core/Hydrate.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Access'); + /** * Doctrine_Hydrate is a base class for Doctrine_RawSql and Doctrine_Query. * Its purpose is to populate object graphs. @@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Access'); * @version $Revision: 1255 $ * @author Konsta Vesterinen */ -class Doctrine_Hydrate2 extends Doctrine_Access +class Doctrine_Hydrate2 { /** * QUERY TYPE CONSTANTS @@ -77,7 +77,9 @@ class Doctrine_Hydrate2 extends Doctrine_Access * * table table object associated with given alias * + * relation the relation object owned by the parent * + * parent the alias of the parent */ protected $_aliasMap = array(); @@ -320,6 +322,7 @@ class Doctrine_Hydrate2 extends Doctrine_Access * * @param Doctrine_Record $record * @param array $row + * @return Doctrine_Record */ public function mapAggregateValues($record, array $row) { @@ -338,6 +341,15 @@ class Doctrine_Hydrate2 extends Doctrine_Access } } return $record; + } + /** + * mapRelated + * + * @return + */ + public function mapRelated() + { + } /** * execute @@ -353,10 +365,11 @@ class Doctrine_Hydrate2 extends Doctrine_Access if (empty($this->_aliasMap)) { throw new Doctrine_Hydrate_Exception("Couldn't execute query. Component alias map was empty."); } - + // initialize some variables used within the main loop $rootMap = current($this->_aliasMap); - $coll = new Doctrine_Collection($rootMap['table']); - $prev[key($this->_aliasMap)] = $coll; + $rootAlias = key($this->_aliasMap); + $coll = new Doctrine_Collection2($rootMap['table']); + $prev[$rootAlias] = $coll; $prevRow = array(); /** @@ -368,47 +381,78 @@ class Doctrine_Hydrate2 extends Doctrine_Access * remove duplicated data rows and map data into objects */ foreach ($data as $tableAlias => $row) { + // skip empty rows (not mappable) if (empty($row)) { continue; } - + // check for validity if ( ! isset($this->tableAliases[$tableAlias])) { throw new Doctrine_Hydrate_Exception('Unknown table alias ' . $tableAlias); } $alias = $this->tableAliases[$tableAlias]; $map = $this->_aliasMap[$alias]; + // initialize previous row array if not set + if ( ! isset($prevRow[$tableAlias])) { + $prevRow[$tableAlias] = array(); + } + + // don't map duplicate rows if ($prevRow[$tableAlias] !== $row) { // set internal data - $this->tables[$name]->setData($row); - + $map['table']->setData($row); + // initialize a new record - $record = $this->tables[$name]->getRecord(); - + $record = $map['table']->getRecord(); + + // map aggregate values (if any) $this->mapAggregateValues($record, $row); - - if ($name == $root) { + + if ($alias == $rootAlias) { // add record into root collection $coll->add($record); - unset($previd); - + unset($prevRow); } else { - $prev = $this->addRelated($prev, $name, $record); + + $relation = $map['relation']; + $parentAlias = $map['parent']; + $parentMap = $this->_aliasMap[$parentAlias]; + $parent = $prev[$parentAlias]->getLast(); + + // check the type of the relation + if ($relation->isOneToOne()) { + $prev[$alias] = $record; + } else { + // one-to-many relation or many-to-many relation + if ( ! $prev[$parentAlias]->getLast()->hasReference($relation->getAlias())) { + // initialize a new collection + $prev[$alias] = new Doctrine_Collection2($parentMap['table']); + $prev[$alias]->setReference($parent, $relation); + } else { + // previous entry found from memory + $prev[$alias] = $prev[$parentAlias]->getLast()->get($relation->getAlias()); + } + // add record to the current collection + $prev[$alias]->add($record); + } + // initialize the relation from parent to the current collection/record + $parent->set($relation->getAlias(), $prev[$alias]); } // following statement is needed to ensure that mappings // are being done properly when the result set doesn't // contain the rows in 'right order' - if ($prev[$name] !== $record) { - $prev[$name] = $record; + if ($prev[$alias] !== $record) { + $prev[$alias] = $record; } } $prevRow[$tableAlias] = $row; } } + return $coll; } /** * execute @@ -418,12 +462,6 @@ class Doctrine_Hydrate2 extends Doctrine_Access * @return Doctrine_Collection the root collection */ public function execute2($params = array(), $return = Doctrine::FETCH_RECORD) { - $array = $this->_fetch($params = array(), $return = Doctrine::FETCH_RECORD); - - $keys = array_keys($this->tables); - $root = $keys[0]; - - $previd = array(); /** * iterate over the fetched data * here $data is a two dimensional array @@ -488,131 +526,11 @@ class Doctrine_Hydrate2 extends Doctrine_Access continue; } - - if ( ! isset($previd[$name])) { - $previd[$name] = array(); - } - if ($previd[$name] !== $row) { - // set internal data - - $this->tables[$name]->setData($row); - - // initialize a new record - - $record = $this->tables[$name]->getRecord(); - - // aggregate values have numeric keys - if (isset($row[0])) { - $path = array_search($name, $this->tableAliases); - $alias = $this->getPathAlias($path); - - // map each aggregate value - foreach ($row as $index => $value) { - $agg = false; - - if (isset($this->pendingAggregates[$alias][$index])) { - $agg = $this->pendingAggregates[$alias][$index][3]; - } elseif (isset($this->subqueryAggregates[$alias][$index])) { - $agg = $this->subqueryAggregates[$alias][$index]; - } - $record->mapValue($agg, $value); - } - } - - if ($name == $root) { - // add record into root collection - - $coll->add($record); - unset($previd); - - } else { - $prev = $this->addRelated($prev, $name, $record); - } - - // following statement is needed to ensure that mappings - // are being done properly when the result set doesn't - // contain the rows in 'right order' - - if ($prev[$name] !== $record) { - $prev[$name] = $record; - } - } - - $previd[$name] = $row; } } return $coll; } - /** - * initRelation - * - * @param array $prev - * @param string $name - * @return array - */ - public function initRelated(array $prev, $name) - { - $pointer = $this->joins[$name]; - $path = array_search($name, $this->tableAliases); - $tmp = explode('.', $path); - $alias = end($tmp); - - if ( ! isset($prev[$pointer]) ) { - return $prev; - } - $fk = $this->tables[$pointer]->getRelation($alias); - - if ( ! $fk->isOneToOne()) { - if ($prev[$pointer]->getLast() instanceof Doctrine_Record) { - if ( ! $prev[$pointer]->getLast()->hasReference($alias)) { - $prev[$name] = $this->getCollection($name); - $prev[$pointer]->getLast()->initReference($prev[$name],$fk); - } else { - $prev[$name] = $prev[$pointer]->getLast()->get($alias); - } - } - } - - return $prev; - } - /** - * addRelated - * - * @param array $prev - * @param string $name - * @return array - */ - public function addRelated(array $prev, $name, Doctrine_Record $record) - { - $pointer = $this->joins[$name]; - - $path = array_search($name, $this->tableAliases); - $tmp = explode('.', $path); - $alias = end($tmp); - - $fk = $this->tables[$pointer]->getRelation($alias); - - if ($fk->isOneToOne()) { - $prev[$pointer]->getLast()->set($fk->getAlias(), $record); - - $prev[$name] = $record; - } else { - // one-to-many relation or many-to-many relation - - if ( ! $prev[$pointer]->getLast()->hasReference($alias)) { - $prev[$name] = $this->getCollection($name); - $prev[$pointer]->getLast()->initReference($prev[$name], $fk); - - } else { - // previous entry found from memory - $prev[$name] = $prev[$pointer]->getLast()->get($alias); - } - - $prev[$pointer]->getLast()->addReference($record, $fk); - } - return $prev; - } /** * isIdentifiable * returns whether or not a given data row is identifiable (it contains