diff --git a/Doctrine/Association.php b/Doctrine/Association.php index 567535a40..951ae049c 100644 --- a/Doctrine/Association.php +++ b/Doctrine/Association.php @@ -24,8 +24,8 @@ class Doctrine_Association extends Doctrine_Relation { * @param integer $type type of relation * @see Doctrine_Table constants */ - public function __construct(Doctrine_Table $table, Doctrine_Table $associationTable, $local, $foreign, $type) { - parent::__construct($table, $local, $foreign, $type); + public function __construct(Doctrine_Table $table, Doctrine_Table $associationTable, $local, $foreign, $type, $alias) { + parent::__construct($table, $local, $foreign, $type, $alias); $this->associationTable = $associationTable; } /** diff --git a/Doctrine/Collection.php b/Doctrine/Collection.php index ded1b9a55..596752f71 100644 --- a/Doctrine/Collection.php +++ b/Doctrine/Collection.php @@ -280,14 +280,14 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator if(isset($this->reference_field)) $record->rawSet($this->reference_field,$this->reference); - $this->reference->addReference($record); + $this->reference->addReference($record, $this->relation); } } else { $i = $offset; foreach($coll as $record) { if(isset($this->reference)) { - $this->reference->addReference($record,$i); + $this->reference->addReference($record, $this->relation, $i); } else $this->data[$i] = $record; diff --git a/Doctrine/Query.php b/Doctrine/Query.php index c1dd32bae..939bfad1b 100644 --- a/Doctrine/Query.php +++ b/Doctrine/Query.php @@ -138,9 +138,9 @@ class Doctrine_Query extends Doctrine_Access { * fields of the tables become: [tablename].[fieldname] as [tablename]__[fieldname] * * @access private - * @param object Doctrine_Table $table a Doctrine_Table object - * @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY - * @param array $names fields to be loaded (only used in lazy property loading) + * @param object Doctrine_Table $table a Doctrine_Table object + * @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY + * @param array $names fields to be loaded (only used in lazy property loading) * @return void */ private function loadFields(Doctrine_Table $table, $fetchmode, array $names, $cpath) { @@ -296,9 +296,17 @@ class Doctrine_Query extends Doctrine_Access { } } - $this->applyInheritance(); - if( ! empty($this->parts["where"])) + $string = $this->applyInheritance(); + + if( ! empty($this->parts["where"])) { $q .= " WHERE ".implode(" ",$this->parts["where"]); + if( ! empty($string)) + $q .= " AND (".$string.")"; + } else { + if( ! empty($string)) + $q .= " WHERE (".$string.")"; + } + if( ! empty($this->parts["groupby"])) $q .= " GROUP BY ".implode(", ",$this->parts["groupby"]); @@ -319,12 +327,9 @@ class Doctrine_Query extends Doctrine_Access { * applyInheritance * applies column aggregation inheritance to DQL query * - * @return boolean + * @return string */ final public function applyInheritance() { - if($this->inheritanceApplied) - return false; - // get the inheritance maps $array = array(); @@ -355,9 +360,7 @@ class Doctrine_Query extends Doctrine_Access { $str .= implode(" AND ",$c); - $this->addWhere($str); - $this->inheritanceApplied = true; - return true; + return $str; } /** * @param string $where @@ -490,7 +493,9 @@ class Doctrine_Query extends Doctrine_Access { $pointer = $this->joins[$name]; $path = array_search($name, $this->tableAliases); - $alias = end( explode(".", $path)); + $tmp = explode(".", $path); + $alias = end($tmp); + unset($tmp); $fk = $this->tables[$pointer]->getForeignKey($alias); if( ! isset($prev[$pointer]) ) @@ -535,7 +540,9 @@ class Doctrine_Query extends Doctrine_Access { $pointer = $this->joins[$name]; $path = array_search($name, $this->tableAliases); - $alias = end( explode(".", $path)); + $tmp = explode(".", $path); + $alias = end($tmp); + unset($tmp); $fk = $this->tables[$pointer]->getForeignKey($alias); $last = $prev[$pointer]->getLast(); @@ -561,7 +568,7 @@ class Doctrine_Query extends Doctrine_Access { $prev[$name] = $last->get($alias); } - $last->addReference($record); + $last->addReference($record, $fk); endswitch; } } @@ -1147,7 +1154,7 @@ class Doctrine_Query extends Doctrine_Access { if($fk instanceof Doctrine_ForeignKey || $fk instanceof Doctrine_LocalKey) { - $this->parts["join"][$tname][$tname2] = $join.$tname2." ON ".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign(); + $this->parts["join"][$tname][$tname2] = $join.$aliasString." ON ".$tname.".".$fk->getLocal()." = ".$tname2.".".$fk->getForeign(); } elseif($fk instanceof Doctrine_Association) { $asf = $fk->getAssociationFactory(); diff --git a/Doctrine/Record.php b/Doctrine/Record.php index 79cb59eba..434900082 100644 --- a/Doctrine/Record.php +++ b/Doctrine/Record.php @@ -1003,13 +1003,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * @return void */ public function initReference(Doctrine_Collection $coll, Doctrine_Relation $connector) { - $name = $this->table->getAlias($coll->getTable()->getComponentName()); + $alias = $connector->getAlias(); if( ! ($connector instanceof Doctrine_Association)) $coll->setReference($this, $connector); - $this->references[$name] = $coll; - $this->originals[$name] = clone $coll; + $this->references[$alias] = $coll; + $this->originals[$alias] = clone $coll; } /** * addReference @@ -1017,11 +1017,11 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * @param mixed $key * @return void */ - public function addReference(Doctrine_Record $record, $key = null) { - $name = $this->table->getAlias($record->getTable()->getComponentName()); + public function addReference(Doctrine_Record $record, Doctrine_Relation $connector, $key = null) { + $alias = $connector->getAlias(); - $this->references[$name]->add($record, $key); - $this->originals[$name]->add($record, $key); + $this->references[$alias]->add($record, $key); + $this->originals[$alias]->add($record, $key); } /** * getReferences diff --git a/Doctrine/Relation.php b/Doctrine/Relation.php index 3b526da12..c414a89f5 100644 --- a/Doctrine/Relation.php +++ b/Doctrine/Relation.php @@ -57,11 +57,12 @@ class Doctrine_Relation { * @param integer $type * @param string $alias */ - public function __construct(Doctrine_Table $table, $local, $foreign, $type) { + public function __construct(Doctrine_Table $table, $local, $foreign, $type, $alias) { $this->table = $table; $this->local = $local; $this->foreign = $foreign; $this->type = $type; + $this->alias = $alias; } /** * @return string the relation alias diff --git a/Doctrine/Table.php b/Doctrine/Table.php index e97a9d7fc..e47867eb6 100644 --- a/Doctrine/Table.php +++ b/Doctrine/Table.php @@ -538,7 +538,7 @@ class Doctrine_Table extends Doctrine_Configurable { if( ! isset($local)) $local = $table->getIdentifier(); - $relation = new Doctrine_LocalKey($table,$foreign,$local,$type); + $relation = new Doctrine_LocalKey($table,$foreign,$local,$type, $alias); } else throw new Doctrine_Mapping_Exception("Only one-to-one relations are possible when local reference key is used."); @@ -547,7 +547,7 @@ class Doctrine_Table extends Doctrine_Configurable { $local = $this->identifier; // ONE-TO-MANY or ONE-TO-ONE - $relation = new Doctrine_ForeignKey($table,$local,$foreign,$type); + $relation = new Doctrine_ForeignKey($table, $local, $foreign, $type, $alias); } else { // MANY-TO-MANY @@ -578,14 +578,14 @@ class Doctrine_Table extends Doctrine_Configurable { if(count($fields) > 1) { // SELF-REFERENCING THROUGH JOIN TABLE - $this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$fields[0],Doctrine_Relation::MANY_COMPOSITE); + $this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$fields[0],Doctrine_Relation::MANY_COMPOSITE, $e2[0]); - $relation = new Doctrine_Association($table,$associationTable,$fields[0],$fields[1],$type); + $relation = new Doctrine_Association($table,$associationTable,$fields[0],$fields[1], $type, $alias); } else { // NORMAL MANY-TO-MANY RELATIONSHIP - $this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE); + $this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE, $e2[0]); - $relation = new Doctrine_Association($table,$associationTable,$e2[1],$foreign,$type); + $relation = new Doctrine_Association($table, $associationTable, $e2[1], $foreign, $type, $alias); } } diff --git a/tests/QueryTestCase.php b/tests/QueryTestCase.php index e06855c61..9366dad05 100644 --- a/tests/QueryTestCase.php +++ b/tests/QueryTestCase.php @@ -5,6 +5,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->tables[] = "Forum_Entry"; $this->tables[] = "Forum_Board"; $this->tables[] = "Forum_Thread"; + $this->tables[] = "ORM_TestEntry"; $this->tables[] = "ORM_TestItem"; $this->tables[] = "Log_Status"; @@ -13,48 +14,17 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { try { $this->dbh->query("DROP TABLE test_items"); } catch(PDOException $e) { - + } try { $this->dbh->query("DROP TABLE test_entries"); } catch(PDOException $e) { - - } + + } parent::prepareTables(); + } - public function testGetPath() { - $this->query->from("User.Group.Email"); - - $this->assertEqual($this->query->getTableAlias("User"), "entity"); - $this->assertEqual($this->query->getTableAlias("User.Group"), "entity2"); - - - $this->query->from("Task.Subtask.Subtask"); - $this->assertEqual($this->query->getTableAlias("Task"), "task"); - $this->assertEqual($this->query->getTableAlias("Task.Subtask"), "task2"); - $this->assertEqual($this->query->getTableAlias("Task.Subtask.Subtask"), "task3"); - } - - public function testMultiComponentFetching2() { - $this->session->clear(); - - $query = new Doctrine_Query($this->session); - - $query->from("User.Email, User.Phonenumber"); - - - $users = $query->execute(); - - $count = count($this->dbh); - - $this->assertEqual($users->count(), 8); - $this->assertTrue($users[0]->Email instanceof Email); - $this->assertEqual($users[0]->Phonenumber->count(), 1); - $this->assertEqual($count, count($this->dbh)); - } - - public function testSelfReferencing() { $category = new Forum_Category(); @@ -81,6 +51,56 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $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]; + + $this->assertEqual($category->name, "Root"); + $this->assertEqual($category->Subcategory[0]->name, "Sub 1"); + $this->assertEqual($category->Subcategory[1]->name, "Sub 2"); + $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)); + } + + public function testGetPath() { + $this->query->from("User.Group.Email"); + + $this->assertEqual($this->query->getTableAlias("User"), "entity"); + $this->assertEqual($this->query->getTableAlias("User.Group"), "entity2"); + + + $this->query->from("Task.Subtask.Subtask"); + $this->assertEqual($this->query->getTableAlias("Task"), "task"); + $this->assertEqual($this->query->getTableAlias("Task.Subtask"), "task2"); + $this->assertEqual($this->query->getTableAlias("Task.Subtask.Subtask"), "task3"); + + + $this->assertEqual($this->query->getQuery(), + "SELECT task.id AS task__id, task.name AS task__name, task.parent_id AS task__parent_id, task2.id AS task2__id, task2.name AS task2__name, task2.parent_id AS task2__parent_id, task3.id AS task3__id, task3.name AS task3__name, task3.parent_id AS task3__parent_id FROM task LEFT JOIN task AS task2 ON task.id = task2.parent_id LEFT JOIN task AS task3 ON task2.id = task3.parent_id"); + } + + public function testMultiComponentFetching2() { + $this->session->clear(); + + $query = new Doctrine_Query($this->session); + + $query->from("User.Email, User.Phonenumber"); + + + $users = $query->execute(); + + $count = count($this->dbh); + + $this->assertEqual($users->count(), 8); + $this->assertTrue($users[0]->Email instanceof Email); + $this->assertEqual($users[0]->Phonenumber->count(), 1); + $this->assertEqual($count, count($this->dbh)); } public function testHaving() {