From bde18d7d41bab8de118aea5081c1c996ffe21b79 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 25 Mar 2016 20:53:26 +1100 Subject: [PATCH] Finish lightweight (and fast) native sqllite implementation, also fix /renamelvl not working properly when level names have + in them on the sqllite backend. --- API/WhoWas.cs | 2 +- Commands/Information/CmdClones.cs | 2 +- Commands/Information/CmdInbox.cs | 2 +- Commands/Information/CmdWhoip.cs | 2 +- Commands/Moderation/CmdBanip.cs | 2 +- Commands/Moderation/CmdPlayerEditDB.cs | 2 +- Commands/Moderation/CmdRenameLvl.cs | 10 ++--- Commands/Moderation/CmdUnbanip.cs | 2 +- Commands/Moderation/CmdZone.cs | 4 +- Commands/building/CmdMessageBlock.cs | 2 +- Commands/other/CmdColor.cs | 2 +- Commands/other/CmdSend.cs | 2 +- Commands/other/CmdTColor.cs | 2 +- Commands/other/CmdTitle.cs | 2 +- ...abaseTransaction.cs => BulkTransaction.cs} | 9 ++-- Database/Database.cs | 6 +-- ...Transaction.cs => MySQLBulkTransaction.cs} | 8 ++-- Database/MySQLParameterisedQuery.cs | 2 +- ...ransaction.cs => NativeBulkTransaction.cs} | 9 ++-- Database/Native/NativeCommand.cs | 42 ++++++++++++------- Database/Native/NativeConnection.cs | 29 +++++++++---- Database/Native/NativeException.cs | 2 + Database/Native/Utils.cs | 6 ++- ...eterisedQuery.cs => ParameterisedQuery.cs} | 4 +- ...ransaction.cs => SQLiteBulkTransaction.cs} | 8 ++-- Database/SQLiteParameterisedQuery.cs | 2 +- Economy/Economy.cs | 4 +- Games/CTF/Auto_CTF.cs | 2 +- Levels/Level.cs | 6 +-- MCGalaxy_.csproj | 10 ++--- Player/Player.Handlers.cs | 6 +-- Player/PlayerInfo.cs | 4 +- Server/AutoSaver.cs | 1 - 33 files changed, 115 insertions(+), 83 deletions(-) rename Database/{BulkDatabaseTransaction.cs => BulkTransaction.cs} (90%) rename Database/{BulkMySQLTransaction.cs => MySQLBulkTransaction.cs} (89%) rename Database/Native/{BulkNativeTransaction.cs => NativeBulkTransaction.cs} (84%) rename Database/{DatabaseParameterisedQuery.cs => ParameterisedQuery.cs} (89%) rename Database/{BulkSQLiteTransaction.cs => SQLiteBulkTransaction.cs} (88%) diff --git a/API/WhoWas.cs b/API/WhoWas.cs index 11f63f2b1..004a7db29 100644 --- a/API/WhoWas.cs +++ b/API/WhoWas.cs @@ -25,7 +25,7 @@ namespace MCGalaxy { Server.s.Log(p); rank = Group.findPlayer(p); - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", p.ToLower()); DataTable playerDb = Database.fillData(query, "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"); if (playerDb.Rows.Count == 0) diff --git a/Commands/Information/CmdClones.cs b/Commands/Information/CmdClones.cs index 5256aed11..bc0e0de85 100644 --- a/Commands/Information/CmdClones.cs +++ b/Commands/Information/CmdClones.cs @@ -49,7 +49,7 @@ namespace MCGalaxy.Commands { message = who.ip; } - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@IP", message); DataTable Clones = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP"); diff --git a/Commands/Information/CmdInbox.cs b/Commands/Information/CmdInbox.cs index 584f7a771..a2802521a 100644 --- a/Commands/Information/CmdInbox.cs +++ b/Commands/Information/CmdInbox.cs @@ -71,7 +71,7 @@ namespace MCGalaxy.Commands Player.SendMessage(p, "\"" + FoundRecord + "\" does not exist."); Inbox.Dispose(); return; } - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); string queryString; //safe against SQL injections because no user input is given here if (FoundRecord == -1) diff --git a/Commands/Information/CmdWhoip.cs b/Commands/Information/CmdWhoip.cs index 658511403..e43e1a4d8 100644 --- a/Commands/Information/CmdWhoip.cs +++ b/Commands/Information/CmdWhoip.cs @@ -33,7 +33,7 @@ namespace MCGalaxy.Commands if (message == "") { Help(p); return; } if (message.IndexOf("'") != -1) { Player.SendMessage(p, "Cannot parse request."); return; } - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@IP", message); DataTable playerDb = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP"); diff --git a/Commands/Moderation/CmdBanip.cs b/Commands/Moderation/CmdBanip.cs index 3c242ca74..3b7bb053b 100644 --- a/Commands/Moderation/CmdBanip.cs +++ b/Commands/Moderation/CmdBanip.cs @@ -68,7 +68,7 @@ namespace MCGalaxy.Commands { // First get names of active ops+ with that ip List opNamesWithThatIP = (from pl in PlayerInfo.players where (pl.ip == message && pl.@group.Permission >= LevelPermission.Operator) select pl.name).ToList(); // Next, add names from the database - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@IP", message); DataTable dbnames = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP"); diff --git a/Commands/Moderation/CmdPlayerEditDB.cs b/Commands/Moderation/CmdPlayerEditDB.cs index 577051e6e..339fe5cae 100644 --- a/Commands/Moderation/CmdPlayerEditDB.cs +++ b/Commands/Moderation/CmdPlayerEditDB.cs @@ -190,7 +190,7 @@ namespace MCGalaxy.Commands { } static void UpdateDB(Player p, string name, string type, string value, string column) { - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", name); if (value != "") { query.AddParam("@ArgValue", value); diff --git a/Commands/Moderation/CmdRenameLvl.cs b/Commands/Moderation/CmdRenameLvl.cs index ce198093b..d6add7439 100644 --- a/Commands/Moderation/CmdRenameLvl.cs +++ b/Commands/Moderation/CmdRenameLvl.cs @@ -103,11 +103,11 @@ namespace MCGalaxy.Commands "`Messages{0}` TO `Messages{1}`, " + "`Zone{0}` TO `Zone{1}`", foundLevel.name.ToLower(), newName.ToLower())); else { - using (BulkDatabaseTransaction helper = BulkSQLiteTransaction.Create()) { // ensures that it's either all work, or none work. - helper.Execute(String.Format("ALTER TABLE Block{0} RENAME TO Block{1}", foundLevel.name.ToLower(), newName.ToLower())); - helper.Execute(String.Format("ALTER TABLE Portals{0} RENAME TO Portals{1}", foundLevel.name.ToLower(), newName.ToLower())); - helper.Execute(String.Format("ALTER TABLE Messages{0} RENAME TO Messages{1}", foundLevel.name.ToLower(), newName.ToLower())); - helper.Execute(String.Format("ALTER TABLE Zone{0} RENAME TO Zone{1}", foundLevel.name.ToLower(), newName.ToLower())); + using (BulkTransaction helper = SQLiteBulkTransaction.Create()) { // ensures that it's either all work, or none work. + helper.Execute(String.Format("ALTER TABLE `Block{0}` RENAME TO `Block{1}`", foundLevel.name.ToLower(), newName.ToLower())); + helper.Execute(String.Format("ALTER TABLE `Portals{0}` RENAME TO `Portals{1}`", foundLevel.name.ToLower(), newName.ToLower())); + helper.Execute(String.Format("ALTER TABLE `Messages{0}` RENAME TO `Messages{1}`", foundLevel.name.ToLower(), newName.ToLower())); + helper.Execute(String.Format("ALTER TABLE `Zone{0}` RENAME TO `Zone{1}`", foundLevel.name.ToLower(), newName.ToLower())); helper.Commit(); } } diff --git a/Commands/Moderation/CmdUnbanip.cs b/Commands/Moderation/CmdUnbanip.cs index 9dfe95ce3..bf3faabe3 100644 --- a/Commands/Moderation/CmdUnbanip.cs +++ b/Commands/Moderation/CmdUnbanip.cs @@ -37,7 +37,7 @@ namespace MCGalaxy.Commands message = message.Remove(0, 1).Trim(); Player who = PlayerInfo.Find(message); if (who == null) { - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", message); DataTable ip = Database.fillData(query, "SELECT IP FROM Players WHERE Name = @Name"); if (ip.Rows.Count > 0) { diff --git a/Commands/Moderation/CmdZone.cs b/Commands/Moderation/CmdZone.cs index 0f3fe9cc1..fc9d320c6 100644 --- a/Commands/Moderation/CmdZone.cs +++ b/Commands/Moderation/CmdZone.cs @@ -88,7 +88,7 @@ namespace MCGalaxy.Commands for (int i = 0; i < p.level.ZoneList.Count; i++) { Level.Zone Zn = p.level.ZoneList[i]; - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Owner", Zn.Owner); Database.executeQuery(query, "DELETE FROM `Zone" + p.level.name + "` WHERE Owner=@Owner AND SmallX='" + Zn.smallX + "' AND SMALLY='" + Zn.smallY + "' AND SMALLZ='" + Zn.smallZ + "' AND BIGX='" + Zn.bigX + "' AND BIGY='" + Zn.bigY + "' AND BIGZ='" + Zn.bigZ + "'"); @@ -160,7 +160,7 @@ namespace MCGalaxy.Commands p.level.ZoneList.Add(Zn); - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Owner", Zn.Owner); Database.executeQuery(query, "INSERT INTO `Zone" + p.level.name + "` (SmallX, SmallY, SmallZ, BigX, BigY, BigZ, Owner) VALUES (" + Zn.smallX + ", " + Zn.smallY + ", " + Zn.smallZ + ", " + Zn.bigX + ", " + Zn.bigY + ", " + Zn.bigZ + ", @Owner)"); diff --git a/Commands/building/CmdMessageBlock.cs b/Commands/building/CmdMessageBlock.cs index 3f4fc4a75..e7ca7db46 100644 --- a/Commands/building/CmdMessageBlock.cs +++ b/Commands/building/CmdMessageBlock.cs @@ -90,7 +90,7 @@ namespace MCGalaxy.Commands { cpos.message = cpos.message.Replace("'", "\\'"); cpos.message = Colors.EscapeColors(cpos.message); //safe against SQL injections because no user input is given here - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); DataTable Messages = Database.fillData(query, "SELECT * FROM `Messages" + p.level.name + "` WHERE X=" + x + " AND Y=" + y + " AND Z=" + z); query.AddParam("@Message", cpos.message); diff --git a/Commands/other/CmdColor.cs b/Commands/other/CmdColor.cs index 01b809225..a65e24ecb 100644 --- a/Commands/other/CmdColor.cs +++ b/Commands/other/CmdColor.cs @@ -37,7 +37,7 @@ namespace MCGalaxy.Commands { Player.SendMessage(p, "Cannot change the color of someone of greater rank"); return; } - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); if (args.Length == 1) { Player.SendChatFrom(who, who.color + who.DisplayName + " %Shad their color removed.", false); who.color = who.group.color; diff --git a/Commands/other/CmdSend.cs b/Commands/other/CmdSend.cs index 0f8deaa2c..b6b521128 100644 --- a/Commands/other/CmdSend.cs +++ b/Commands/other/CmdSend.cs @@ -71,7 +71,7 @@ namespace MCGalaxy.Commands if (!Server.useMySQL) Server.s.Log(message.Replace("'", "\\'")); - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@From", fromname); query.AddParam("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); query.AddParam("@Content", message); diff --git a/Commands/other/CmdTColor.cs b/Commands/other/CmdTColor.cs index b92c32928..f0e82158e 100644 --- a/Commands/other/CmdTColor.cs +++ b/Commands/other/CmdTColor.cs @@ -37,7 +37,7 @@ namespace MCGalaxy.Commands { Player.SendMessage(p, "Cannot change the title color of someone of greater rank"); return; } - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); if (args.Length == 1) { Player.SendChatFrom(who, who.color + who.DisplayName + Server.DefaultColor + " had their title color removed.", false); who.titlecolor = ""; diff --git a/Commands/other/CmdTitle.cs b/Commands/other/CmdTitle.cs index 96e6e5df4..901695798 100644 --- a/Commands/other/CmdTitle.cs +++ b/Commands/other/CmdTitle.cs @@ -39,7 +39,7 @@ namespace MCGalaxy.Commands { } string newTitle = parts.Length > 1 ? parts[1] : ""; - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); if (newTitle != "") newTitle = newTitle.Replace("[", "").Replace("]", ""); if (newTitle.Length > 17) { Player.SendMessage(p, "Title must be under 17 letters."); return; } diff --git a/Database/BulkDatabaseTransaction.cs b/Database/BulkTransaction.cs similarity index 90% rename from Database/BulkDatabaseTransaction.cs rename to Database/BulkTransaction.cs index 9e185635b..0976d2cd7 100644 --- a/Database/BulkDatabaseTransaction.cs +++ b/Database/BulkTransaction.cs @@ -22,16 +22,17 @@ using System.Data.Common; using System.Linq; using System.Text; using MySql.Data.MySqlClient; +using MCGalaxy.SQL.Native; namespace MCGalaxy.SQL { - public abstract class BulkDatabaseTransaction : IDisposable { + public abstract class BulkTransaction : IDisposable { protected IDbConnection connection; protected IDbTransaction transaction; - public static BulkDatabaseTransaction Create() { - if (Server.useMySQL) return BulkMySQLTransaction.Create(MySQL.connString); - else return BulkSQLiteTransaction.Create(SQLite.connString); + public static BulkTransaction Create() { + if (Server.useMySQL) return MySQLBulkTransaction.Create(MySQL.connString); + else return SQLiteBulkTransaction.Create(SQLite.connString); } public abstract bool Execute(string query); diff --git a/Database/Database.cs b/Database/Database.cs index b1ba3facb..e1a587bdf 100644 --- a/Database/Database.cs +++ b/Database/Database.cs @@ -240,7 +240,7 @@ namespace MCGalaxy else executeQuery(SQLite.query, queryString, createDB); } - public static void executeQuery(DatabaseParameterisedQuery query, string queryString, bool createDB = false) { + public static void executeQuery(ParameterisedQuery query, string queryString, bool createDB = false) { Exception e = null; for (int i = 0; i < 10; i++) { try { @@ -262,7 +262,7 @@ namespace MCGalaxy else return fillData(SQLite.query, queryString, skipError); } - public static DataTable fillData(DatabaseParameterisedQuery query, string queryString, bool skipError = false) { + public static DataTable fillData(ParameterisedQuery query, string queryString, bool skipError = false) { using (DataTable results = new DataTable("toReturn")) { Exception e = null; for (int i = 0; i < 10; i++) { @@ -301,7 +301,7 @@ namespace MCGalaxy string[] cmds = script.Split(';'); StringBuilder sb = new StringBuilder(); - using (BulkDatabaseTransaction helper = BulkDatabaseTransaction.Create()) + using (BulkTransaction helper = BulkTransaction.Create()) { foreach (string cmd in cmds) diff --git a/Database/BulkMySQLTransaction.cs b/Database/MySQLBulkTransaction.cs similarity index 89% rename from Database/BulkMySQLTransaction.cs rename to Database/MySQLBulkTransaction.cs index 04a01f242..c9d2e8ba9 100644 --- a/Database/BulkMySQLTransaction.cs +++ b/Database/MySQLBulkTransaction.cs @@ -25,9 +25,9 @@ using MySql.Data.MySqlClient; namespace MCGalaxy.SQL { - public sealed class BulkMySQLTransaction : BulkDatabaseTransaction { + public sealed class MySQLBulkTransaction : BulkTransaction { - public BulkMySQLTransaction(string connString) { + public MySQLBulkTransaction(string connString) { Init(connString); } @@ -39,9 +39,9 @@ namespace MCGalaxy.SQL { transaction = connection.BeginTransaction(); } - public static BulkDatabaseTransaction Create(string connString) { + public static BulkTransaction Create(string connString) { try { - return new BulkMySQLTransaction(connString); + return new MySQLBulkTransaction(connString); } catch (Exception ex) { Server.ErrorLog(ex); return null; diff --git a/Database/MySQLParameterisedQuery.cs b/Database/MySQLParameterisedQuery.cs index 7489937af..7b4f4a63e 100644 --- a/Database/MySQLParameterisedQuery.cs +++ b/Database/MySQLParameterisedQuery.cs @@ -21,7 +21,7 @@ using MySql.Data.MySqlClient; namespace MCGalaxy.SQL { - public sealed class MySQLParameterisedQuery : DatabaseParameterisedQuery { + public sealed class MySQLParameterisedQuery : ParameterisedQuery { public override void Execute(string queryString, bool createDB = false) { using (var conn = new MySqlConnection(MySQL.connString)) { diff --git a/Database/Native/BulkNativeTransaction.cs b/Database/Native/NativeBulkTransaction.cs similarity index 84% rename from Database/Native/BulkNativeTransaction.cs rename to Database/Native/NativeBulkTransaction.cs index b67349f0a..12a903e1b 100644 --- a/Database/Native/BulkNativeTransaction.cs +++ b/Database/Native/NativeBulkTransaction.cs @@ -21,9 +21,9 @@ using System.Runtime.InteropServices; namespace MCGalaxy.SQL.Native { - public partial class BulkNativeTransaction : BulkDatabaseTransaction { + public partial class NativeBulkTransaction : BulkTransaction { - private BulkNativeTransaction(string connString) { + private NativeBulkTransaction(string connString) { Init(connString); } @@ -34,9 +34,9 @@ namespace MCGalaxy.SQL.Native { transaction = connection.BeginTransaction(); } - public static BulkDatabaseTransaction Create(string connString) { + public static BulkTransaction Create(string connString) { try { - return new BulkNativeTransaction(connString); + return new NativeBulkTransaction(connString); } catch (Exception ex) { Server.ErrorLog(ex); return null; @@ -52,6 +52,7 @@ namespace MCGalaxy.SQL.Native { cmd.CommandText = query; cmd.Connection = connection; cmd.Transaction = transaction; + cmd.Prepare(); return cmd; } diff --git a/Database/Native/NativeCommand.cs b/Database/Native/NativeCommand.cs index 9e6adb050..97623c040 100644 --- a/Database/Native/NativeCommand.cs +++ b/Database/Native/NativeCommand.cs @@ -22,7 +22,7 @@ using System.Runtime.InteropServices; namespace MCGalaxy.SQL.Native { - sealed class NativeCommand : IDbCommand { + unsafe sealed class NativeCommand : IDbCommand { public IntPtr Statement; NativeParamsList args = new NativeParamsList(); @@ -52,7 +52,7 @@ namespace MCGalaxy.SQL.Native { BindParam(param); int code = sqlite3_step(Statement); - if (code > 0) throw new NativeException(code); + if (code > 0 && code != 101) throw new NativeException(code); code = sqlite3_reset(Statement); if (code > 0) throw new NativeException(code); return 0; @@ -61,18 +61,19 @@ namespace MCGalaxy.SQL.Native { public void Dispose() { int code = sqlite3_finalize(Statement); if (code > 0) throw new NativeException(code); + if (dataCount == 0) return; + Marshal.FreeHGlobal((IntPtr)dataPtr); } void BindParam(IDataParameter param) { NativeParameter nParam = (NativeParameter)param; if (nParam.Index == -1) BindIndex(nParam); - DbType type = param.DbType; int code = 0; - switch (type) { + switch (nParam.type) { case DbType.AnsiStringFixedLength: - byte[] data = NativeUtils.MakeUTF8((string)nParam.Value); - code = sqlite3_bind_text(Statement, nParam.Index, data, data.Length - 1, IntPtr.Zero); + MakeString((string)nParam.Value); + code = sqlite3_bind_text(Statement, nParam.Index, dataPtr, dataCount - 1, IntPtr.Zero); break; case DbType.UInt16: ushort value_u16 = (ushort)nParam.Value; @@ -90,30 +91,43 @@ namespace MCGalaxy.SQL.Native { if (code > 0) throw new NativeException(code); } + byte* dataPtr; + int dataCount; + void MakeString(string value) { + if ((value.Length + 1) > dataCount) { + if (dataCount > 0) + Marshal.FreeHGlobal((IntPtr)dataPtr); + dataCount = value.Length + 1; + dataPtr = (byte*)Marshal.AllocHGlobal(dataCount); + } + for (int i = 0; i < value.Length; i++) + dataPtr[i] = (byte)value[i]; + } + void BindIndex(NativeParameter nParam) { byte[] name = NativeUtils.MakeUTF8(nParam.ParameterName); nParam.Index = sqlite3_bind_parameter_index(Statement, name); } - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_bind_int(IntPtr stmt, int index, int value); - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] name); - [DllImport("sqlite3.dll")] - static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] text, int textLen, IntPtr reserved); + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] + static extern int sqlite3_bind_text(IntPtr stmt, int index, byte* text, int textLen, IntPtr reserved); - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_finalize(IntPtr stmt); - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_prepare_v2(IntPtr db, byte[] sql, int nBytes, out IntPtr stmt, out IntPtr sqlTail); - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_reset(IntPtr stmt); - [DllImport("sqlite3.dll")] + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_step(IntPtr stmt); } } \ No newline at end of file diff --git a/Database/Native/NativeConnection.cs b/Database/Native/NativeConnection.cs index fcd4b4f49..87a91c995 100644 --- a/Database/Native/NativeConnection.cs +++ b/Database/Native/NativeConnection.cs @@ -33,11 +33,11 @@ namespace MCGalaxy.SQL.Native { public void ChangeDatabase(string databaseName) { } public IDbTransaction BeginTransaction(IsolationLevel il) { - return null; + return new NativeTransaction(this); } public void Close() { - int code = sqlite3_close_v2(DB); + int code = sqlite3_close(DB); DB = IntPtr.Zero; if (code > 0) throw new NativeException(code); } @@ -53,17 +53,30 @@ namespace MCGalaxy.SQL.Native { Close(); } + string path; public void Open() { - string[] args = ConnectionString.Split(';'); - byte[] filename = NativeUtils.MakeUTF8(args[0]); - int code = sqlite3_open_v2(filename, out DB, 0, IntPtr.Zero); + ParseConnectionString(); + byte[] filename = NativeUtils.MakeUTF8(path); + int code = sqlite3_open_v2(filename, out DB, 0x2, IntPtr.Zero); if (code > 0) throw new NativeException(code); } - [DllImport("sqlite3.dll")] + void ParseConnectionString() { + string[] args = ConnectionString.Split(';'); + foreach (string kvp in args) { + int sepIndex = kvp.IndexOf('='); + if (sepIndex < 0) continue; + string key = kvp.Substring(0, sepIndex).Trim(); + string value = kvp.Substring(sepIndex + 1).Trim(); + + if (key == "Data Source") path = value; + } + } + + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] static extern int sqlite3_open_v2(byte[] filename, out IntPtr db, int flags, IntPtr vfs); - [DllImport("sqlite3.dll")] - static extern int sqlite3_close_v2(IntPtr db); + [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)] + static extern int sqlite3_close(IntPtr db); } } \ No newline at end of file diff --git a/Database/Native/NativeException.cs b/Database/Native/NativeException.cs index 436c6466e..cb134a104 100644 --- a/Database/Native/NativeException.cs +++ b/Database/Native/NativeException.cs @@ -27,6 +27,8 @@ namespace MCGalaxy.SQL.Native { public NativeException(int errorCode) { ErrorCode = errorCode; } + + public override string Message { get { return ToString(); } } public override string ToString() { byte primaryCode = (byte)ErrorCode; diff --git a/Database/Native/Utils.cs b/Database/Native/Utils.cs index 68f95f950..7a9436ec8 100644 --- a/Database/Native/Utils.cs +++ b/Database/Native/Utils.cs @@ -44,14 +44,16 @@ namespace MCGalaxy.SQL.Native { } } - sealed class NativeParameter : IDataParameter { - public DbType DbType { get; set; } + sealed class NativeParameter : IDataParameter { + public DbType DbType { get { return type; } set { type = value; } } public ParameterDirection Direction { get; set; } public bool IsNullable { get { return false; } } public string ParameterName { get; set; } public string SourceColumn { get; set; } public DataRowVersion SourceVersion { get; set; } public object Value { get; set; } + + public DbType type; public int Index = -1; } diff --git a/Database/DatabaseParameterisedQuery.cs b/Database/ParameterisedQuery.cs similarity index 89% rename from Database/DatabaseParameterisedQuery.cs rename to Database/ParameterisedQuery.cs index 9424fd4c2..85a95ce7f 100644 --- a/Database/DatabaseParameterisedQuery.cs +++ b/Database/ParameterisedQuery.cs @@ -21,7 +21,7 @@ using System.Data; namespace MCGalaxy.SQL { - public abstract class DatabaseParameterisedQuery { + public abstract class ParameterisedQuery { protected Dictionary parameters = new Dictionary(); public void AddParam(string name, object param) { @@ -36,7 +36,7 @@ namespace MCGalaxy.SQL { public abstract void Fill(string query, DataTable results); - public static DatabaseParameterisedQuery Create() { + public static ParameterisedQuery Create() { if (Server.useMySQL) return new MySQLParameterisedQuery(); else return new SQLiteParameterisedQuery(); } diff --git a/Database/BulkSQLiteTransaction.cs b/Database/SQLiteBulkTransaction.cs similarity index 88% rename from Database/BulkSQLiteTransaction.cs rename to Database/SQLiteBulkTransaction.cs index 19693d977..0b204aff4 100644 --- a/Database/BulkSQLiteTransaction.cs +++ b/Database/SQLiteBulkTransaction.cs @@ -22,9 +22,9 @@ using System.Data.SQLite; namespace MCGalaxy.SQL { - public sealed class BulkSQLiteTransaction : BulkDatabaseTransaction { + public sealed class SQLiteBulkTransaction : BulkTransaction { - private BulkSQLiteTransaction(string connString) { + private SQLiteBulkTransaction(string connString) { Init(connString); } @@ -35,9 +35,9 @@ namespace MCGalaxy.SQL { transaction = connection.BeginTransaction(); } - public static BulkDatabaseTransaction Create(string connString) { + public static BulkTransaction Create(string connString) { try { - return new BulkSQLiteTransaction(connString); + return new SQLiteBulkTransaction(connString); } catch (Exception ex) { Server.ErrorLog(ex); return null; diff --git a/Database/SQLiteParameterisedQuery.cs b/Database/SQLiteParameterisedQuery.cs index 83a129999..fbdf7ccb2 100644 --- a/Database/SQLiteParameterisedQuery.cs +++ b/Database/SQLiteParameterisedQuery.cs @@ -21,7 +21,7 @@ using System.Data.SQLite; namespace MCGalaxy.SQL { - public sealed class SQLiteParameterisedQuery : DatabaseParameterisedQuery { + public sealed class SQLiteParameterisedQuery : ParameterisedQuery { public override void Execute(string query, bool createDB = false) { using (var conn = new SQLiteConnection(SQLite.connString)) { diff --git a/Economy/Economy.cs b/Economy/Economy.cs index 5d4476e74..73766b256 100644 --- a/Economy/Economy.cs +++ b/Economy/Economy.cs @@ -113,7 +113,7 @@ namespace MCGalaxy { public static EcoStats RetrieveEcoStats(string playername) { EcoStats es; es.playerName = playername; - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", playername); using (DataTable eco = Database.fillData(query, "SELECT * FROM Economy WHERE player=@Name")) { if (eco.Rows.Count >= 1) { @@ -136,7 +136,7 @@ namespace MCGalaxy { } public static void UpdateEcoStats(EcoStats es) { - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", es.playerName); query.AddParam("@Money", es.money); query.AddParam("@Total", es.totalSpent); diff --git a/Games/CTF/Auto_CTF.cs b/Games/CTF/Auto_CTF.cs index 2722e5526..ba7a392f4 100644 --- a/Games/CTF/Auto_CTF.cs +++ b/Games/CTF/Auto_CTF.cs @@ -431,7 +431,7 @@ namespace MCGalaxy.Games { const string syntax = "UPDATE CTF SET Points=@Points, Captures=@Captures, tags=@Tags WHERE Name=@Name"; d.hasflag = false; - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Points", d.points); query.AddParam("@Captures", d.cap); query.AddParam("@Tags", d.tag); diff --git a/Levels/Level.cs b/Levels/Level.cs index 197df855c..64aee0cbe 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -366,7 +366,7 @@ namespace MCGalaxy List tempCache = blockCache; string date = new String('-', 19); //yyyy-mm-dd hh:mm:ss - using (BulkDatabaseTransaction transaction = BulkDatabaseTransaction.Create()) { + using (BulkTransaction transaction = BulkTransaction.Create()) { fixed (char* ptr = date) { ptr[4] = '-'; ptr[7] = '-'; ptr[10] = ' '; ptr[13] = ':'; ptr[16] = ':'; DoSaveChanges(tempCache, ptr, date, transaction); @@ -378,7 +378,7 @@ namespace MCGalaxy } unsafe bool DoSaveChanges(List tempCache, char* ptr, string date, - BulkDatabaseTransaction transaction) { + BulkTransaction transaction) { string template = "INSERT INTO `Block" + name + "` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@Name, @Time, @X, @Y, @Z, @Tile, @Del)"; ushort x, y, z; @@ -405,7 +405,7 @@ namespace MCGalaxy tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawType; delP.Value = (bP.flags & 1) != 0; - if (!BulkDatabaseTransaction.Execute(template, cmd)) { + if (!BulkTransaction.Execute(template, cmd)) { cmd.Dispose(); transaction.Rollback(); return false; } diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 7cb865ae8..20251dbdd 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -391,11 +391,11 @@ - + - + @@ -541,7 +541,7 @@ - + @@ -553,13 +553,13 @@ EditText.cs - + - + diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs index 522fd3072..7eeed24b8 100644 --- a/Player/Player.Handlers.cs +++ b/Player/Player.Handlers.cs @@ -402,7 +402,7 @@ namespace MCGalaxy { onWhitelist = true; } else { // Verify Names is off. Gotta check the hard way. - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@IP", ip); DataTable ipQuery = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP"); @@ -458,7 +458,7 @@ namespace MCGalaxy { //OpenClassic Client Check SendBlockchange(0, 0, 0, 0); - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", name); DataTable playerDb = Database.fillData(query, "SELECT * FROM Players WHERE Name=@Name"); @@ -1524,7 +1524,7 @@ return; try { //opstats patch (since 5.5.11) if (Server.opstats.Contains(cmd) || (cmd == "review" && message.ToLower() == "next" && Server.reviewlist.Count > 0)) { - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); query.AddParam("@Name", name); query.AddParam("@Cmd", cmd); diff --git a/Player/PlayerInfo.cs b/Player/PlayerInfo.cs index 14a74fc19..aa075491f 100644 --- a/Player/PlayerInfo.cs +++ b/Player/PlayerInfo.cs @@ -163,7 +163,7 @@ namespace MCGalaxy { public static OfflinePlayer FindOffline(string name, bool fullStats = false) { OfflinePlayer pl = new OfflinePlayer(); - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", name); string syntax = Server.useMySQL ? "SELECT * FROM Players WHERE Name=@Name COLLATE utf8_general_ci" : "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"; @@ -195,7 +195,7 @@ namespace MCGalaxy { } public static string FindOfflineName(string name) { - DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); + ParameterisedQuery query = ParameterisedQuery.Create(); query.AddParam("@Name", name); string syntax = Server.useMySQL ? "SELECT Name FROM Players WHERE Name=@Name COLLATE utf8_general_ci" : "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"; diff --git a/Server/AutoSaver.cs b/Server/AutoSaver.cs index fe4a16933..7ee53f22a 100644 --- a/Server/AutoSaver.cs +++ b/Server/AutoSaver.cs @@ -22,7 +22,6 @@ using System.Threading; namespace MCGalaxy { - //I public sealed class AutoSaver { static int _interval;