/** * Setup file pointers then call diff_doc_work() to do the actual diffing * @param string $old_xml_file * @param string $new_xml_file * @param SimpleXMLElement $old_database * @param SimpleXMLElement $new_database * @param string $upgrade_prefix */ public static function diff_doc($old_xml_file, $new_xml_file, $old_database, $new_database, $upgrade_prefix) { if (!dbsteward::$generate_slonik) { // if we are not generating slonik, defer to parent return parent::diff_doc($old_xml_file, $new_xml_file, $old_database, $new_database, $upgrade_prefix); } $timestamp = date('r'); // use output_file_segementer router to route changes to the correct ofs // also ignore unknown replica set IDs so changes that are not part of replicaed tables // are not put in upgrade stage files $ofsm_stage1 = new ofs_replica_set_router(); $ofsm_stage1->skip_unknown_set_ids(); $ofsm_stage2 = new ofs_replica_set_router(); $ofsm_stage2->skip_unknown_set_ids(); $ofsm_stage3 = new ofs_replica_set_router(); $ofsm_stage3->skip_unknown_set_ids(); $ofsm_stage4 = new ofs_replica_set_router(); $ofsm_stage4->skip_unknown_set_ids(); foreach (pgsql8::get_slony_replica_sets($new_database) as $replica_set) { $replica_set_id = (string) $replica_set['id']; $old_set_new_set = "-- Old definition: " . $old_xml_file . "\n" . "-- New definition: " . $new_xml_file . "\n" . "-- Replica Set: " . $replica_set_id . "\n"; $ofsm_stage1->set_replica_set_ofs($replica_set_id, new output_file_segmenter($upgrade_prefix . '_slony_replica_set_' . $replica_set['id'] . '_stage1_schema', 1))->set_header("-- DBSteward slony replica set " . $replica_set['id'] . " stage 1 structure additions and modifications - generated " . $timestamp . "\n" . $old_set_new_set); $ofsm_stage2->set_replica_set_ofs($replica_set_id, new output_file_segmenter($upgrade_prefix . '_slony_replica_set_' . $replica_set['id'] . '_stage2_data', 1))->set_header("-- DBSteward slony replica set " . $replica_set['id'] . " stage 2 data definitions removed - generated " . $timestamp . "\n" . $old_set_new_set); $ofsm_stage3->set_replica_set_ofs($replica_set_id, new output_file_segmenter($upgrade_prefix . '_slony_replica_set_' . $replica_set['id'] . '_stage3_schema', 1))->set_header("-- DBSteward slony replica set " . $replica_set['id'] . " stage 3 structure changes, constraints and removals - generated " . $timestamp . "\n" . $old_set_new_set); $ofsm_stage4->set_replica_set_ofs($replica_set_id, new output_file_segmenter($upgrade_prefix . '_slony_replica_set_' . $replica_set['id'] . '_stage4_data', 1))->set_header("-- DBSteward slony replica set " . $replica_set['id'] . " stage 4 data definition changes and additions - generated " . $timestamp . "\n" . $old_set_new_set); } dbsteward::$old_database = $old_database; dbsteward::$new_database = $new_database; static::diff_doc_work($ofsm_stage1, $ofsm_stage2, $ofsm_stage3, $ofsm_stage4); }
protected function build_replica_sets_for_test() { dbsteward::$old_database = new SimpleXMLElement($this->oldxml); dbsteward::$new_database = new SimpleXMLElement($this->newxml); pgsql8_diff::$new_table_dependency = xml_parser::table_dependency_order(dbsteward::$new_database); pgsql8_diff::$old_table_dependency = xml_parser::table_dependency_order(dbsteward::$old_database); $old_replica_set = pgsql8::get_slony_replica_sets(dbsteward::$old_database); $new_replica_set = pgsql8::get_slony_replica_sets(dbsteward::$new_database); $slony_prefix = dirname(__FILE__) . '/../testdata/slonyid_diff_test'; pgsql8::build_upgrade_slonik_replica_set(dbsteward::$old_database, dbsteward::$new_database, $old_replica_set, $new_replica_set, $slony_prefix); return $slony_prefix; }
public static function build_upgrade($old_output_prefix, $old_composite_file, $old_db_doc, $old_files, $new_output_prefix, $new_composite_file, $new_db_doc, $new_files) { // place the upgrade files with the new_files set $upgrade_prefix = $new_output_prefix . '_upgrade'; // pgsql8_diff needs these to intelligently create SQL difference statements in dependency order dbsteward::info("Calculating old table foreign key dependency order.."); pgsql8_diff::$old_table_dependency = xml_parser::table_dependency_order($old_db_doc); dbsteward::info("Calculating new table foreign key dependency order.."); pgsql8_diff::$new_table_dependency = xml_parser::table_dependency_order($new_db_doc); pgsql8_diff::diff_doc($old_composite_file, $new_composite_file, $old_db_doc, $new_db_doc, $upgrade_prefix); if (dbsteward::$generate_slonik) { $replica_sets = pgsql8::get_slony_replica_sets($new_db_doc); foreach ($replica_sets as $replica_set) { dbsteward::info("Generating replica set " . $replica_set['id'] . " upgrade slonik"); // separate upgrade slonik file sets for each replica set $slonik_upgrade_prefix = $upgrade_prefix . "_slony_replica_set_" . $replica_set['id']; // generate upgrade slonik to apply generated sql changes $old_new_slonik_header = "# Old definition: " . implode(', ', $old_files) . "\n" . "# New definition: " . implode(', ', $new_files) . "\n" . "# Replica set ID " . $replica_set['id'] . "\n"; $old_replica_set = pgsql8::get_slony_replica_set($old_db_doc, (string) $replica_set['id']); pgsql8::build_upgrade_slonik_replica_set($old_db_doc, $new_db_doc, $old_replica_set, $replica_set, $slonik_upgrade_prefix, $old_new_slonik_header); } } return $new_db_doc; }
private function common_mismatch($a, $b, $expected) { $docxml = <<<XML <dbsteward> <database> <host>db-host</host> <name>dbsteward</name> <role> <application>dbsteward_phpunit_app</application> <owner>deployment</owner> <replication/> <readonly/> </role> <slony clusterName="duplicate_slony_ids_testsuite"> <slonyNode id="1" comment="DSI - Local Primary" dbName="test" dbHost="db-dev1" dbUser="******" dbPassword="******"/> <slonyNode id="2" comment="DSI - Local Backup" dbName="test" dbHost="db-dev1" dbUser="******" dbPassword="******"/> <slonyNode id="3" comment="DSI - Local Backup" dbName="test" dbHost="db-dev1" dbUser="******" dbPassword="******"/> <slonyReplicaSet id="100" originNodeId="1" upgradeSetId="101" comment="common duplicate testing database definition"> <slonyReplicaSetNode id="2" providerNodeId="1"/> <slonyReplicaSetNode id="3" providerNodeId="2"/> </slonyReplicaSet> </slony> <configurationParameter name="TIME ZONE" value="America/New_York"/> </database> <schema name="dbsteward" owner="ROLE_OWNER"> XML; $adoc = new SimpleXMLElement($docxml . $a . "</schema></dbsteward>"); $bdoc = new SimpleXMLElement($docxml . $b . "</schema></dbsteward>"); pgsql8::$table_slony_ids = array(); pgsql8::$sequence_slony_ids = array(); pgsql8::$known_pg_identifiers = array(); // for ease in testing, since replica_sets will be the same between // adoc and bdoc, just use adoc for iterating over replica sets $replica_sets = pgsql8::get_slony_replica_sets($adoc); if ($expected !== false) { $this->expect_exception($expected, function () use($adoc, $bdoc, $replica_sets) { foreach ($replica_sets as $replica_set) { pgsql8::build_upgrade_slonik_replica_set($adoc, $bdoc, $replica_set, $replica_set, __DIR__ . '/../testdata/DuplicateSlonyIdsTest'); } }); } else { $this->expect_no_exception(function () use($adoc, $bdoc, $replica_sets) { foreach ($replica_sets as $replica_set) { pgsql8::build_upgrade_slonik_replica_set($adoc, $bdoc, $replica_set, $replica_set, __DIR__ . '/../testdata/DuplicateSlonyIdsTest'); } }); } }