Settings for the server are now combined with the settings from the SDK. This introduces a large breaking change and a migration should be created. This refactor utilizes .NET Configuration and the Options pattern. This will allow for the overriding of any setting using envionment variables. It also means that Settings.yml can be used to override any .NET configuration. A SettingsProvider implementation was created, and any updating of settings was changed from SettingsService.SaveSettings() to SettingsProvider.Update(s => { ... })
105 lines
No EOL
4.7 KiB
C#
105 lines
No EOL
4.7 KiB
C#
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;
|
|
using Microsoft.Data.Sqlite;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Octokit;
|
|
using Serilog;
|
|
|
|
namespace LANCommander.Server.Startup;
|
|
|
|
public static class Database
|
|
{
|
|
public static WebApplicationBuilder AddDatabase(this WebApplicationBuilder builder, string[] args)
|
|
{
|
|
var settings = new Settings.Settings();
|
|
builder.Configuration.Bind(settings);
|
|
|
|
builder.Services.AddDbContextFactory<DatabaseContext>();
|
|
builder.Services.AddDbContext<DatabaseContext>();
|
|
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
|
|
|
var databaseProviderParameter = args.FirstOrDefault(arg => arg.StartsWith("--database-provider="))?.Split('=', 2).Last();
|
|
var connectionStringParameter = args.FirstOrDefault(arg => arg.StartsWith("--connection-string="))?.Split('=', 2).Last();
|
|
|
|
if (!String.IsNullOrWhiteSpace(databaseProviderParameter))
|
|
DatabaseContext.Provider = Enum.Parse<DatabaseProvider>(databaseProviderParameter);
|
|
else
|
|
DatabaseContext.Provider = settings.Server.Database.Provider;
|
|
|
|
if (!String.IsNullOrWhiteSpace(connectionStringParameter))
|
|
DatabaseContext.ConnectionString = connectionStringParameter;
|
|
else
|
|
DatabaseContext.ConnectionString = settings.Server.Database.ConnectionString;
|
|
|
|
return builder;
|
|
}
|
|
|
|
public static async Task MigrateDatabaseAsync(this WebApplication app)
|
|
{
|
|
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>>();
|
|
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;
|
|
|
|
var backupName = Path.Combine("Backups", $"LANCommander.db.{DateTime.Now.ToString("dd-MM-yyyy-HH.mm.ss.bak")}");
|
|
|
|
if (File.Exists(dataSource))
|
|
{
|
|
Log.Information("Migrations pending, database will be backed up to {BackupName}", backupName);
|
|
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
|
|
{
|
|
Path = "Uploads",
|
|
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
|
|
{
|
|
Path = "Media",
|
|
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
|
|
{
|
|
Path = "Saves",
|
|
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.");
|
|
}
|
|
}
|
|
} |