From cff3c43017bf7995ef14b447fa6b6cad0e51e52e Mon Sep 17 00:00:00 2001 From: doctrine Date: Mon, 26 Jun 2006 21:18:19 +0000 Subject: [PATCH] DQL: improved self-reference handling --- Doctrine/Query.php | 15 ++++--- Doctrine/Record.php | 7 ++-- tests/QueryTestCase.php | 89 ++++++++++++++++++++++++++++++++++++++--- tests/classes.php | 1 + 4 files changed, 99 insertions(+), 13 deletions(-) diff --git a/Doctrine/Query.php b/Doctrine/Query.php index 939bfad1b..e83edd4c4 100644 --- a/Doctrine/Query.php +++ b/Doctrine/Query.php @@ -524,7 +524,6 @@ class Doctrine_Query extends Doctrine_Access { if( ! isset($previd[$name])) $previd[$name] = array(); - if($previd[$name] !== $row) { // set internal data @@ -536,6 +535,8 @@ class Doctrine_Query extends Doctrine_Access { if($name == $root) { // add record into root collection $coll->add($record); + unset($previd); + } else { $pointer = $this->joins[$name]; @@ -549,15 +550,17 @@ class Doctrine_Query extends Doctrine_Access { switch($fk->getType()): case Doctrine_Relation::ONE_COMPOSITE: case Doctrine_Relation::ONE_AGGREGATE: + // one-to-one relation $last->internalSet($fk->getLocal(), $record->getID()); - $last->initSingleReference($record); + $last->initSingleReference($record, $fk); $prev[$name] = $record; break; default: + // one-to-many relation or many-to-many relation if( ! $last->hasReference($alias)) { @@ -1059,9 +1062,9 @@ class Doctrine_Query extends Doctrine_Access { * @return string */ final public function generateAlias($tableName) { - if(isset($this->tableIndexes[$tableName])) + if(isset($this->tableIndexes[$tableName])) { return $tableName.++$this->tableIndexes[$tableName]; - else { + } else { $this->tableIndexes[$tableName] = 1; return $tableName; } @@ -1106,7 +1109,9 @@ class Doctrine_Query extends Doctrine_Access { $table = $this->session->getTable($name); $tname = $table->getTableName(); - $this->tableIndexes[$tname] = 1; + + if( ! isset($this->tableAliases[$currPath])) + $this->tableIndexes[$tname] = 1; $this->parts["from"][$tname] = true; diff --git a/Doctrine/Record.php b/Doctrine/Record.php index 434900082..256a6e282 100644 --- a/Doctrine/Record.php +++ b/Doctrine/Record.php @@ -991,9 +991,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * @param Doctrine_Relation $connector * @return void */ - public function initSingleReference(Doctrine_Record $record) { - $name = $this->table->getAlias($record->getTable()->getComponentName()); - $this->references[$name] = $record; + public function initSingleReference(Doctrine_Record $record, Doctrine_Relation $connector) { + $alias = $connector->getAlias(); + + $this->references[$alias] = $record; } /** * initalizes a one-to-many / many-to-many relation diff --git a/tests/QueryTestCase.php b/tests/QueryTestCase.php index 9366dad05..0769a7a84 100644 --- a/tests/QueryTestCase.php +++ b/tests/QueryTestCase.php @@ -26,6 +26,8 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { } public function testSelfReferencing() { + $query = new Doctrine_Query($this->session); + $category = new Forum_Category(); $category->name = "Root"; @@ -38,6 +40,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->session->flush(); $this->session->clear(); + $category = $category->getTable()->find($category->id); $this->assertEqual($category->name, "Root"); @@ -49,23 +52,99 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->assertEqual($category->Subcategory[1]->Subcategory[1]->name, "Sub 2 Sub 2"); $this->session->clear(); - - $query = new Doctrine_Query($this->session); - - $count = count($this->dbh); + + $query->from("Forum_Category.Subcategory.Subcategory"); $coll = $query->execute(); $category = $coll[0]; + $count = count($this->dbh); + $this->assertEqual($category->name, "Root"); + + $this->assertEqual($count, count($this->dbh)); $this->assertEqual($category->Subcategory[0]->name, "Sub 1"); $this->assertEqual($category->Subcategory[1]->name, "Sub 2"); + + $this->assertEqual($count, count($this->dbh)); $this->assertEqual($category->Subcategory[0]->Subcategory[0]->name, "Sub 1 Sub 1"); $this->assertEqual($category->Subcategory[0]->Subcategory[1]->name, "Sub 1 Sub 2"); $this->assertEqual($category->Subcategory[1]->Subcategory[0]->name, "Sub 2 Sub 1"); $this->assertEqual($category->Subcategory[1]->Subcategory[1]->name, "Sub 2 Sub 2"); - $this->assertEqual(($count + 1), count($this->dbh)); + $this->assertEqual($count, count($this->dbh)); + + $this->session->clear(); + $query->from("Forum_Category.Parent.Parent")->where("Forum_Category.name LIKE 'Sub%Sub%'"); + $coll = $query->execute(); + + $count = count($this->dbh); + $this->assertEqual($coll->count(), 4); + $this->assertEqual($coll[0]->name, "Sub 1 Sub 1"); + $this->assertEqual($coll[1]->name, "Sub 1 Sub 2"); + $this->assertEqual($coll[2]->name, "Sub 2 Sub 1"); + $this->assertEqual($coll[3]->name, "Sub 2 Sub 2"); + + $this->assertEqual($count, count($this->dbh)); + + $this->assertEqual($coll[0]->Parent->name, "Sub 1"); + $this->assertEqual($coll[1]->Parent->name, "Sub 1"); + $this->assertEqual($coll[2]->Parent->name, "Sub 2"); + $this->assertEqual($coll[3]->Parent->name, "Sub 2"); + + $this->assertEqual($count, count($this->dbh)); + + $this->assertEqual($coll[0]->Parent->Parent->name, "Root"); + $this->assertEqual($coll[1]->Parent->Parent->name, "Root"); + $this->assertEqual($coll[2]->Parent->Parent->name, "Root"); + $this->assertEqual($coll[3]->Parent->Parent->name, "Root"); + + $this->assertEqual($count, count($this->dbh)); + + $query->from("Forum_Category.Parent, Forum_Category.Subcategory")->where("Forum_Category.name = 'Sub 1' OR Forum_Category.name = 'Sub 2'"); + + $coll = $query->execute(); + + $count = count($this->dbh); + + $this->assertEqual($coll->count(), 2); + $this->assertEqual($coll[0]->name, "Sub 1"); + $this->assertEqual($coll[1]->name, "Sub 2"); + + $this->assertEqual($count, count($this->dbh)); + + $this->assertEqual($coll[0]->Subcategory[0]->name, "Sub 1 Sub 1"); + $this->assertEqual($coll[0]->Subcategory[1]->name, "Sub 1 Sub 2"); + $this->assertEqual($coll[1]->Subcategory[0]->name, "Sub 2 Sub 1"); + $this->assertEqual($coll[1]->Subcategory[1]->name, "Sub 2 Sub 2"); + + $this->assertEqual($count, count($this->dbh)); + + $this->assertEqual($coll[0]->Parent->name, "Root"); + $this->assertEqual($coll[1]->Parent->name, "Root"); + + $this->assertEqual($count, count($this->dbh)); + + $this->session->clear(); + + $query->from("Forum_Category.Subcategory.Subcategory")->where("Forum_Category.parent_category_id IS NULL"); + $coll = $query->execute(); + $this->assertEqual($coll->count(), 1); + + $count = count($this->dbh); + + $this->assertEqual($category->name, "Root"); + + $this->assertEqual($count, count($this->dbh)); + $this->assertEqual($category->Subcategory[0]->name, "Sub 1"); + $this->assertEqual($category->Subcategory[1]->name, "Sub 2"); + + $this->assertEqual($count, count($this->dbh)); + $this->assertEqual($category->Subcategory[0]->Subcategory[0]->name, "Sub 1 Sub 1"); + $this->assertEqual($category->Subcategory[0]->Subcategory[1]->name, "Sub 1 Sub 2"); + $this->assertEqual($category->Subcategory[1]->Subcategory[0]->name, "Sub 2 Sub 1"); + $this->assertEqual($category->Subcategory[1]->Subcategory[1]->name, "Sub 2 Sub 2"); + $this->assertEqual($count, count($this->dbh)); } public function testGetPath() { diff --git a/tests/classes.php b/tests/classes.php index 3802d0908..5ba6ccf4d 100644 --- a/tests/classes.php +++ b/tests/classes.php @@ -180,6 +180,7 @@ class Forum_Category extends Doctrine_Record { } public function setUp() { $this->hasMany("Forum_Category as Subcategory", "Subcategory.parent_category_id"); + $this->hasOne("Forum_Category as Parent", "Forum_Category.parent_category_id"); $this->hasOne("Forum_Category as Rootcategory", "Forum_Category.root_category_id"); } }