136 lines
5.1 KiB
C#
136 lines
5.1 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())
|
|
{
|
|
db.Database.OpenConnection();
|
|
try
|
|
{
|
|
EnsureLegacySchemaHistory(db);
|
|
EnsureSplitMigrationHistory(db);
|
|
}
|
|
finally
|
|
{
|
|
db.Database.CloseConnection();
|
|
}
|
|
}
|
|
|
|
db.Database.Migrate();
|
|
}
|
|
|
|
private static void EnsureLegacySchemaHistory(RpgRollerDbContext db)
|
|
{
|
|
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();
|
|
|
|
InsertMigrationHistory(db, InitialMigrationId);
|
|
}
|
|
|
|
private static void EnsureSplitMigrationHistory(RpgRollerDbContext db)
|
|
{
|
|
if (!TableExists(db, "__EFMigrationsHistory"))
|
|
return;
|
|
|
|
if (!MigrationExists(db, CharactersCampaignDeletionMigrationId))
|
|
return;
|
|
|
|
if (MigrationExists(db, AuthorizationRolesMigrationId))
|
|
return;
|
|
|
|
if (!ColumnExists(db, "Users", "Roles"))
|
|
return;
|
|
|
|
InsertMigrationHistory(db, AuthorizationRolesMigrationId);
|
|
}
|
|
|
|
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 static bool MigrationExists(RpgRollerDbContext db, string migrationId)
|
|
{
|
|
using var command = db.Database.GetDbConnection().CreateCommand();
|
|
command.CommandText = """
|
|
SELECT 1
|
|
FROM "__EFMigrationsHistory"
|
|
WHERE "MigrationId" = $migrationId
|
|
LIMIT 1;
|
|
""";
|
|
var migrationParameter = command.CreateParameter();
|
|
migrationParameter.ParameterName = "$migrationId";
|
|
migrationParameter.Value = migrationId;
|
|
command.Parameters.Add(migrationParameter);
|
|
|
|
return command.ExecuteScalar() is not null;
|
|
}
|
|
|
|
private static void InsertMigrationHistory(RpgRollerDbContext db, string migrationId)
|
|
{
|
|
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 = migrationId;
|
|
insertHistoryCommand.Parameters.Add(migrationParameter);
|
|
|
|
var productVersionParameter = insertHistoryCommand.CreateParameter();
|
|
productVersionParameter.ParameterName = "$productVersion";
|
|
productVersionParameter.Value = ProductVersion;
|
|
insertHistoryCommand.Parameters.Add(productVersionParameter);
|
|
|
|
_ = insertHistoryCommand.ExecuteNonQuery();
|
|
}
|
|
|
|
private const string InitialMigrationId = "20260226084000_InitialSchema";
|
|
private const string CharactersCampaignDeletionMigrationId = "20260226160859_AddAuthorizationRolesAndCampaignDeletion";
|
|
private const string AuthorizationRolesMigrationId = "20260226170000_AddAuthorizationRoles";
|
|
private const string ProductVersion = "10.0.2";
|
|
} |