1
0
mirror of synced 2025-02-21 14:43:14 +03:00

DQL: improved self-reference handling

This commit is contained in:
doctrine 2006-06-26 21:18:19 +00:00
parent 8c4d8293e5
commit cff3c43017
4 changed files with 99 additions and 13 deletions

View File

@ -524,7 +524,6 @@ class Doctrine_Query extends Doctrine_Access {
if( ! isset($previd[$name])) if( ! isset($previd[$name]))
$previd[$name] = array(); $previd[$name] = array();
if($previd[$name] !== $row) { if($previd[$name] !== $row) {
// set internal data // set internal data
@ -536,6 +535,8 @@ class Doctrine_Query extends Doctrine_Access {
if($name == $root) { if($name == $root) {
// add record into root collection // add record into root collection
$coll->add($record); $coll->add($record);
unset($previd);
} else { } else {
$pointer = $this->joins[$name]; $pointer = $this->joins[$name];
@ -549,15 +550,17 @@ class Doctrine_Query extends Doctrine_Access {
switch($fk->getType()): switch($fk->getType()):
case Doctrine_Relation::ONE_COMPOSITE: case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE: case Doctrine_Relation::ONE_AGGREGATE:
// one-to-one relation // one-to-one relation
$last->internalSet($fk->getLocal(), $record->getID()); $last->internalSet($fk->getLocal(), $record->getID());
$last->initSingleReference($record); $last->initSingleReference($record, $fk);
$prev[$name] = $record; $prev[$name] = $record;
break; break;
default: default:
// one-to-many relation or many-to-many relation // one-to-many relation or many-to-many relation
if( ! $last->hasReference($alias)) { if( ! $last->hasReference($alias)) {
@ -1059,9 +1062,9 @@ class Doctrine_Query extends Doctrine_Access {
* @return string * @return string
*/ */
final public function generateAlias($tableName) { final public function generateAlias($tableName) {
if(isset($this->tableIndexes[$tableName])) if(isset($this->tableIndexes[$tableName])) {
return $tableName.++$this->tableIndexes[$tableName]; return $tableName.++$this->tableIndexes[$tableName];
else { } else {
$this->tableIndexes[$tableName] = 1; $this->tableIndexes[$tableName] = 1;
return $tableName; return $tableName;
} }
@ -1106,7 +1109,9 @@ class Doctrine_Query extends Doctrine_Access {
$table = $this->session->getTable($name); $table = $this->session->getTable($name);
$tname = $table->getTableName(); $tname = $table->getTableName();
$this->tableIndexes[$tname] = 1;
if( ! isset($this->tableAliases[$currPath]))
$this->tableIndexes[$tname] = 1;
$this->parts["from"][$tname] = true; $this->parts["from"][$tname] = true;

View File

@ -991,9 +991,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* @param Doctrine_Relation $connector * @param Doctrine_Relation $connector
* @return void * @return void
*/ */
public function initSingleReference(Doctrine_Record $record) { public function initSingleReference(Doctrine_Record $record, Doctrine_Relation $connector) {
$name = $this->table->getAlias($record->getTable()->getComponentName()); $alias = $connector->getAlias();
$this->references[$name] = $record;
$this->references[$alias] = $record;
} }
/** /**
* initalizes a one-to-many / many-to-many relation * initalizes a one-to-many / many-to-many relation

View File

@ -26,6 +26,8 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
} }
public function testSelfReferencing() { public function testSelfReferencing() {
$query = new Doctrine_Query($this->session);
$category = new Forum_Category(); $category = new Forum_Category();
$category->name = "Root"; $category->name = "Root";
@ -38,6 +40,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->session->flush(); $this->session->flush();
$this->session->clear(); $this->session->clear();
$category = $category->getTable()->find($category->id); $category = $category->getTable()->find($category->id);
$this->assertEqual($category->name, "Root"); $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->assertEqual($category->Subcategory[1]->Subcategory[1]->name, "Sub 2 Sub 2");
$this->session->clear(); $this->session->clear();
$query = new Doctrine_Query($this->session);
$count = count($this->dbh);
$query->from("Forum_Category.Subcategory.Subcategory"); $query->from("Forum_Category.Subcategory.Subcategory");
$coll = $query->execute(); $coll = $query->execute();
$category = $coll[0]; $category = $coll[0];
$count = count($this->dbh);
$this->assertEqual($category->name, "Root"); $this->assertEqual($category->name, "Root");
$this->assertEqual($count, count($this->dbh));
$this->assertEqual($category->Subcategory[0]->name, "Sub 1"); $this->assertEqual($category->Subcategory[0]->name, "Sub 1");
$this->assertEqual($category->Subcategory[1]->name, "Sub 2"); $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[0]->name, "Sub 1 Sub 1");
$this->assertEqual($category->Subcategory[0]->Subcategory[1]->name, "Sub 1 Sub 2"); $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[0]->name, "Sub 2 Sub 1");
$this->assertEqual($category->Subcategory[1]->Subcategory[1]->name, "Sub 2 Sub 2"); $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() { public function testGetPath() {

View File

@ -180,6 +180,7 @@ class Forum_Category extends Doctrine_Record {
} }
public function setUp() { public function setUp() {
$this->hasMany("Forum_Category as Subcategory", "Subcategory.parent_category_id"); $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"); $this->hasOne("Forum_Category as Rootcategory", "Forum_Category.root_category_id");
} }
} }