Commit 07c5c92e authored by zYne's avatar zYne

deletes are no longer stacked in the end of transaction, now transactional...

deletes are no longer stacked in the end of transaction, now transactional integrity is always assured
parent 5d0caba0
......@@ -622,6 +622,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$conn = $this->_table->getConnection();
}
$conn->beginTransaction();
$conn->transaction->addCollection($this);
$this->processDiff();
......@@ -631,7 +632,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
$conn->commit();
return $this;
}
/**
......
......@@ -815,7 +815,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function exec($query, array $params = array()) {
$this->connect();
print $query . print_r($params, true) . "<br>";
try {
if ( ! empty($params)) {
$stmt = $this->prepare($query);
......
......@@ -183,7 +183,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} else {
$conn->transaction->addInvalid($record);
}
$state = $record->state();
$record->state(Doctrine_Record::STATE_LOCKED);
......@@ -261,18 +261,24 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record->getTable()->getRecordListener()->preDelete($event);
$state = $record->state();
$record->state(Doctrine_Record::STATE_LOCKED);
$this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
if ( ! $event->skipOperation) {
$this->conn->transaction->addDelete($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
$this->deleteRecord($record);
$record->state(Doctrine_Record::STATE_TCLEAN);
} else {
// return to original state
$record->state($state);
}
$record->getTable()->getRecordListener()->postDelete($event);
$record->postDelete($event);
......@@ -281,7 +287,77 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
return true;
}
public function deleteRecord(Doctrine_Record $record)
{
$ids = $record->identifier();
$tmp = array();
foreach (array_keys($ids) as $id) {
$tmp[] = $id . ' = ? ';
}
$params = array_values($ids);
$query = 'DELETE FROM '
. $this->conn->quoteIdentifier($record->getTable()->getTableName())
. ' WHERE ' . implode(' AND ', $tmp);
return $this->conn->exec($query, $params);
}
/**
* deleteMultiple
* deletes all records from the pending delete list
*
* @return void
*/
public function deleteMultiple(array $records)
{
foreach ($this->delete as $name => $deletes) {
$record = false;
$ids = array();
if (is_array($deletes[count($deletes)-1]->getTable()->getIdentifier())) {
if (count($deletes) > 0) {
$query = 'DELETE FROM '
. $this->conn->quoteIdentifier($deletes[0]->getTable()->getTableName())
. ' WHERE ';
$params = array();
$cond = array();
foreach ($deletes as $k => $record) {
$ids = $record->identifier();
$tmp = array();
foreach (array_keys($ids) as $id){
$tmp[] = $id . ' = ? ';
}
$params = array_merge($params, array_values($ids));
$cond[] = '(' . implode(' AND ', $tmp) . ')';
}
$query .= implode(' OR ', $cond);
$this->conn->execute($query, $params);
}
} else {
foreach ($deletes as $k => $record) {
$ids[] = $record->getIncremented();
}
if ($record instanceof Doctrine_Record) {
$params = substr(str_repeat('?, ', count($ids)), 0, -2);
$query = 'DELETE FROM '
. $this->conn->quoteIdentifier($record->getTable()->getTableName())
. ' WHERE '
. $record->getTable()->getIdentifier()
. ' IN(' . $params . ')';
$this->conn->execute($query, $ids);
}
}
}
}
/**
* saveRelated
* saves all related records to $record
......@@ -325,7 +401,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* 3, 4 and 5, this method would first destroy the associations to 1 and 2 and then
* save new associations to 4 and 5
*
* @throws PDOException if something went wrong at database level
* @throws Doctrine_Connection_Exception if something went wrong at database level
* @param Doctrine_Record $record
* @return void
*/
......
......@@ -54,11 +54,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
* @var array $invalid an array containing all invalid records within this transaction
*/
protected $invalid = array();
/**
* @var array $delete two dimensional pending delete list, the records in
* this list will be deleted when transaction is committed
*/
protected $delete = array();
/**
* @var array $savepoints an array containing all savepoints
*/
......@@ -106,19 +101,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
}
}
/**
* addDelete
* adds record into pending delete list
*
* @param Doctrine_Record $record a record to be added
* @return void
*/
public function addDelete(Doctrine_Record $record)
{
$name = $record->getTable()->getComponentName();
$this->delete[$name][] = $record;
}
/**
* addInvalid
* adds record into invalid records list
......@@ -136,70 +118,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
return true;
}
/**
* returns the pending delete list
*
* @return array
*/
public function getDeletes()
{
return $this->delete;
}
/**
* bulkDelete
* deletes all records from the pending delete list
*
* @return void
*/
public function bulkDelete()
{
foreach ($this->delete as $name => $deletes) {
$record = false;
$ids = array();
if (is_array($deletes[count($deletes)-1]->getTable()->getIdentifier())) {
if (count($deletes) > 0) {
$query = 'DELETE FROM '
. $this->conn->quoteIdentifier($deletes[0]->getTable()->getTableName())
. ' WHERE ';
$params = array();
$cond = array();
foreach ($deletes as $k => $record) {
$ids = $record->identifier();
$tmp = array();
foreach (array_keys($ids) as $id){
$tmp[] = $id . ' = ? ';
}
$params = array_merge($params, array_values($ids));
$cond[] = '(' . implode(' AND ', $tmp) . ')';
}
$query .= implode(' OR ', $cond);
$this->conn->execute($query, $params);
}
} else {
foreach ($deletes as $k => $record) {
$ids[] = $record->getIncremented();
}
if ($record instanceof Doctrine_Record) {
$params = substr(str_repeat('?, ', count($ids)), 0, -2);
$query = 'DELETE FROM '
. $this->conn->quoteIdentifier($record->getTable()->getTableName())
. ' WHERE '
. $record->getTable()->getIdentifier()
. ' IN(' . $params . ')';
$this->conn->execute($query, $ids);
}
}
}
$this->delete = array();
}
/**
* getTransactionLevel
* get the current transaction nesting level
......@@ -311,40 +229,30 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$listener->postSavepointCommit($event);
} else {
if ($this->transactionLevel == 1) {
$event = new Doctrine_Event($this, Doctrine_Event::TX_COMMIT);
if ($this->transactionLevel == 1) {
if ( ! empty($this->invalid)) {
$this->rollback();
$tmp = $this->invalid;
$this->invalid = array();
throw new Doctrine_Validator_Exception($tmp);
}
// take snapshots of all collections used within this transaction
foreach ($this->_collections as $coll) {
$coll->takeSnapshot();
}
$this->_collections = array();
$event = new Doctrine_Event($this, Doctrine_Event::TX_COMMIT);
$listener->preTransactionCommit($event);
if ( ! $event->skipOperation) {
try {
$this->bulkDelete();
} catch(Exception $e) {
$this->rollback();
throw new Doctrine_Transaction_Exception($e->getMessage());
}
if ( ! empty($this->invalid)) {
$this->rollback();
$tmp = $this->invalid;
$this->invalid = array();
throw new Doctrine_Validator_Exception($tmp);
}
// take snapshots of all collections used within this transaction
foreach ($this->_collections as $coll) {
$coll->takeSnapshot();
}
$this->_collections = array();
$this->conn->getDbh()->commit();
//$this->conn->unitOfWork->reset();
}
$listener->postTransactionCommit($event);
}
$this->transactionLevel--;
......@@ -395,8 +303,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$listener->preTransactionRollback($event);
if ( ! $event->skipOperation) {
$this->deteles = array();
$this->transactionLevel = 0;
try {
$this->conn->getDbh()->rollback();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment