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.
This commit is contained in:
parent
4c13084eb3
commit
9c473e35a6
8 changed files with 79 additions and 111 deletions
|
|
@ -78,7 +78,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (DllNotFoundException)
|
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)"));
|
throw new Exception(GetString("Could not find a database library (probably Sqlite3.dll)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,9 +355,7 @@ namespace TShockAPI.DB
|
||||||
return Bans[id];
|
return Bans[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
string query = $"SELECT * FROM PlayerBans WHERE {"TicketNumber".EscapeSqlId(database)}=@0";
|
using var reader = database.QueryReader("SELECT * FROM PlayerBans WHERE TicketNumber=@0", id);
|
||||||
|
|
||||||
using var reader = database.QueryReader(query, id);
|
|
||||||
|
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
|
@ -382,11 +380,10 @@ namespace TShockAPI.DB
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<Ban> RetrieveBansByIdentifier(string identifier, bool currentOnly = true)
|
public IEnumerable<Ban> 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)
|
if (currentOnly)
|
||||||
{
|
{
|
||||||
query += $" AND {"Expiration".EscapeSqlId(database)} > {DateTime.UtcNow.Ticks}";
|
query += $" AND Expiration > {DateTime.UtcNow.Ticks}";
|
||||||
}
|
}
|
||||||
|
|
||||||
using var reader = database.QueryReader(query, identifier);
|
using var reader = database.QueryReader(query, identifier);
|
||||||
|
|
@ -415,11 +412,11 @@ namespace TShockAPI.DB
|
||||||
//Generate a sequence of '@0, @1, @2, ... etc'
|
//Generate a sequence of '@0, @1, @2, ... etc'
|
||||||
var parameters = string.Join(", ", Enumerable.Range(0, identifiers.Length).Select(p => $"@{p}"));
|
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)
|
if (currentOnly)
|
||||||
{
|
{
|
||||||
query += $" AND {"Expiration".EscapeSqlId(database)} > {DateTime.UtcNow.Ticks}";
|
query += $" AND Expiration > {DateTime.UtcNow.Ticks}";
|
||||||
}
|
}
|
||||||
|
|
||||||
using var reader = database.QueryReader(query, identifiers);
|
using var reader = database.QueryReader(query, identifiers);
|
||||||
|
|
@ -452,7 +449,7 @@ namespace TShockAPI.DB
|
||||||
List<Ban> banlist = new List<Ban>();
|
List<Ban> banlist = new List<Ban>();
|
||||||
try
|
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())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
|
@ -493,12 +490,12 @@ namespace TShockAPI.DB
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SortToOrderByMap(BanSortMethod sortMethod) => sortMethod switch
|
private readonly Dictionary<BanSortMethod, string> SortToOrderByMap = new()
|
||||||
{
|
{
|
||||||
BanSortMethod.AddedNewestToOldest => $"{"Date".EscapeSqlId(database)} DESC",
|
{ BanSortMethod.AddedNewestToOldest, "Date DESC" },
|
||||||
BanSortMethod.AddedOldestToNewest => $"{"Date".EscapeSqlId(database)} ASC",
|
{ BanSortMethod.AddedOldestToNewest, "Date ASC" },
|
||||||
BanSortMethod.ExpirationSoonestToLatest => $"{"Expiration".EscapeSqlId(database)} ASC",
|
{ BanSortMethod.ExpirationSoonestToLatest, "Expiration ASC" },
|
||||||
BanSortMethod.ExpirationLatestToSoonest => $"{"Expiration".EscapeSqlId(database)} DESC"
|
{ BanSortMethod.ExpirationLatestToSoonest, "Expiration DESC" }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ namespace TShockAPI.DB
|
||||||
|
|
||||||
try
|
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())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
playerData.exists = true;
|
playerData.exists = true;
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,13 @@ namespace TShockAPI.DB
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="group">The group.</param>
|
/// <param name="group">The group.</param>
|
||||||
/// <returns><c>true</c> if it does; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if it does; otherwise, <c>false</c>.</returns>
|
||||||
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()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
{
|
{
|
||||||
|
|
@ -264,14 +270,21 @@ namespace TShockAPI.DB
|
||||||
/// Gets the enumerator.
|
/// Gets the enumerator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The enumerator.</returns>
|
/// <returns>The enumerator.</returns>
|
||||||
public IEnumerator<Group> GetEnumerator() => groups.GetEnumerator();
|
public IEnumerator<Group> GetEnumerator()
|
||||||
|
{
|
||||||
|
return groups.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the group matching the specified name.
|
/// Gets the group matching the specified name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <returns>The group.</returns>
|
/// <returns>The group.</returns>
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds group with name and permissions if it does not exist.
|
/// 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.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.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."))
|
_ => throw new NotSupportedException(GetString("Unsupported database type."))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -356,12 +369,9 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure any group validation is also persisted to the DB.
|
// Ensure any group validation is also persisted to the DB.
|
||||||
var newGroup = new Group(name, parent, chatcolor, permissions)
|
var newGroup = new Group(name, parent, chatcolor, permissions);
|
||||||
{
|
newGroup.Prefix = prefix;
|
||||||
Prefix = prefix,
|
newGroup.Suffix = suffix;
|
||||||
Suffix = suffix
|
|
||||||
};
|
|
||||||
|
|
||||||
string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2, Suffix=@3, Prefix=@4 WHERE GroupName=@5";
|
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)
|
if (database.Query(query, parentname, newGroup.Permissions, newGroup.ChatColor, suffix, prefix, name) != 1)
|
||||||
throw new GroupManagerException(GetString($"Failed to update group \"{name}\"."));
|
throw new GroupManagerException(GetString($"Failed to update group \"{name}\"."));
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ public class PostgresQueryCreator : GenericQueryCreator
|
||||||
dataType = DbTypeToString(c.Type, c.Length);
|
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,
|
dataType,
|
||||||
c.Primary ? "PRIMARY KEY" : "",
|
c.Primary ? "PRIMARY KEY" : "",
|
||||||
c.NotNull && !c.AutoIncrement ? "NOT NULL" : "", // SERIAL implies NOT NULL
|
c.NotNull && !c.AutoIncrement ? "NOT NULL" : "", // SERIAL implies NOT NULL
|
||||||
|
|
@ -76,12 +76,12 @@ public class PostgresQueryCreator : GenericQueryCreator
|
||||||
});
|
});
|
||||||
|
|
||||||
string[] uniques = table.Columns
|
string[] uniques = table.Columns
|
||||||
.Where(c => c.Unique).Select(c => $"\"{c.Name}\"")
|
.Where(c => c.Unique).Select(c => c.Name)
|
||||||
.ToArray(); // No re-enumeration
|
.ToArray(); // No re-enumeration
|
||||||
|
|
||||||
return $"CREATE TABLE {EscapeTableName(table.Name)} ({string.Join(", ", columns)} {(uniques.Any() ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : "")})";
|
return $"CREATE TABLE {EscapeTableName(table.Name)} ({string.Join(", ", columns)} {(uniques.Any() ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : "")})";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,9 +67,9 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var reader = database.QueryReader($"SELECT * FROM Regions WHERE {"WorldID".EscapeSqlId(database)}=@0", Main.worldID.ToString());
|
using var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", Main.worldID.ToString());
|
||||||
Regions.Clear();
|
|
||||||
|
|
||||||
|
Regions.Clear();
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
int id = reader.Get<int>("Id");
|
int id = reader.Get<int>("Id");
|
||||||
|
|
@ -135,19 +135,11 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string query = database.GetSqlType() switch
|
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);",
|
||||||
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);",
|
tx, ty, width, height, regionname, worldid, "", 1, "", owner, z);
|
||||||
_ => "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);
|
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
using (QueryResult res = database.QueryReader("SELECT Id FROM Regions WHERE RegionName = @0 AND WorldID = @1", regionname, worldid))
|
||||||
using (QueryResult res = database.QueryReader(
|
|
||||||
$"SELECT {"Id".EscapeSqlId(database)} FROM Regions WHERE {"RegionName".EscapeSqlId(database)} = @0 AND {"WorldID".EscapeSqlId(database)} = @1", regionname, worldid))
|
|
||||||
{
|
{
|
||||||
if (res.Read())
|
if (res.Read())
|
||||||
{
|
{
|
||||||
|
|
@ -158,7 +150,6 @@ namespace TShockAPI.DB
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = new Region(id, new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z);
|
Region region = new Region(id, new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z);
|
||||||
Regions.Add(region);
|
Regions.Add(region);
|
||||||
Hooks.RegionHooks.OnRegionCreated(region);
|
Hooks.RegionHooks.OnRegionCreated(region);
|
||||||
|
|
@ -180,7 +171,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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 worldid = Main.worldID.ToString();
|
||||||
var region = Regions.FirstOrDefault(r => r.ID == id && r.WorldID == worldid);
|
var region = Regions.FirstOrDefault(r => r.ID == id && r.WorldID == worldid);
|
||||||
Regions.RemoveAll(r => r.ID == id && r.WorldID == worldid);
|
Regions.RemoveAll(r => r.ID == id && r.WorldID == worldid);
|
||||||
|
|
@ -203,7 +194,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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 worldid = Main.worldID.ToString();
|
||||||
var region = Regions.FirstOrDefault(r => r.Name == name && r.WorldID == worldid);
|
var region = Regions.FirstOrDefault(r => r.Name == name && r.WorldID == worldid);
|
||||||
Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid);
|
Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid);
|
||||||
|
|
@ -253,7 +244,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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());
|
Main.worldID.ToString());
|
||||||
var region = GetRegionByName(name);
|
var region = GetRegionByName(name);
|
||||||
if (region != null)
|
if (region != null)
|
||||||
|
|
|
||||||
|
|
@ -70,22 +70,15 @@ namespace TShockAPI.DB
|
||||||
int ret;
|
int ret;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string query = _database.GetSqlType() switch
|
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"));
|
||||||
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"));
|
|
||||||
}
|
}
|
||||||
// Detect duplicate user using a regexp as Sqlite doesn't have well structured exceptions
|
catch (Exception ex)
|
||||||
catch (Exception e) when (Regex.IsMatch(e.Message, "Username.*not unique|UNIQUE constraint failed: Users\\.Username"))
|
|
||||||
{
|
{
|
||||||
throw new UserAccountExistsException(account.Name);
|
// 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"))
|
||||||
catch (Exception e)
|
throw new UserAccountExistsException(account.Name);
|
||||||
{
|
throw new UserAccountManagerException(GetString($"AddUser SQL returned an error ({ex.Message})"), ex);
|
||||||
throw new UserAccountManagerException(GetString($"AddUser SQL returned an error ({e.Message})"), e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 > ret)
|
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());
|
TShock.Players.Where(p => p?.IsLoggedIn == true && p.Account.Name == account.Name).ForEach(p => p.Logout());
|
||||||
|
|
||||||
UserAccount tempuser = GetUserAccount(account);
|
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)
|
if (affected < 1)
|
||||||
throw new UserAccountNotExistException(account.Name);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
|
|
@ -131,11 +124,10 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
account.CreateBCryptHash(password);
|
account.CreateBCryptHash(password);
|
||||||
|
|
||||||
if (_database.Query($"UPDATE Users SET {"Password".EscapeSqlId(_database)} = @0 WHERE {"Username".EscapeSqlId(_database)} = @1;",
|
if (
|
||||||
account.Password, account.Name) is 0)
|
_database.Query("UPDATE Users SET Password = @0 WHERE Username = @1;", account.Password,
|
||||||
{
|
account.Name) == 0)
|
||||||
throw new UserAccountNotExistException(account.Name);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -152,10 +144,10 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +169,7 @@ namespace TShockAPI.DB
|
||||||
if (AccountHooks.OnAccountGroupUpdate(account, ref grp))
|
if (AccountHooks.OnAccountGroupUpdate(account, ref grp))
|
||||||
throw new UserGroupUpdateLockedException(account.Name);
|
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);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -208,7 +200,7 @@ namespace TShockAPI.DB
|
||||||
if (AccountHooks.OnAccountGroupUpdate(account, author, ref grp))
|
if (AccountHooks.OnAccountGroupUpdate(account, author, ref grp))
|
||||||
throw new UserGroupUpdateLockedException(account.Name);
|
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);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -231,12 +223,8 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_database.Query(
|
if (_database.Query("UPDATE Users SET LastAccessed = @0, KnownIps = @1 WHERE Username = @2;", DateTime.UtcNow.ToString("s"), account.KnownIps, account.Name) == 0)
|
||||||
$"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
|
|
||||||
) {
|
|
||||||
throw new UserAccountNotExistException(account.Name);
|
throw new UserAccountNotExistException(account.Name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -251,7 +239,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
return reader.Get<int>("ID");
|
return reader.Get<int>("ID");
|
||||||
|
|
@ -305,13 +293,13 @@ namespace TShockAPI.DB
|
||||||
object arg;
|
object arg;
|
||||||
if (account.ID != 0)
|
if (account.ID != 0)
|
||||||
{
|
{
|
||||||
query = $"SELECT * FROM Users WHERE {"ID".EscapeSqlId(_database)}=@0";
|
query = "SELECT * FROM Users WHERE ID=@0";
|
||||||
arg = account.ID;
|
arg = account.ID;
|
||||||
type = "id";
|
type = "id";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query = $"SELECT * FROM Users WHERE {"Username".EscapeSqlId(_database)}=@0";
|
query = "SELECT * FROM Users WHERE Username=@0";
|
||||||
arg = account.Name;
|
arg = account.Name;
|
||||||
type = "name";
|
type = "name";
|
||||||
}
|
}
|
||||||
|
|
@ -370,9 +358,9 @@ namespace TShockAPI.DB
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<UserAccount> accounts = new List<UserAccount>();
|
List<UserAccount> accounts = new List<UserAccount>();
|
||||||
string search = $"{(notAtStart ? "%" : "")}{username}%";
|
string search = notAtStart ? string.Format("%{0}%", username) : string.Format("{0}%", username);
|
||||||
using var reader = _database.QueryReader($"SELECT * FROM Users WHERE {"Username".EscapeSqlId(_database)} LIKE @0", search);
|
using var reader = _database.QueryReader("SELECT * FROM Users WHERE Username LIKE @0",
|
||||||
|
search);
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
accounts.Add(LoadUserAccountFromResult(new UserAccount(), reader));
|
accounts.Add(LoadUserAccountFromResult(new UserAccount(), reader));
|
||||||
|
|
@ -400,7 +388,7 @@ namespace TShockAPI.DB
|
||||||
account.Name = result.Get<string>("Username");
|
account.Name = result.Get<string>("Username");
|
||||||
account.Registered = result.Get<string>("Registered");
|
account.Registered = result.Get<string>("Registered");
|
||||||
account.LastAccessed = result.Get<string>("LastAccessed");
|
account.LastAccessed = result.Get<string>("LastAccessed");
|
||||||
account.KnownIps = result.Get<string>("KnownIPs");
|
account.KnownIps = result.Get<string>("KnownIps");
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,13 +65,8 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string query = database.GetSqlType() switch
|
if (database.Query("INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);",
|
||||||
{
|
x, y, name, Main.worldID.ToString()) > 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
Warps.Add(new Warp(new Point(x, y), name));
|
Warps.Add(new Warp(new Point(x, y), name));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -81,7 +76,6 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
TShock.Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,7 +86,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
Warps.Clear();
|
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());
|
Main.worldID.ToString());
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
|
@ -112,7 +106,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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)
|
warpName, Main.worldID.ToString()) > 0)
|
||||||
{
|
{
|
||||||
Warps.RemoveAll(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase));
|
Warps.RemoveAll(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
@ -147,7 +141,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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)
|
x, y, warpName, Main.worldID.ToString()) > 0)
|
||||||
{
|
{
|
||||||
Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).Position = new Point(x, y);
|
Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).Position = new Point(x, y);
|
||||||
|
|
@ -171,7 +165,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
try
|
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)
|
state ? "1" : "0", warpName, Main.worldID.ToString()) > 0)
|
||||||
{
|
{
|
||||||
Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).IsPrivate = state;
|
Warps.Find(w => string.Equals(w.Name, warpName, StringComparison.OrdinalIgnoreCase)).IsPrivate = state;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Diagnostics.Contracts;
|
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
|
|
@ -43,14 +42,15 @@ namespace TShockAPI.DB
|
||||||
[SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
|
[SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
|
||||||
public static int Query(this IDbConnection olddb, string query, params object[] args)
|
public static int Query(this IDbConnection olddb, string query, params object[] args)
|
||||||
{
|
{
|
||||||
using IDbConnection db = olddb.CloneEx();
|
using var db = olddb.CloneEx();
|
||||||
db.Open();
|
db.Open();
|
||||||
using IDbCommand com = db.CreateCommand();
|
|
||||||
|
using var com = db.CreateCommand();
|
||||||
com.CommandText = query;
|
com.CommandText = query;
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
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();
|
return com.ExecuteNonQuery();
|
||||||
|
|
@ -272,18 +272,6 @@ namespace TShockAPI.DB
|
||||||
|
|
||||||
return (T)reader.GetValue(column);
|
return (T)reader.GetValue(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Escapes an identifier for use in a SQL query.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The identifier to escape, typically a table or column name.</param>
|
|
||||||
/// <returns>The escaped identifier.</returns>
|
|
||||||
[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
|
public enum SqlType
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue