From c8c1397f8a7062a4b0de3158320af41a2adf0729 Mon Sep 17 00:00:00 2001 From: zYne Date: Thu, 28 Sep 2006 20:03:29 +0000 Subject: [PATCH] fixes #133 Ticket: 133 --- lib/Doctrine/Association.php | 17 +++++ lib/Doctrine/ForeignKey.php | 64 ++++++++++++++++- lib/Doctrine/LocalKey.php | 25 +++++-- lib/Doctrine/Query.php | 4 +- lib/Doctrine/Record.php | 135 +++++++++++------------------------ lib/Doctrine/Relation.php | 19 ++++- 6 files changed, 161 insertions(+), 103 deletions(-) diff --git a/lib/Doctrine/Association.php b/lib/Doctrine/Association.php index 2dada81e5..b38306f1b 100644 --- a/lib/Doctrine/Association.php +++ b/lib/Doctrine/Association.php @@ -78,5 +78,22 @@ class Doctrine_Association extends Doctrine_Relation { return $dql; } + /** + * fetchRelatedFor + * + * fetches a component related to given record + * + * @param Doctrine_Record $record + * @return Doctrine_Record|Doctrine_Collection + */ + public function fetchRelatedFor(Doctrine_Record $record) { + $id = $record->getIncremented(); + if(empty($id)) + $coll = new Doctrine_Collection($this->table); + else + $coll = Doctrine_Query::create()->parseQuery($this->getRelationDql(1))->execute(array($id)); + + return $coll; + } } diff --git a/lib/Doctrine/ForeignKey.php b/lib/Doctrine/ForeignKey.php index d392aa127..f989225b3 100644 --- a/lib/Doctrine/ForeignKey.php +++ b/lib/Doctrine/ForeignKey.php @@ -1,6 +1,64 @@ . */ -class Doctrine_ForeignKey extends Doctrine_Relation { } +Doctrine::autoload('Doctrine_Relation'); +/** + * Doctrine_ForeignKey + * This class represents a foreign key relation + * + * @author Konsta Vesterinen + * @license LGPL + * @package Doctrine + */ +class Doctrine_ForeignKey extends Doctrine_Relation { + /** + * fetchRelatedFor + * + * fetches a component related to given record + * + * @param Doctrine_Record $record + * @return Doctrine_Record|Doctrine_Collection + */ + public function fetchRelatedFor(Doctrine_Record $record) { + $id = $record->get($this->local); + if($this->isOneToOne()) { + if(empty($id)) { + $related = $this->table->create(); + } else { + $dql = "FROM ".$this->table->getComponentName()." WHERE ".$this->table->getComponentName().".".$this->foreign." = ?"; + $coll = $this->table->getConnection()->query($dql, array($id)); + $related = $coll[0]; + } + + $related->set($this->foreign, $record, false); + + } else { + if(empty($id)) { + $related = new Doctrine_Collection($this->table); + } else { + $query = $this->getRelationDql(1); + $related = $this->table->getConnection()->query($query, array($id)); + } + $related->setReference($record, $this); + } + return $related; + } +} diff --git a/lib/Doctrine/LocalKey.php b/lib/Doctrine/LocalKey.php index 799ac3836..f4a2aac17 100644 --- a/lib/Doctrine/LocalKey.php +++ b/lib/Doctrine/LocalKey.php @@ -28,13 +28,26 @@ Doctrine::autoload('Doctrine_Relation'); * @package Doctrine */ class Doctrine_LocalKey extends Doctrine_Relation { - public function fetch($id = null) { - if(empty($id)) - return $this->table->create(); - else { - $record = $this->table->find($id); + /** + * fetchRelatedFor + * + * fetches a component related to given record + * + * @param Doctrine_Record $record + * @return Doctrine_Record|Doctrine_Collection + */ + public function fetchRelatedFor(Doctrine_Record $record) { + $id = $record->get($this->local); - return ($record !== false) ? $record : $this->table->create(); + if(empty($id)) + $related = $this->table->create(); + else { + if( ! ($related = $this->table->find($id))) + $related = $this->table->create(); } + + $record->set($this->local, $related, false); + + return $related; } } diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index 3996da49b..25198ea23 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -417,7 +417,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { * parsers for each part * * @param string $query DQL query - * @return void + * @return Doctrine_Query */ public function parseQuery($query) { $this->clear(); @@ -483,6 +483,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { break; endswitch; } + + return $this; } /** * DQL ORDER BY PARSER diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php index 76daded6a..f89e4f542 100644 --- a/lib/Doctrine/Record.php +++ b/lib/Doctrine/Record.php @@ -731,46 +731,50 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } } else { try { - $rel = $this->table->getRelation($name); + $this->coreSetRelated($name, $value); } catch(Doctrine_Table_Exception $e) { throw new Doctrine_Record_Exception("Unknown property / related component '$name'."); } + } + } + + public function coreSetRelated($name, $value) { + $rel = $this->table->getRelation($name); + // one-to-many or one-to-one relation + if($rel instanceof Doctrine_ForeignKey || + $rel instanceof Doctrine_LocalKey) { + switch($rel->getType()) { + case Doctrine_Relation::MANY_COMPOSITE: + case Doctrine_Relation::MANY_AGGREGATE: + // one-to-many relation found + if( ! ($value instanceof Doctrine_Collection)) + throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references."); - // one-to-many or one-to-one relation - if($rel instanceof Doctrine_ForeignKey || - $rel instanceof Doctrine_LocalKey) { - switch($rel->getType()): - case Doctrine_Relation::MANY_COMPOSITE: - case Doctrine_Relation::MANY_AGGREGATE: - // one-to-many relation found - if( ! ($value instanceof Doctrine_Collection)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references."); + $value->setReference($this,$rel); + break; + case Doctrine_Relation::ONE_COMPOSITE: + case Doctrine_Relation::ONE_AGGREGATE: + // one-to-one relation found + if( ! ($value instanceof Doctrine_Record)) + throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references."); - $value->setReference($this,$rel); - break; - case Doctrine_Relation::ONE_COMPOSITE: - case Doctrine_Relation::ONE_AGGREGATE: - // one-to-one relation found - if( ! ($value instanceof Doctrine_Record)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references."); - - if($rel->getLocal() == $this->table->getIdentifier()) { - $value->set($rel->getForeign(), $this, false); - } else { - $this->set($rel->getLocal(),$value); - } - break; - endswitch; - - } elseif($rel instanceof Doctrine_Association) { - // join table relation found - if( ! ($value instanceof Doctrine_Collection)) - throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references."); + if($rel->getLocal() == $this->table->getIdentifier()) { + $value->set($rel->getForeign(), $this, false); + } else { + $this->set($rel->getLocal(),$value); + } + break; } - $this->references[$name] = $value; + } elseif($rel instanceof Doctrine_Association) { + // join table relation found + if( ! ($value instanceof Doctrine_Collection)) + throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references."); + } + + $this->references[$name] = $value; } /** * contains @@ -782,6 +786,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite if(isset($this->data[$name])) return true; + if(isset($this->id[$name])) + return true; + if(isset($this->references[$name])) return true; @@ -1211,70 +1218,14 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite final public function loadReference($name) { $fk = $this->table->getRelation($name); - $table = $fk->getTable(); - $local = $fk->getLocal(); - $foreign = $fk->getForeign(); - $graph = $table->getQueryObject(); - $type = $fk->getType(); - - if( ! $this->exists()) { - if($fk->isOneToOne()) { - // ONE-TO-ONE - $this->references[$name] = $table->create(); - - if($fk instanceof Doctrine_ForeignKey) { - $this->references[$name]->set($fk->getForeign(),$this); - } else { - $this->set($fk->getLocal(),$this->references[$name]); - } - } else { - $this->references[$name] = new Doctrine_Collection($table); - if($fk instanceof Doctrine_ForeignKey) { - // ONE-TO-MANY - $this->references[$name]->setReference($this,$fk); - } - $this->originals[$name] = new Doctrine_Collection($table); - } + if($fk->isOneToOne()) { + $this->references[$name] = $fk->fetchRelatedFor($this); } else { - if($fk->isOneToOne()) { - // ONE-TO-ONE - $id = $this->get($local); + $coll = $fk->fetchRelatedFor($this); - if($fk instanceof Doctrine_LocalKey) { - $this->references[$name] = $fk->fetch($id); - $this->set($fk->getLocal(), $this->references[$name], false); - - } elseif ($fk instanceof Doctrine_ForeignKey) { - - if(empty($id)) { - $this->references[$name] = $table->create(); - } else { - $dql = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$fk->getForeign()." = ?"; - $coll = $graph->query($dql, array($id)); - $this->references[$name] = $coll[0]; - } - - $this->references[$name]->set($fk->getForeign(), $this); - } - } else { - - $query = $fk->getRelationDql(1); - - // ONE-TO-MANY - if($fk instanceof Doctrine_ForeignKey) { - $id = $this->get($local); - $coll = $graph->query($query,array($id)); - $coll->setReference($this, $fk); - } elseif($fk instanceof Doctrine_Association_Self) { - $coll = $fk->fetchRelatedFor($this); - } elseif($fk instanceof Doctrine_Association) { - $id = $this->getIncremented(); - $coll = $graph->query($query, array($id)); - } - $this->references[$name] = $coll; - $this->originals[$name] = clone $coll; - } + $this->references[$name] = $coll; + $this->originals[$name] = clone $coll; } } /** diff --git a/lib/Doctrine/Relation.php b/lib/Doctrine/Relation.php index 379b09169..802a14b5b 100644 --- a/lib/Doctrine/Relation.php +++ b/lib/Doctrine/Relation.php @@ -26,7 +26,7 @@ * @url www.phpdoctrine.com * @license LGPL */ -class Doctrine_Relation { +abstract class Doctrine_Relation { /** * RELATION CONSTANTS */ @@ -166,6 +166,10 @@ class Doctrine_Relation { * * We iterate through the old collection and get the records * that do not exists in the new collection (Doctrine_Records that need to be deleted). + * + * @param Doctrine_Collection $old + * @param Doctrine_Collection $new + * @return array */ public static function getDeleteOperations(Doctrine_Collection $old, Doctrine_Collection $new) { $r = array(); @@ -204,6 +208,10 @@ class Doctrine_Relation { * * We iterate through the old collection and get the records * that exists only in the new collection (Doctrine_Records that need to be added). + * + * @param Doctrine_Collection $old + * @param Doctrine_Collection $new + * @return array */ public static function getInsertOperations(Doctrine_Collection $old, Doctrine_Collection $new) { $r = array(); @@ -228,6 +236,15 @@ class Doctrine_Relation { return $r; } + /** + * fetchRelatedFor + * + * fetches a component related to given record + * + * @param Doctrine_Record $record + * @return Doctrine_Record|Doctrine_Collection + */ + abstract public function fetchRelatedFor(Doctrine_Record $record); /** * __toString *