From 0021f9884d9eb664561607b9c5ff4484ebe33a11 Mon Sep 17 00:00:00 2001 From: Sakura Akeno Isayeki Date: Mon, 21 Apr 2025 14:04:07 +0200 Subject: [PATCH] refactor(server/db): Move database connection logic to separate class Implements a DbBuilder class to streamline the creation of database connections for both SQLite and MySQL storage types. Enhances error handling for database setup and ensures that necessary directories are created dynamically based on configuration settings. This refactor improves code maintainability and readability, consolidating connection logic into a dedicated builder class. --- TShockAPI/DB/DbBuilder.cs | 89 +++++++++++++++++++++++++++++++++++++++ TShockAPI/TShock.cs | 34 ++------------- 2 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 TShockAPI/DB/DbBuilder.cs 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);