diff --git a/TShockAPI/DB/DbBuilder.cs b/TShockAPI/DB/DbBuilder.cs
new file mode 100644
index 00000000..d02f993b
--- /dev/null
+++ b/TShockAPI/DB/DbBuilder.cs
@@ -0,0 +1,89 @@
+using System.Data;
+using System.Diagnostics;
+using System.IO;
+using Microsoft.Data.Sqlite;
+using MySql.Data.MySqlClient;
+using TerrariaApi.Server;
+using TShockAPI.Configuration;
+
+namespace TShockAPI.DB;
+
+///
+/// Provides logic to build a DB connection.
+///
+public sealed class DbBuilder
+{
+ private readonly TShock _caller;
+ private readonly TShockConfig _config;
+ private readonly string _savePath;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The TShock instance calling this DbBuilder.
+ /// The TShock configuration, supplied by at init.
+ /// The savePath registered by TShock. See .
+ public DbBuilder(TShock caller, TShockConfig config, string savePath)
+ {
+ _caller = caller;
+ _config = config;
+ _savePath = savePath;
+ }
+
+ ///
+ /// Builds a DB connection based on the provided configuration.
+ ///
+ /// The TShock configuration.
+ ///
+ /// Default settings will result in a local sqlite database file named "tshock.db" in the current directory to be used as server DB.
+ ///
+ public IDbConnection BuildDbConnection()
+ {
+ string dbType = _config.Settings.StorageType.ToLowerInvariant();
+
+ return dbType switch
+ {
+ "sqlite" => BuildSqliteConnection(),
+ "mysql" => BuildMySqlConnection(),
+ _ => throw new("Invalid storage type")
+ };
+ }
+
+ private SqliteConnection BuildSqliteConnection()
+ {
+ string dbFilePath = Path.Combine(_savePath, _config.Settings.SqliteDBPath);
+
+ if (Path.GetDirectoryName(dbFilePath) is not { } dbDirPath)
+ {
+ throw new DirectoryNotFoundException($"The SQLite database path '{dbFilePath}' could not be found.");
+ }
+
+ Directory.CreateDirectory(dbDirPath);
+
+ return new($"Data Source={dbFilePath}");
+ }
+
+ private MySqlConnection BuildMySqlConnection()
+ {
+ try
+ {
+ string[] hostport = _config.Settings.MySqlHost.Split(':');
+
+ MySqlConnectionStringBuilder connStrBuilder = new()
+ {
+ Server = hostport[0],
+ Port = hostport.Length > 1 ? uint.Parse(hostport[1]) : 3306,
+ Database = _config.Settings.MySqlDbName,
+ UserID = _config.Settings.MySqlUsername,
+ Password = _config.Settings.MySqlPassword
+ };
+
+ return new(connStrBuilder.ToString());
+ }
+ catch (MySqlException e)
+ {
+ ServerApi.LogWriter.PluginWriteLine(_caller, e.ToString(), TraceLevel.Error);
+ throw new("MySql not setup correctly", e);
+ }
+ }
+}
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index bd2a113e..0e453b40 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -314,37 +314,9 @@ namespace TShockAPI
// Further exceptions are written to TShock's log from now on.
try
{
- if (Config.Settings.StorageType.ToLower() == "sqlite")
- {
- string sql = Path.Combine(SavePath, Config.Settings.SqliteDBPath);
- Directory.CreateDirectory(Path.GetDirectoryName(sql));
- DB = new Microsoft.Data.Sqlite.SqliteConnection(string.Format("Data Source={0}", sql));
- }
- else if (Config.Settings.StorageType.ToLower() == "mysql")
- {
- try
- {
- var hostport = Config.Settings.MySqlHost.Split(':');
- DB = new MySqlConnection();
- DB.ConnectionString =
- String.Format("Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};",
- hostport[0],
- hostport.Length > 1 ? hostport[1] : "3306",
- Config.Settings.MySqlDbName,
- Config.Settings.MySqlUsername,
- Config.Settings.MySqlPassword
- );
- }
- catch (MySqlException ex)
- {
- ServerApi.LogWriter.PluginWriteLine(this, ex.ToString(), TraceLevel.Error);
- throw new Exception("MySql not setup correctly");
- }
- }
- else
- {
- throw new Exception("Invalid storage type");
- }
+ // Build database
+ DbBuilder dbBuilder = new(this, Config, SavePath);
+ DB = dbBuilder.BuildDbConnection();
if (Config.Settings.UseSqlLogs)
Log = new SqlLog(DB, logFilename, LogClear);