This commit is contained in:
parent
330bf1d408
commit
82ba74e2e8
@ -549,26 +549,22 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
|||||||
* Snapshot with the objects 1, 2 and 4
|
* Snapshot with the objects 1, 2 and 4
|
||||||
* Current data with objects 2, 3 and 5
|
* Current data with objects 2, 3 and 5
|
||||||
*
|
*
|
||||||
* The process would:
|
* The process would remove object 4
|
||||||
* 1. remove object 4
|
|
||||||
* 2. add objects 3 and 5
|
|
||||||
*
|
*
|
||||||
* @return Doctrine_Collection
|
* @return Doctrine_Collection
|
||||||
*/
|
*/
|
||||||
public function processDiff()
|
public function processDiff()
|
||||||
{
|
{
|
||||||
foreach (array_diff($this->snapshot, $this->data) as $record) {
|
foreach (array_diff($this->_snapshot, $this->data) as $record) {
|
||||||
$record->delete();
|
$record->delete();
|
||||||
}
|
}
|
||||||
foreach (array_diff($this->data, $this->snapshot) as $record) {
|
|
||||||
$record->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* save
|
* save
|
||||||
* saves all records of this collection
|
* saves all records of this collection and processes the
|
||||||
|
* difference of the last snapshot and the current data
|
||||||
*
|
*
|
||||||
* @return Doctrine_Collection
|
* @return Doctrine_Collection
|
||||||
*/
|
*/
|
||||||
@ -579,6 +575,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
|||||||
}
|
}
|
||||||
$conn->beginTransaction();
|
$conn->beginTransaction();
|
||||||
|
|
||||||
|
$this->processDiff();
|
||||||
|
|
||||||
foreach ($this as $key => $record) {
|
foreach ($this as $key => $record) {
|
||||||
$record->save($conn);
|
$record->save($conn);
|
||||||
}
|
}
|
||||||
|
@ -140,10 +140,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module implemen
|
|||||||
public function saveRelated(Doctrine_Record $record)
|
public function saveRelated(Doctrine_Record $record)
|
||||||
{
|
{
|
||||||
$saveLater = array();
|
$saveLater = array();
|
||||||
foreach ($record->getReferences() as $k=>$v) {
|
foreach ($record->getReferences() as $k => $v) {
|
||||||
$fk = $record->getTable()->getRelation($k);
|
$fk = $record->getTable()->getRelation($k);
|
||||||
if ($fk instanceof Doctrine_Relation_ForeignKey ||
|
if ($fk instanceof Doctrine_Relation_ForeignKey ||
|
||||||
$fk instanceof Doctrine_Relation_LocalKey) {
|
$fk instanceof Doctrine_Relation_LocalKey) {
|
||||||
$local = $fk->getLocal();
|
$local = $fk->getLocal();
|
||||||
$foreign = $fk->getForeign();
|
$foreign = $fk->getForeign();
|
||||||
|
|
||||||
@ -157,8 +157,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module implemen
|
|||||||
// ONE-TO-ONE relationship
|
// ONE-TO-ONE relationship
|
||||||
$obj = $record->get($fk->getAlias());
|
$obj = $record->get($fk->getAlias());
|
||||||
|
|
||||||
$state = $obj->state();
|
if ($obj->exists()) {
|
||||||
if ( !($state == Doctrine_Record::STATE_CLEAN || $state == Doctrine_Record::STATE_TCLEAN) ) {
|
|
||||||
$obj->save($this->conn);
|
$obj->save($this->conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,8 +188,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module implemen
|
|||||||
foreach ($record->getTable()->getRelations() as $rel) {
|
foreach ($record->getTable()->getRelations() as $rel) {
|
||||||
$table = $rel->getTable();
|
$table = $rel->getTable();
|
||||||
$alias = $rel->getAlias();
|
$alias = $rel->getAlias();
|
||||||
|
|
||||||
$rel->processDiff($record, $this->conn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -499,8 +499,8 @@ class Doctrine_Hydrate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// take snapshots from all initialized collections
|
// take snapshots from all initialized collections
|
||||||
foreach(array_unique($colls) as $coll) {
|
foreach(array_unique($colls) as $c) {
|
||||||
$coll->takeSnapshot();
|
$c->takeSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $coll;
|
return $coll;
|
||||||
|
@ -111,10 +111,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
* @var array $references an array containing all the references
|
* @var array $references an array containing all the references
|
||||||
*/
|
*/
|
||||||
private $references = array();
|
private $references = array();
|
||||||
/**
|
|
||||||
* @var array $originals an array containing all the original references
|
|
||||||
*/
|
|
||||||
private $originals = array();
|
|
||||||
/**
|
/**
|
||||||
* @var integer $index this index is used for creating object identifiers
|
* @var integer $index this index is used for creating object identifiers
|
||||||
*/
|
*/
|
||||||
@ -1175,19 +1171,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
{
|
{
|
||||||
return new Doctrine_Record_Iterator($this);
|
return new Doctrine_Record_Iterator($this);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* getOriginals
|
|
||||||
* returns an original collection of related component
|
|
||||||
*
|
|
||||||
* @return Doctrine_Collection|false
|
|
||||||
*/
|
|
||||||
public function obtainOriginals($name)
|
|
||||||
{
|
|
||||||
if (isset($this->originals[$name])) {
|
|
||||||
return $this->originals[$name];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* deletes this data access object and all the related composites
|
* deletes this data access object and all the related composites
|
||||||
* this operation is isolated by a transaction
|
* this operation is isolated by a transaction
|
||||||
@ -1266,17 +1249,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
$this->_modified = array();
|
$this->_modified = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* assignOriginals
|
|
||||||
*
|
|
||||||
* @param string $alias
|
|
||||||
* @param Doctrine_Collection $coll
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function assignOriginals($alias, Doctrine_Collection $coll)
|
|
||||||
{
|
|
||||||
$this->originals[$alias] = $coll;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* returns the primary keys of this object
|
* returns the primary keys of this object
|
||||||
*
|
*
|
||||||
@ -1332,36 +1304,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
return $this->references[$name];
|
return $this->references[$name];
|
||||||
}
|
}
|
||||||
throw new Doctrine_Record_Exception("Unknown reference $name");
|
throw new Doctrine_Record_Exception("Unknown reference $name");
|
||||||
}
|
|
||||||
/**
|
|
||||||
* initalizes a one-to-many / many-to-many relation
|
|
||||||
*
|
|
||||||
* @param Doctrine_Collection $coll
|
|
||||||
* @param Doctrine_Relation $connector
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function initReference($coll, Doctrine_Relation $connector)
|
|
||||||
{
|
|
||||||
$alias = $connector->getAlias();
|
|
||||||
|
|
||||||
if (isset($this->references[$alias])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( ! $connector->isOneToOne()) {
|
|
||||||
if ( ! ($connector instanceof Doctrine_Relation_Association)) {
|
|
||||||
$coll->setReference($this, $connector);
|
|
||||||
}
|
|
||||||
$this->references[$alias] = $coll;
|
|
||||||
$this->originals[$alias] = clone $coll;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lazyInitRelated(Doctrine_Collection $coll, Doctrine_Relation $connector)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* addReference
|
* addReference
|
||||||
@ -1374,7 +1316,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
$alias = $connector->getAlias();
|
$alias = $connector->getAlias();
|
||||||
|
|
||||||
$this->references[$alias]->add($record, $key);
|
$this->references[$alias]->add($record, $key);
|
||||||
$this->originals[$alias]->add($record, $key);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* getReferences
|
* getReferences
|
||||||
@ -1393,7 +1334,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
final public function setRelated($alias, Doctrine_Access $coll)
|
final public function setRelated($alias, Doctrine_Access $coll)
|
||||||
{
|
{
|
||||||
$this->references[$alias] = $coll;
|
$this->references[$alias] = $coll;
|
||||||
$this->originals[$alias] = $coll;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* loadReference
|
* loadReference
|
||||||
@ -1410,12 +1350,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
|||||||
|
|
||||||
if ($fk->isOneToOne()) {
|
if ($fk->isOneToOne()) {
|
||||||
$this->references[$name] = $fk->fetchRelatedFor($this);
|
$this->references[$name] = $fk->fetchRelatedFor($this);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$coll = $fk->fetchRelatedFor($this);
|
$coll = $fk->fetchRelatedFor($this);
|
||||||
|
|
||||||
$this->references[$name] = $coll;
|
$this->references[$name] = $coll;
|
||||||
$this->originals[$name] = clone $coll;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -239,90 +239,6 @@ abstract class Doctrine_Relation
|
|||||||
|
|
||||||
return $dql;
|
return $dql;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* getDeleteOperations
|
|
||||||
*
|
|
||||||
* get the records that need to be deleted in order to change the old collection
|
|
||||||
* to the new one
|
|
||||||
*
|
|
||||||
* 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(n^2)
|
|
||||||
*
|
|
||||||
* 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();
|
|
||||||
|
|
||||||
foreach ($old as $k => $record) {
|
|
||||||
$id = $record->getIncremented();
|
|
||||||
|
|
||||||
if (empty($id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$found = false;
|
|
||||||
foreach ($new as $k2 => $record2) {
|
|
||||||
if ($record2->getIncremented() === $record->getIncremented()) {
|
|
||||||
$found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $found) {
|
|
||||||
$r[] = $record;
|
|
||||||
unset($old[$k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $r;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* getInsertOperations
|
|
||||||
*
|
|
||||||
* get the records that need to be added in order to change the old collection
|
|
||||||
* to the new one
|
|
||||||
*
|
|
||||||
* 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(n^2)
|
|
||||||
*
|
|
||||||
* 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();
|
|
||||||
|
|
||||||
foreach ($new as $k => $record) {
|
|
||||||
$found = false;
|
|
||||||
|
|
||||||
$id = $record->getIncremented();
|
|
||||||
if ( ! empty($id)) {
|
|
||||||
foreach ($old as $k2 => $record2) {
|
|
||||||
if ($record2->getIncremented() === $record->getIncremented()) {
|
|
||||||
$found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( ! $found) {
|
|
||||||
$old[] = $record;
|
|
||||||
$r[] = $record;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $r;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* fetchRelatedFor
|
* fetchRelatedFor
|
||||||
*
|
*
|
||||||
|
@ -33,26 +33,6 @@ Doctrine::autoload('Doctrine_Relation');
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Relation_LocalKey extends Doctrine_Relation
|
class Doctrine_Relation_LocalKey extends Doctrine_Relation
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* processDiff
|
|
||||||
*
|
|
||||||
* @param Doctrine_Record $record
|
|
||||||
* @param Doctrine_Connection $conn
|
|
||||||
*/
|
|
||||||
public function processDiff(Doctrine_Record $record, $conn = null)
|
|
||||||
{
|
|
||||||
if (!$conn) {
|
|
||||||
$conn = $this->getTable()->getConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
$alias = $this->getAlias();
|
|
||||||
|
|
||||||
if ($record->obtainOriginals($alias)
|
|
||||||
&& $record->obtainOriginals($alias)->obtainIdentifier() != $this->references[$alias]->obtainIdentifier()
|
|
||||||
) {
|
|
||||||
$record->obtainOriginals($alias)->delete($conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* fetchRelatedFor
|
* fetchRelatedFor
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user