/** * @todo should *all* sequences be dropped in stage3, rather than just the shim? * the only reason we don't is because pgsql8 drops in stage 1... */ public static function diff_sequences($ofs1, $ofs3, $old_schema, $new_schema) { $new_sequences = static::get_sequences($new_schema); if ($old_schema != null) { $old_sequences = static::get_sequences($old_schema); } else { $old_sequences = array(); } if (empty($new_sequences)) { // there are no sequences in the new schema, so if there used to be sequences, // we can just drop the whole shim table if (!empty($old_sequences)) { $ofs3->write(mysql5_sequence::get_shim_drop_sql()); } } else { // there *are* sequences in the new schema, so if there didn't used to be, // we need to add the shim in before adding any sequences if (empty($old_sequences)) { $ofs1->write(mysql5_sequence::get_shim_creation_sql() . "\n\n"); $ofs1->write(mysql5_sequence::get_creation_sql($new_schema, $new_sequences) . "\n"); } else { // there were schemas in the old schema $common_sequences = array(); // only drop sequences not in the new schema $to_drop = array(); foreach ($old_sequences as $old_seq) { if (static::schema_contains_sequence($new_schema, $old_seq['name'], true)) { // if the sequence *is* in the new schema, then it might have changed $common_sequences[(string) $old_seq['name']] = $old_seq; } else { $to_drop[] = $old_seq; } } if (!empty($to_drop)) { $ofs1->write(mysql5_sequence::get_drop_sql($old_schema, $to_drop) . "\n\n"); } // only add sequences not in the old schema $to_insert = array(); foreach ($new_sequences as $new_seq) { if (static::schema_contains_sequence($old_schema, $new_seq['name'])) { // there used to be a sequence named $new_seq['name'] self::diff_single($ofs1, $common_sequences[(string) $new_seq['name']], $new_seq); } elseif (!dbsteward::$ignore_oldnames && !empty($new_seq['oldSequenceName']) && static::schema_contains_sequence($old_schema, $new_seq['oldSequenceName'])) { // there used to be a sequence named $new_seq['oldSequenceName'] self::diff_single($ofs1, $common_sequences[(string) $new_seq['oldSequenceName']], $new_seq); } else { $to_insert[] = $new_seq; } } if (!empty($to_insert)) { $ofs1->write(mysql5_sequence::get_creation_sql($new_schema, $to_insert) . "\n"); } } } }
protected static function drop_old_schemas($ofs) { $drop_sequences = array(); if (is_array(mysql5_diff::$old_table_dependency)) { $deps = mysql5_diff::$old_table_dependency; $processed_schemas = array(); foreach ($deps as $dep) { $old_schema = $dep['schema']; if (!dbx::get_schema(dbsteward::$new_database, $old_schema['name'])) { // this schema is being dropped, drop all children objects in it if (!in_array(trim($old_schema['name']), $processed_schemas)) { // this schema hasn't been processed yet, go ahead and drop views, types, functions, sequences // only do it once per schema foreach ($old_schema->type as $node_type) { $ofs->write(mysql5_type::get_drop_sql($old_schema, $node_type) . "\n"); } foreach ($old_schema->function as $node_function) { $ofs->write(mysql5_function::get_drop_sql($old_schema, $node_function) . "\n"); } foreach ($old_schema->sequence as $node_sequence) { $ofs->write(mysql5_sequence::get_drop_sql($old_schema, $node_sequence) . "\n"); } $processed_schemas[] = trim($old_schema['name']); } if ($dep['table']['name'] === dbsteward::TABLE_DEPENDENCY_IGNORABLE_NAME) { // don't do anything with this table, it is a magic internal DBSteward value continue; } // constraints, indexes, triggers will be deleted along with the tables they're attached to // tables will drop themselves later on // $ofs->write(mysql5_table::get_drop_sql($old_schema, $dep['table']) . "\n"); $table_name = mysql5::get_fully_qualified_table_name($dep['schema']['name'], $dep['table']['name']); $ofs->write("-- {$table_name} triggers, indexes, constraints will be implicitly dropped when the table is dropped\n"); $ofs->write("-- {$table_name} will be dropped later according to table dependency order\n"); // table sequences need dropped separately foreach (mysql5_table::get_sequences_needed($old_schema, $dep['table']) as $node_sequence) { $ofs->write(mysql5_sequence::get_drop_sql($old_schema, $node_sequence) . "\n"); } } } } else { foreach (dbsteward::$old_database->schema as $old_schema) { if (!dbx::get_schema(dbsteward::$new_database, $old_schema['name'])) { foreach ($old_schema->type as $node_type) { $ofs->write(mysql5_type::get_drop_sql($old_schema, $node_type) . "\n"); } foreach ($old_schema->function as $node_function) { $ofs->write(mysql5_function::get_drop_sql($old_schema, $node_function) . "\n"); } foreach ($old_schema->sequence as $node_sequence) { $ofs->write(mysql5_sequence::get_drop_sql($old_schema, $node_sequence) . "\n"); } foreach ($old_schema->table as $node_table) { // tables will drop themselves later on // $ofs->write(mysql5_table::get_drop_sql($old_schema, $node_table) . "\n"); $table_name = mysql5::get_fully_qualified_table_name($old_schema['name'], $node_table['name']); $ofs->write("-- {$table_name} triggers, indexes, constraints will be implicitly dropped when the table is dropped\n"); $ofs->write("-- {$table_name} will be dropped later according to table dependency order\n"); foreach (mysql5_table::get_sequences_needed($old_schema, $node_table) as $node_sequence) { $ofs->write(mysql5_sequence::get_drop_sql($old_schema, $node_sequence) . "\n"); } } } } } }
public function testMultipleSequences() { $xml = <<<XML <schema name="test" owner="NOBODY"> <sequence name="seq0" max="10" cycle="true" inc="3" start="2"/> <sequence name="seq1" max="10" cycle="true" inc="3" start="2"/> <sequence name="seq2" max="10" cycle="true" inc="3" start="2"/> </schema> XML; $schema = new SimpleXMLElement($xml); $expected = <<<SQL INSERT INTO `__sequences` (`name`, `increment`, `min_value`, `max_value`, `cur_value`, `start_value`, `cycle`) VALUES ('seq0', 3, DEFAULT, 10, 2, 2, TRUE), ('seq1', 3, DEFAULT, 10, 2, 2, TRUE), ('seq2', 3, DEFAULT, 10, 2, 2, TRUE); SQL; $actual = trim(preg_replace('/--.*/', '', mysql5_sequence::get_creation_sql($schema, $schema->sequence))); $this->assertEquals($expected, $actual); $expected_drop = "DELETE FROM `__sequences` WHERE `name` IN ('seq0', 'seq1', 'seq2');"; $actual_drop = trim(preg_replace('/--.*/', '', mysql5_sequence::get_drop_sql($schema, $schema->sequence))); $this->assertEquals($expected_drop, $actual_drop); }