public override void Execute(HortonOptions options) { if (!options.Unattend) { Program.PrintLine("=== Add Migration ==="); Program.PrintLine(); } var migrationName = ""; if (options.ExtraArguments.Length > 0) { migrationName = options.ExtraArguments[0]; } while (string.IsNullOrEmpty(migrationName)) { if (options.Unattend) { Program.PrintErrorLine("Migration name is required while running in Unattend mode. Specificy Migration name as the last argument."); Environment.Exit(1); } Program.PrintLine("Please enter a name for the migration and press return."); migrationName = Console.ReadLine(); Program.PrintLine(); } migrationName = migrationName.Replace(" ", "_"); var loader = new FileLoader(options.MigrationsDirectoryPath); loader.LoadAllFiles(); var lastMigrationScript = loader.Files.OfType<MigrationScript>().OrderBy(x => x.SerialNumber).Last(); var newSerialNumber = lastMigrationScript.SerialNumber + 1; var serialNumberDigits = lastMigrationScript.FileName.IndexOf('_'); var newMigrationDirectory = Path.GetDirectoryName(lastMigrationScript.FilePath); var migrationFileName = newSerialNumber.ToString().PadLeft(serialNumberDigits, '0') + "_" + migrationName + ".sql"; var newMigrationFullFilePath = Path.Combine(newMigrationDirectory, migrationFileName); Program.Print("Writing migration: "); Program.PrintLine(ConsoleColor.DarkGreen, newMigrationFullFilePath); File.WriteAllText(newMigrationFullFilePath, ""); if (!options.Unattend) { System.Diagnostics.Process.Start(newMigrationFullFilePath); Program.PrintLine(); Program.PrintLine("Finished."); } }
public override void Execute(HortonOptions options) { using (var schemaInfo = new SchemaInfo(options)) { schemaInfo.InitializeTable(); Program.PrintLine("=== History ==="); Program.PrintLine(); Program.PrintLine("Timestamp (UTC) | File Name | User"); Program.PrintLine("---------------------------------------------------------------------"); foreach (var item in schemaInfo.AppliedMigrations) { Program.PrintLine($"{item.AppliedUTC.ToString("yyyy-MM-dd HH:mm:ss.ff")} | {TrimOrPad(item.FileName, 20)} | {TrimOrPad(item.SystemUser, 20)}"); } } }
public override void Execute(HortonOptions options) { using (var schemaInfo = new SchemaInfo(options)) { schemaInfo.InitializeTable(); var loader = new FileLoader(options.MigrationsDirectoryPath); loader.LoadAllFiles(); Program.PrintLine("=== Info ==="); Program.PrintLine(); Program.PrintLine("The following scripts will execute..."); bool willExecuteMigrations = true; foreach (var file in loader.Files) { var existingRecord = schemaInfo.AppliedMigrations.SingleOrDefault(x => x.FileNameMD5Hash == file.FileNameHash); if (existingRecord != null) { if (file.ContentMatches(existingRecord.ContentSHA1Hash)) { continue; } if (file.ConflictOnContent) { Program.PrintLine(ConsoleColor.Red, $"\nCONFLICT: The script \"{file.FileName}\" has changed since it was applied on \"{existingRecord.AppliedUTC.ToString("yyyy-MM-dd HH:mm:ss.ff")}\"."); willExecuteMigrations = false; continue; } } Program.PrintLine(ConsoleColor.DarkGreen, $"\n\"{file.FileName}\" will execute on UPDATE."); } if (!willExecuteMigrations) { Program.PrintLine(ConsoleColor.Red, $"\nWARNING! Migrations will not execute until conflicts are resolved."); Environment.Exit(1); } Program.PrintLine(); Program.PrintLine("Finished."); } }
public override void Execute(HortonOptions options) { using (var schemaInfo = new SchemaInfo(options)) { schemaInfo.InitializeTable(); var loader = new FileLoader(options.MigrationsDirectoryPath); loader.LoadAllFiles(); Program.PrintLine("=== Sync ==="); Program.PrintLine(); Program.PrintLine("Synchronizing conflicting scripts..."); foreach (var file in loader.Files) { var existingRecord = schemaInfo.AppliedMigrations.SingleOrDefault(x => x.FileNameMD5Hash == file.FileNameHash); if (existingRecord != null) { if (!file.ContentMatches(existingRecord.ContentSHA1Hash)) { Program.Print(ConsoleColor.Red, $"\n\"{file.FileName}\" has changed since it was applied on \"{existingRecord.AppliedUTC.ToString("yyyy-MM-dd HH:mm:ss.ff")}\" and will be updated."); Program.Print(ConsoleColor.Red, " Type 'Y' to Continue."); Program.PrintLine(); var c = Console.ReadKey(); if (c.KeyChar == 'y' || c.KeyChar == 'Y') { Program.PrintLine($"\nUpdating \"{file.FileName}\" with hash \"{file.ContentSHA1Hash}\""); schemaInfo.ResyncMigration(file); } else { Program.PrintLine("\nAborting..."); Environment.Exit(1); } } } } Program.PrintLine(); Program.PrintLine("Finished."); } }
private static void MainInternal(string[] args) { var options = new HortonOptions(); bool showHelp = false; bool printVersion = false; var p = new OptionSet() { { "m|migrations=", "path to migration scripts.\n(leave blank for current directory)", v => options.MigrationsDirectoryPath = v }, { "s|server=", "server hostname.\n(leave blank for \"localhost\")", v => options.ServerHostname = v }, { "d|database=", "database name.\n(leave blank to look for \"database.name\")", v => options.DatabaseName = v }, { "u|username="******"username of the database connection.\n(leave blank for integrated security)", v => options.Username = v }, { "p|password="******"password of the database connection.\n(required if username is provided)", v => options.Password = v }, { "c|connectionString=", "ADO.NET connection string.\n(optional, overrides other parameters)", v => options.ConnectionString = v }, { "U|UNATTEND", "Surpress user acknowledgement during\nexecution.", v => options.Unattend = v != null }, { "v|version", "Print version number and exit.", v => printVersion = v != null }, { "h|help|?", "show help message and exit.", v => showHelp = v != null }, }; if (args.Length == 0) { showHelp = true; } List<string> extra; try { extra = p.Parse(args); } catch (OptionException e) { Console.WriteLine(e.Message); Console.WriteLine("Try `horton.exe --help' for more information."); return; } if (!options.Unattend) { Console.WriteLine("Horton. The simple database migration utility."); } if (showHelp) { ShowHelp(p); return; } if (printVersion) { Console.WriteLine("Version: " + typeof(Program).Assembly.GetName().Version.ToString()); return; } options.Command = HortonCommands.TryParseCommand(extra.FirstOrDefault() ?? ""); options.ExtraArguments = extra.Skip(1).ToArray(); string firstValidationMessage = ""; if (!options.AssertValid(out firstValidationMessage)) { Console.WriteLine(firstValidationMessage); Console.WriteLine("Try `horton.exe --help' for more information."); Environment.Exit(1); } options.Command.Execute(options); }