diff --git a/TShockAPI/Configuration/TShockConfig.cs b/TShockAPI/Configuration/TShockConfig.cs index 54ce26a25..4573c5bf3 100644 --- a/TShockAPI/Configuration/TShockConfig.cs +++ b/TShockAPI/Configuration/TShockConfig.cs @@ -532,10 +532,35 @@ public class TShockSettings [Description("The type of database to use when storing data (either \"sqlite\", \"mysql\" or \"postgres\").")] public string StorageType = "sqlite"; + /// + /// The connection string to use when connecting to a SQLite database. + /// + /// This property will override the property, if used. + /// Example SQLite connection strings (connectionstrings.com) + [Description("The connection string to use when connecting to a SQLite database. This property will override the SqliteDBPath property, if used.")] + public string SqliteConnectionString = ""; + /// The path of sqlite db. [Description("The path of sqlite db.")] public string SqliteDBPath = "tshock.sqlite"; + /// + /// The connection string to use when connecting to a MySQL database. + /// + /// + /// This property will override the + /// , + /// , + /// , + /// and properties, if used. + /// + /// + /// Example MySQL connection strings (connectionstrings.com) + /// + [Description("The connection string to use when connecting to a MySQL database. " + + "This property will override the MySqlHost, MySqlDbName, MySqlUsername and MySqlPassword properties, if used.")] + public string MySqlConnectionString = ""; + /// The MySQL hostname and port to direct connections to. [Description("The MySQL hostname and port to direct connections to.")] public string MySqlHost = "localhost:3306"; @@ -552,6 +577,21 @@ public class TShockSettings [Description("The password used when connecting to a MySQL database.")] public string MySqlPassword = ""; + /// + /// The connection string to use when connecting to a Postgres database. + /// + /// + /// This property will override the + /// , + /// , + /// , + /// and properties, if used. + /// + /// Example Npgsql connection strings (connectionstrings.com) + [Description("The connection string to use when connecting to a Postgres database. " + + "This property will override the PostgresHost, PostgresDbName, PostgresUsername and PostgresPassword properties, if used.")] + public string PostgresConnectionString = ""; + ///The Postgres hostname and port to direct connections to. [Description("The Postgres hostname and port to direct connections to.")] public string PostgresHost = ""; diff --git a/TShockAPI/DB/DbBuilder.cs b/TShockAPI/DB/DbBuilder.cs index dc6e20dfd..98aedcdf9 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 IDbConnection BuildDbConnection() private SqliteConnection BuildSqliteConnection() { - string dbFilePath = Path.Combine(_savePath, _config.Settings.SqliteDBPath); + try + { + // 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); + } - if (Path.GetDirectoryName(dbFilePath) is not { } dbDirPath) + // Fallback to SqliteDBPath setting. + string dbFilePath = GetDbFile(_config.Settings.SqliteDBPath).FullName; + return new($"Data Source={dbFilePath};"); + } + catch (SqliteException e) { - throw new DirectoryNotFoundException($"The SQLite database path '{dbFilePath}' could not be found."); + 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 @@ private NpgsqlConnection BuildPostgresConnection() { 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 @@ private NpgsqlConnection BuildPostgresConnection() 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; + } }