From 2fa07303f723b08f05583d5ec21d8f32479382f3 Mon Sep 17 00:00:00 2001 From: Sakura Akeno Isayeki Date: Fri, 23 May 2025 14:39:34 +0200 Subject: [PATCH] feat: Add connectrion string handling to database connection builders Allows override of default database connection parameters by providing explicit connection strings for SQLite, MySQL, and PostgreSQL, improving configuration flexibility and setup robustness. Includes refactoring path handling and directory creation for SQLite files. --- TShockAPI/DB/DbBuilder.cs | 60 +++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/TShockAPI/DB/DbBuilder.cs b/TShockAPI/DB/DbBuilder.cs index dc6e20df..98aedcdf 100644 --- a/TShockAPI/DB/DbBuilder.cs +++ b/TShockAPI/DB/DbBuilder.cs @@ -1,4 +1,5 @@ -using System.Data; +using System; +using System.Data; using System.Diagnostics; using System.IO; using Microsoft.Data.Sqlite; @@ -53,22 +54,39 @@ public sealed class DbBuilder private SqliteConnection BuildSqliteConnection() { - string dbFilePath = Path.Combine(_savePath, _config.Settings.SqliteDBPath); - - if (Path.GetDirectoryName(dbFilePath) is not { } dbDirPath) + try { - throw new DirectoryNotFoundException($"The SQLite database path '{dbFilePath}' could not be found."); + // Handle first the connection string, if specified. + if (_config.Settings.SqliteConnectionString is not (null or "")) + { + // Use factory to build the string, the path may be relative. + SqliteConnectionStringBuilder builder = new(_config.Settings.SqliteConnectionString); + builder.DataSource = GetDbFile(builder.DataSource).FullName; + return new(builder.ConnectionString); + } + + // Fallback to SqliteDBPath setting. + string dbFilePath = GetDbFile(_config.Settings.SqliteDBPath).FullName; + return new($"Data Source={dbFilePath};"); + } + catch (SqliteException e) + { + ServerApi.LogWriter.PluginWriteLine(_caller, e.ToString(), TraceLevel.Error); + throw new("Sqlite not setup correctly", e); } - - Directory.CreateDirectory(dbDirPath); - - return new($"Data Source={dbFilePath}"); } private MySqlConnection BuildMySqlConnection() { try { + // If specified, use the connection string instead of other parameters. + if (_config.Settings.MySqlConnectionString is not (null or "")) + { + MySqlConnectionStringBuilder builder = new(_config.Settings.MySqlConnectionString); + return new(builder.ToString()); + } + string[] hostport = _config.Settings.MySqlHost.Split(':'); MySqlConnectionStringBuilder connStrBuilder = new() @@ -93,6 +111,13 @@ public sealed class DbBuilder { try { + // If specified, use the connection string instead of other parameters. + if (_config.Settings.PostgresConnectionString is not (null or "")) + { + NpgsqlConnectionStringBuilder builder = new(_config.Settings.PostgresConnectionString); + return new(builder.ToString()); + } + string[] hostport = _config.Settings.PostgresHost.Split(':'); NpgsqlConnectionStringBuilder connStrBuilder = new() @@ -112,4 +137,21 @@ public sealed class DbBuilder throw new("Postgres not setup correctly", e); } } + + private FileInfo GetDbFile(string path) + { + FileInfo dbFile = new(Path.IsPathRooted(path) ? path : Path.Combine(_savePath, path)); + + if (dbFile.Directory is not { } dbDir) + { + throw new DirectoryNotFoundException($"The SQLite database path '{path}' could not be found."); + } + + if (!dbDir.Exists) + { + dbDir.Create(); + } + + return dbFile; + } }