diff --git a/Doctrine/Connection.php b/Doctrine/Connection.php index c89d4ba79..a28dc6280 100644 --- a/Doctrine/Connection.php +++ b/Doctrine/Connection.php @@ -28,16 +28,20 @@ */ abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate { /** - * @var $dbh the database handler + * @var $dbh the database handler */ 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 - * keys representing Doctrine_Table component names and values as Doctrine_Table objects + * @var Doctrine_UnitOfWork $unitOfWork the unit of work object + */ + 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(); /** @@ -49,7 +53,8 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun public function __construct(Doctrine_Manager $manager,PDO $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); @@ -58,6 +63,16 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun $this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this); } + /** + * getUnitOfWork + * + * returns the unit of work object + * + * @return Doctrine_UnitOfWork + */ + public function getUnitOfWork() { + return $this->unitOfWork; + } /** * getTransaction * @@ -66,7 +81,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return Doctrine_Transaction */ public function getTransaction() { - return $this->tx; + return $this->transaction; } /** * returns the manager that created this connection @@ -211,119 +226,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun public function create($name) { 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 $nm...
"; - } - - $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...
"; - - } else { - $tree[] = $name; - //print "$k -- adding $nm :$name...
"; - } - - } 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 $index...
"; - - } else { - //array_splice($tree, $index, 0, $name); - array_unshift($tree,$name); - $index++; - - //print "$k -- pushing $name into 0...
"; - } - } 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...
"; - - } else { - $tree[] = $n; - //print "$k -- adding $nm :$name...
"; - } - } - //print_r($tree); - } - //print_r($tree); - - } - return array_values($tree); - } - /** * flush * saves all the records from all tables @@ -343,7 +245,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return void */ private function saveAll() { - $tree = $this->buildFlushTree($this->tables); + $tree = $this->unitOfWork->buildFlushTree($this->tables); foreach($tree as $name) { $table = $this->tables[$name]; @@ -397,7 +299,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return integer */ public function getTransactionLevel() { - return $this->tx->getTransactionLevel(); + return $this->transaction->getTransactionLevel(); } /** * beginTransaction @@ -405,7 +307,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return void */ public function beginTransaction() { - $this->tx->beginTransaction(); + $this->transaction->beginTransaction(); } /** * commits the current transaction @@ -415,7 +317,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return void */ public function commit() { - $this->tx->commit(); + $this->transaction->commit(); } /** * rollback @@ -427,7 +329,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun * @return void */ public function rollback() { - $this->tx->rollback(); + $this->transaction->rollback(); } /** * returns maximum identifier values @@ -492,11 +394,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun public function save(Doctrine_Record $record) { switch($record->getState()): case Doctrine_Record::STATE_TDIRTY: - $this->tx->addInsert($record); + $this->transaction->addInsert($record); break; case Doctrine_Record::STATE_DIRTY: case Doctrine_Record::STATE_PROXY: - $this->tx->addUpdate($record); + $this->transaction->addUpdate($record); break; case Doctrine_Record::STATE_CLEAN: case Doctrine_Record::STATE_TCLEAN: @@ -657,7 +559,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun $this->beginTransaction(); $this->deleteComposites($record); - $this->tx->addDelete($record); + $this->transaction->addDelete($record); $this->commit(); return true; diff --git a/Doctrine/UnitOfWork.php b/Doctrine/UnitOfWork.php new file mode 100644 index 000000000..98ac95185 --- /dev/null +++ b/Doctrine/UnitOfWork.php @@ -0,0 +1,140 @@ +. + */ + +/** + * 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() { } +} diff --git a/tests/ConnectionTestCase.php b/tests/ConnectionTestCase.php index 0d89742a8..e3aa5c332 100644 --- a/tests/ConnectionTestCase.php +++ b/tests/ConnectionTestCase.php @@ -2,7 +2,7 @@ require_once("UnitTestCase.php"); class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase { - public function testBuildFlushTree() { + public function testbuildFlushTree() { $correct = array("Task","ResourceType","Resource","Assignment","ResourceReference"); // new model might switch some many-to-many components (NO HARM!) @@ -17,89 +17,89 @@ class Doctrine_ConnectionTestCase extends Doctrine_UnitTestCase { $task = new Task(); - $tree = $this->connection->buildFlushTree(array("Task")); + $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Task")); $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); - $tree = $this->connection->buildFlushTree(array("Task","Assignment","Resource")); + $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Task","Assignment","Resource")); $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); $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); - $tree = $this->connection->buildFlushTree(array("Forum_Category","Forum_Board")); + $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Category","Forum_Board")); $this->assertEqual($tree, $correct); $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); - $tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Entry")); + $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Entry")); $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); - $tree = $this->connection->buildFlushTree(array("Forum_Board","Forum_Thread")); + $tree = $this->connection->getUnitOfWork()->buildFlushTree(array("Forum_Board","Forum_Thread")); $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); - $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); }