public override void Perform(SchemaChanges changes, IOutput output) { foreach (var pending in PendingReorderTableType.AllFrom(changes.Current)) { var originalTable = TableType.Identifier(pending.Name); var tempTable = pending.ParentIdentifier; if (object.Equals(originalTable, tempTable)) { // If the database fails at precisely the wrong time, the rename can be succeed without dropping the PendingReorder, // so the table thinks it's to be renamed to itself. In that case we need to drop the PendingReorder, NOT drop the table! output.Verbose("Cleaning up after completed reorder of columns in " + originalTable); changes.Remove(null, pending); } else if (changes.Current.ContainsRoot(originalTable)) { // If the original table still exists, we drop the temp table so we can start over (in case the data in the table has changed since the temp table // was created, or the reordering has somehow become unnecessary). output.Verbose("Clearing pending reorder of columns in " + originalTable); changes.Remove(changes.SchemaDriver.GetDropTableSql(pending.ParentName), changes.Current.GetRoot(pending.ParentIdentifier)); } else { // The original table has been dropped so we need to recreate it by renaming the temp table. output.Verbose("Completing pending reordering of columns in " + originalTable); changes.Rename(changes.SchemaDriver.GetRenameTableSql(tempTable.Name, originalTable.Name), tempTable, originalTable); // And forget about the pending rename. changes.Remove(null, pending.WithParent(originalTable)); } } }
private void renameTempTables(SchemaChanges changes, IOutput output) { // For any PendingReorderTables where the original table doesn't exist, rename the table to the target name and remove the pending rename. foreach (var pending in PendingReorderTableType.AllFrom(changes.Current)) { var originalTable = TableType.Identifier(pending.Name); var tempTable = pending.ParentIdentifier; if (changes.Current.ContainsRoot(originalTable)) { continue; } changes.Rename(changes.SchemaDriver.GetRenameTableSql(tempTable.Name, originalTable.Name), tempTable, originalTable); changes.Remove(null, pending.WithParent(originalTable)); } }
private void dropOriginalTables(SchemaChanges changes, IOutput output) { // For any tables that are the target of existing PendingReorderTables, drop them (without prompting). foreach (var pending in PendingReorderTableType.AllFrom(changes.Current)) { var originalTable = TableType.Identifier(pending.Name); var tempTable = pending.ParentIdentifier; if (!changes.Current.ContainsRoot(originalTable)) { continue; } // FIXME: (Consider sanity checks before doing this - anything from "confirm all the right column names exist" to "confirm the right number of rows exist" to // "confirm all the data is identical in all the rows") changes.Remove(changes.SchemaDriver.GetDropTableSql(originalTable.Name), changes.Current.GetRoot(originalTable)); } }
public override void Perform(SchemaChanges changes, IOutput output) { var renames = from rename in TableRenameType.AllFrom(changes.Desired) where changes.Current.ContainsRoot(TableType.Identifier(rename.Name)) group rename by rename.State.ToTable into destination select destination; foreach (var rename in renames) { var toTable = rename.Key; if (rename.Count() > 1) { changes.Fail("Rename conflict: Multiple tables (" + string.Join(", ", from source in rename select source.Name) + ") wish to be renamed to " + toTable.Name); continue; } var fromTable = TableType.Identifier(rename.Single().Name); if (changes.Current.ContainsRoot(toTable)) { changes.Fail("Rename conflict: " + fromTable + " wishes to be renamed to " + rename.Key.Name + ", but that table already exists."); continue; } if (changes.Desired.ContainsRoot(fromTable)) { changes.Fail("Rename conflict: " + fromTable + " wishes to be renamed to " + rename.Key.Name + " but also to continue existing with its current name."); continue; } if (!changes.Desired.ContainsRoot(toTable)) { changes.Fail("Rename conflict: " + fromTable + " wishes to be renamed to " + rename.Key.Name + " but that table is not supposed to exist."); continue; } changes.Rename(changes.SchemaDriver.GetRenameTableSql(fromTable.Name, toTable.Name), fromTable, toTable); } }