Make migrations atomic and error-proof

This commit is contained in:
Laura Hausmann 2022-02-09 18:26:27 +01:00
parent 572926650c
commit 2d8fdc27d2
Signed by: zotan
GPG key ID: D044E84C5BE01605

View file

@ -55,7 +55,6 @@ public static class Migrations {
Console.Write("has been created with the password "); Console.Write("has been created with the password ");
Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.ForegroundColor = ConsoleColor.DarkMagenta;
Console.WriteLine(password); Console.WriteLine(password);
Console.WriteLine();
} }
else if (db.DataProvider.GetSchemaProvider().GetSchema(db).Tables.All(t => t.TableName != "DbInfo")) { else if (db.DataProvider.GetSchemaProvider().GetSchema(db).Tables.All(t => t.TableName != "DbInfo")) {
db.CreateTable<DbInfo>(); db.CreateTable<DbInfo>();
@ -71,7 +70,20 @@ public static class Migrations {
Console.WriteLine("No migrations to run."); Console.WriteLine("No migrations to run.");
} }
else { 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 newdb = new AppDb.DbConn();
var dbinfo = newdb.DbInfo.First(); var dbinfo = newdb.DbInfo.First();
@ -87,8 +99,6 @@ public static class Migrations {
Console.ForegroundColor = ccolor; Console.ForegroundColor = ccolor;
} }
private static void RunMigration(Migration mig) => mig.Run();
private class Migration { private class Migration {
private readonly string _sql; private readonly string _sql;
public readonly int IntroducedWithDbVer; public readonly int IntroducedWithDbVer;
@ -98,9 +108,7 @@ public static class Migrations {
_sql = sql; _sql = sql;
} }
public void Run() { public void Run(DataConnection db) {
using var db = new AppDb.DbConn();
Console.ForegroundColor = ConsoleColor.DarkCyan; Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write("Running migration: "); Console.Write("Running migration: ");
Console.ForegroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Yellow;