Doctrine_Collection::loadRelated() bug fixed
This commit is contained in:
parent
d6eb961c0c
commit
bce726d66c
@ -40,18 +40,19 @@ class Doctrine_Association extends Doctrine_Relation {
|
||||
* @return string
|
||||
*/
|
||||
public function getRelationDql($count, $context = 'record') {
|
||||
switch($context):
|
||||
case "record":
|
||||
$sub = "SELECT ".$this->foreign.
|
||||
" FROM ".$this->associationTable->getTableName().
|
||||
" WHERE ".$this->local.
|
||||
" IN (".substr(str_repeat("?, ", $count),0,-2).")";
|
||||
|
||||
switch($context):
|
||||
case "record":
|
||||
$dql = "FROM ".$this->table->getComponentName();
|
||||
$dql .= ":".$this->associationTable->getComponentName();
|
||||
$dql .= " WHERE ".$this->table->getComponentName().".".$this->table->getIdentifier()." IN ($sub)";
|
||||
break;
|
||||
case "collection":
|
||||
$sub = substr(str_repeat("?, ", $count),0,-2);
|
||||
$dql = "FROM ".$this->associationTable->getComponentName().".".$this->table->getComponentName();
|
||||
$dql .= " WHERE ".$this->associationTable->getComponentName().".".$this->local." IN ($sub)";
|
||||
endswitch;
|
||||
|
@ -624,10 +624,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
$list[] = $value;
|
||||
endforeach;
|
||||
}
|
||||
$rel = $this->table->getRelation($name);
|
||||
$this->table->getRelation($name);
|
||||
$dql = $rel->getRelationDql(count($list), 'collection');
|
||||
|
||||
$coll = $query->query($dql, $list);
|
||||
|
||||
$this->populateRelated($name, $coll);
|
||||
}
|
||||
/**
|
||||
@ -671,6 +672,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
} elseif($rel instanceof Doctrine_Association) {
|
||||
$identifier = $this->table->getIdentifier();
|
||||
$asf = $rel->getAssociationFactory();
|
||||
$name = $table->getComponentName();
|
||||
|
||||
foreach($this->data as $key => $record) {
|
||||
if($record->getState() == Doctrine_Record::STATE_TCLEAN ||
|
||||
@ -680,6 +682,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
$sub = new Doctrine_Collection($table);
|
||||
foreach($coll as $k => $related) {
|
||||
if($related->get($local) == $record[$identifier]) {
|
||||
|
||||
$sub->add($related->get($name));
|
||||
}
|
||||
}
|
||||
|
@ -331,6 +331,11 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
|
||||
if($needsSubQuery) {
|
||||
$subquery = $this->connection->modifyLimitQuery($subquery,$this->parts["limit"],$this->parts["offset"]);
|
||||
$dbh = $this->connection->getDBH();
|
||||
|
||||
// mysql doesn't support LIMIT in subqueries
|
||||
if($dbh->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { }
|
||||
//$dbh->query();
|
||||
|
||||
$field = $table->getTableName().'.'.$table->getIdentifier();
|
||||
array_unshift($this->parts['where'], $field.' IN ('.$subquery.')');
|
||||
@ -804,6 +809,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
|
||||
return $func;
|
||||
} else {
|
||||
|
||||
return $func;
|
||||
}
|
||||
}
|
||||
@ -816,7 +822,9 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
|
||||
$exploded = Doctrine_Query::bracketExplode($string, ',');
|
||||
foreach($exploded as $k => $value) {
|
||||
$exploded[$k] = $this->parseAggregateFunction($value, $currPath);
|
||||
$func = $this->parseAggregateFunction($value, $currPath);
|
||||
$exploded[$k] = $func;
|
||||
|
||||
$this->parts["select"][] = $exploded[$k];
|
||||
}
|
||||
}
|
||||
|
@ -1302,6 +1302,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
}
|
||||
/**
|
||||
* merge
|
||||
* merges this record with an array of values
|
||||
*
|
||||
* @param array $values
|
||||
*/
|
||||
|
@ -52,7 +52,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable {
|
||||
*/
|
||||
private $identifier;
|
||||
/**
|
||||
* @var integer $identifierType
|
||||
* @see Doctrine_Identifier constants
|
||||
* @var integer $identifierType the type of identifier this table uses
|
||||
*/
|
||||
private $identifierType;
|
||||
/**
|
||||
@ -623,6 +624,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable {
|
||||
|
||||
$relation = new Doctrine_Association($table,$associationTable,$fields[0],$fields[1], $type, $alias);
|
||||
} else {
|
||||
|
||||
// auto initialize a new one-to-one relationship for association table
|
||||
$associationTable->bind($this->getComponentName(), $associationTable->getComponentName().'.'.$e2[1], Doctrine_Relation::ONE_AGGREGATE, 'id');
|
||||
$associationTable->bind($table->getComponentName(), $associationTable->getComponentName().'.'.$foreign, Doctrine_Relation::ONE_AGGREGATE, 'id');
|
||||
|
||||
// NORMAL MANY-TO-MANY RELATIONSHIP
|
||||
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE, $e2[0]);
|
||||
|
||||
@ -633,7 +639,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable {
|
||||
$this->relations[$alias] = $relation;
|
||||
return $this->relations[$alias];
|
||||
}
|
||||
throw new Doctrine_Table_Exception('Unknown relation '.$original);
|
||||
throw new Doctrine_Table_Exception($this->name . " doesn't have a relation to " . $original);
|
||||
}
|
||||
/**
|
||||
* returns an array containing all foreign key objects
|
||||
|
@ -1,49 +1,5 @@
|
||||
<?php
|
||||
class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
|
||||
public function testLoadRelatedForNormalAssociation() {
|
||||
$resource = new Doctrine_Collection('Resource');
|
||||
$resource[0]->name = 'resource 1';
|
||||
$resource[0]->Type[0]->type = 'type 1';
|
||||
$resource[0]->Type[1]->type = 'type 2';
|
||||
$resource[1]->name = 'resource 2';
|
||||
$resource[1]->Type[0]->type = 'type 3';
|
||||
$resource[1]->Type[1]->type = 'type 4';
|
||||
|
||||
$resource->save();
|
||||
|
||||
$this->connection->clear();
|
||||
|
||||
$resources = $this->connection->query('FROM Resource');
|
||||
|
||||
$count = $this->dbh->count();
|
||||
$resources->loadRelated('Type');
|
||||
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
$this->assertEqual($resources[0]->name, 'resource 1');
|
||||
$this->assertEqual($resource[0]->Type[0]->type, 'type 1');
|
||||
$this->assertEqual($resource[0]->Type[1]->type, 'type 2');
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
|
||||
$this->assertEqual($resource[1]->name, 'resource 2');
|
||||
$this->assertEqual($resource[1]->Type[0]->type, 'type 3');
|
||||
$this->assertEqual($resource[1]->Type[1]->type, 'type 4');
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
}
|
||||
public function testAdd() {
|
||||
$coll = new Doctrine_Collection($this->objTable);
|
||||
$coll->add(new User());
|
||||
$this->assertEqual($coll->count(),1);
|
||||
$coll->add(new User());
|
||||
$this->assertTrue($coll->count(),2);
|
||||
|
||||
$this->assertEqual($coll->getKeys(), array(0,1));
|
||||
|
||||
$coll[2] = new User();
|
||||
|
||||
$this->assertTrue($coll->count(),3);
|
||||
$this->assertEqual($coll->getKeys(), array(0,1,2));
|
||||
}
|
||||
|
||||
public function testLoadRelatedForAssociation() {
|
||||
$coll = $this->connection->query("FROM User");
|
||||
|
||||
@ -98,6 +54,53 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
|
||||
|
||||
$this->connection->clear();
|
||||
}
|
||||
|
||||
public function testLoadRelatedForNormalAssociation() {
|
||||
$resource = new Doctrine_Collection('Resource');
|
||||
$resource[0]->name = 'resource 1';
|
||||
$resource[0]->Type[0]->type = 'type 1';
|
||||
$resource[0]->Type[1]->type = 'type 2';
|
||||
$resource[1]->name = 'resource 2';
|
||||
$resource[1]->Type[0]->type = 'type 3';
|
||||
$resource[1]->Type[1]->type = 'type 4';
|
||||
|
||||
$resource->save();
|
||||
|
||||
$this->connection->clear();
|
||||
|
||||
$resources = $this->connection->query('FROM Resource');
|
||||
|
||||
$count = $this->dbh->count();
|
||||
$resources->loadRelated('Type');
|
||||
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
$this->assertEqual($resources[0]->name, 'resource 1');
|
||||
$this->assertEqual($resource[0]->Type[0]->type, 'type 1');
|
||||
$this->assertEqual($resource[0]->Type[1]->type, 'type 2');
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
|
||||
$this->assertEqual($resource[1]->name, 'resource 2');
|
||||
$this->assertEqual($resource[1]->Type[0]->type, 'type 3');
|
||||
$this->assertEqual($resource[1]->Type[1]->type, 'type 4');
|
||||
$this->assertEqual(($count + 1), $this->dbh->count());
|
||||
}
|
||||
|
||||
public function testAdd() {
|
||||
$coll = new Doctrine_Collection($this->objTable);
|
||||
$coll->add(new User());
|
||||
$this->assertEqual($coll->count(),1);
|
||||
$coll->add(new User());
|
||||
$this->assertTrue($coll->count(),2);
|
||||
|
||||
$this->assertEqual($coll->getKeys(), array(0,1));
|
||||
|
||||
$coll[2] = new User();
|
||||
|
||||
$this->assertTrue($coll->count(),3);
|
||||
$this->assertEqual($coll->getKeys(), array(0,1,2));
|
||||
}
|
||||
|
||||
|
||||
public function testLoadRelated() {
|
||||
$coll = $this->connection->query("FROM User(id)");
|
||||
|
||||
@ -269,5 +272,6 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
|
||||
$this->assertEqual($users[4]->Phonenumber[1]->exists(), false);
|
||||
$this->assertEqual($users[4]->Phonenumber[2]->getState(), Doctrine_Record::STATE_CLEAN);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
@ -5,6 +5,16 @@ class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase {
|
||||
public function testBuildFlushTree() {
|
||||
$correct = array("Task","ResourceType","Resource","Assignment","ResourceReference");
|
||||
|
||||
// new model might switch some many-to-many components (NO HARM!)
|
||||
|
||||
$correct2 = array (
|
||||
0 => 'Resource',
|
||||
1 => 'Task',
|
||||
2 => 'ResourceType',
|
||||
3 => 'Assignment',
|
||||
4 => 'ResourceReference',
|
||||
);
|
||||
|
||||
$task = new Task();
|
||||
|
||||
$tree = $this->connection->buildFlushTree(array("Task"));
|
||||
@ -17,7 +27,8 @@ class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase {
|
||||
$this->assertEqual($tree,$correct);
|
||||
|
||||
$tree = $this->connection->buildFlushTree(array("Assignment","Task","Resource"));
|
||||
$this->assertEqual($tree,$correct);
|
||||
|
||||
$this->assertEqual($tree,$correct2);
|
||||
|
||||
|
||||
$correct = array("Forum_Category","Forum_Board","Forum_Thread");
|
||||
|
@ -7,57 +7,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
|
||||
$this->tables[] = "enumTest";
|
||||
parent::prepareTables();
|
||||
}
|
||||
public function testToArray() {
|
||||
$user = new User();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], null);
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertEqual($a['id'], null);
|
||||
|
||||
$user->name = 'Someone';
|
||||
|
||||
$user->save();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertEqual($a['id'], 12);
|
||||
|
||||
$user->refresh();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertEqual($a['id'], 12);
|
||||
$this->connection->clear();
|
||||
$user = $user->getTable()->find($user->id);
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertEqual($a['id'], 12);
|
||||
}
|
||||
|
||||
public function testReferences2() {
|
||||
$user = new User();
|
||||
$user->Phonenumber[0]->phonenumber = '123 123';
|
||||
$this->assertEqual($user->Phonenumber[0]->entity_id, $user);
|
||||
}
|
||||
|
||||
public function testJoinTableSelfReferencing() {
|
||||
public function testJoinTableSelfReferencingInsertingData() {
|
||||
$e = new Entity();
|
||||
$e->name = "Entity test";
|
||||
$this->assertTrue($e->Entity[0] instanceof Entity);
|
||||
@ -112,22 +62,55 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
|
||||
|
||||
$this->assertTrue(is_numeric($e->id));
|
||||
|
||||
$result = $this->dbh->query("SELECT * FROM entity_reference")->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$this->assertEqual(count($result), 6);
|
||||
|
||||
$q = "SELECT entity.id AS entity__id,
|
||||
entity.name AS entity__name,
|
||||
entity.loginname AS entity__loginname,
|
||||
entity.password AS entity__password,
|
||||
entity.type AS entity__type,
|
||||
entity.created AS entity__created,
|
||||
entity.updated AS entity__updated,
|
||||
entity.email_id AS entity__email_id,
|
||||
entity_reference.entity1 AS entity_reference__entity1,
|
||||
entity_reference.entity2 AS entity_reference__entity2
|
||||
FROM entity
|
||||
INNER JOIN entity_reference
|
||||
ON entity.id = entity_reference.entity1
|
||||
WHERE entity.id IN (SELECT entity2 FROM entity_reference WHERE entity1 IN (?))";
|
||||
$stmt = $this->dbh->prepare($q);
|
||||
|
||||
$stmt->execute(array(18));
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$this->connection->clear();
|
||||
|
||||
$e = $e->getTable()->find($e->id);
|
||||
|
||||
$count = count($this->dbh);
|
||||
|
||||
$this->assertTrue($e instanceof Entity);
|
||||
|
||||
$this->assertTrue($e->Entity[0] instanceof Entity);
|
||||
$this->assertTrue($e->Entity[1] instanceof Entity);
|
||||
|
||||
$this->assertEqual(count($this->dbh), ($count + 1));
|
||||
|
||||
$this->assertEqual($e->Entity[0]->name, "Friend 1");
|
||||
$this->assertEqual($e->Entity[1]->name, "Friend 2");
|
||||
|
||||
$this->assertEqual($e->Entity[0]->Entity[0]->name, "Friend 1 1");
|
||||
$this->assertEqual($e->Entity[0]->Entity[1]->name, "Friend 1 2");
|
||||
|
||||
$this->assertEqual(count($this->dbh), ($count + 2));
|
||||
|
||||
$this->assertEqual($e->Entity[1]->Entity[0]->name, "Friend 2 1");
|
||||
$this->assertEqual($e->Entity[1]->Entity[1]->name, "Friend 2 2");
|
||||
|
||||
$this->assertEqual(count($this->dbh), ($count + 3));
|
||||
|
||||
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
|
||||
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
|
||||
|
||||
@ -145,6 +128,58 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
|
||||
|
||||
$this->assertEqual($coll->count(), 1);
|
||||
}
|
||||
/**
|
||||
public function testToArray() {
|
||||
$user = new User();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], null);
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertEqual($a['id'], null);
|
||||
|
||||
$user->name = 'Someone';
|
||||
|
||||
$user->save();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertTrue(is_numeric($a['id']));
|
||||
|
||||
$user->refresh();
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertTrue(is_numeric($a['id']));
|
||||
$this->connection->clear();
|
||||
$user = $user->getTable()->find($user->id);
|
||||
|
||||
$a = $user->toArray();
|
||||
|
||||
$this->assertTrue(is_array($a));
|
||||
$this->assertTrue(array_key_exists('name', $a));
|
||||
$this->assertEqual($a['name'], 'Someone');
|
||||
$this->assertTrue(array_key_exists('id', $a));
|
||||
$this->assertTrue(is_numeric($a['id']));
|
||||
}
|
||||
|
||||
public function testReferences2() {
|
||||
$user = new User();
|
||||
$user->Phonenumber[0]->phonenumber = '123 123';
|
||||
$this->assertEqual($user->Phonenumber[0]->entity_id, $user);
|
||||
}
|
||||
|
||||
|
||||
public function testCountRelated() {
|
||||
$user = $this->connection->getTable('Entity')->find(5);
|
||||
$c = $user->countRelated('Phonenumber');
|
||||
@ -888,6 +923,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
|
||||
$user = $this->connection->getTable("User")->find(4);
|
||||
$this->assertTrue($user->getIterator() instanceof ArrayIterator);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
?>
|
||||
|
@ -32,10 +32,10 @@ error_reporting(E_ALL);
|
||||
|
||||
$test = new GroupTest("Doctrine Framework Unit Tests");
|
||||
|
||||
$test->addTestCase(new Doctrine_TableTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_RecordTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_TableTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ConnectionTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ManagerTestCase());
|
||||
@ -62,8 +62,6 @@ $test->addTestCase(new Doctrine_Filter_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ValueHolder_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_QueryTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_RawSql_TestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_Query_Limit_TestCase());
|
||||
@ -72,9 +70,14 @@ $test->addTestCase(new Doctrine_SchemaTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ImportTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ValidatorTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_QueryTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_CollectionTestCase());
|
||||
|
||||
$test->addTestCase(new Doctrine_ValidatorTestCase());
|
||||
|
||||
|
||||
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
||||
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user