From 9c473e35a6ddb6a9a80544093b00e7002b54bc45 Mon Sep 17 00:00:00 2001 From: Sakura Akeno Isayeki Date: Sat, 3 May 2025 19:20:21 +0200 Subject: [PATCH] refactor(db/pgsql): Revert SQL queries, lower column casing for PGSQL Reverts SQL query identifier escaping to simplify queries and improves overall readability by using lowercase column names. Enhances maintainability and alignment with database conventions by adopting a uniform casing scheme across all SQL operations. Removes unnecessary complexity in query construction, streamlining the database operations performed within the application. --- TShockAPI/DB/BanManager.cs | 27 ++++----- TShockAPI/DB/CharacterManager.cs | 2 +- TShockAPI/DB/GroupManager.cs | 30 ++++++---- TShockAPI/DB/Queries/PostgresQueryCreator.cs | 6 +- TShockAPI/DB/RegionManager.cs | 27 +++------ TShockAPI/DB/UserManager.cs | 60 ++++++++------------ TShockAPI/DB/WarpsManager.cs | 18 ++---- TShockAPI/Extensions/DbExt.cs | 20 ++----- 8 files changed, 79 insertions(+), 111 deletions(-) diff --git a/TShockAPI/DB/BanManager.cs b/TShockAPI/DB/BanManager.cs index 2dfb6322..c56e3d0d 100644 --- a/TShockAPI/DB/BanManager.cs +++ b/TShockAPI/DB/BanManager.cs @@ -78,7 +78,7 @@ namespace TShockAPI.DB } catch (DllNotFoundException) { - Console.WriteLine(GetString("Possible problem with your database - is Sqlite3.dll present?")); + System.Console.WriteLine(GetString("Possible problem with your database - is Sqlite3.dll present?")); throw new Exception(GetString("Could not find a database library (probably Sqlite3.dll)")); } @@ -355,9 +355,7 @@ namespace TShockAPI.DB return Bans[id]; } - string query = $"SELECT * FROM PlayerBans WHERE {"TicketNumber".EscapeSqlId(database)}=@0"; - - using var reader = database.QueryReader(query, id); + using var reader = database.QueryReader("SELECT * FROM PlayerBans WHERE TicketNumber=@0", id); if (reader.Read()) { @@ -382,11 +380,10 @@ namespace TShockAPI.DB /// public IEnumerable RetrieveBansByIdentifier(string identifier, bool currentOnly = true) { - string query = $"SELECT * FROM PlayerBans WHERE {"Identifier".EscapeSqlId(database)}=@0"; - + string query = "SELECT * FROM PlayerBans WHERE Identifier=@0"; if (currentOnly) { - query += $" AND {"Expiration".EscapeSqlId(database)} > {DateTime.UtcNow.Ticks}"; + query += $" AND Expiration > {DateTime.UtcNow.Ticks}"; } using var reader = database.QueryReader(query, identifier); @@ -415,11 +412,11 @@ namespace TShockAPI.DB //Generate a sequence of '@0, @1, @2, ... etc' var parameters = string.Join(", ", Enumerable.Range(0, identifiers.Length).Select(p => $"@{p}")); - string query = $"SELECT * FROM PlayerBans WHERE {"Identifier".EscapeSqlId(database)} IN ({parameters})"; + string query = $"SELECT * FROM PlayerBans WHERE Identifier IN ({parameters})"; if (currentOnly) { - query += $" AND {"Expiration".EscapeSqlId(database)} > {DateTime.UtcNow.Ticks}"; + query += $" AND Expiration > {DateTime.UtcNow.Ticks}"; } using var reader = database.QueryReader(query, identifiers); @@ -452,7 +449,7 @@ namespace TShockAPI.DB List banlist = new List(); try { - using var reader = database.QueryReader($"SELECT * FROM PlayerBans ORDER BY {SortToOrderByMap(sortMethod)}"); + using var reader = database.QueryReader($"SELECT * FROM PlayerBans ORDER BY {SortToOrderByMap[sortMethod]}"); while (reader.Read()) { @@ -493,12 +490,12 @@ namespace TShockAPI.DB return false; } - private string SortToOrderByMap(BanSortMethod sortMethod) => sortMethod switch + private readonly Dictionary SortToOrderByMap = new() { - BanSortMethod.AddedNewestToOldest => $"{"Date".EscapeSqlId(database)} DESC", - BanSortMethod.AddedOldestToNewest => $"{"Date".EscapeSqlId(database)} ASC", - BanSortMethod.ExpirationSoonestToLatest => $"{"Expiration".EscapeSqlId(database)} ASC", - BanSortMethod.ExpirationLatestToSoonest => $"{"Expiration".EscapeSqlId(database)} DESC" + { BanSortMethod.AddedNewestToOldest, "Date DESC" }, + { BanSortMethod.AddedOldestToNewest, "Date ASC" }, + { BanSortMethod.ExpirationSoonestToLatest, "Expiration ASC" }, + { BanSortMethod.ExpirationLatestToSoonest, "Expiration DESC" } }; } diff --git a/TShockAPI/DB/CharacterManager.cs b/TShockAPI/DB/CharacterManager.cs index 08d6d1ec..3b9890a3 100644 --- a/TShockAPI/DB/CharacterManager.cs +++ b/TShockAPI/DB/CharacterManager.cs @@ -82,7 +82,7 @@ namespace TShockAPI.DB try { - using var reader = database.QueryReader($"SELECT * FROM tsCharacter WHERE {"Account".EscapeSqlId(database)}=@0", acctid); + using var reader = database.QueryReader("SELECT * FROM tsCharacter WHERE Account=@0", acctid); if (reader.Read()) { playerData.exists = true; diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index f655b987..060b4606 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -253,7 +253,13 @@ namespace TShockAPI.DB /// /// The group. /// true if it does; otherwise, false. - public bool GroupExists(string group) => group is "superadmin" || groups.Any(g => g.Name.Equals(group)); + public bool GroupExists(string group) + { + if (group == "superadmin") + return true; + + return groups.Any(g => g.Name.Equals(group)); + } IEnumerator IEnumerable.GetEnumerator() { @@ -264,14 +270,21 @@ namespace TShockAPI.DB /// Gets the enumerator. /// /// The enumerator. - public IEnumerator GetEnumerator() => groups.GetEnumerator(); + public IEnumerator GetEnumerator() + { + return groups.GetEnumerator(); + } /// /// Gets the group matching the specified name. /// /// The name. /// The group. - public Group GetGroupByName(string name) => groups.FirstOrDefault(g => g.Name == name); + public Group GetGroupByName(string name) + { + var ret = groups.Where(g => g.Name == name); + return 1 == ret.Count() ? ret.ElementAt(0) : null; + } /// /// Adds group with name and permissions if it does not exist. @@ -305,7 +318,7 @@ namespace TShockAPI.DB { SqlType.Sqlite => "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);", SqlType.Mysql => "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3", - SqlType.Postgres => "INSERT INTO GroupList (\"GroupName\", \"Parent\", \"Commands\", \"ChatColor\") VALUES (@0, @1, @2, @3) ON CONFLICT (\"GroupName\") DO NOTHING", + SqlType.Postgres => "INSERT INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3) ON CONFLICT (GroupName) DO NOTHING", _ => throw new NotSupportedException(GetString("Unsupported database type.")) }; @@ -356,12 +369,9 @@ namespace TShockAPI.DB } // Ensure any group validation is also persisted to the DB. - var newGroup = new Group(name, parent, chatcolor, permissions) - { - Prefix = prefix, - Suffix = suffix - }; - + var newGroup = new Group(name, parent, chatcolor, permissions); + newGroup.Prefix = prefix; + newGroup.Suffix = suffix; string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2, Suffix=@3, Prefix=@4 WHERE GroupName=@5"; if (database.Query(query, parentname, newGroup.Permissions, newGroup.ChatColor, suffix, prefix, name) != 1) throw new GroupManagerException(GetString($"Failed to update group \"{name}\".")); diff --git a/TShockAPI/DB/Queries/PostgresQueryCreator.cs b/TShockAPI/DB/Queries/PostgresQueryCreator.cs index 5637d689..c12e2ec8 100644 --- a/TShockAPI/DB/Queries/PostgresQueryCreator.cs +++ b/TShockAPI/DB/Queries/PostgresQueryCreator.cs @@ -68,7 +68,7 @@ public class PostgresQueryCreator : GenericQueryCreator dataType = DbTypeToString(c.Type, c.Length); } - return "\"{0}\" {1} {2} {3} {4}".SFormat(c.Name, + return "{0} {1} {2} {3} {4}".SFormat(c.Name, dataType, c.Primary ? "PRIMARY KEY" : "", c.NotNull && !c.AutoIncrement ? "NOT NULL" : "", // SERIAL implies NOT NULL @@ -76,12 +76,12 @@ public class PostgresQueryCreator : GenericQueryCreator }); string[] uniques = table.Columns - .Where(c => c.Unique).Select(c => $"\"{c.Name}\"") + .Where(c => c.Unique).Select(c => c.Name) .ToArray(); // No re-enumeration return $"CREATE TABLE {EscapeTableName(table.Name)} ({string.Join(", ", columns)} {(uniques.Any() ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : "")})"; } /// - public override string RenameTable(string from, string to) => /*lang=postgresql*/"ALTER TABLE {0} RENAME TO {1}".SFormat(from, to); + public override string RenameTable(string from, string to) => "ALTER TABLE {0} RENAME TO {1}".SFormat(from, to); } diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 27acd7a6..d657980a 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -67,9 +67,9 @@ namespace TShockAPI.DB { try { - using var reader = database.QueryReader($"SELECT * FROM Regions WHERE {"WorldID".EscapeSqlId(database)}=@0", Main.worldID.ToString()); - Regions.Clear(); + using var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", Main.worldID.ToString()); + Regions.Clear(); while (reader.Read()) { int id = reader.Get("Id"); @@ -135,19 +135,11 @@ namespace TShockAPI.DB } try { - string query = database.GetSqlType() switch - { - SqlType.Postgres => "INSERT INTO Regions (\"X1\", \"Y1\", \"width\", \"height\", \"RegionName\", \"WorldID\", \"UserIds\", \"Protected\", \"Groups\", \"Owner\", \"Z\") VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);", - _ => "INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner, Z) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);", - - }; - - database.Query(query, tx, ty, width, height, regionname, worldid, "", 1, "", owner, z); - + database.Query( + "INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, `Groups`, Owner, Z) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);", + tx, ty, width, height, regionname, worldid, "", 1, "", owner, z); int id; - - using (QueryResult res = database.QueryReader( - $"SELECT {"Id".EscapeSqlId(database)} FROM Regions WHERE {"RegionName".EscapeSqlId(database)} = @0 AND {"WorldID".EscapeSqlId(database)} = @1", regionname, worldid)) + using (QueryResult res = database.QueryReader("SELECT Id FROM Regions WHERE RegionName = @0 AND WorldID = @1", regionname, worldid)) { if (res.Read()) { @@ -158,7 +150,6 @@ namespace TShockAPI.DB return false; } } - Region region = new Region(id, new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z); Regions.Add(region); Hooks.RegionHooks.OnRegionCreated(region); @@ -180,7 +171,7 @@ namespace TShockAPI.DB { try { - database.Query($"DELETE FROM Regions WHERE Id=@0 AND {"WorldID".EscapeSqlId(database)}=@1", id, Main.worldID.ToString()); + database.Query("DELETE FROM Regions WHERE Id=@0 AND WorldID=@1", id, Main.worldID.ToString()); var worldid = Main.worldID.ToString(); var region = Regions.FirstOrDefault(r => r.ID == id && r.WorldID == worldid); Regions.RemoveAll(r => r.ID == id && r.WorldID == worldid); @@ -203,7 +194,7 @@ namespace TShockAPI.DB { try { - database.Query($"DELETE FROM Regions WHERE {"RegionName".EscapeSqlId(database)}=@0 AND {"WorldID".EscapeSqlId(database)}=@1", name, Main.worldID.ToString()); + database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString()); var worldid = Main.worldID.ToString(); var region = Regions.FirstOrDefault(r => r.Name == name && r.WorldID == worldid); Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid); @@ -253,7 +244,7 @@ namespace TShockAPI.DB { try { - database.Query($"UPDATE Regions SET {"Protected".EscapeSqlId(database)}=@0 WHERE {"RegionName".EscapeSqlId(database)}=@1 AND {"WorldID".EscapeSqlId(database)}=@2", state ? 1 : 0, name, + database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, Main.worldID.ToString()); var region = GetRegionByName(name); if (region != null) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index e5077ce1..e705e3fc 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -70,22 +70,15 @@ namespace TShockAPI.DB int ret; try { - string query = _database.GetSqlType() switch - { - SqlType.Postgres => "INSERT INTO Users (\"Username\", \"Password\", \"UUID\", \"Usergroup\", \"Registered\") VALUES (@0, @1, @2, @3, @4);", - _ => "INSERT INTO Users (Username, Password, UUID, Usergroup, Registered) VALUES (@0, @1, @2, @3, @4);" - }; - - ret = _database.Query(query, account.Name, account.Password, account.UUID, account.Group, DateTime.UtcNow.ToString("s")); + ret = _database.Query("INSERT INTO Users (Username, Password, UUID, UserGroup, Registered) VALUES (@0, @1, @2, @3, @4);", account.Name, + account.Password, account.UUID, account.Group, DateTime.UtcNow.ToString("s")); } - // Detect duplicate user using a regexp as Sqlite doesn't have well structured exceptions - catch (Exception e) when (Regex.IsMatch(e.Message, "Username.*not unique|UNIQUE constraint failed: Users\\.Username")) + catch (Exception ex) { - throw new UserAccountExistsException(account.Name); - } - catch (Exception e) - { - throw new UserAccountManagerException(GetString($"AddUser SQL returned an error ({e.Message})"), e); + // Detect duplicate user using a regexp as Sqlite doesn't have well structured exceptions + if (Regex.IsMatch(ex.Message, "Username.*not unique|UNIQUE constraint failed: Users\\.Username")) + throw new UserAccountExistsException(account.Name); + throw new UserAccountManagerException(GetString($"AddUser SQL returned an error ({ex.Message})"), ex); } if (1 > ret) @@ -106,7 +99,7 @@ namespace TShockAPI.DB TShock.Players.Where(p => p?.IsLoggedIn == true && p.Account.Name == account.Name).ForEach(p => p.Logout()); UserAccount tempuser = GetUserAccount(account); - int affected = _database.Query($"DELETE FROM Users WHERE {"Username".EscapeSqlId(_database)}=@0", account.Name); + int affected = _database.Query("DELETE FROM Users WHERE Username=@0", account.Name); if (affected < 1) throw new UserAccountNotExistException(account.Name); @@ -131,11 +124,10 @@ namespace TShockAPI.DB { account.CreateBCryptHash(password); - if (_database.Query($"UPDATE Users SET {"Password".EscapeSqlId(_database)} = @0 WHERE {"Username".EscapeSqlId(_database)} = @1;", - account.Password, account.Name) is 0) - { + if ( + _database.Query("UPDATE Users SET Password = @0 WHERE Username = @1;", account.Password, + account.Name) == 0) throw new UserAccountNotExistException(account.Name); - } } catch (Exception ex) { @@ -152,10 +144,10 @@ namespace TShockAPI.DB { try { - if (_database.Query(/*lang=sql*/$"UPDATE Users SET {"UUID".EscapeSqlId(_database)} = @0 WHERE {"Username".EscapeSqlId(_database)} = @1;", uuid, account.Name) is 0) - { + if ( + _database.Query("UPDATE Users SET UUID = @0 WHERE Username = @1;", uuid, + account.Name) == 0) throw new UserAccountNotExistException(account.Name); - } } catch (Exception ex) { @@ -177,7 +169,7 @@ namespace TShockAPI.DB if (AccountHooks.OnAccountGroupUpdate(account, ref grp)) throw new UserGroupUpdateLockedException(account.Name); - if (_database.Query($"UPDATE Users SET {"UserGroup".EscapeSqlId(_database)} = @0 WHERE {"Username".EscapeSqlId(_database)} = @1;", grp.Name, account.Name) == 0) + if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", grp.Name, account.Name) == 0) throw new UserAccountNotExistException(account.Name); try @@ -208,7 +200,7 @@ namespace TShockAPI.DB if (AccountHooks.OnAccountGroupUpdate(account, author, ref grp)) throw new UserGroupUpdateLockedException(account.Name); - if (_database.Query($"UPDATE Users SET {"UserGroup".EscapeSqlId(_database)} = @0 WHERE {"Username".EscapeSqlId(_database)} = @1;", grp.Name, account.Name) == 0) + if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", grp.Name, account.Name) == 0) throw new UserAccountNotExistException(account.Name); try @@ -231,12 +223,8 @@ namespace TShockAPI.DB { try { - if (_database.Query( - $"UPDATE Users SET {"LastAccessed".EscapeSqlId(_database)} = @0, {"KnownIPs".EscapeSqlId(_database)} = @1 WHERE {"Username".EscapeSqlId(_database)} = @2;", - DateTime.UtcNow.ToString("s"), account.KnownIps, account.Name) is 0 - ) { + if (_database.Query("UPDATE Users SET LastAccessed = @0, KnownIps = @1 WHERE Username = @2;", DateTime.UtcNow.ToString("s"), account.KnownIps, account.Name) == 0) throw new UserAccountNotExistException(account.Name); - } } catch (Exception ex) { @@ -251,7 +239,7 @@ namespace TShockAPI.DB { try { - using var reader = _database.QueryReader($"SELECT * FROM Users WHERE {"Username".EscapeSqlId(_database)}=@0", username); + using var reader = _database.QueryReader("SELECT * FROM Users WHERE Username=@0", username); if (reader.Read()) { return reader.Get("ID"); @@ -305,13 +293,13 @@ namespace TShockAPI.DB object arg; if (account.ID != 0) { - query = $"SELECT * FROM Users WHERE {"ID".EscapeSqlId(_database)}=@0"; + query = "SELECT * FROM Users WHERE ID=@0"; arg = account.ID; type = "id"; } else { - query = $"SELECT * FROM Users WHERE {"Username".EscapeSqlId(_database)}=@0"; + query = "SELECT * FROM Users WHERE Username=@0"; arg = account.Name; type = "name"; } @@ -370,9 +358,9 @@ namespace TShockAPI.DB try { List accounts = new List(); - string search = $"{(notAtStart ? "%" : "")}{username}%"; - using var reader = _database.QueryReader($"SELECT * FROM Users WHERE {"Username".EscapeSqlId(_database)} LIKE @0", search); - + string search = notAtStart ? string.Format("%{0}%", username) : string.Format("{0}%", username); + using var reader = _database.QueryReader("SELECT * FROM Users WHERE Username LIKE @0", + search); while (reader.Read()) { accounts.Add(LoadUserAccountFromResult(new UserAccount(), reader)); @@ -400,7 +388,7 @@ namespace TShockAPI.DB account.Name = result.Get("Username"); account.Registered = result.Get("Registered"); account.LastAccessed = result.Get("LastAccessed"); - account.KnownIps = result.Get("KnownIPs"); + account.KnownIps = result.Get("KnownIps"); return account; } } diff --git a/TShockAPI/DB/WarpsManager.cs b/TShockAPI/DB/WarpsManager.cs index 0bd49d0a..06723281 100644 --- a/TShockAPI/DB/WarpsManager.cs +++ b/TShockAPI/DB/WarpsManager.cs @@ -65,13 +65,8 @@ namespace TShockAPI.DB { try { - string query = database.GetSqlType() switch - { - SqlType.Postgres => "INSERT INTO Warps (\"X\", \"Y\", \"WarpName\", \"WorldID\") VALUES (@0, @1, @2, @3);", - _ => "INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);" - }; - - if (database.Query(query, x, y, name, Main.worldID.ToString()) > 0) + if (database.Query("INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);", + x, y, name, Main.worldID.ToString()) > 0) { Warps.Add(new Warp(new Point(x, y), name)); return true; @@ -81,7 +76,6 @@ namespace TShockAPI.DB { TShock.Log.Error(ex.ToString()); } - return false; } @@ -92,7 +86,7 @@ namespace TShockAPI.DB { Warps.Clear(); - using var reader = database.QueryReader($"SELECT * FROM Warps WHERE {"WorldID".EscapeSqlId(database)} = @0", + using var reader = database.QueryReader("SELECT * FROM Warps WHERE WorldID = @0", Main.worldID.ToString()); while (reader.Read()) { @@ -112,7 +106,7 @@ namespace TShockAPI.DB { try { - if (database.Query($"DELETE FROM Warps WHERE {"WarpName".EscapeSqlId(database)} = @0 AND {"WorldID".EscapeSqlId(database)} = @1", + if (database.Query("DELETE FROM Warps WHERE WarpName = @0 AND WorldID = @1", warpName, Main.worldID.ToString()) > 0) { Warps.RemoveAll(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)); @@ -147,7 +141,7 @@ namespace TShockAPI.DB { try { - if (database.Query($"UPDATE Warps SET X = @0, Y = @1 WHERE {"WarpName".EscapeSqlId(database)} = @2 AND WorldID = @3", + if (database.Query("UPDATE Warps SET X = @0, Y = @1 WHERE WarpName = @2 AND WorldID = @3", x, y, warpName, Main.worldID.ToString()) > 0) { Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).Position = new Point(x, y); @@ -171,7 +165,7 @@ namespace TShockAPI.DB { try { - if (database.Query($"UPDATE Warps SET {"Private".EscapeSqlId(database)} = @0 WHERE {"WarpName".EscapeSqlId(database)} = @1 AND {"WorldID".EscapeSqlId(database)} = @2", + if (database.Query("UPDATE Warps SET Private = @0 WHERE WarpName = @1 AND WorldID = @2", state ? "1" : "0", warpName, Main.worldID.ToString()) > 0) { Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).IsPrivate = state; diff --git a/TShockAPI/Extensions/DbExt.cs b/TShockAPI/Extensions/DbExt.cs index 55a681dd..ba2cfd1f 100644 --- a/TShockAPI/Extensions/DbExt.cs +++ b/TShockAPI/Extensions/DbExt.cs @@ -20,7 +20,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; using Microsoft.Data.Sqlite; using MySql.Data.MySqlClient; using Npgsql; @@ -43,14 +42,15 @@ namespace TShockAPI.DB [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] public static int Query(this IDbConnection olddb, string query, params object[] args) { - using IDbConnection db = olddb.CloneEx(); + using var db = olddb.CloneEx(); db.Open(); - using IDbCommand com = db.CreateCommand(); + + using var com = db.CreateCommand(); com.CommandText = query; for (int i = 0; i < args.Length; i++) { - com.AddParameter("@" + i, args[i] ?? DBNull.Value); + com.AddParameter($"@{i}", args[i] ?? DBNull.Value); } return com.ExecuteNonQuery(); @@ -272,18 +272,6 @@ namespace TShockAPI.DB return (T)reader.GetValue(column); } - - /// - /// Escapes an identifier for use in a SQL query. - /// - /// The identifier to escape, typically a table or column name. - /// The escaped identifier. - [Pure] - public static string EscapeSqlId(this string id, IDbConnection db) => db.GetSqlType() switch - { - SqlType.Postgres => $"\"{id}\"", // The main PITA and culprit - _ => id // Default case for agnostic SQL - }; } public enum SqlType