Merge pull request #3105 from SakuraIsayeki/feature/db-connectionstrings

Feature: Add connection strings handling for DB providers
This commit is contained in:
Chris 2026-01-18 16:13:48 +10:30 committed by GitHub
commit 43ae60edab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 91 additions and 9 deletions

View file

@ -532,10 +532,35 @@ namespace TShockAPI.Configuration
[Description("The type of database to use when storing data (either \"sqlite\", \"mysql\" or \"postgres\").")]
public string StorageType = "sqlite";
/// <summary>
/// The connection string to use when connecting to a SQLite database.
/// </summary>
/// <remarks>This property will override the <see cref="SqliteDBPath"/> property, if used.</remarks>
/// <seealso href="https://www.connectionstrings.com/sqlite-net-provider/">Example SQLite connection strings (connectionstrings.com)</seealso>
[Description("The connection string to use when connecting to a SQLite database. This property will override the SqliteDBPath property, if used.")]
public string SqliteConnectionString = "";
/// <summary>The path of sqlite db.</summary>
[Description("The path of sqlite db.")]
public string SqliteDBPath = "tshock.sqlite";
/// <summary>
/// The connection string to use when connecting to a MySQL database.
/// </summary>
/// <remarks>
/// This property will override the
/// <see cref="MySqlHost"/>,
/// <see cref="MySqlDbName"/>,
/// <see cref="MySqlUsername"/>,
/// and <see cref="MySqlPassword"/> properties, if used.
/// </remarks>
/// <seealso href="https://www.connectionstrings.com/mysql-connector-net-mysqlconnection/">
/// Example MySQL connection strings (connectionstrings.com)
/// </seealso>
[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 = "";
/// <summary>The MySQL hostname and port to direct connections to.</summary>
[Description("The MySQL hostname and port to direct connections to.")]
public string MySqlHost = "localhost:3306";
@ -552,6 +577,21 @@ namespace TShockAPI.Configuration
[Description("The password used when connecting to a MySQL database.")]
public string MySqlPassword = "";
/// <summary>
/// The connection string to use when connecting to a Postgres database.
/// </summary>
/// <remarks>
/// This property will override the
/// <see cref="PostgresHost"/>,
/// <see cref="PostgresDbName"/>,
/// <see cref="PostgresUsername"/>,
/// and <see cref="PostgresPassword"/> properties, if used.
/// </remarks>
/// <seealso href="https://www.connectionstrings.com/npgsql/">Example Npgsql connection strings (connectionstrings.com)</seealso>
[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 = "";
///<summary>The Postgres hostname and port to direct connections to.</summary>
[Description("The Postgres hostname and port to direct connections to.")]
public string PostgresHost = "";

View file

@ -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;
}
}