Add migrations

This commit is contained in:
Laura Hausmann 2022-02-09 20:42:02 +01:00
parent 34fbc4d7f5
commit f8aeed318f
Signed by: zotan
GPG Key ID: D044E84C5BE01605
4 changed files with 133 additions and 33 deletions

View File

@ -5,30 +5,31 @@ using LinqToDB;
using LinqToDB.Configuration;
using LinqToDB.Data;
namespace c3stream.DataModels {
public class Database {
public class ConnectionStringSettings : IConnectionStringSettings {
public string ConnectionString { get; set; }
public string Name { get; set; }
public string ProviderName { get; set; }
public bool IsGlobal => false;
}
namespace c3stream.DataModels;
public class Settings : ILinqToDBSettings {
public IEnumerable<IDataProviderSettings> DataProviders => Enumerable.Empty<IDataProviderSettings>();
public class Database {
public class ConnectionStringSettings : IConnectionStringSettings {
public string ConnectionString { get; set; }
public string Name { get; set; }
public string ProviderName { get; set; }
public bool IsGlobal => false;
}
public string DefaultConfiguration => "SQLite";
public string DefaultDataProvider => "SQLite";
public class Settings : ILinqToDBSettings {
public IEnumerable<IDataProviderSettings> DataProviders => Enumerable.Empty<IDataProviderSettings>();
public IEnumerable<IConnectionStringSettings> ConnectionStrings {
get { yield return new ConnectionStringSettings {Name = "db", ProviderName = "SQLite", ConnectionString = @"Data Source=data/c3stream.sqlite;"}; }
}
}
public string DefaultConfiguration => "SQLite";
public string DefaultDataProvider => "SQLite";
public class DbConn : DataConnection {
public DbConn() : base("db") { }
public ITable<States> States => GetTable<States>();
public IEnumerable<IConnectionStringSettings> ConnectionStrings {
get { yield return new ConnectionStringSettings { Name = "db", ProviderName = "SQLite", ConnectionString = @"Data Source=data/c3stream.sqlite;" }; }
}
}
public class DbConn : DataConnection {
public DbConn() : base("db") { }
public ITable<States> States => GetTable<States>();
public ITable<DbInfo> DbInfo => GetTable<DbInfo>();
}
}

View File

@ -0,0 +1,9 @@
using LinqToDB.Mapping;
namespace c3stream.DataModels.Tables;
[Table(Name = "DbInfo")]
public class DbInfo {
[Column(Name = "ID"), PrimaryKey, Identity, NotNull] public int Id { get; set; }
[Column(Name = "DbVer"), NotNull] public int DbVer { get; set; }
}

90
Migrations.cs Normal file
View File

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using c3stream.DataModels;
using c3stream.DataModels.Tables;
using LinqToDB;
using LinqToDB.Data;
namespace c3stream;
public static class Migrations {
private const int DbVer = 0;
private static readonly List<Migration> _migrations = new() { };
public static void RunMigrations() {
using var db = new Database.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<States>();
db.CreateTable<DbInfo>();
db.InsertWithIdentity(new DbInfo { DbVer = DbVer });
}
else if (db.DataProvider.GetSchemaProvider().GetSchema(db).Tables.All(t => t.TableName != "DbInfo")) {
db.CreateTable<DbInfo>();
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 {
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 Database.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 class Migration {
private readonly string _sql;
public readonly int IntroducedWithDbVer;
public Migration(int introducedWithDbVer, string sql) {
IntroducedWithDbVer = introducedWithDbVer;
_sql = sql;
}
public void Run(DataConnection db) {
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write("Running migration: ");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(_sql);
db.Execute(_sql);
}
}
}

View File

@ -7,36 +7,36 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="linq2db" Version="3.2.2" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.1" PrivateAssets="none" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="linq2db" Version="3.6.0"/>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3"/>
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.115.5"/>
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="data\database.json" />
<_ContentIncludedByDefault Remove="data\_c3stream.json" />
<_ContentIncludedByDefault Remove="data\33c3.json" />
<_ContentIncludedByDefault Remove="data\34c3.json" />
<_ContentIncludedByDefault Remove="data\35c3.json" />
<_ContentIncludedByDefault Remove="data\database.json"/>
<_ContentIncludedByDefault Remove="data\_c3stream.json"/>
<_ContentIncludedByDefault Remove="data\33c3.json"/>
<_ContentIncludedByDefault Remove="data\34c3.json"/>
<_ContentIncludedByDefault Remove="data\35c3.json"/>
</ItemGroup>
<ItemGroup>
<Compile Remove="data\**" />
<Compile Remove="data\**"/>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="data\**" />
<EmbeddedResource Remove="data\**"/>
</ItemGroup>
<ItemGroup>
<None Remove="data\**" />
<None Remove="data\**"/>
</ItemGroup>
<ItemGroup>
<Content Remove="data\**" />
<Content Remove="data\**"/>
</ItemGroup>
<ItemGroup>
<Folder Include="DataModels" />
<Folder Include="DataModels"/>
</ItemGroup>
</Project>