1
0
mirror of synced 2024-12-14 15:16:04 +03:00
Ticket: 133
This commit is contained in:
zYne 2006-09-28 20:03:29 +00:00
parent 1ab5a4fcea
commit c8c1397f8a
6 changed files with 161 additions and 103 deletions

View File

@ -78,5 +78,22 @@ class Doctrine_Association extends Doctrine_Relation {
return $dql; 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;
}
} }

View File

@ -1,6 +1,64 @@
<?php <?php
/** /*
* Foreign Key * $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/ */
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;
}
}

View File

@ -28,13 +28,26 @@ Doctrine::autoload('Doctrine_Relation');
* @package Doctrine * @package Doctrine
*/ */
class Doctrine_LocalKey extends Doctrine_Relation { class Doctrine_LocalKey extends Doctrine_Relation {
public function fetch($id = null) { /**
if(empty($id)) * fetchRelatedFor
return $this->table->create(); *
else { * fetches a component related to given record
$record = $this->table->find($id); *
* @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;
} }
} }

View File

@ -417,7 +417,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* parsers for each part * parsers for each part
* *
* @param string $query DQL query * @param string $query DQL query
* @return void * @return Doctrine_Query
*/ */
public function parseQuery($query) { public function parseQuery($query) {
$this->clear(); $this->clear();
@ -483,6 +483,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
break; break;
endswitch; endswitch;
} }
return $this;
} }
/** /**
* DQL ORDER BY PARSER * DQL ORDER BY PARSER

View File

@ -731,16 +731,20 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} }
} else { } else {
try { try {
$rel = $this->table->getRelation($name); $this->coreSetRelated($name, $value);
} catch(Doctrine_Table_Exception $e) { } catch(Doctrine_Table_Exception $e) {
throw new Doctrine_Record_Exception("Unknown property / related component '$name'."); 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 // one-to-many or one-to-one relation
if($rel instanceof Doctrine_ForeignKey || if($rel instanceof Doctrine_ForeignKey ||
$rel instanceof Doctrine_LocalKey) { $rel instanceof Doctrine_LocalKey) {
switch($rel->getType()): switch($rel->getType()) {
case Doctrine_Relation::MANY_COMPOSITE: case Doctrine_Relation::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE: case Doctrine_Relation::MANY_AGGREGATE:
// one-to-many relation found // one-to-many relation found
@ -761,17 +765,17 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->set($rel->getLocal(),$value); $this->set($rel->getLocal(),$value);
} }
break; break;
endswitch; }
} elseif($rel instanceof Doctrine_Association) { } elseif($rel instanceof Doctrine_Association) {
// join table relation found // join table relation found
if( ! ($value instanceof Doctrine_Collection)) 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."); 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; $this->references[$name] = $value;
} }
}
/** /**
* contains * contains
* *
@ -782,6 +786,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if(isset($this->data[$name])) if(isset($this->data[$name]))
return true; return true;
if(isset($this->id[$name]))
return true;
if(isset($this->references[$name])) if(isset($this->references[$name]))
return true; return true;
@ -1211,72 +1218,16 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
final public function loadReference($name) { final public function loadReference($name) {
$fk = $this->table->getRelation($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()) { if($fk->isOneToOne()) {
// ONE-TO-ONE $this->references[$name] = $fk->fetchRelatedFor($this);
$this->references[$name] = $table->create();
if($fk instanceof Doctrine_ForeignKey) {
$this->references[$name]->set($fk->getForeign(),$this);
} else { } 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);
}
} else {
if($fk->isOneToOne()) {
// ONE-TO-ONE
$id = $this->get($local);
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); $coll = $fk->fetchRelatedFor($this);
} elseif($fk instanceof Doctrine_Association) {
$id = $this->getIncremented();
$coll = $graph->query($query, array($id));
}
$this->references[$name] = $coll; $this->references[$name] = $coll;
$this->originals[$name] = clone $coll; $this->originals[$name] = clone $coll;
} }
} }
}
/** /**
* filterRelated * filterRelated
* lazy initializes a new filter instance for given related component * lazy initializes a new filter instance for given related component

View File

@ -26,7 +26,7 @@
* @url www.phpdoctrine.com * @url www.phpdoctrine.com
* @license LGPL * @license LGPL
*/ */
class Doctrine_Relation { abstract class Doctrine_Relation {
/** /**
* RELATION CONSTANTS * RELATION CONSTANTS
*/ */
@ -166,6 +166,10 @@ class Doctrine_Relation {
* *
* We iterate through the old collection and get the records * 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). * 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) { public static function getDeleteOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
$r = array(); $r = array();
@ -204,6 +208,10 @@ class Doctrine_Relation {
* *
* We iterate through the old collection and get the records * We iterate through the old collection and get the records
* that exists only in the new collection (Doctrine_Records that need to be added). * 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) { public static function getInsertOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
$r = array(); $r = array();
@ -228,6 +236,15 @@ class Doctrine_Relation {
return $r; 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 * __toString
* *