Files
RpgRoller/RpgRoller/Hosting/SqliteSchemaUpgrader.cs
2026-02-26 11:08:02 +01:00

92 lines
3.6 KiB
C#

using Microsoft.EntityFrameworkCore;
using RpgRoller.Data;
namespace RpgRoller.Hosting;
public static class SqliteSchemaUpgrader
{
public static void ApplyPendingChanges(RpgRollerDbContext db)
{
if (db.Database.IsSqlite())
EnsureLegacySchemaHistory(db);
db.Database.Migrate();
}
private static void EnsureLegacySchemaHistory(RpgRollerDbContext db)
{
db.Database.OpenConnection();
try
{
if (TableExists(db, "__EFMigrationsHistory"))
return;
if (!TableExists(db, "Skills"))
return;
if (!ColumnExists(db, "Skills", "WildDice") || !ColumnExists(db, "Skills", "AllowFumble"))
return;
using var createHistoryCommand = db.Database.GetDbConnection().CreateCommand();
createHistoryCommand.CommandText = """
CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
"MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY,
"ProductVersion" TEXT NOT NULL
);
""";
_ = createHistoryCommand.ExecuteNonQuery();
using var insertHistoryCommand = db.Database.GetDbConnection().CreateCommand();
insertHistoryCommand.CommandText = """
INSERT OR IGNORE INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ($migrationId, $productVersion);
""";
var migrationParameter = insertHistoryCommand.CreateParameter();
migrationParameter.ParameterName = "$migrationId";
migrationParameter.Value = InitialMigrationId;
insertHistoryCommand.Parameters.Add(migrationParameter);
var productVersionParameter = insertHistoryCommand.CreateParameter();
productVersionParameter.ParameterName = "$productVersion";
productVersionParameter.Value = ProductVersion;
insertHistoryCommand.Parameters.Add(productVersionParameter);
_ = insertHistoryCommand.ExecuteNonQuery();
}
finally
{
db.Database.CloseConnection();
}
}
private static bool TableExists(RpgRollerDbContext db, string tableName)
{
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = "SELECT 1 FROM sqlite_master WHERE type='table' AND name=$name LIMIT 1;";
var parameter = command.CreateParameter();
parameter.ParameterName = "$name";
parameter.Value = tableName;
command.Parameters.Add(parameter);
return command.ExecuteScalar() is not null;
}
private static bool ColumnExists(RpgRollerDbContext db, string tableName, string columnName)
{
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = $"PRAGMA table_info('{tableName}');";
using var reader = command.ExecuteReader();
while (reader.Read())
{
var currentColumnName = reader.GetString(1);
if (string.Equals(currentColumnName, columnName, StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
private const string InitialMigrationId = "20260226084000_InitialSchema";
private const string ProductVersion = "10.0.2";
}