From ad44c656482c0abdedabdd1af3a1465c17447165 Mon Sep 17 00:00:00 2001 From: zYne Date: Mon, 23 Jul 2007 18:50:32 +0000 Subject: [PATCH] new record locking mechanism --- lib/Doctrine/Collection.php | 1 - lib/Doctrine/Connection/UnitOfWork.php | 80 +++++++++++++++++++------- lib/Doctrine/Record.php | 3 +- lib/Doctrine/Transaction.php | 39 ------------- 4 files changed, 60 insertions(+), 63 deletions(-) diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php index dd93969bb..661c24dbb 100644 --- a/lib/Doctrine/Collection.php +++ b/lib/Doctrine/Collection.php @@ -635,7 +635,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $record->delete($conn); } - Doctrine::debug(true); $conn->commit(); $this->data = array(); diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/Connection/UnitOfWork.php index 1b8982ba9..980d80d8d 100644 --- a/lib/Doctrine/Connection/UnitOfWork.php +++ b/lib/Doctrine/Connection/UnitOfWork.php @@ -141,21 +141,52 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module { $conn = $this->getConnection(); - if ($conn->transaction->isSaved($record)) { + $state = $record->state(); + if ($state === Doctrine_Record::STATE_LOCKED) { return false; } - $conn->transaction->addSaved($record); + $record->state(Doctrine_Record::STATE_LOCKED); $conn->beginTransaction(); $saveLater = $this->saveRelated($record); + $record->state($state); + if ($record->isValid()) { - $this->save($record); + $event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE); + + $record->preSave($event); + + $record->getTable()->getRecordListener()->preSave($event); + + if ( ! $event->skipOperation) { + switch ($state) { + case Doctrine_Record::STATE_TDIRTY: + $this->insert($record); + break; + case Doctrine_Record::STATE_DIRTY: + case Doctrine_Record::STATE_PROXY: + $this->update($record); + break; + case Doctrine_Record::STATE_CLEAN: + case Doctrine_Record::STATE_TCLEAN: + + break; + } + } + + $record->getTable()->getRecordListener()->postSave($event); + + $record->postSave($event); } else { $conn->transaction->addInvalid($record); } + + $state = $record->state(); + + $record->state(Doctrine_Record::STATE_LOCKED); foreach ($saveLater as $fk) { $alias = $fk->getAlias(); @@ -169,8 +200,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module // save the MANY-TO-MANY associations $this->saveAssociations($record); + $record->state($state); + $conn->commit(); - + return true; } /** @@ -262,26 +295,25 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module foreach ($record->getReferences() as $k => $v) { $rel = $record->getTable()->getRelation($k); - if ($rel instanceof Doctrine_Relation_ForeignKey || - $rel instanceof Doctrine_Relation_LocalKey) { - $local = $rel->getLocal(); - $foreign = $rel->getForeign(); + $local = $rel->getLocal(); + $foreign = $rel->getForeign(); - if ($record->getTable()->hasPrimaryKey($rel->getLocal())) { - if ( ! $record->exists()) { - $saveLater[$k] = $rel; - } else { - $v->save($this->conn); - } + if ($rel instanceof Doctrine_Relation_ForeignKey) { + //if ( ! $record->exists()) { + $saveLater[$k] = $rel; + /** } else { - // ONE-TO-ONE relationship - $obj = $record->get($rel->getAlias()); + $v->save($this->conn); + } + */ + } elseif ($rel instanceof Doctrine_Relation_LocalKey) { + // ONE-TO-ONE relationship + $obj = $record->get($rel->getAlias()); - // Protection against infinite function recursion before attempting to save - if ($obj instanceof Doctrine_Record && - $obj->isModified()) { - $obj->save($this->conn); - } + // Protection against infinite function recursion before attempting to save + if ($obj instanceof Doctrine_Record && + $obj->isModified()) { + $obj->save($this->conn); } } } @@ -319,11 +351,15 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module $this->conn->execute($query, array($r->getIncremented(), $record->getIncremented())); } + foreach ($v->getInsertDiff() as $r) { + + $assocRecord = $assocTable->create(); $assocRecord->set($rel->getForeign(), $r); $assocRecord->set($rel->getLocal(), $record); - $assocRecord->save($this->conn); + + $this->saveGraph($assocRecord); } } } diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php index e5fdc0509..3f87d59a8 100644 --- a/lib/Doctrine/Record.php +++ b/lib/Doctrine/Record.php @@ -1044,10 +1044,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count if ($this->_data[$v] instanceof Doctrine_Record) { $this->_data[$v] = $this->_data[$v]->getIncremented(); } - + /** TODO: if ($this->_data[$v] === null) { throw new Doctrine_Record_Exception('Unexpected null value.'); } + */ $a[$v] = $this->_data[$v]; } diff --git a/lib/Doctrine/Transaction.php b/lib/Doctrine/Transaction.php index 93bf4f36b..997fd85f0 100644 --- a/lib/Doctrine/Transaction.php +++ b/lib/Doctrine/Transaction.php @@ -67,11 +67,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module * @var array $_collections an array of Doctrine_Collection objects that were affected during the Transaction */ protected $_collections = array(); - /** - * @var array $_saved an array of already saved records, this array is used for avoiding infinite loops in circular - * saving operations - */ - protected $_saved = array(); /** * addCollection @@ -90,38 +85,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module return $this; } - - /** - * addSaved - * adds a record into internal array of saved records - * - * at the end of each commit this array is emptied - * - * @param Doctrine_Record record to be added - * @retrun Doctrine_Transaction this object - */ - public function addSaved(Doctrine_Record $record) - { - $this->_saved[] = $record; - - return $this; - } - - /** - * isSaved - * returns whether or not given record is already saved - * - * this method is used for avoiding infinite loops within - * cascading saves - * - * @param Doctrine_Record record to be checked - * @return boolean whether or not given record is already saved - */ - public function isSaved(Doctrine_Record $record) - { - return in_array($record, $this->_saved, true); - } - /** * getState * returns the state of this connection @@ -376,7 +339,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module $coll->takeSnapshot(); } $this->_collections = array(); - $this->_saved = array(); $this->conn->getDbh()->commit(); //$this->conn->unitOfWork->reset(); @@ -442,7 +404,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module throw new Doctrine_Transaction_Exception($e->getMessage()); } } - $this->_saved = array(); $listener->postTransactionRollback($event); }