fixed migration scripts, moved migration code to dbservice
This commit is contained in:
parent
211f610d28
commit
45b507bf79
4 changed files with 69 additions and 78 deletions
src/EllieBot
|
@ -1,18 +1,22 @@
|
|||
using LinqToDB.Common;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using EllieBot.Migrations;
|
||||
|
||||
namespace EllieBot.Db;
|
||||
|
||||
public sealed class EllieDbService : DbService
|
||||
public sealed class EllieDbService : DbService
|
||||
{
|
||||
private readonly IBotCredsProvider _creds;
|
||||
|
||||
// these are props because creds can change at runtime
|
||||
private string DbType => _creds.GetCreds().Db.Type.ToLowerInvariant().Trim();
|
||||
private string ConnString => _creds.GetCreds().Db.ConnectionString;
|
||||
|
||||
private string DbType
|
||||
=> _creds.GetCreds().Db.Type.ToLowerInvariant().Trim();
|
||||
|
||||
private string ConnString
|
||||
=> _creds.GetCreds().Db.ConnectionString;
|
||||
|
||||
public EllieDbService(IBotCredsProvider creds)
|
||||
{
|
||||
LinqToDBForEFTools.Initialize();
|
||||
|
@ -28,14 +32,14 @@ public sealed class EllieDbService : DbService
|
|||
|
||||
await using var context = CreateRawDbContext(dbType, connString);
|
||||
|
||||
await MigrationRunner.RunMigration(context);
|
||||
|
||||
await RunMigration(context);
|
||||
|
||||
// make sure sqlite db is in wal journal mode
|
||||
if (context is SqliteContext)
|
||||
{
|
||||
await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL");
|
||||
}
|
||||
|
||||
|
||||
// await context.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
|
@ -53,7 +57,7 @@ public sealed class EllieDbService : DbService
|
|||
throw new NotSupportedException($"The database provide type of '{dbType}' is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private EllieContext GetDbContextInternal()
|
||||
{
|
||||
var dbType = DbType;
|
||||
|
@ -74,4 +78,52 @@ public sealed class EllieDbService : DbService
|
|||
|
||||
public override EllieContext GetDbContext()
|
||||
=> GetDbContextInternal();
|
||||
|
||||
private static async Task RunMigration(DbContext ctx)
|
||||
{
|
||||
// if database doesn't exist, run the baseline migration
|
||||
if (!await ctx.Database.CanConnectAsync())
|
||||
{
|
||||
Log.Information("Database does not exist. Creating a new database...");
|
||||
await ctx.Database.MigrateAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// get the latest applied migration
|
||||
|
||||
var applied = await ctx.Database.GetAppliedMigrationsAsync();
|
||||
|
||||
// get all .sql file names from the migrations folder
|
||||
var available = Directory.GetFiles("Migrations/Sqlite", "*_*.sql")
|
||||
.Select(x => Path.GetFileNameWithoutExtension(x))
|
||||
.OrderBy(x => x);
|
||||
|
||||
var lastApplied = applied.Last();
|
||||
Log.Information("Last applied migration: {LastApplied}", lastApplied);
|
||||
|
||||
// apply all mirations with names greater than the last applied
|
||||
foreach (var runnable in available)
|
||||
{
|
||||
if (string.Compare(lastApplied, runnable, StringComparison.Ordinal) < 0)
|
||||
{
|
||||
Log.Warning("Migration {MigrationName} has not been applied yet", runnable);
|
||||
|
||||
var query = await File.ReadAllTextAsync(GetMigrationPath(ctx.Database, runnable));
|
||||
await ctx.Database.ExecuteSqlRawAsync(query);
|
||||
}
|
||||
}
|
||||
|
||||
// run all migrations that have not been applied yet
|
||||
}
|
||||
|
||||
private static string GetMigrationPath(DatabaseFacade ctxDatabase, string runnable)
|
||||
{
|
||||
if (ctxDatabase.IsSqlite())
|
||||
return $"Migrations/Sqlite/{runnable}.sql";
|
||||
|
||||
if (ctxDatabase.IsNpgsql())
|
||||
return $"Migrations/PostgreSql/{runnable}.sql";
|
||||
|
||||
throw new NotSupportedException("This database type is not supported.");
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace EllieBot.Migrations;
|
||||
|
||||
public class MigrationRunner
|
||||
{
|
||||
public static async Task RunMigration(DbContext ctx)
|
||||
{
|
||||
// if database doesn't exist, run the baseline migration
|
||||
if (!await ctx.Database.CanConnectAsync())
|
||||
{
|
||||
Log.Information("Database does not exist. Creating a new database...");
|
||||
await ctx.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
// get the latest applied migration
|
||||
|
||||
var applied = await ctx.Database.GetAppliedMigrationsAsync();
|
||||
|
||||
// get all .sql file names from the migrations folder
|
||||
var available = Directory.GetFiles("Migrations/Sqlite", "*_*.sql")
|
||||
.Select(x => Path.GetFileNameWithoutExtension(x))
|
||||
.OrderBy(x => x);
|
||||
|
||||
string lastApplied = applied.Last();
|
||||
Log.Information("Last applied migration: {LastApplied}", lastApplied);
|
||||
|
||||
// apply all mirations with names greater than the last applied
|
||||
foreach (var runnable in available)
|
||||
{
|
||||
if (string.Compare(lastApplied, runnable, StringComparison.Ordinal) < 0)
|
||||
{
|
||||
Log.Warning("Migration {MigrationName} has not been applied yet", runnable);
|
||||
|
||||
var query = await File.ReadAllTextAsync(GetMigrationPath(ctx.Database, runnable));
|
||||
await ctx.Database.ExecuteSqlRawAsync(query);
|
||||
}
|
||||
}
|
||||
|
||||
// run all migrations that have not been applied yet
|
||||
}
|
||||
|
||||
private static string GetMigrationPath(DatabaseFacade ctxDatabase, string runnable)
|
||||
{
|
||||
if (ctxDatabase.IsSqlite())
|
||||
return $"Migrations/Sqlite/{runnable}.sql";
|
||||
|
||||
if (ctxDatabase.IsNpgsql())
|
||||
return $"Migrations/PostgreSql/{runnable}.sql";
|
||||
|
||||
throw new NotSupportedException("This database type is not supported.");
|
||||
}
|
||||
}
|
|
@ -8,10 +8,6 @@ Write-Output "Creating new migration..."
|
|||
# Step 1: Create initial migrations
|
||||
dotnet build
|
||||
|
||||
# Get previous migration IDs
|
||||
$firstMigrationIdSqlite = (dotnet ef migrations list --context SqliteContext --no-build --no-connect | Select-Object -Last 2 | Select-Object -First 1) -split ' ' | Select-Object -First 1
|
||||
$firstMigrationIdPostgresql = (dotnet ef migrations list --context PostgresqlContext --no-build --no-connect | Select-Object -Last 2 | Select-Object -First 1) -split ' ' | Select-Object -First 1
|
||||
|
||||
dotnet ef migrations add $MigrationName --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add $MigrationName --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
||||
|
||||
|
@ -28,8 +24,8 @@ Write-Output "Generating diff SQL scripts..."
|
|||
$newMigrationIdSqlite = (dotnet ef migrations list --context SqliteContext --no-build --no-connect | Select-Object -Last 2 | Select-Object -First 1) -split ' ' | Select-Object -First 1
|
||||
$newMigrationIdPostgresql = (dotnet ef migrations list --context PostgresqlContext --no-build --no-connect | Select-Object -Last 2 | Select-Object -First 1) -split ' ' | Select-Object -First 1
|
||||
|
||||
dotnet ef migrations script ($firstMigrationIdSqlite -replace '^.*_', '') $MigrationName --context SqliteContext -o "Migrations/Sqlite/$newMigrationIdSqlite.sql" --no-build
|
||||
dotnet ef migrations script ($firstMigrationIdPostgresql -replace '^.*_', '') $MigrationName --context PostgresqlContext -o "Migrations/Postgresql/$newMigrationIdPostgresql.sql" --no-build
|
||||
dotnet ef migrations script init $MigrationName --context SqliteContext -o "Migrations/Sqlite/$newMigrationIdSqlite.sql" --no-build
|
||||
dotnet ef migrations script init $MigrationName --context PostgresqlContext -o "Migrations/Postgresql/$newMigrationIdPostgresql.sql" --no-build
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Error: Failed to generate SQL script"
|
||||
|
@ -53,5 +49,5 @@ dotnet build
|
|||
|
||||
# Step 4: Create new initial migrations
|
||||
Write-Output "Creating new initial migration..."
|
||||
dotnet ef migrations add $MigrationName --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add $MigrationName --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
||||
dotnet ef migrations add init --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add init --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
|
@ -15,9 +15,6 @@ echo "Creating new migration..."
|
|||
dotnet build
|
||||
|
||||
# Getting previous migration names in order to generate SQL scripts
|
||||
FIRST_MIGRATION_ID_SQLITE=$(dotnet ef migrations list --context SqliteContext --no-build --no-connect | tail -2 | head -1 | cut -d' ' -f1)
|
||||
FIRST_MIGRATION_ID_POSTGRESQL=$(dotnet ef migrations list --context PostgresqlContext --no-build --no-connect | tail -2 | head -1 | cut -d' ' -f1)
|
||||
|
||||
dotnet ef migrations add "${MIGRATION_NAME}" --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add "${MIGRATION_NAME}" --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
||||
|
||||
|
@ -35,8 +32,8 @@ echo "Generating diff SQL scripts..."
|
|||
NEW_MIGRATION_ID_SQLITE=$(dotnet ef migrations list --context SqliteContext --no-build --no-connect | tail -2 | head -1 | cut -d' ' -f1)
|
||||
NEW_MIGRATION_ID_POSTGRESQL=$(dotnet ef migrations list --context PostgresqlContext --no-build --no-connect | tail -2 | head -1 | cut -d' ' -f1)
|
||||
|
||||
dotnet ef migrations script "${FIRST_MIGRATION_ID_SQLITE#*_}" $MIGRATION_NAME --context SqliteContext -o "Migrations/Sqlite/${NEW_MIGRATION_ID_SQLITE}.sql" --no-build
|
||||
dotnet ef migrations script "${FIRST_MIGRATION_ID_POSTGRESQL#*_}" $MIGRATION_NAME --context PostgresqlContext -o "Migrations/Postgresql/${NEW_MIGRATION_ID_POSTGRESQL}.sql" --no-build
|
||||
dotnet ef migrations script init $MIGRATION_NAME --context SqliteContext -o "Migrations/Sqlite/${NEW_MIGRATION_ID_SQLITE}.sql" --no-build
|
||||
dotnet ef migrations script init $MIGRATION_NAME --context PostgresqlContext -o "Migrations/Postgresql/${NEW_MIGRATION_ID_POSTGRESQL}.sql" --no-build
|
||||
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -78,8 +75,8 @@ for file in "Migrations/Postgresql"/*; do
|
|||
done
|
||||
|
||||
# Step 4: Adding new initial migration
|
||||
echo "Creating new initial migration..."
|
||||
|
||||
dotnet build
|
||||
echo "Creating new initial migration..."
|
||||
dotnet ef migrations add "${MIGRATION_NAME}" --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add "${MIGRATION_NAME}" --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
||||
dotnet ef migrations add init --context SqliteContext --output-dir "Migrations/Sqlite" --no-build
|
||||
dotnet ef migrations add init --context PostgresqlContext --output-dir "Migrations/PostgreSql" --no-build
|
Loading…
Add table
Reference in a new issue