1
0
mirror of synced 2024-12-13 06:46:03 +03:00

Doctrine_Collection::loadRelated() bug fixed

This commit is contained in:
zYne 2006-09-08 23:20:51 +00:00
parent d6eb961c0c
commit bce726d66c
9 changed files with 186 additions and 114 deletions

View File

@ -39,19 +39,20 @@ class Doctrine_Association extends Doctrine_Relation {
* @param integer $count
* @return string
*/
public function getRelationDql($count, $context = 'record') {
$sub = "SELECT ".$this->foreign.
" FROM ".$this->associationTable->getTableName().
" WHERE ".$this->local.
" IN (".substr(str_repeat("?, ", $count),0,-2).")";
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).")";
$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;

View File

@ -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));
}
}

View File

@ -331,7 +331,12 @@ 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.')');
$modifyLimit = false;
@ -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];
}
}

View File

@ -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
*/

View File

@ -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

View File

@ -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);
}
}
?>

View File

@ -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");

View File

@ -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);
@ -109,15 +59,44 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$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");
@ -125,9 +104,13 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$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);
}
*/
}
?>

View File

@ -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());