LANCommander/LANCommander.Server/UI/Pages/FirstTimeSetup/Database.razor
Pat Hartl add770b227 Refactor Settings
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 => { ... })
2025-11-16 12:31:25 -06:00

155 lines
5.6 KiB
Text

@page "/FirstTimeSetup"
@page "/FirstTimeSetup/Database"
@layout FirstTimeSetupLayout
@using LANCommander.SDK
@using LANCommander.Server.Settings
@using LANCommander.Server.Settings.Enums
@using Microsoft.Data.Sqlite
@using Microsoft.Extensions.Options
@using MySqlConnector
@using Npgsql
@inject SetupService SetupService
@inject SettingsProvider<Settings> SettingsProvider
@inject IOptions<Settings> Settings
@inject NavigationManager NavigationManager
@inject IMessageService MessageService
@inject ILogger<Index> Logger
<PageTitle>Database Config - First Time Setup</PageTitle>
<Form Model="@Settings.Value" Loading="Loading" OnFinish="ValidateDatabaseConnection" Layout="FormLayout.Vertical">
<FormItem>
LANCommander requires a database to run. If you require something other than SQLite, configure that here.
</FormItem>
<FormItem Label="Database Provider">
<Select
@bind-Value="context.Server.Database.Provider"
TItem="DatabaseProvider"
TItemValue="DatabaseProvider"
DataSource="Enum.GetValues<DatabaseProvider>()"
OnSelectedItemChanged="OnDatabaseProviderChanged">
<LabelTemplate Context="Value">@Value.GetDisplayName()</LabelTemplate>
<ItemTemplate Context="Value">@Value.GetDisplayName()</ItemTemplate>
</Select>
</FormItem>
<FormItem Label="Connection String">
<Input @bind-Value="context.Server.Database.ConnectionString" />
</FormItem>
<FormItem WrapperColOffset="8" WrapperColSpan="16">
<GridRow Justify="RowJustify.End" Style="margin-top: 16px;">
<GridCol>
<Button Type="ButtonType.Primary" HtmlType="submit">
Connect
</Button>
</GridCol>
</GridRow>
</FormItem>
</Form>
@code {
[CascadingParameter] FirstTimeSetupLayout Layout { get; set; }
bool Loading = false;
protected override async Task OnInitializedAsync()
{
await Layout.ChangeCurrentStep(FirstTimeSetupStep.Database);
if (SettingsProvider.CurrentValue.Server.Database.Provider != DatabaseProvider.Unknown)
{
var isSetupInitialized = await SetupService.IsSetupInitialized();
if (isSetupInitialized)
NavigationManager.NavigateTo("/");
}
}
void OnDatabaseProviderChanged()
{
switch (SettingsProvider.CurrentValue.Server.Database.Provider)
{
case DatabaseProvider.SQLite:
var dbPath = Path.Join(AppPaths.GetConfigDirectory(), "LANCommander.db");
SettingsProvider.Update(s =>
{
s.Server.Database.ConnectionString = $"Data Source={dbPath};Cache=Shared";
});
break;
case DatabaseProvider.MySQL:
SettingsProvider.Update(s =>
{
s.Server.Database.ConnectionString = "Server=localhost;Uid=root;Pwd=password;Database=LANCommander";
});
break;
case DatabaseProvider.PostgreSQL:
SettingsProvider.Update(s =>
{
s.Server.Database.ConnectionString = "Host=localhost;Port=5432;Database=LANCommander;User Id=postgres;Password=password";
});
break;
}
}
async Task ValidateDatabaseConnection()
{
bool valid = false;
Loading = true;
StateHasChanged();
await Task.Yield();
try
{
SetupService.ValidateConnectionString(SettingsProvider.CurrentValue.Server.Database.Provider, SettingsProvider.CurrentValue.Server.Database.ConnectionString);
valid = true;
}
catch (SqliteException ex)
{
Logger?.LogError(ex, "Could not use SQLite database connection");
MessageService.Error($"Could not use SQLite database: {ex.Message}", 10);
}
catch (MySqlException ex)
{
Logger?.LogError(ex, "Could not connect to MySQL database");
MessageService.Error($"Could not connect to MySQL database: {ex.Message}", 10);
}
catch (NpgsqlException ex)
{
Logger?.LogError(ex, "Could not connect to PostgreSQL database");
MessageService.Error($"Could not connect to PostgreSQL database: {ex.Message}", 10);
}
catch (Exception ex)
{
Logger?.LogError(ex, "An unknown error occurred trying to access the database", 10);
MessageService.Error("Could not validate the connection string!");
}
if (valid)
{
try
{
await InvokeAsync(async () =>
{
await SetupService.ChangeProviderAsync(SettingsProvider.CurrentValue.Server.Database.Provider, SettingsProvider.CurrentValue.Server.Database.ConnectionString);
SettingsProvider.Update(s =>
{
s.Server.Database.Provider = Settings.Value.Server.Database.Provider;
s.Server.Database.ConnectionString = Settings.Value.Server.Database.ConnectionString;
});
NavigationManager.NavigateTo("/FirstTimeSetup/Paths", true);
});
}
catch (Exception ex)
{
Logger?.LogError(ex, "Could not initialize database!");
MessageService.Error($"Could not initialize database: {ex.Message}", 10);
}
}
Loading = false;
}
}