Commit 9d4c4216 authored by zYne's avatar zYne

added Doctrine_UnitOfWork, removed unnecessary methods from Connection class

parent 20c34260
...@@ -28,16 +28,20 @@ ...@@ -28,16 +28,20 @@
*/ */
abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate { abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate {
/** /**
* @var $dbh the database handler * @var $dbh the database handler
*/ */
private $dbh; private $dbh;
/** /**
* @var Doctrine_Transaction $tx the transaction object * @var Doctrine_Transaction $transaction the transaction object
*/ */
private $tx; private $transaction;
/** /**
* @var array $tables an array containing all the initialized Doctrine_Table objects * @var Doctrine_UnitOfWork $unitOfWork the unit of work object
* keys representing Doctrine_Table component names and values as Doctrine_Table objects */
private $unitOfWork;
/**
* @var array $tables an array containing all the initialized Doctrine_Table objects
* keys representing Doctrine_Table component names and values as Doctrine_Table objects
*/ */
protected $tables = array(); protected $tables = array();
/** /**
...@@ -49,7 +53,8 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -49,7 +53,8 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function __construct(Doctrine_Manager $manager,PDO $pdo) { public function __construct(Doctrine_Manager $manager,PDO $pdo) {
$this->dbh = $pdo; $this->dbh = $pdo;
$this->tx = new Doctrine_Transaction($this); $this->transaction = new Doctrine_Transaction($this);
$this->unitOfWork = new Doctrine_UnitOfWork($this);
$this->setParent($manager); $this->setParent($manager);
...@@ -58,6 +63,16 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -58,6 +63,16 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this); $this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this);
} }
/**
* getUnitOfWork
*
* returns the unit of work object
*
* @return Doctrine_UnitOfWork
*/
public function getUnitOfWork() {
return $this->unitOfWork;
}
/** /**
* getTransaction * getTransaction
* *
...@@ -66,7 +81,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -66,7 +81,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return Doctrine_Transaction * @return Doctrine_Transaction
*/ */
public function getTransaction() { public function getTransaction() {
return $this->tx; return $this->transaction;
} }
/** /**
* returns the manager that created this connection * returns the manager that created this connection
...@@ -211,119 +226,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -211,119 +226,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function create($name) { public function create($name) {
return $this->getTable($name)->create(); return $this->getTable($name)->create();
} }
/**
* buildFlushTree
* builds a flush tree that is used in transactions
*
* @return array
*/
public function buildFlushTree(array $tables) {
$tree = array();
foreach($tables as $k => $table) {
$k = $k.$table;
if( ! ($table instanceof Doctrine_Table))
$table = $this->getTable($table);
$nm = $table->getComponentName();
$index = array_search($nm,$tree);
if($index === false) {
$tree[] = $nm;
$index = max(array_keys($tree));
//print "$k -- adding <b>$nm</b>...<br \>";
}
$rels = $table->getRelations();
// group relations
foreach($rels as $key => $rel) {
if($rel instanceof Doctrine_ForeignKey) {
unset($rels[$key]);
array_unshift($rels, $rel);
}
}
foreach($rels as $rel) {
$name = $rel->getTable()->getComponentName();
$index2 = array_search($name,$tree);
$type = $rel->getType();
// skip self-referenced relations
if($name === $nm)
continue;
if($rel instanceof Doctrine_ForeignKey) {
if($index2 !== false) {
if($index2 >= $index)
continue;
unset($tree[$index]);
array_splice($tree,$index2,0,$nm);
$index = $index2;
//print "$k -- pushing $nm into $index2...<br \>";
} else {
$tree[] = $name;
//print "$k -- adding $nm :$name...<br>";
}
} elseif($rel instanceof Doctrine_LocalKey) {
if($index2 !== false) {
if($index2 <= $index)
continue;
unset($tree[$index2]);
array_splice($tree,$index,0,$name);
//print "$k -- pushing $name into <b>$index</b>...<br \>";
} else {
//array_splice($tree, $index, 0, $name);
array_unshift($tree,$name);
$index++;
//print "$k -- pushing <b>$name</b> into 0...<br \>";
}
} elseif($rel instanceof Doctrine_Association) {
$t = $rel->getAssociationFactory();
$n = $t->getComponentName();
if($index2 !== false)
unset($tree[$index2]);
array_splice($tree,$index, 0,$name);
$index++;
$index3 = array_search($n,$tree);
if($index3 !== false) {
if($index3 >= $index)
continue;
unset($tree[$index]);
array_splice($tree,$index3,0,$n);
$index = $index2;
//print "$k -- pushing $nm into $index3...<br \>";
} else {
$tree[] = $n;
//print "$k -- adding $nm :$name...<br>";
}
}
//print_r($tree);
}
//print_r($tree);
}
return array_values($tree);
}
/** /**
* flush * flush
* saves all the records from all tables * saves all the records from all tables
...@@ -343,7 +245,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -343,7 +245,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return void * @return void
*/ */
private function saveAll() { private function saveAll() {
$tree = $this->buildFlushTree($this->tables); $tree = $this->unitOfWork->buildFlushTree($this->tables);
foreach($tree as $name) { foreach($tree as $name) {
$table = $this->tables[$name]; $table = $this->tables[$name];
...@@ -397,7 +299,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -397,7 +299,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return integer * @return integer
*/ */
public function getTransactionLevel() { public function getTransactionLevel() {
return $this->tx->getTransactionLevel(); return $this->transaction->getTransactionLevel();
} }
/** /**
* beginTransaction * beginTransaction
...@@ -405,7 +307,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -405,7 +307,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return void * @return void
*/ */
public function beginTransaction() { public function beginTransaction() {
$this->tx->beginTransaction(); $this->transaction->beginTransaction();
} }
/** /**
* commits the current transaction * commits the current transaction
...@@ -415,7 +317,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -415,7 +317,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return void * @return void
*/ */
public function commit() { public function commit() {
$this->tx->commit(); $this->transaction->commit();
} }
/** /**
* rollback * rollback
...@@ -427,7 +329,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -427,7 +329,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return void * @return void
*/ */
public function rollback() { public function rollback() {
$this->tx->rollback(); $this->transaction->rollback();
} }
/** /**
* returns maximum identifier values * returns maximum identifier values
...@@ -492,11 +394,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -492,11 +394,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function save(Doctrine_Record $record) { public function save(Doctrine_Record $record) {
switch($record->getState()): switch($record->getState()):
case Doctrine_Record::STATE_TDIRTY: case Doctrine_Record::STATE_TDIRTY:
$this->tx->addInsert($record); $this->transaction->addInsert($record);
break; break;
case Doctrine_Record::STATE_DIRTY: case Doctrine_Record::STATE_DIRTY:
case Doctrine_Record::STATE_PROXY: case Doctrine_Record::STATE_PROXY:
$this->tx->addUpdate($record); $this->transaction->addUpdate($record);
break; break;
case Doctrine_Record::STATE_CLEAN: case Doctrine_Record::STATE_CLEAN:
case Doctrine_Record::STATE_TCLEAN: case Doctrine_Record::STATE_TCLEAN:
...@@ -657,7 +559,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -657,7 +559,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->beginTransaction(); $this->beginTransaction();
$this->deleteComposites($record); $this->deleteComposites($record);
$this->tx->addDelete($record); $this->transaction->addDelete($record);
$this->commit(); $this->commit();
return true; return true;
......
<?php
/*
* $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>.
*/
/**
* Doctrine_Transaction
*
* @package Doctrine ORM
* @url www.phpdoctrine.com
* @license LGPL
*/
class Doctrine_UnitOfWork implements IteratorAggregate, Countable {
/**
* @var Doctrine_Connection $conn the connection object
*/
private $connection;
/**
* the constructor
*
* @param Doctrine_Connection $conn
*/
public function __construct(Doctrine_Connection $conn) {
$this->conn = $conn;
}
/**
* buildFlushTree
* builds a flush tree that is used in transactions
*
* @return array
*/
public function buildFlushTree(array $tables) {
$tree = array();
foreach($tables as $k => $table) {
$k = $k.$table;
if( ! ($table instanceof Doctrine_Table))
$table = $this->conn->getTable($table);
$nm = $table->getComponentName();
$index = array_search($nm,$tree);
if($index === false) {
$tree[] = $nm;
$index = max(array_keys($tree));
}
$rels = $table->getRelations();
// group relations
foreach($rels as $key => $rel) {
if($rel instanceof Doctrine_ForeignKey) {
unset($rels[$key]);
array_unshift($rels, $rel);
}
}
foreach($rels as $rel) {
$name = $rel->getTable()->getComponentName();
$index2 = array_search($name,$tree);
$type = $rel->getType();
// skip self-referenced relations
if($name === $nm)
continue;
if($rel instanceof Doctrine_ForeignKey) {
if($index2 !== false) {
if($index2 >= $index)
continue;
unset($tree[$index]);
array_splice($tree,$index2,0,$nm);
$index = $index2;
} else {
$tree[] = $name;
}
} elseif($rel instanceof Doctrine_LocalKey) {
if($index2 !== false) {
if($index2 <= $index)
continue;
unset($tree[$index2]);
array_splice($tree,$index,0,$name);
} else {
array_unshift($tree,$name);
$index++;
}
} elseif($rel instanceof Doctrine_Association) {
$t = $rel->getAssociationFactory();
$n = $t->getComponentName();
if($index2 !== false)
unset($tree[$index2]);
array_splice($tree,$index, 0,$name);
$index++;
$index3 = array_search($n,$tree);
if($index3 !== false) {
if($index3 >= $index)
continue;
unset($tree[$index]);
array_splice($tree,$index3,0,$n);
$index = $index2;
} else {
$tree[] = $n;
}
}
}
}
return array_values($tree);
}
public function getIterator() { }
public function count() { }
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require_once("UnitTestCase.php"); require_once("UnitTestCase.php");
class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase { class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase {
public function testBuildFlushTree() { public function testbuildFlushTree() {
$correct = array("Task","ResourceType","Resource","Assignment","ResourceReference"); $correct = array("Task","ResourceType","Resource","Assignment","ResourceReference");
// new model might switch some many-to-many components (NO HARM!) // new model might switch some many-to-many components (NO HARM!)
...@@ -17,89 +17,89 @@ class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase { ...@@ -17,89 +17,89 @@ class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase {
$task = new Task(); $task = new Task();
$tree = $this->connection->buildFlushTree(array("Task")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Task"));
$this->assertEqual($tree,array("Resource","Task","Assignment")); $this->assertEqual($tree,array("Resource","Task","Assignment"));
$tree = $this->connection->buildFlushTree(array("Task","Resource")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Task","Resource"));
$this->assertEqual($tree,$correct); $this->assertEqual($tree,$correct);
$tree = $this->connection->buildFlushTree(array("Task","Assignment","Resource")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Task","Assignment","Resource"));
$this->assertEqual($tree,$correct); $this->assertEqual($tree,$correct);
$tree = $this->connection->buildFlushTree(array("Assignment","Task","Resource")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Assignment","Task","Resource"));
$this->assertEqual($tree,$correct2); $this->assertEqual($tree,$correct2);
$correct = array("Forum_Category","Forum_Board","Forum_Thread"); $correct = array("Forum_Category","Forum_Board","Forum_Thread");
$tree = $this->connection->buildFlushTree(array("Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$correct = array("Forum_Category","Forum_Board","Forum_Thread","Forum_Entry"); $correct = array("Forum_Category","Forum_Board","Forum_Thread","Forum_Entry");
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Entry","Forum_Thread")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Entry","Forum_Thread"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Board","Forum_Thread")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Board","Forum_Thread"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Entry","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Entry","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Category")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Category"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Thread","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Thread","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Category")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Category"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Category","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Category","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Entry","Forum_Category")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread","Forum_Entry","Forum_Category"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Category","Forum_Thread","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Category","Forum_Thread","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Board","Forum_Category")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Board","Forum_Category"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Category","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Thread","Forum_Category","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Entry","Forum_Category","Forum_Board","Forum_Thread")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Entry","Forum_Category","Forum_Board","Forum_Thread"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Category","Forum_Board","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Category","Forum_Board","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Entry","Forum_Category","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Entry","Forum_Category","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Entry","Forum_Category")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Thread","Forum_Board","Forum_Entry","Forum_Category"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Entry","Forum_Board","Forum_Thread")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Entry","Forum_Board","Forum_Thread"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Thread","Forum_Entry","Forum_Board")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Thread","Forum_Entry","Forum_Board"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
$tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Board","Forum_Thread","Forum_Entry")); $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Board","Forum_Thread","Forum_Entry"));
$this->assertEqual($tree, $correct); $this->assertEqual($tree, $correct);
} }
......
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