using IBKRTrader.Core.Settings;
using MySqlConnector;
namespace IBKRTrader.Core.Configuration;
///
/// Die eine maßgebliche Datenbankverbindung der Anwendung – aufgelöst aus den beiden Quellen,
/// die es historisch gab.
///
/// Bisher lasen EF-Kontexte den Connection-String aus appsettings(.Local).json,
/// während BackupWorker und die Versionsdiagnose Host/Port/Datenbank/Benutzer aus
/// settings.json nahmen. Nichts erzwang, dass beide dasselbe meinen: eine Installation
/// konnte monatelang sauber laufen und dabei eine Datenbank sichern, die es gar nicht gibt.
///
/// Regel: Ist in der Konfiguration ein Connection-String hinterlegt, ist er
/// maßgeblich und alles Weitere wird aus ihm abgeleitet. Fehlt er, wird die Verbindung aus
/// settings.json gebaut – dann sind beide Quellen zwangsläufig deckungsgleich.
///
public sealed class DatabaseEndpoint
{
public string ConnectionString { get; }
public string Host { get; }
public int Port { get; }
public string Database { get; }
public string User { get; }
public string Password { get; }
/// Woher die maßgebliche Verbindung stammt – für die Startmeldung.
public string Source { get; }
private DatabaseEndpoint(string connectionString, string source)
{
ConnectionString = connectionString;
Source = source;
var b = new MySqlConnectionStringBuilder(connectionString);
Host = b.Server;
Port = (int)b.Port;
Database = b.Database;
User = b.UserID;
Password = b.Password;
}
///
/// Löst die maßgebliche Verbindung auf. Ein unlesbarer Connection-String fällt auf
/// settings.json zurück, statt den Start zu verhindern – sichtbar wird das über
/// und die Startprüfung.
///
public static DatabaseEndpoint Resolve(string? configuredConnectionString, DatabaseSettings settings)
{
if (!string.IsNullOrWhiteSpace(configuredConnectionString))
{
try { return new DatabaseEndpoint(configuredConnectionString, "appsettings"); }
catch (Exception ex)
{
return new DatabaseEndpoint(settings.BuildConnectionString(),
$"settings.json (Connection-String unlesbar: {ex.Message})");
}
}
return new DatabaseEndpoint(settings.BuildConnectionString(), "settings.json");
}
///
/// Beschreibt eine Abweichung zwischen der maßgeblichen Verbindung und dem, was in
/// settings.json steht – sonst null. Beides darf existieren, aber wer sie
/// auseinanderlaufen lässt, sichert die falsche Datenbank.
///
public string? DescribeDivergence(DatabaseSettings settings)
{
if (Source != "appsettings") return null;
var differs = !string.Equals(Host, settings.Host, StringComparison.OrdinalIgnoreCase)
|| !string.Equals(Database, settings.Database, StringComparison.OrdinalIgnoreCase)
|| Port != settings.Port;
return differs
? $"Datenbank-Konfiguration weicht ab: maßgeblich ist {this} (appsettings), " +
$"settings.json nennt {settings}. Es gilt die maßgebliche Verbindung."
: null;
}
/// Benutzer@Host:Port/Datenbank – nie das Passwort.
public override string ToString() => $"{User}@{Host}:{Port}/{Database}";
}