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

Preliminary support for join table self-referencing

This commit is contained in:
doctrine 2006-05-17 09:37:41 +00:00
parent 90d34063af
commit c9e345d4ac
6 changed files with 98 additions and 18 deletions

View File

@ -3,8 +3,8 @@
* thrown when user tries to get a foreign key object but the mapping is not done right
*/
class Doctrine_Mapping_Exception extends Doctrine_Exception {
public function __construct() {
parent::__construct("An error occured in the mapping logic.",Doctrine::ERR_MAPPING);
public function __construct($message = "An error occured in the mapping logic.") {
parent::__construct($message,Doctrine::ERR_MAPPING);
}
}
?>

View File

@ -319,10 +319,17 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* @return boolean
*/
final public function refresh() {
if($this->getID() == null) return false;
$id = $this->getID();
if( ! is_array($id))
$id = array($id);
if(empty($id))
return false;
$id = array_values($id);
$query = $this->table->getQuery()." WHERE ".implode(" = ? && ",$this->table->getPrimaryKeys())." = ?";
$this->data = $this->table->getSession()->execute($query,array($this->getID()))->fetch(PDO::FETCH_ASSOC);
$this->data = $this->table->getSession()->execute($query,$id)->fetch(PDO::FETCH_ASSOC);
$this->modified = array();
$this->cleanData();

View File

@ -333,8 +333,9 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
* @return void
*/
public function clear() {
foreach($this->tables as $k => $objTable) {
$objTable->getRepository()->evictAll();
foreach($this->tables as $k => $table) {
$table->getRepository()->evictAll();
$table->clear();
}
$this->tables = array();
}

View File

@ -451,9 +451,7 @@ class Doctrine_Table extends Doctrine_Configurable {
if(isset($this->bound[$name])) {
$type = $this->bound[$name][1];
$local = $this->bound[$name][2];
$e = explode(".",$this->bound[$name][0]);
$component = $e[0];
$foreign = $e[1];
list($component, $foreign) = explode(".",$this->bound[$name][0]);
$alias = $name;
$name = $this->bound[$alias][3];
@ -469,7 +467,7 @@ class Doctrine_Table extends Doctrine_Configurable {
$relation = new Doctrine_LocalKey($table,$foreign,$local,$type);
} else
throw new Doctrine_Mapping_Exception();
throw new Doctrine_Mapping_Exception("Only one-to-one relations are possible when local reference key is used.");
} elseif($component == $name || ($component == $alias && $name == $this->name)) {
if( ! isset($local))
@ -483,31 +481,39 @@ class Doctrine_Table extends Doctrine_Configurable {
// only aggregate relations allowed
if($type != Doctrine_Relation::MANY_AGGREGATE)
throw new Doctrine_Mapping_Exception();
throw new Doctrine_Mapping_Exception("Only aggregate relations are allowed for many-to-many relations");
$classes = array_merge($this->parents, array($this->name));
foreach($classes as $class) {
foreach(array_reverse($classes) as $class) {
try {
$bound = $table->getBoundForName($class);
break;
} catch(InvalidKeyException $exc) {
} catch(InvalidKeyException $exc) { }
}
}
if( ! isset($local))
$local = $this->identifier;
$e2 = explode(".",$bound[0]);
$fields = explode("-",$e2[1]);
if($e2[0] != $component)
throw new Doctrine_Mapping_Exception();
throw new Doctrine_Mapping_Exception($e2[0]." doesn't match ".$component);
$associationTable = $this->session->getTable($e2[0]);
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE);
if(count($fields) > 1) {
// SELF-REFERENCING THROUGH JOIN TABLE
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$fields[0],Doctrine_Relation::MANY_COMPOSITE);
$relation = new Doctrine_Association($table,$associationTable,$fields[0],$fields[1],$type);
} else {
// NORMAL MANY-TO-MANY RELATIONSHIP
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE);
$relation = new Doctrine_Association($table,$associationTable,$e2[1],$foreign,$type);
$relation = new Doctrine_Association($table,$associationTable,$e2[1],$foreign,$type);
}
}
$this->relations[$alias] = $relation;

View File

@ -2,6 +2,52 @@
require_once("UnitTestCase.class.php");
class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
public function testJoinTableSelfReferencing() {
$e = new Entity();
$e->name = "Entity test";
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TCLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TCLEAN);
$e->Entity[0]->name = "Subentity 1";
$e->Entity[1]->name = "Subentity 2";
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TDIRTY);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TDIRTY);
$e->save();
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$e = $e->getTable()->find($e->getID());
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$coll = $this->session->query("FROM Entity WHERE Entity.name = 'Subentity 1'");
$this->assertEqual($coll->count(), 1);
$this->assertEqual($coll[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($coll[0]->name, "Subentity 1");
}
public function testCompositePK() {
$record = new EntityReference();
@ -48,6 +94,26 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->getID(), array("entity1" => 2, "entity2" => 5));
$record->refresh();
$this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->getID(), array("entity1" => 2, "entity2" => 5));
$record = new EntityReference();
$record->entity2 = 6;
$record->entity1 = 2;
$record->save();
$coll = $this->session->query("FROM EntityReference-b");
$this->assertTrue($coll[0] instanceof EntityReference);
$this->assertEqual($coll[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertTrue($coll[1] instanceof EntityReference);
$this->assertEqual($coll[1]->getState(), Doctrine_Record::STATE_CLEAN);
$coll = $this->session->query("FROM EntityReference-b WHERE EntityReference.entity2 = 5");
$this->assertEqual($coll->count(), 1);
}
@ -605,6 +671,5 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$user = $this->session->getTable("User")->find(4);
$this->assertTrue($user->getIterator() instanceof ArrayIterator);
}
}
?>

View File

@ -4,6 +4,7 @@ class Entity extends Doctrine_Record {
$this->ownsOne("Email","Entity.email_id");
$this->ownsMany("Phonenumber","Phonenumber.entity_id");
$this->ownsOne("Account","Account.entity_id");
$this->hasMany("Entity","EntityReference.entity1-entity2");
}
public function setTableDefinition() {
$this->hasColumn("id","integer",20,"autoincrement|primary");