From 2d8fdc27d20ea25bed4fd2a0e66bef7da40bd0b5 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Wed, 9 Feb 2022 18:26:27 +0100 Subject: [PATCH] Make migrations atomic and error-proof --- Migrations.cs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Migrations.cs b/Migrations.cs index b6622b4..31ef739 100644 --- a/Migrations.cs +++ b/Migrations.cs @@ -55,7 +55,6 @@ public static class Migrations { Console.Write("has been created with the password "); Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.WriteLine(password); - Console.WriteLine(); } else if (db.DataProvider.GetSchemaProvider().GetSchema(db).Tables.All(t => t.TableName != "DbInfo")) { db.CreateTable(); @@ -71,7 +70,20 @@ public static class Migrations { Console.WriteLine("No migrations to run."); } else { - migrationsToRun.ForEach(RunMigration); + new Migration(0, "BEGIN TRANSACTION").Run(db); + try { + migrationsToRun.ForEach(p => p.Run(db)); + } + catch { + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.WriteLine($"Migrating to database version {DbVer} failed."); + new Migration(0, "ROLLBACK TRANSACTION").Run(db); + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine("Rolled back migrations."); + Environment.Exit(1); + } + + new Migration(0, "COMMIT TRANSACTION").Run(db); var newdb = new AppDb.DbConn(); var dbinfo = newdb.DbInfo.First(); @@ -87,8 +99,6 @@ public static class Migrations { Console.ForegroundColor = ccolor; } - private static void RunMigration(Migration mig) => mig.Run(); - private class Migration { private readonly string _sql; public readonly int IntroducedWithDbVer; @@ -98,9 +108,7 @@ public static class Migrations { _sql = sql; } - public void Run() { - using var db = new AppDb.DbConn(); - + public void Run(DataConnection db) { Console.ForegroundColor = ConsoleColor.DarkCyan; Console.Write("Running migration: "); Console.ForegroundColor = ConsoleColor.Yellow;