diff --git a/classes/DB.class.php b/classes/DB.class.php index 6345907d1..d45ff3e10 100644 --- a/classes/DB.class.php +++ b/classes/DB.class.php @@ -128,7 +128,7 @@ class Doctrine_DBStatement extends PDOStatement { /** * @param array $params */ - public function execute($params) { + public function execute(array $params = null) { $time = microtime(); $result = parent::execute($params); diff --git a/classes/Identifier.class.php b/classes/Identifier.class.php index 6b30fba5d..9bcc3a20b 100644 --- a/classes/Identifier.class.php +++ b/classes/Identifier.class.php @@ -16,5 +16,9 @@ class Doctrine_Identifier { * constant for normal identifier */ const NORMAL = 3; + /** + * constant for composite identifier + */ + const COMPOSITE = 4; } ?> diff --git a/classes/Record.class.php b/classes/Record.class.php index 61d96d73a..94df3e2c1 100644 --- a/classes/Record.class.php +++ b/classes/Record.class.php @@ -127,26 +127,25 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite // clean data array $cols = $this->cleanData(); - + + $this->prepareIdentifiers($exists); + if( ! $exists) { - if($cols > 0) $this->state = Doctrine_Record::STATE_TDIRTY; else $this->state = Doctrine_Record::STATE_TCLEAN; - - - + // listen the onCreate event $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onCreate($this); + } else { - $this->state = Doctrine_Record::STATE_CLEAN; + $this->state = Doctrine_Record::STATE_CLEAN; if($cols <= 1) $this->state = Doctrine_Record::STATE_PROXY; - $this->prepareIdentifiers(); // listen the onLoad event $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); @@ -200,16 +199,26 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * * @return void */ - public function prepareIdentifiers() { + private function prepareIdentifiers($exists = true) { switch($this->table->getIdentifierType()): case Doctrine_Identifier::AUTO_INCREMENT: case Doctrine_Identifier::SEQUENCE: - $name = $this->table->getIdentifier(); + if($exists) { + $name = $this->table->getIdentifier(); + + if(isset($this->data[$name])) + $this->id = $this->data[$name]; + + unset($this->data[$name]); + } + break; + case Doctrine_Identifier::COMPOSITE: + $names = $this->table->getIdentifier(); + $this->id = array(); - if(isset($this->data[$name])) - $this->id = $this->data[$name]; - - unset($this->data[$name]); + foreach($names as $name) { + $this->id[$name] = isset($this->data[$name])?$this->data[$name]:null; + } break; endswitch; } @@ -603,10 +612,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite */ final public function saveAssociations() { foreach($this->table->getForeignKeys() as $fk): - $table = $fk->getTable(); + $table = $fk->getTable(); $name = $table->getComponentName(); - - + $alias = $this->table->getAlias($name); + if($fk instanceof Doctrine_Association) { switch($fk->getType()): case Doctrine_Relation::MANY_COMPOSITE: @@ -614,15 +623,16 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite break; case Doctrine_Relation::MANY_AGGREGATE: $asf = $fk->getAssociationFactory(); - if(isset($this->references[$name])) { - $new = $this->references[$name]; + if(isset($this->references[$alias])) { - if( ! isset($this->originals[$name])) { - $this->loadReference($name); + $new = $this->references[$alias]; + + if( ! isset($this->originals[$alias])) { + $this->loadReference($alias); } - $r = $this->getRelationOperations($name,$new); + $r = $this->getRelationOperations($alias,$new); foreach($r["delete"] as $record) { $query = "DELETE FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." = ?" @@ -635,7 +645,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $reldao->set($fk->getLocal(),$this); $reldao->save(); } - $this->originals[$name] = clone $this->references[$name]; + $this->originals[$alias] = clone $this->references[$alias]; } break; endswitch; @@ -644,24 +654,24 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite switch($fk->getType()): case Doctrine_Relation::ONE_COMPOSITE: - if(isset($this->originals[$name]) && $this->originals[$name]->getID() != $this->references[$name]->getID()) - $this->originals[$name]->delete(); + if(isset($this->originals[$alias]) && $this->originals[$alias]->getID() != $this->references[$alias]->getID()) + $this->originals[$alias]->delete(); break; case Doctrine_Relation::MANY_COMPOSITE: - if(isset($this->references[$name])) { - $new = $this->references[$name]; + if(isset($this->references[$alias])) { + $new = $this->references[$alias]; - if( ! isset($this->originals[$name])) - $this->loadReference($name); + if( ! isset($this->originals[$alias])) + $this->loadReference($alias); - $r = $this->getRelationOperations($name,$new); + $r = $this->getRelationOperations($alias,$new); foreach($r["delete"] as $record) { $record->delete(); } - $this->originals[$name] = clone $this->references[$name]; + $this->originals[$alias] = clone $this->references[$alias]; } break; endswitch; @@ -675,7 +685,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite * * The algorithm here is very simple and definitely not * the fastest one, since we have to iterate through the collections twice. - * the complexity of this algorithm is O(2*n^2) + * the complexity of this algorithm is O(n^2) * * First we iterate through the new collection and get the * records that do not exist in the old collection (Doctrine_Records that need to be added). @@ -764,6 +774,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->cleanData(); $this->state = Doctrine_Record::STATE_TCLEAN; $this->modified = array(); + } elseif($id === true) { + $this->prepareIdentifiers(false); + $this->state = Doctrine_Record::STATE_CLEAN; + $this->modified = array(); } else { $this->id = $id; $this->state = Doctrine_Record::STATE_CLEAN; @@ -771,8 +785,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } } /** - * return the primary key this object is pointing at - * @return int id + * return the primary key(s) this object is pointing at + * @return mixed id */ final public function getID() { return $this->id; @@ -916,6 +930,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } /** + * binds One-to-One composite relation + * * @param string $objTableName * @param string $fkField * @return void @@ -924,6 +940,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_COMPOSITE, $localKey); } /** + * binds One-to-Many composite relation + * * @param string $objTableName * @param string $fkField * @return void @@ -932,6 +950,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->table->bind($componentName,$foreignKey,Doctrine_Relation::MANY_COMPOSITE, $localKey); } /** + * binds One-to-One aggregate relation + * * @param string $objTableName * @param string $fkField * @return void @@ -940,6 +960,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite $this->table->bind($componentName,$foreignKey,Doctrine_Relation::ONE_AGGREGATE, $localKey); } /** + * binds One-to-Many aggregate relation + * * @param string $objTableName * @param string $fkField * @return void @@ -957,7 +979,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } /** * setPrimaryKey - * @param string $key + * @param mixed $key */ final public function setPrimaryKey($key) { $this->table->setPrimaryKey($key); @@ -982,6 +1004,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } /** * hasColumn + * sets a column definition + * * @param string $name * @param string $type * @param integer $length diff --git a/classes/Sensei/Sensei.class.php b/classes/Sensei/Sensei.class.php index bd90350f6..44cf0cf46 100644 --- a/classes/Sensei/Sensei.class.php +++ b/classes/Sensei/Sensei.class.php @@ -155,6 +155,12 @@ class Sensei extends Doctrine_Access { return false; } } + /** + * returns a session variable + * + * @param mixed $name + * @return mixed + */ public function get($name) { foreach($this->vars as $var) { if($var->name == $name) { @@ -162,6 +168,14 @@ class Sensei extends Doctrine_Access { } } } + /** + * sets a session variable + * returns true on success, false on failure + * + * @param mixed $name + * @param mixed $value + * @return boolean + */ public function set($name,$value) { foreach($this->vars as $var) { if($var->name == $name) { diff --git a/classes/Session.class.php b/classes/Session.class.php index b8e268744..a92bbca73 100644 --- a/classes/Session.class.php +++ b/classes/Session.class.php @@ -41,7 +41,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab private $transaction_level = 0; /** - * @var PDO $cacheHandler + * @var PDO $cacheHandler cache handler */ private $cacheHandler; /** @@ -328,7 +328,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab } /** * clear - * clears the whole registry + * clears all repositories * * @return void */ @@ -341,6 +341,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab /** * close * closes the session + * * @return void */ public function close() { @@ -353,7 +354,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab } /** * get the current transaction nesting level - * @return integer transaction nesting level + * + * @return integer */ public function getTransactionLevel() { return $this->transaction_level; @@ -471,16 +473,17 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab $this->insert($record); - - if($increment && $k == 0) { - // record uses auto_increment column + if($increment) { + if($k == 0) { + // record uses auto_increment column - $id = $table->getMaxIdentifier(); - } - - $record->setID($id); - - $id++; + $id = $table->getMaxIdentifier(); + } + + $record->setID($id); + $id++; + } else + $record->setID(true); // listen the onInsert event $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); @@ -693,14 +696,22 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab } $params = array_values($array); - $params[] = $record->getID(); + $id = $record->getID(); + + + if( ! is_array($id)) + $id = array($id); + + $id = array_values($id); + $params = array_merge($params, $id); $sql = "UPDATE ".$record->getTable()->getTableName()." SET ".implode(", ",$set)." WHERE ".implode(" = ? && ",$record->getTable()->getPrimaryKeys())." = ?"; + $stmt = $this->dbh->prepare($sql); $stmt->execute($params); - $record->setID($record->getID()); + $record->setID(true); return true; } diff --git a/classes/Table.class.php b/classes/Table.class.php index cf4c198dd..e23d7564d 100644 --- a/classes/Table.class.php +++ b/classes/Table.class.php @@ -77,6 +77,12 @@ class Doctrine_Table extends Doctrine_Configurable { * @var array $bound bound relations */ private $bound = array(); + /** + * @var array $boundAliases bound relation aliases + */ + private $boundAliases = array(); + + /** * @var array $inheritanceMap inheritanceMap is used for inheritance mapping, keys representing columns and values * the column values that should correspond to child classes @@ -144,37 +150,43 @@ class Doctrine_Table extends Doctrine_Configurable { $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; break; default: - foreach($this->primaryKeys as $pk) { - $o = $this->columns[$pk][2]; - $e = explode("|",$o); - $found = false; + if(count($this->primaryKeys) > 1) { + $this->identifier = $this->primaryKeys; + $this->identifierType = Doctrine_Identifier::COMPOSITE; + + } else { + foreach($this->primaryKeys as $pk) { + $o = $this->columns[$pk][2]; + $e = explode("|",$o); + $found = false; + - - foreach($e as $option) { - if($found) - break; - - $e2 = explode(":",$option); - - switch(strtolower($e2[0])): - case "unique": - $this->identifierType = Doctrine_Identifier::UNIQUE; - $found = true; - break; - case "autoincrement": - $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; - $found = true; - break; - case "seq": - $this->identifierType = Doctrine_Identifier::SEQUENCE; - $found = true; - break; - endswitch; + foreach($e as $option) { + if($found) + break; + + $e2 = explode(":",$option); + + switch(strtolower($e2[0])): + case "unique": + $this->identifierType = Doctrine_Identifier::UNIQUE; + $found = true; + break; + case "autoincrement": + $this->identifierType = Doctrine_Identifier::AUTO_INCREMENT; + $found = true; + break; + case "seq": + $this->identifierType = Doctrine_Identifier::SEQUENCE; + $found = true; + break; + endswitch; + } + if( ! isset($this->identifierType)) + $this->identifierType = Doctrine_Identifier::NORMAL; + + $this->identifier = $pk; } - if( ! isset($this->identifierType)) - $this->identifierType = Doctrine_Identifier::NORMAL; - - $this->identifier = $pk; } endswitch; @@ -259,6 +271,20 @@ class Doctrine_Table extends Doctrine_Configurable { final public function hasColumn($name) { return isset($this->columns[$name]); } + /** + * @param mixed $key + * @return void + */ + final public function setPrimaryKey($key) { + switch(gettype($key)): + case "array": + $this->primaryKeys = array_values($key); + break; + case "string": + $this->primaryKeys[] = $key; + break; + endswitch; + } /** * returns all primary keys * @return array @@ -348,6 +374,32 @@ class Doctrine_Table extends Doctrine_Configurable { return $this->bound[$name]; } + /** + * returns a bound relation array + * + * @param string $name + * @return array + */ + final public function getBoundForName($name) { + foreach($this->bound as $k => $bound) { + if($bound[3] == $name) { + return $this->bound[$k]; + } + } + throw new InvalidKeyException(); + } + /** + * returns the alias for given component name + * + * @param string $name + * @return string + */ + final public function getAlias($name) { + if(isset($this->boundAliases[$name])) + return $this->boundAliases[$name]; + + return $name; + } /** * @param string $name * @param string $field @@ -360,11 +412,13 @@ class Doctrine_Table extends Doctrine_Configurable { $e = explode(" as ",$name); $name = $e[0]; - if(isset($e[1])) + if(isset($e[1])) { $alias = $e[1]; - else + $this->boundAliases[$name] = $alias; + } else $alias = $name; + $this->bound[$alias] = array($field,$type,$localKey,$name); } /** @@ -395,7 +449,6 @@ class Doctrine_Table extends Doctrine_Configurable { return $this->relations[$name]; if(isset($this->bound[$name])) { - $type = $this->bound[$name][1]; $local = $this->bound[$name][2]; $e = explode(".",$this->bound[$name][0]); @@ -436,7 +489,7 @@ class Doctrine_Table extends Doctrine_Configurable { foreach($classes as $class) { try { - $bound = $table->getBound($class); + $bound = $table->getBoundForName($class); break; } catch(InvalidKeyException $exc) { @@ -517,10 +570,15 @@ class Doctrine_Table extends Doctrine_Configurable { */ public function find($id) { if($id !== null) { + if( ! is_array($id)) + $id = array($id); + else + $id = array_values($id); + $query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?"; $query = $this->applyInheritance($query); - $params = array_merge(array($id), array_values($this->inheritanceMap)); + $params = array_merge($id, array_values($this->inheritanceMap)); $this->data = $this->session->execute($query,$params)->fetch(PDO::FETCH_ASSOC); @@ -588,19 +646,28 @@ class Doctrine_Table extends Doctrine_Configurable { */ public function getRecord() { $key = $this->getIdentifier(); - if(isset($this->data[$key])) { - $id = $this->data[$key]; - if(isset($this->identityMap[$id])) - $record = $this->identityMap[$id]; - else { - $record = new $this->name($this); - $this->identityMap[$id] = $record; - } - $this->data = array(); - return $record; + if( ! is_array($key)) + $key = array($key); + + + foreach($key as $k) { + if( ! isset($this->data[$k])) + throw new Doctrine_Exception("No primary key found"); + + $id[] = $this->data[$k]; } - throw new Doctrine_Exception("No primary key found"); + $id = implode(' ', $id); + + if(isset($this->identityMap[$id])) + $record = $this->identityMap[$id]; + else { + $record = new $this->name($this); + $this->identityMap[$id] = $record; + } + $this->data = array(); + + return $record; } /** * @param $id database row id diff --git a/classes/Validator.class.php b/classes/Validator.class.php index ec563b9d4..59a7b4275 100644 --- a/classes/Validator.class.php +++ b/classes/Validator.class.php @@ -1,6 +1,11 @@ assertEqual($record->getTable()->getIdentifier(), array("entity1","entity2")); + $this->assertEqual($record->getTable()->getIdentifierType(), Doctrine_Identifier::COMPOSITE); + $this->assertEqual($record->getID(), array("entity1" => null, "entity2" => null)); + $this->assertEqual($record->getState(), Doctrine_Record::STATE_TCLEAN); + + $record->entity1 = 3; + $record->entity2 = 4; + $this->assertEqual($record->entity2, 4); + $this->assertEqual($record->entity1, 3); + $this->assertEqual($record->getState(), Doctrine_Record::STATE_TDIRTY); + $this->assertEqual($record->getID(), array("entity1" => null, "entity2" => null)); + + $record->save(); + $this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN); + $this->assertEqual($record->entity2, 4); + $this->assertEqual($record->entity1, 3); + $this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4)); + + $record = $record->getTable()->find($record->getID()); + $this->assertEqual($record->getState(), Doctrine_Record::STATE_CLEAN); + $this->assertEqual($record->entity2, 4); + $this->assertEqual($record->entity1, 3); + + $this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4)); + + $record->entity2 = 5; + $record->entity1 = 2; + $this->assertEqual($record->getState(), Doctrine_Record::STATE_DIRTY); + $this->assertEqual($record->entity2, 5); + $this->assertEqual($record->entity1, 2); + $this->assertEqual($record->getID(), array("entity1" => 3, "entity2" => 4)); + + $record->save(); + $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 = $record->getTable()->find($record->getID()); + + $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)); + } + + public function testManyToManyTreeStructure() { $task = $this->session->create("Task"); + $this->assertEqual($task->getTable()->getAlias("Resource"), "ResourceAlias"); $task->name = "Task 1"; - $task->Resource[0]->name = "Resource 1"; + $task->ResourceAlias[0]->name = "Resource 1"; $this->session->flush(); + + $this->assertTrue($task->ResourceAlias[0] instanceof Resource); + $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1"); $this->assertEqual($this->dbh->query("SELECT COUNT(*) FROM assignment")->fetch(PDO::FETCH_NUM),array(1)); $task = new Task(); @@ -18,28 +70,28 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { $this->assertTrue($task->Subtask[0] instanceof Task); $this->assertEqual($task->Subtask[0]->getState(), Doctrine_Record::STATE_TCLEAN); - $this->assertTrue($task->Resource[0] instanceof Resource); - $this->assertEqual($task->Resource[0]->getState(), Doctrine_Record::STATE_TCLEAN); + $this->assertTrue($task->ResourceAlias[0] instanceof Resource); + $this->assertEqual($task->ResourceAlias[0]->getState(), Doctrine_Record::STATE_TCLEAN); $task->name = "Task 1"; - $task->Resource[0]->name = "Resource 1"; + $task->ResourceAlias[0]->name = "Resource 1"; $task->Subtask[0]->name = "Subtask 1"; $this->assertEqual($task->name, "Task 1"); - $this->assertEqual($task->Resource[0]->name, "Resource 1"); - $this->assertEqual($task->Resource->count(), 1); + $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1"); + $this->assertEqual($task->ResourceAlias->count(), 1); $this->assertEqual($task->Subtask[0]->name, "Subtask 1"); $this->session->flush(); - + $task = $task->getTable()->find($task->getID()); $this->assertEqual($task->name, "Task 1"); - $this->assertEqual($task->Resource[0]->name, "Resource 1"); - $this->assertEqual($task->Resource->count(), 1); + $this->assertEqual($task->ResourceAlias[0]->name, "Resource 1"); + $this->assertEqual($task->ResourceAlias->count(), 1); $this->assertEqual($task->Subtask[0]->name, "Subtask 1"); - } + } public function testOne2OneForeign() { @@ -248,7 +300,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { $this->assertEqual($e->code,2); $this->assertEqual($e->message,"changed message"); $this->assertEqual($e->Description[0]->description, "1st changed description"); - $this->assertEqual($e->Description[1]->description, "2nd changed description"); + $this->assertEqual($e->Description[1]->description, "2nd changed description"); } public function testInsert() { @@ -553,5 +605,6 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { $user = $this->session->getTable("User")->find(4); $this->assertTrue($user->getIterator() instanceof ArrayIterator); } + } ?> diff --git a/tests/SenseiTestCase.class.php b/tests/SenseiTestCase.class.php index 49d8f7ef4..38ca46053 100644 --- a/tests/SenseiTestCase.class.php +++ b/tests/SenseiTestCase.class.php @@ -92,11 +92,16 @@ class Sensei_UnitTestCase extends UnitTestCase { $this->assertEqual($this->record->entity_id, 1); } + public function testLogout() { $this->assertTrue($this->sensei->logout()); $this->assertEqual($this->record->logged_in, 0); $this->assertEqual($this->record->entity_id, 0); + $this->assertEqual($this->record->getState(), Doctrine_Record::STATE_DIRTY); + $this->assertEqual($this->record->getTable()->getIdentifierType(), Doctrine_Identifier::AUTO_INCREMENT); + + $this->assertEqual($this->record->getID(), 1); $this->sensei->flush(); @@ -104,5 +109,6 @@ class Sensei_UnitTestCase extends UnitTestCase { $this->assertEqual($this->record->entity_id, 0); } + } ?> diff --git a/tests/UnitTestCase.class.php b/tests/UnitTestCase.class.php index 478299680..5e60cbfe2 100644 --- a/tests/UnitTestCase.class.php +++ b/tests/UnitTestCase.class.php @@ -31,7 +31,7 @@ class Doctrine_UnitTestCase extends UnitTestCase { $this->manager->setAttribute(Doctrine::ATTR_CACHE, Doctrine::CACHE_NONE); $this->manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE); - $this->tables = array("entity","email","phonenumber","groupuser","album","song","element","error","description","address","account","task","resource","assignment"); + $this->tables = array("entity","entityReference","email","phonenumber","groupuser","album","song","element","error","description","address","account","task","resource","assignment"); diff --git a/tests/classes.php b/tests/classes.php index 5f06b2ec5..d4e193c6e 100644 --- a/tests/classes.php +++ b/tests/classes.php @@ -16,7 +16,13 @@ class Entity extends Doctrine_Record { $this->hasColumn("email_id","integer"); } } - +class EntityReference extends Doctrine_Record { + public function setTableDefinition() { + $this->hasColumn("entity1","integer"); + $this->hasColumn("entity2","integer"); + $this->setPrimaryKey(array("entity1","entity2")); + } +} class Account extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn("entity_id","integer"); @@ -128,7 +134,7 @@ class Song extends Doctrine_Record { class Task extends Doctrine_Record { public function setUp() { - $this->hasMany("Resource","Assignment.resource_id"); + $this->hasMany("Resource as ResourceAlias","Assignment.resource_id"); $this->hasMany("Task as Subtask","Subtask.parent_id"); } public function setTableDefinition() { @@ -139,11 +145,11 @@ class Task extends Doctrine_Record { class Resource extends Doctrine_Record { public function setUp() { - $this->hasMany("Task","Assignment.task_id"); + $this->hasMany("Task as TaskAlias","Assignment.task_id"); } public function setTableDefinition() { $this->hasColumn("name","string",100); - } + } } class Assignment extends Doctrine_Record {