From c500f710821eca5bd5e194897842cf085666fb4d Mon Sep 17 00:00:00 2001 From: zYne Date: Thu, 10 May 2007 21:31:35 +0000 Subject: [PATCH] --- draft/new-core/Hydrate.php | 81 ++++++++++++++++++++++++++++++++++---- tests/NewCoreTestCase.php | 57 +++++++++++++++++++-------- 2 files changed, 115 insertions(+), 23 deletions(-) diff --git a/draft/new-core/Hydrate.php b/draft/new-core/Hydrate.php index 3f7f1f7bf..3d0b624df 100644 --- a/draft/new-core/Hydrate.php +++ b/draft/new-core/Hydrate.php @@ -145,6 +145,10 @@ class Doctrine_Hydrate2 extends Doctrine_Access { return $this->tableAliases; } + public function setTableAliases(array $aliases) + { + $this->tableAliases = $aliases; + } /** * copyAliases * @@ -299,7 +303,6 @@ class Doctrine_Hydrate2 extends Doctrine_Access } $stmt = $this->conn->execute($query, $params); - return $this->parseData($stmt); } @@ -311,6 +314,31 @@ class Doctrine_Hydrate2 extends Doctrine_Access { return $this->_aliasMap; } + /** + * mapAggregateValues + * map the aggregate values of given dataset row to a given record + * + * @param Doctrine_Record $record + * @param array $row + */ + public function mapAggregateValues($record, array $row) + { + // aggregate values have numeric keys + if (isset($row[0])) { + // 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); + } + } + return $record; + } /** * execute * executes the dql query and populates all collections @@ -320,12 +348,17 @@ class Doctrine_Hydrate2 extends Doctrine_Access */ public function execute($params = array(), $return = Doctrine::FETCH_RECORD) { - $array = $this->_fetch($params = array(), $return = Doctrine::FETCH_RECORD); + $array = (array) $this->_fetch($params = array(), $return = Doctrine::FETCH_RECORD); - $coll = new Doctrine_Collection(key($this->_aliasMap)); - $prev[$root] = $coll; + if (empty($this->_aliasMap)) { + throw new Doctrine_Hydrate_Exception("Couldn't execute query. Component alias map was empty."); + } - $previd = array(); + $rootMap = current($this->_aliasMap); + $coll = new Doctrine_Collection($rootMap['table']); + $prev[key($this->_aliasMap)] = $coll; + + $prevRow = array(); /** * iterate over the fetched data * here $data is a two dimensional array @@ -334,13 +367,47 @@ class Doctrine_Hydrate2 extends Doctrine_Access /** * remove duplicated data rows and map data into objects */ - foreach ($data as $key => $row) { + foreach ($data as $tableAlias => $row) { if (empty($row)) { continue; } + if ( ! isset($this->tableAliases[$tableAlias])) { + throw new Doctrine_Hydrate_Exception('Unknown table alias ' . $tableAlias); + } + $alias = $this->tableAliases[$tableAlias]; + $map = $this->_aliasMap[$alias]; + + if ($prevRow[$tableAlias] !== $row) { + // set internal data + $this->tables[$name]->setData($row); + + // initialize a new record + $record = $this->tables[$name]->getRecord(); + + $this->mapAggregateValues($record, $row); + + + 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; + } + } + $prevRow[$tableAlias] = $row; } - } } /** diff --git a/tests/NewCoreTestCase.php b/tests/NewCoreTestCase.php index 9c087c130..f176068ac 100644 --- a/tests/NewCoreTestCase.php +++ b/tests/NewCoreTestCase.php @@ -38,27 +38,52 @@ require_once('../draft/new-core/Collection.php'); */ -class Doctrine_NewCore_TestCase extends Doctrine_UnitTestCase +class Doctrine_NewCore_TestCase extends Doctrine_UnitTestCase { + protected $testData1 = array( + array( + 'e' => array('id' => 1, 'name' => 'zYne'), + 'p' => array('id' => 1, 'phonenumber' => '123 123', 'user_id' => 1) + ), + array( + 'e' => array('id' => 2, 'name' => 'John'), + 'p' => array('id' => 2, 'phonenumber' => '222 222', 'user_id' => 2) + ), + array( + 'e' => array('id' => 3, 'name' => 'Arnold'), + 'p' => array('id' => 3, 'phonenumber' => '333 333', 'user_id' => 3) + ) + ); + + public function testExecuteForEmptyAliasMapThrowsException() + { + $h = new Doctrine_Hydrate_Mock(); + + try { + $h->execute(); + $this->fail('Should throw exception'); + } catch(Doctrine_Hydrate_Exception $e) { + $this->pass(); + } + } + public function testExecuteForEmptyTableAliasMapThrowsException() + { + $h = new Doctrine_Hydrate_Mock(); + $h->setData($this->testData1); + $h->setAliasMap(array('u' => array('table' => $this->conn->getTable('User')))); + try { + $h->execute(); + $this->fail('Should throw exception'); + } catch(Doctrine_Hydrate_Exception $e) { + $this->pass(); + } + } public function testHydrate() { $h = new Doctrine_Hydrate_Mock(); - $h->setData(array( - array( - 'e' => array('id' => 1, 'name' => 'zYne'), - 'p' => array('id' => 1, 'phonenumber' => '123 123', 'user_id' => 1) - ), - array( - 'e' => array('id' => 2, 'name' => 'John'), - 'p' => array('id' => 2, 'phonenumber' => '222 222', 'user_id' => 2) - ), - array( - 'e' => array('id' => 3, 'name' => 'Arnold'), - 'p' => array('id' => 3, 'phonenumber' => '333 333', 'user_id' => 3) - ) - ) - ); + $h->setData($this->testData1); $h->setAliasMap(array('u' => array('table' => $this->conn->getTable('User')))); + $h->setTableAliases(array('e' => 'u')); } } class Doctrine_Hydrate_Mock extends Doctrine_Hydrate2