LANCommander/LANCommander.Server/Migrations/SqliteDatabaseLocationMigration.cs
Aaron Powell 8600bae9ec Overhauling the migrations to be a bit more explicit in the steps that they go through.
Changed the IMigration interface to have a series of steps, first a method to indicate that the migration should run, next some pre-checks (like is it in a container), and lastly the actual execution.

Next, the settings and folder migrations are broken into individual migrations, which means that it's a lot more obvious which ones run and which ones are skipped.
2025-12-18 10:57:26 +11:00

79 lines
3.1 KiB
C#

using LANCommander.SDK;
using LANCommander.SDK.Migrations;
using Microsoft.Data.Sqlite;
using Semver;
namespace LANCommander.Server.Migrations;
/// <summary>
/// Migration for moving SQLite database from old location to new config directory and update the connection string.
/// </summary>
public class SqliteDatabaseLocationMigration(ILogger<SqliteDatabaseLocationMigration> logger, SettingsProvider<Settings.Settings> settingsProvider) : FileSystemMigration(logger)
{
public override SemVersion Version => new(2, 0, 0);
public override Task<bool> ShouldExecuteAsync()
{
var settings = settingsProvider.CurrentValue;
// Ensure we have settings available
if (settings is null)
{
logger.LogWarning("Settings are null, cannot perform SQLite database location migration.");
return Task.FromResult(false);
}
// Only proceed if using SQLite
if (settings.Server.Database.Provider != Settings.Enums.DatabaseProvider.SQLite)
{
logger.LogInformation("Database provider is not SQLite, skipping database location migration.");
return Task.FromResult(false);
}
var oldConnectionString = settings.Server.Database.ConnectionString;
// Ensure connection string is not empty
if (string.IsNullOrWhiteSpace(oldConnectionString))
{
logger.LogWarning("Database connection string is empty, cannot perform SQLite database location migration.");
return Task.FromResult(false);
}
var csb = new SqliteConnectionStringBuilder(oldConnectionString);
var location = csb.DataSource;
// Check if the file exists at the old location
if (!Path.Exists(location))
{
logger.LogWarning("SQLite database file does not exist at the specified location: {Location}", location);
return Task.FromResult(false);
}
// Ensure the new config path exists
if (!Path.Exists(AppPaths.GetConfigDirectory()))
{
logger.LogWarning("Config path does not exist: {ConfigPath}", AppPaths.GetConfigDirectory());
return Task.FromResult(false);
}
return Task.FromResult(true);
}
public override Task ExecuteAsync()
{
var settings = settingsProvider.CurrentValue;
var oldConnectionString = settings.Server.Database.ConnectionString;
var csb = new SqliteConnectionStringBuilder(oldConnectionString);
var location = csb.DataSource;
// Copy the database file to the new location and update the connection string
var newDatabasePath = AppPaths.GetConfigPath(Settings.Settings.SQLITE_DEFAULT_DB_NAME);
File.Copy(location, newDatabasePath);
csb.DataSource = newDatabasePath;
settingsProvider.Update(s =>
{
s.Server.Database.ConnectionString = csb.ConnectionString;
});
logger.LogInformation("SQLite database file moved to new location: {NewLocation} and settings have been updated.", newDatabasePath);
return Task.CompletedTask;
}
}