using System; using System.Collections.Generic; using System.Linq; using LinqToDB; using LinqToDB.Data; using RTMPDash.DataModels; using RTMPDash.DataModels.Tables; using RTMPDash.Pages; namespace RTMPDash; /** * TODO: Initial migrations should create all tables & an admin user and print a randomly generated password for the admin user * * */ public static class Migrations { public const int DbVer = 2; private static readonly List _migrations = new() { new Migration(1, "ALTER TABLE Users ADD IsPrivate INTEGER DEFAULT 0 NOT NULL"), new Migration(1, "ALTER TABLE Users ADD PrivateAccessKey TEXT"), new Migration(2, "ALTER TABLE Users ADD PronounPlural INTEGER DEFAULT 0 NOT NULL"), new Migration(2, "UPDATE Users SET PronounPlural = 1 WHERE PronounSubject = 'they'") }; public static void RunMigrations() { using var db = new AppDb.DbConn(); var ccolor = Console.ForegroundColor; if (!db.DataProvider.GetSchemaProvider().GetSchema(db).Tables.Any()) { Console.ForegroundColor = ConsoleColor.DarkCyan; Console.Write("Running migration: "); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Initialize Database"); db.CreateTable(); db.CreateTable(); db.CreateTable(); db.InsertWithIdentity(new DbInfo { DbVer = DbVer }); var password = Convert.ToBase64String(Guid.NewGuid().ToByteArray())[..12]; db.InsertWithIdentity(new User { Username = "admin", Password = password.Sha256(), StreamKey = Guid.NewGuid().ToString(), PronounSubject = "they", PronounPossessive = "their", PronounPlural = true, AllowRestream = true }); Console.ForegroundColor = ConsoleColor.Green; Console.Write("The user "); Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.Write("admin "); Console.ForegroundColor = ConsoleColor.Green; 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(); db.InsertWithIdentity(new DbInfo { DbVer = 0 }); } Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Database version: {db.DbInfo.ToList().First().DbVer}"); var migrationsToRun = _migrations.FindAll(p => p.IntroducedWithDbVer > db.DbInfo.First().DbVer); if (migrationsToRun.Count == 0) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("No migrations to run."); } else { migrationsToRun.ForEach(RunMigration); var newdb = new AppDb.DbConn(); var dbinfo = newdb.DbInfo.First(); dbinfo.DbVer = DbVer; newdb.Update(dbinfo); Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine($"Database version is now: {DbVer}"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Finished running migrations."); } Console.ForegroundColor = ccolor; } private static void RunMigration(Migration mig) => mig.Run(); private class Migration { private readonly string _sql; public readonly int IntroducedWithDbVer; public Migration(int introducedWithDbVer, string sql) { IntroducedWithDbVer = introducedWithDbVer; _sql = sql; } public void Run() { using var db = new AppDb.DbConn(); Console.ForegroundColor = ConsoleColor.DarkCyan; Console.Write("Running migration: "); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(_sql); db.Execute(_sql); } } }