Preliminary support for join table self-referencing
This commit is contained in:
parent
90d34063af
commit
c9e345d4ac
@ -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);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user