LANCommander/LANCommander.Server/Startup/Database.cs

111 lines
5 KiB
C#
Raw Permalink Normal View History

2025-12-16 19:35:36 -06:00
using LANCommander.SDK;
2025-03-11 21:21:16 -05:00
using LANCommander.SDK.Enums;
using LANCommander.Server.Data;
using LANCommander.Server.Data.Enums;
using LANCommander.Server.Data.Models;
using LANCommander.Server.Services;
using LANCommander.Server.Services.Models;
using LANCommander.Server.Settings.Enums;
2025-11-17 20:31:11 -06:00
using LANCommander.Server.Settings.Models;
2025-03-11 21:21:16 -05:00
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
2025-11-17 20:31:11 -06:00
using Microsoft.Extensions.Options;
using Octokit;
2025-03-11 21:21:16 -05:00
namespace LANCommander.Server.Startup;
public static class Database
{
public static WebApplicationBuilder AddDatabase(this WebApplicationBuilder builder, string[] args)
2025-03-11 21:21:16 -05:00
{
builder.Services.AddDbContextFactory<DatabaseContext>();
builder.Services.AddDbContext<DatabaseContext>();
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
2025-11-17 20:31:11 -06:00
return builder;
}
public static WebApplication UseDatabase(this WebApplication app, string[] args)
{
var settings = app.Services.GetRequiredService<IOptions<Settings.Settings>>();
2025-03-11 21:21:16 -05:00
var databaseProviderParameter = args.FirstOrDefault(arg => arg.StartsWith("--database-provider="))?.Split('=', 2).Last();
var connectionStringParameter = args.FirstOrDefault(arg => arg.StartsWith("--connection-string="))?.Split('=', 2).Last();
2025-03-11 21:21:16 -05:00
if (!String.IsNullOrWhiteSpace(databaseProviderParameter))
DatabaseContext.Provider = Enum.Parse<DatabaseProvider>(databaseProviderParameter);
else
2025-11-17 20:31:11 -06:00
DatabaseContext.Provider = settings.Value.Server.Database.Provider;
2025-03-11 21:21:16 -05:00
if (!String.IsNullOrWhiteSpace(connectionStringParameter))
DatabaseContext.ConnectionString = connectionStringParameter;
else
2025-11-17 20:31:11 -06:00
DatabaseContext.ConnectionString = settings.Value.Server.Database.ConnectionString;
2025-03-11 21:21:16 -05:00
2025-11-17 20:31:11 -06:00
return app;
}
2025-03-11 21:21:16 -05:00
2025-12-13 00:27:54 -06:00
public static async Task RunDatabaseMigrationsAsync(this WebApplication app)
2025-03-11 21:21:16 -05:00
{
if (DatabaseContext.Provider != DatabaseProvider.Unknown)
{
using var scope = app.Services.CreateAsyncScope();
using var db = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
var settingsProvider = scope.ServiceProvider.GetRequiredService<SettingsProvider<Settings.Settings>>();
2025-03-11 21:21:16 -05:00
logger.LogDebug("Migrating database if required");
if ((await db.Database.GetPendingMigrationsAsync()).Any())
{
if (DatabaseContext.Provider == DatabaseProvider.SQLite)
{
var dataSource = new SqliteConnectionStringBuilder(settingsProvider.CurrentValue.Server.Database.ConnectionString).DataSource;
2025-03-11 21:21:16 -05:00
2025-12-16 19:35:36 -06:00
var backupName = AppPaths.GetConfigPath("Backups", $"LANCommander.db.{DateTime.Now.ToString("dd-MM-yyyy-HH.mm.ss.bak")}");
2025-03-11 21:21:16 -05:00
if (File.Exists(dataSource))
{
2025-12-11 15:26:27 +11:00
logger.LogInformation("Migrations pending, database will be backed up to {BackupName}", backupName);
2025-03-11 21:21:16 -05:00
File.Copy(dataSource, backupName);
}
}
await db.Database.MigrateAsync();
var storageLocationService = scope.ServiceProvider.GetRequiredService<StorageLocationService>();
var archiveLocation = await storageLocationService.AddMissingAsync(l => l.Type == StorageLocationType.Archive && l.Default, new StorageLocation
{
2025-12-16 19:35:36 -06:00
Path = AppPaths.GetConfigPath("Uploads"),
2025-03-11 21:21:16 -05:00
Type = StorageLocationType.Archive,
Default = true,
});
if (!Directory.Exists(archiveLocation.Value.Path))
Directory.CreateDirectory(archiveLocation.Value.Path);
var mediaLocation = await storageLocationService.AddMissingAsync(l => l.Type == StorageLocationType.Media && l.Default, new StorageLocation
{
2025-12-16 19:35:36 -06:00
Path = AppPaths.GetConfigPath("Media"),
2025-03-11 21:21:16 -05:00
Type = StorageLocationType.Media,
Default = true,
});
if (!Directory.Exists(mediaLocation.Value.Path))
Directory.CreateDirectory(mediaLocation.Value.Path);
var saveLocation = await storageLocationService.AddMissingAsync(l => l.Type == StorageLocationType.Save && l.Default, new StorageLocation
{
2025-12-16 19:35:36 -06:00
Path = AppPaths.GetConfigPath("Saves"),
2025-03-11 21:21:16 -05:00
Type = StorageLocationType.Save,
Default = true,
});
if (!Directory.Exists(saveLocation.Value.Path))
Directory.CreateDirectory(saveLocation.Value.Path);
}
else
logger.LogDebug("No pending migrations are available. Skipping database migration.");
}
}
}