Fix connection configuration - respect ConnectionString and individual options from database.xml

This commit is contained in:
2026-03-10 12:55:49 -04:00
parent a872ebc640
commit 077f10a4af
2 changed files with 105 additions and 19 deletions
@@ -99,17 +99,17 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
// Store the configuration for later use
databaseConfig = databaseConfiguration;
static T? GetOption<T>(ICollection<CustomDatabaseOption>? options, string key, Func<string, T> converter, Func<T>? defaultValue = null)
static T? GetOption<T>(ICollection<CustomDatabaseOption>? options, string key, Func<string, T> converter, T? defaultValue = default)
{
if (options is null)
{
return defaultValue is not null ? defaultValue() : default;
return defaultValue;
}
var value = options.FirstOrDefault(e => e.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
if (value is null)
{
return defaultValue is not null ? defaultValue() : default;
return defaultValue;
}
return converter(value.Value);
@@ -117,20 +117,106 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
var customOptions = databaseConfiguration.CustomProviderOptions?.Options;
var connectionBuilder = new NpgsqlConnectionStringBuilder
// Start with connection string if provided, then override with individual options
NpgsqlConnectionStringBuilder connectionBuilder;
if (!string.IsNullOrWhiteSpace(databaseConfiguration.CustomProviderOptions?.ConnectionString))
{
Host = GetOption(customOptions, "host", e => e, () => "localhost")!,
Port = GetOption(customOptions, "port", int.Parse, () => 5432),
Database = GetOption(customOptions, "database", e => e, () => "jellyfin")!,
Username = GetOption(customOptions, "username", e => e, () => "jellyfin")!,
Password = GetOption(customOptions, "password", e => e, () => string.Empty)!,
Pooling = GetOption(customOptions, "pooling", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), () => true),
CommandTimeout = GetOption(customOptions, "command-timeout", int.Parse, () => 120),
Timeout = GetOption(customOptions, "connection-timeout", int.Parse, () => 15),
Multiplexing = GetOption(customOptions, "multiplexing", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), () => false),
MaxPoolSize = GetOption(customOptions, "max-pool-size", int.Parse, () => 100),
MinPoolSize = GetOption(customOptions, "min-pool-size", int.Parse, () => 0)
};
// Use the provided connection string as base
connectionBuilder = new NpgsqlConnectionStringBuilder(databaseConfiguration.CustomProviderOptions.ConnectionString);
logger.LogDebug("Using ConnectionString from configuration as base");
}
else
{
// Start with defaults
connectionBuilder = new NpgsqlConnectionStringBuilder
{
Host = "localhost",
Port = 5432,
Database = "jellyfin",
Username = "jellyfin",
Password = string.Empty,
Pooling = true,
CommandTimeout = 120,
Timeout = 15,
Multiplexing = false,
MaxPoolSize = 100,
MinPoolSize = 0
};
logger.LogDebug("Using default connection parameters");
}
// Override with individual options if provided (these take precedence over ConnectionString)
if (customOptions is not null && customOptions.Count > 0)
{
var host = GetOption<string>(customOptions, "host", e => e, null);
if (host is not null)
{
connectionBuilder.Host = host;
}
var port = GetOption<int?>(customOptions, "port", e => int.Parse(e), null);
if (port.HasValue)
{
connectionBuilder.Port = port.Value;
}
var database = GetOption<string>(customOptions, "database", e => e, null);
if (database is not null)
{
connectionBuilder.Database = database;
}
var username = GetOption<string>(customOptions, "username", e => e, null);
if (username is not null)
{
connectionBuilder.Username = username;
}
var password = GetOption<string>(customOptions, "password", e => e, null);
if (password is not null)
{
connectionBuilder.Password = password;
}
var pooling = GetOption<bool?>(customOptions, "pooling", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), null);
if (pooling.HasValue)
{
connectionBuilder.Pooling = pooling.Value;
}
var commandTimeout = GetOption<int?>(customOptions, "command-timeout", e => int.Parse(e), null);
if (commandTimeout.HasValue)
{
connectionBuilder.CommandTimeout = commandTimeout.Value;
}
var timeout = GetOption<int?>(customOptions, "connection-timeout", e => int.Parse(e), null);
if (timeout.HasValue)
{
connectionBuilder.Timeout = timeout.Value;
}
var multiplexing = GetOption<bool?>(customOptions, "multiplexing", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), null);
if (multiplexing.HasValue)
{
connectionBuilder.Multiplexing = multiplexing.Value;
}
var maxPoolSize = GetOption<int?>(customOptions, "max-pool-size", e => int.Parse(e), null);
if (maxPoolSize.HasValue)
{
connectionBuilder.MaxPoolSize = maxPoolSize.Value;
}
var minPoolSize = GetOption<int?>(customOptions, "min-pool-size", e => int.Parse(e), null);
if (minPoolSize.HasValue)
{
connectionBuilder.MinPoolSize = minPoolSize.Value;
}
logger.LogDebug("Applied {Count} individual option overrides", customOptions.Count);
}
var connectionString = connectionBuilder.ToString();
@@ -153,7 +239,7 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
if (configurationManager is not null)
{
// Check if backups are explicitly disabled
var disableBackups = GetOption(customOptions, "disable-backups", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), () => false);
var disableBackups = GetOption<bool?>(customOptions, "disable-backups", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), null) ?? false;
if (disableBackups)
{
@@ -195,7 +281,7 @@ public sealed class PostgresDatabaseProvider : IJellyfinDatabaseProvider
.ConfigureWarnings(warnings =>
warnings.Ignore(Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.PendingModelChangesWarning));
var enableSensitiveDataLogging = GetOption(customOptions, "EnableSensitiveDataLogging", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), () => false);
var enableSensitiveDataLogging = GetOption<bool?>(customOptions, "EnableSensitiveDataLogging", e => e.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase), null) ?? false;
if (enableSensitiveDataLogging)
{
options.EnableSensitiveDataLogging(enableSensitiveDataLogging);