From 4c582bec6c1b7e0bfebb11a82f01010846f1eee2 Mon Sep 17 00:00:00 2001 From: doctrine Date: Fri, 19 May 2006 10:22:15 +0000 Subject: [PATCH] DQL with aliases bug fixed --- classes/Collection.class.php | 5 +++-- classes/Query.class.php | 26 ++++++++++++++++------ classes/Record.class.php | 17 +++++++++++---- classes/Table.class.php | 12 ++++++++++ tests/CollectionTestCase.class.php | 2 +- tests/QueryTestCase.class.php | 35 +++++++++++++++++++++++------- tests/classes.php | 2 +- tests/run.php | 5 ++--- 8 files changed, 78 insertions(+), 26 deletions(-) diff --git a/classes/Collection.class.php b/classes/Collection.class.php index c0605fefe..2612707bc 100644 --- a/classes/Collection.class.php +++ b/classes/Collection.class.php @@ -109,9 +109,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator public function setReference(Doctrine_Record $record,Doctrine_Relation $relation) { $this->reference = $record; $this->relation = $relation; - + if($relation instanceof Doctrine_ForeignKey || $relation instanceof Doctrine_LocalKey) { + $this->reference_field = $relation->getForeign(); $value = $record->get($relation->getLocal()); @@ -221,7 +222,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator if( ! isset($offset)) { foreach($coll as $record) { if(isset($this->reference_field)) - $record->set($this->reference_field,$this->reference); + $record->rawSet($this->reference_field,$this->reference); $this->reference->addReference($record); } diff --git a/classes/Query.class.php b/classes/Query.class.php index f29df9990..f017cfba8 100644 --- a/classes/Query.class.php +++ b/classes/Query.class.php @@ -356,6 +356,9 @@ class Doctrine_Query extends Doctrine_Access { * @return Doctrine_Collection the root collection */ public function execute($params = array()) { + $this->data = array(); + $this->collections = array(); + switch(count($this->tables)): case 0: throw new DQLException(); @@ -364,7 +367,7 @@ class Doctrine_Query extends Doctrine_Access { $query = $this->getQuery(); $keys = array_keys($this->tables); - + $name = $this->tables[$keys[0]]->getComponentName(); $stmt = $this->session->execute($query,$params); @@ -396,6 +399,7 @@ class Doctrine_Query extends Doctrine_Access { $array = $this->parseData($stmt); + foreach($array as $data): /** @@ -405,7 +409,6 @@ class Doctrine_Query extends Doctrine_Access { if(empty($row)) continue; - $key = ucwords($key); $name = $this->tables[$key]->getComponentName(); if( ! isset($previd[$name])) @@ -417,15 +420,13 @@ class Doctrine_Query extends Doctrine_Access { $record = $this->tables[$name]->getRecord(); if($name == $root) { - $this->tables[$name]->setData($row); - $record = $this->tables[$name]->getRecord(); $coll->add($record); } else { $last = $coll->getLast(); - if( ! $last->hasReference($name)) { + if( ! $last->hasReference($name)) $last->initReference($this->getCollection($name),$this->connectors[$name]); - } + $last->addReference($record); } } @@ -445,6 +446,11 @@ class Doctrine_Query extends Doctrine_Access { */ public function parseData(PDOStatement $stmt) { $array = array(); + $keys = array(); + foreach(array_keys($this->tables) as $key) { + $k = strtolower($key); + $keys[$k] = $key; + } while($data = $stmt->fetch(PDO::FETCH_ASSOC)): /** * parse the data into two-dimensional array @@ -453,7 +459,7 @@ class Doctrine_Query extends Doctrine_Access { $e = explode("__",$key); if(count($e) > 1) { - $data[$e[0]][$e[1]] = $value; + $data[$keys[$e[0]]][$e[1]] = $value; } else { $data[0][$e[0]] = $value; } @@ -810,6 +816,9 @@ class Doctrine_Query extends Doctrine_Access { break; case Doctrine_Relation::MANY_AGGREGATE: case Doctrine_Relation::MANY_COMPOSITE: + + // subquery needed + $b = $fk->getTable()->getComponentName(); $graph = new Doctrine_Query($this->session); @@ -844,6 +853,8 @@ class Doctrine_Query extends Doctrine_Access { } } else { $fk = $objTable->getForeignKey($name); + $name = $fk->getTable()->getComponentName(); + $tname = $objTable->getTableName(); $next = $fk->getTable(); $tname2 = $next->getTableName(); @@ -886,6 +897,7 @@ class Doctrine_Query extends Doctrine_Access { $objTable = $next; } + if( ! isset($this->tables[$name])) { $this->tables[$name] = $objTable; } diff --git a/classes/Record.class.php b/classes/Record.class.php index 415ac25d2..1e941d09f 100644 --- a/classes/Record.class.php +++ b/classes/Record.class.php @@ -442,6 +442,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite endswitch; } } + + if($this->state == Doctrine_Record::STATE_TCLEAN) + $this->state = Doctrine_Record::STATE_TDIRTY; + $this->data[$name] = $value; $this->modified[] = $name; } @@ -798,6 +802,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite /** * hasRefence * @param string $name + * @return boolean */ public function hasReference($name) { return isset($this->references[$name]); @@ -807,16 +812,20 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * @param string $connectorField */ public function initReference(Doctrine_Collection $coll, Doctrine_Relation $connector) { - $name = $coll->getTable()->getComponentName(); + $name = $this->table->getAlias($coll->getTable()->getComponentName()); $coll->setReference($this, $connector); $this->references[$name] = $coll; $this->originals[$name] = clone $coll; } /** * addReference + * @param Doctrine_Record $record + * @param mixed $key + * @return void */ public function addReference(Doctrine_Record $record, $key = null) { - $name = $record->getTable()->getComponentName(); + $name = $this->table->getAlias($record->getTable()->getComponentName()); + $this->references[$name]->add($record, $key); $this->originals[$name]->add($record, $key); } @@ -909,9 +918,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $id = $this->get($local); $query = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$fk->getForeign()." = ?"; $coll = $graph->query($query,array($id)); - + $this->references[$name] = $coll; - $this->references[$name]->setReference($this,$fk); + $this->references[$name]->setReference($this, $fk); $this->originals[$name] = clone $coll; diff --git a/classes/Table.class.php b/classes/Table.class.php index 8862e0913..22076fb66 100644 --- a/classes/Table.class.php +++ b/classes/Table.class.php @@ -400,6 +400,18 @@ class Doctrine_Table extends Doctrine_Configurable { return $name; } + /** + * returns component name for given alias + * + * @param string $alias + * @return string + */ + final public function getAliasName($alias) { + if($name = array_search($this->boundAliases,$alias)) + return $name; + + throw new InvalidKeyException(); + } /** * unbinds all relations * diff --git a/tests/CollectionTestCase.class.php b/tests/CollectionTestCase.class.php index 8bf17e754..1c08fc246 100644 --- a/tests/CollectionTestCase.class.php +++ b/tests/CollectionTestCase.class.php @@ -35,7 +35,7 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase { $this->assertEqual(count($coll), 3); - //$this->assertEqual($coll[2]->getState(), Doctrine_Record::STATE_PROXY); + $this->assertEqual($coll[2]->getState(), Doctrine_Record::STATE_PROXY); $generator = new Doctrine_IndexGenerator($this->objTable->getIdentifier()); diff --git a/tests/QueryTestCase.class.php b/tests/QueryTestCase.class.php index ea619a077..020bca1c7 100644 --- a/tests/QueryTestCase.class.php +++ b/tests/QueryTestCase.class.php @@ -7,11 +7,16 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->tables[] = "Forum_Thread"; parent::prepareTables(); } - public function testQueryWithComplexAliases() { + $board = new Forum_Board(); $table = $board->getTable(); - $this->assertTrue($table->getForeignKey("Threads") instanceof Doctrine_ForeignKey); + $fk = $table->getForeignKey("Threads"); + + $this->assertEqual($table->getComponentName(), "Forum_Board"); + $this->assertTrue($fk instanceof Doctrine_ForeignKey); + $this->assertEqual($fk->getTable()->getComponentName(), "Forum_Thread"); + $entry = new Forum_Entry(); $this->assertTrue($entry->getTable()->getForeignKey("Thread") instanceof Doctrine_LocalKey); @@ -22,22 +27,35 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->assertEqual($board->name, "Doctrine Forum"); $this->assertEqual($board->Category->name, "General discussion"); $this->assertEqual($board->Category->getState(), Doctrine_Record::STATE_TDIRTY); - //$this->assertEqual($board->Threads[0]->getState(), Doctrine_Record::STATE_TDIRTY); + $this->assertEqual($board->Threads[0]->getState(), Doctrine_Record::STATE_TDIRTY); $this->assertTrue($board->Threads[0] instanceof Forum_Thread); - - //print_r($this->session->buildFlushTree()); + + $thread = $board->Threads[0]; + $thread->Entries[0]->topic = "My first topic"; + $this->assertEqual($thread->Entries[0]->topic, "My first topic"); + $this->assertEqual($thread->Entries[0]->getState(), Doctrine_Record::STATE_TDIRTY); + $this->assertTrue($thread->Entries[0] instanceof Forum_Entry); $this->session->flush(); - /** + $board->getTable()->clear(); $board = $board->getTable()->find($board->getID()); $this->assertEqual($board->Threads->count(), 1); $this->assertEqual($board->name, "Doctrine Forum"); $this->assertEqual($board->Category->name, "General discussion"); - $this->assertEqual($board->Category->getState(), Doctrine_Record::STATE_TDIRTY); + $this->assertEqual($board->Category->getState(), Doctrine_Record::STATE_CLEAN); $this->assertEqual($board->Threads[0]->getState(), Doctrine_Record::STATE_CLEAN); $this->assertTrue($board->Threads[0] instanceof Forum_Thread); - */ + + + $q = new Doctrine_Query($this->session); + $q->from("Forum_Board"); + $coll = $q->execute(); + $this->assertEqual($coll->count(), 1); + + $q->from("Forum_Board, Forum_Board.Threads"); + $coll = $q->execute(); + $this->assertEqual($coll->count(), 1); } public function testQueryWithAliases() { @@ -306,5 +324,6 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->assertTrue(isset($values['users'])); $this->assertTrue(isset($values['max'])); } + } ?> diff --git a/tests/classes.php b/tests/classes.php index ee0b633c8..a5e6c65b9 100644 --- a/tests/classes.php +++ b/tests/classes.php @@ -207,7 +207,7 @@ class Forum_Thread extends Doctrine_Record { } public function setUp() { $this->hasOne("Forum_Board as Board", "Forum_Thread.board_id"); - $this->ownsMany("Forum_Entry as Entry", "Forum_Entry.thread_id"); + $this->ownsMany("Forum_Entry as Entries", "Forum_Entry.thread_id"); } } diff --git a/tests/run.php b/tests/run.php index 7484f9bc0..388a71cb1 100644 --- a/tests/run.php +++ b/tests/run.php @@ -23,7 +23,6 @@ error_reporting(E_ALL); $test = new GroupTest("Doctrine Framework Unit Tests"); - $test->addTestCase(new Doctrine_SessionTestCase()); $test->addTestCase(new Doctrine_TableTestCase()); @@ -42,12 +41,12 @@ $test->addTestCase(new Doctrine_BatchIteratorTestCase()); $test->addTestCase(new Doctrine_ConfigurableTestCase()); -$test->addTestCase(new Doctrine_CollectionTestCase()); - $test->addTestCase(new Doctrine_Collection_OffsetTestCase()); $test->addTestCase(new Sensei_UnitTestCase()); +$test->addTestCase(new Doctrine_CollectionTestCase()); + $test->addTestCase(new Doctrine_QueryTestCase());