public function testExecuteRecursivelyCallsExecuteOnSteps() { $dummy_pdo_dbh = null; $plan = new SDO_DAS_Relational_Plan(); $unit_test_action = new UnitTestAction(); $plan->addAction($unit_test_action); $exception_thrown = false; try { $plan->execute($dummy_pdo_dbh); } catch (UnitTestException $e) { $exception_thrown = true; } $this->assertTrue($exception_thrown, 'Unit test action did not get executed'); }
/** * Given a datagraph containing a change summary, and a PDO database handle, apply the changes to the database. * * Initialise an empty Plan and then for each change in the change summary augment the plan with * the database interactions needed. These may be inserts, updates or deletes. Some changes can * cause more than one interaction with the database. A non-exhaustive list of the sort of things * we might need to do are (just inserts at the moment): * 1. given a data object that has been created, insert a row to the database. Interpret PHP null as * a null in the datbase, and an unset property as one that must not be set in the SQL * insert statement * 2. insert a row and obtain the autogenerated primary key, Remember the key in the object-key map * (keeps track of data objects -> PKs) for later use. * 3. insert a row using a mixture of data from the data object and a previously obtained key which we * retrieve from the identity map. This will occur when we come to insert a row that contains a * foreign key to a row in another table that we have only just inserted * 4. go back and update a row we inserted earlier with a key that we have only just obtained. * this is an unusual scenario but it occurs for example when inserting a company/department/employee * combination where all the keys are autogenerated and hence you do not know the key to put in the * employee of the month field in the company record until after you have inserted the employee row. */ public function applyChanges(PDO $dbh, $data_object) { $root = self::goUpTheTreeToTheRoot($data_object); $change_summary = $root->getChangeSummary(); if (self::DEBUG_CHANGE_SUMMARY) { self::displayChangeSummary($change_summary); } $changed_data_objects = $change_summary->getChangedDataObjects(); $plan = new SDO_DAS_Relational_Plan(); foreach ($changed_data_objects as $do) { switch ($change_summary->getChangeType($do)) { case SDO_DAS_ChangeSummary::ADDITION: $plan->addAction(new SDO_DAS_Relational_InsertAction($this->object_model, $do)); break; case SDO_DAS_ChangeSummary::MODIFICATION: if (self::isRoot($do)) { continue; // currently not interested in modifications on the root - they appear as creates/deletes in their own right // TODO the way the change summary works is going to change and this modification will in future be the right way to find the create } $old_values = $change_summary->getOldValues($do); $plan->addAction(new SDO_DAS_Relational_UpdateAction($this->object_model, $do, $old_values)); break; case SDO_DAS_ChangeSummary::DELETION: $old_values = $change_summary->getOldValues($do); $plan->addAction(new SDO_DAS_Relational_DeleteAction($this->object_model, $do, $old_values)); break; default: assert(false, 'SDO_DAS_Relational.php found a change in the change summary with an improper type'); } } $dbh->beginTransaction(); $plan->execute($dbh); $dbh->commit(); // turn logging off and on again to clear out the change summary. The user can now continue to work with the data graph. $root->getChangeSummary()->endLogging(); $root->getChangeSummary()->beginLogging(); }