Finish lightweight (and fast) native sqllite implementation, also fix /renamelvl not working properly when level names have + in them on the sqllite backend.

This commit is contained in:
UnknownShadow200 2016-03-25 20:53:26 +11:00
parent 18ba121b88
commit bde18d7d41
33 changed files with 115 additions and 83 deletions

View File

@ -25,7 +25,7 @@ namespace MCGalaxy
{ {
Server.s.Log(p); Server.s.Log(p);
rank = Group.findPlayer(p); rank = Group.findPlayer(p);
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", p.ToLower()); query.AddParam("@Name", p.ToLower());
DataTable playerDb = Database.fillData(query, "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"); DataTable playerDb = Database.fillData(query, "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE");
if (playerDb.Rows.Count == 0) if (playerDb.Rows.Count == 0)

View File

@ -49,7 +49,7 @@ namespace MCGalaxy.Commands
{ {
message = who.ip; message = who.ip;
} }
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@IP", message); query.AddParam("@IP", message);
DataTable Clones = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP"); DataTable Clones = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP");

View File

@ -71,7 +71,7 @@ namespace MCGalaxy.Commands
Player.SendMessage(p, "\"" + FoundRecord + "\" does not exist."); Inbox.Dispose(); return; Player.SendMessage(p, "\"" + FoundRecord + "\" does not exist."); Inbox.Dispose(); return;
} }
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
string queryString; string queryString;
//safe against SQL injections because no user input is given here //safe against SQL injections because no user input is given here
if (FoundRecord == -1) if (FoundRecord == -1)

View File

@ -33,7 +33,7 @@ namespace MCGalaxy.Commands
if (message == "") { Help(p); return; } if (message == "") { Help(p); return; }
if (message.IndexOf("'") != -1) { Player.SendMessage(p, "Cannot parse request."); return; } if (message.IndexOf("'") != -1) { Player.SendMessage(p, "Cannot parse request."); return; }
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@IP", message); query.AddParam("@IP", message);
DataTable playerDb = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP"); DataTable playerDb = Database.fillData(query, "SELECT Name FROM Players WHERE IP=@IP");

View File

@ -68,7 +68,7 @@ namespace MCGalaxy.Commands {
// First get names of active ops+ with that ip // First get names of active ops+ with that ip
List<string> opNamesWithThatIP = (from pl in PlayerInfo.players where (pl.ip == message && pl.@group.Permission >= LevelPermission.Operator) select pl.name).ToList(); List<string> 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 // Next, add names from the database
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@IP", message); query.AddParam("@IP", message);
DataTable dbnames = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP"); DataTable dbnames = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP");

View File

@ -190,7 +190,7 @@ namespace MCGalaxy.Commands {
} }
static void UpdateDB(Player p, string name, string type, string value, string column) { 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); query.AddParam("@Name", name);
if (value != "") { if (value != "") {
query.AddParam("@ArgValue", value); query.AddParam("@ArgValue", value);

View File

@ -103,11 +103,11 @@ namespace MCGalaxy.Commands
"`Messages{0}` TO `Messages{1}`, " + "`Messages{0}` TO `Messages{1}`, " +
"`Zone{0}` TO `Zone{1}`", foundLevel.name.ToLower(), newName.ToLower())); "`Zone{0}` TO `Zone{1}`", foundLevel.name.ToLower(), newName.ToLower()));
else { else {
using (BulkDatabaseTransaction helper = BulkSQLiteTransaction.Create()) { // ensures that it's either all work, or none work. 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 `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 `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 `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.Execute(String.Format("ALTER TABLE `Zone{0}` RENAME TO `Zone{1}`", foundLevel.name.ToLower(), newName.ToLower()));
helper.Commit(); helper.Commit();
} }
} }

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Commands
message = message.Remove(0, 1).Trim(); message = message.Remove(0, 1).Trim();
Player who = PlayerInfo.Find(message); Player who = PlayerInfo.Find(message);
if (who == null) { if (who == null) {
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", message); query.AddParam("@Name", message);
DataTable ip = Database.fillData(query, "SELECT IP FROM Players WHERE Name = @Name"); DataTable ip = Database.fillData(query, "SELECT IP FROM Players WHERE Name = @Name");
if (ip.Rows.Count > 0) { if (ip.Rows.Count > 0) {

View File

@ -88,7 +88,7 @@ namespace MCGalaxy.Commands
for (int i = 0; i < p.level.ZoneList.Count; i++) for (int i = 0; i < p.level.ZoneList.Count; i++)
{ {
Level.Zone Zn = p.level.ZoneList[i]; Level.Zone Zn = p.level.ZoneList[i];
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Owner", Zn.Owner); 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 + 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 + "'"); "' 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); p.level.ZoneList.Add(Zn);
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Owner", Zn.Owner); query.AddParam("@Owner", Zn.Owner);
Database.executeQuery(query, "INSERT INTO `Zone" + p.level.name + "` (SmallX, SmallY, SmallZ, BigX, BigY, BigZ, Owner) VALUES (" 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)"); + Zn.smallX + ", " + Zn.smallY + ", " + Zn.smallZ + ", " + Zn.bigX + ", " + Zn.bigY + ", " + Zn.bigZ + ", @Owner)");

View File

@ -90,7 +90,7 @@ namespace MCGalaxy.Commands {
cpos.message = cpos.message.Replace("'", "\\'"); cpos.message = cpos.message.Replace("'", "\\'");
cpos.message = Colors.EscapeColors(cpos.message); cpos.message = Colors.EscapeColors(cpos.message);
//safe against SQL injections because no user input is given here //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); 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); query.AddParam("@Message", cpos.message);

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Commands {
Player.SendMessage(p, "Cannot change the color of someone of greater rank"); return; 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) { if (args.Length == 1) {
Player.SendChatFrom(who, who.color + who.DisplayName + " %Shad their color removed.", false); Player.SendChatFrom(who, who.color + who.DisplayName + " %Shad their color removed.", false);
who.color = who.group.color; who.color = who.group.color;

View File

@ -71,7 +71,7 @@ namespace MCGalaxy.Commands
if (!Server.useMySQL) if (!Server.useMySQL)
Server.s.Log(message.Replace("'", "\\'")); Server.s.Log(message.Replace("'", "\\'"));
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@From", fromname); query.AddParam("@From", fromname);
query.AddParam("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); query.AddParam("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
query.AddParam("@Content", message); query.AddParam("@Content", message);

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Commands {
Player.SendMessage(p, "Cannot change the title color of someone of greater rank"); return; 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) { if (args.Length == 1) {
Player.SendChatFrom(who, who.color + who.DisplayName + Server.DefaultColor + " had their title color removed.", false); Player.SendChatFrom(who, who.color + who.DisplayName + Server.DefaultColor + " had their title color removed.", false);
who.titlecolor = ""; who.titlecolor = "";

View File

@ -39,7 +39,7 @@ namespace MCGalaxy.Commands {
} }
string newTitle = parts.Length > 1 ? parts[1] : ""; string newTitle = parts.Length > 1 ? parts[1] : "";
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
if (newTitle != "") if (newTitle != "")
newTitle = newTitle.Replace("[", "").Replace("]", ""); newTitle = newTitle.Replace("[", "").Replace("]", "");
if (newTitle.Length > 17) { Player.SendMessage(p, "Title must be under 17 letters."); return; } if (newTitle.Length > 17) { Player.SendMessage(p, "Title must be under 17 letters."); return; }

View File

@ -22,16 +22,17 @@ using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using MCGalaxy.SQL.Native;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public abstract class BulkDatabaseTransaction : IDisposable { public abstract class BulkTransaction : IDisposable {
protected IDbConnection connection; protected IDbConnection connection;
protected IDbTransaction transaction; protected IDbTransaction transaction;
public static BulkDatabaseTransaction Create() { public static BulkTransaction Create() {
if (Server.useMySQL) return BulkMySQLTransaction.Create(MySQL.connString); if (Server.useMySQL) return MySQLBulkTransaction.Create(MySQL.connString);
else return BulkSQLiteTransaction.Create(SQLite.connString); else return SQLiteBulkTransaction.Create(SQLite.connString);
} }
public abstract bool Execute(string query); public abstract bool Execute(string query);

View File

@ -240,7 +240,7 @@ namespace MCGalaxy
else executeQuery(SQLite.query, queryString, createDB); 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; Exception e = null;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
try { try {
@ -262,7 +262,7 @@ namespace MCGalaxy
else return fillData(SQLite.query, queryString, skipError); 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")) { using (DataTable results = new DataTable("toReturn")) {
Exception e = null; Exception e = null;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
@ -301,7 +301,7 @@ namespace MCGalaxy
string[] cmds = script.Split(';'); string[] cmds = script.Split(';');
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
using (BulkDatabaseTransaction helper = BulkDatabaseTransaction.Create()) using (BulkTransaction helper = BulkTransaction.Create())
{ {
foreach (string cmd in cmds) foreach (string cmd in cmds)

View File

@ -25,9 +25,9 @@ using MySql.Data.MySqlClient;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public sealed class BulkMySQLTransaction : BulkDatabaseTransaction { public sealed class MySQLBulkTransaction : BulkTransaction {
public BulkMySQLTransaction(string connString) { public MySQLBulkTransaction(string connString) {
Init(connString); Init(connString);
} }
@ -39,9 +39,9 @@ namespace MCGalaxy.SQL {
transaction = connection.BeginTransaction(); transaction = connection.BeginTransaction();
} }
public static BulkDatabaseTransaction Create(string connString) { public static BulkTransaction Create(string connString) {
try { try {
return new BulkMySQLTransaction(connString); return new MySQLBulkTransaction(connString);
} catch (Exception ex) { } catch (Exception ex) {
Server.ErrorLog(ex); Server.ErrorLog(ex);
return null; return null;

View File

@ -21,7 +21,7 @@ using MySql.Data.MySqlClient;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public sealed class MySQLParameterisedQuery : DatabaseParameterisedQuery { public sealed class MySQLParameterisedQuery : ParameterisedQuery {
public override void Execute(string queryString, bool createDB = false) { public override void Execute(string queryString, bool createDB = false) {
using (var conn = new MySqlConnection(MySQL.connString)) { using (var conn = new MySqlConnection(MySQL.connString)) {

View File

@ -21,9 +21,9 @@ using System.Runtime.InteropServices;
namespace MCGalaxy.SQL.Native { namespace MCGalaxy.SQL.Native {
public partial class BulkNativeTransaction : BulkDatabaseTransaction { public partial class NativeBulkTransaction : BulkTransaction {
private BulkNativeTransaction(string connString) { private NativeBulkTransaction(string connString) {
Init(connString); Init(connString);
} }
@ -34,9 +34,9 @@ namespace MCGalaxy.SQL.Native {
transaction = connection.BeginTransaction(); transaction = connection.BeginTransaction();
} }
public static BulkDatabaseTransaction Create(string connString) { public static BulkTransaction Create(string connString) {
try { try {
return new BulkNativeTransaction(connString); return new NativeBulkTransaction(connString);
} catch (Exception ex) { } catch (Exception ex) {
Server.ErrorLog(ex); Server.ErrorLog(ex);
return null; return null;
@ -52,6 +52,7 @@ namespace MCGalaxy.SQL.Native {
cmd.CommandText = query; cmd.CommandText = query;
cmd.Connection = connection; cmd.Connection = connection;
cmd.Transaction = transaction; cmd.Transaction = transaction;
cmd.Prepare();
return cmd; return cmd;
} }

View File

@ -22,7 +22,7 @@ using System.Runtime.InteropServices;
namespace MCGalaxy.SQL.Native { namespace MCGalaxy.SQL.Native {
sealed class NativeCommand : IDbCommand { unsafe sealed class NativeCommand : IDbCommand {
public IntPtr Statement; public IntPtr Statement;
NativeParamsList args = new NativeParamsList(); NativeParamsList args = new NativeParamsList();
@ -52,7 +52,7 @@ namespace MCGalaxy.SQL.Native {
BindParam(param); BindParam(param);
int code = sqlite3_step(Statement); 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); code = sqlite3_reset(Statement);
if (code > 0) throw new NativeException(code); if (code > 0) throw new NativeException(code);
return 0; return 0;
@ -61,18 +61,19 @@ namespace MCGalaxy.SQL.Native {
public void Dispose() { public void Dispose() {
int code = sqlite3_finalize(Statement); int code = sqlite3_finalize(Statement);
if (code > 0) throw new NativeException(code); if (code > 0) throw new NativeException(code);
if (dataCount == 0) return;
Marshal.FreeHGlobal((IntPtr)dataPtr);
} }
void BindParam(IDataParameter param) { void BindParam(IDataParameter param) {
NativeParameter nParam = (NativeParameter)param; NativeParameter nParam = (NativeParameter)param;
if (nParam.Index == -1) BindIndex(nParam); if (nParam.Index == -1) BindIndex(nParam);
DbType type = param.DbType;
int code = 0; int code = 0;
switch (type) { switch (nParam.type) {
case DbType.AnsiStringFixedLength: case DbType.AnsiStringFixedLength:
byte[] data = NativeUtils.MakeUTF8((string)nParam.Value); MakeString((string)nParam.Value);
code = sqlite3_bind_text(Statement, nParam.Index, data, data.Length - 1, IntPtr.Zero); code = sqlite3_bind_text(Statement, nParam.Index, dataPtr, dataCount - 1, IntPtr.Zero);
break; break;
case DbType.UInt16: case DbType.UInt16:
ushort value_u16 = (ushort)nParam.Value; ushort value_u16 = (ushort)nParam.Value;
@ -90,30 +91,43 @@ namespace MCGalaxy.SQL.Native {
if (code > 0) throw new NativeException(code); 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) { void BindIndex(NativeParameter nParam) {
byte[] name = NativeUtils.MakeUTF8(nParam.ParameterName); byte[] name = NativeUtils.MakeUTF8(nParam.ParameterName);
nParam.Index = sqlite3_bind_parameter_index(Statement, name); 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); 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); static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] name);
[DllImport("sqlite3.dll")] [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] text, int textLen, IntPtr reserved); 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); 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); 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); static extern int sqlite3_reset(IntPtr stmt);
[DllImport("sqlite3.dll")] [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int sqlite3_step(IntPtr stmt); static extern int sqlite3_step(IntPtr stmt);
} }
} }

View File

@ -33,11 +33,11 @@ namespace MCGalaxy.SQL.Native {
public void ChangeDatabase(string databaseName) { } public void ChangeDatabase(string databaseName) { }
public IDbTransaction BeginTransaction(IsolationLevel il) { public IDbTransaction BeginTransaction(IsolationLevel il) {
return null; return new NativeTransaction(this);
} }
public void Close() { public void Close() {
int code = sqlite3_close_v2(DB); int code = sqlite3_close(DB);
DB = IntPtr.Zero; DB = IntPtr.Zero;
if (code > 0) throw new NativeException(code); if (code > 0) throw new NativeException(code);
} }
@ -53,17 +53,30 @@ namespace MCGalaxy.SQL.Native {
Close(); Close();
} }
string path;
public void Open() { public void Open() {
string[] args = ConnectionString.Split(';'); ParseConnectionString();
byte[] filename = NativeUtils.MakeUTF8(args[0]); byte[] filename = NativeUtils.MakeUTF8(path);
int code = sqlite3_open_v2(filename, out DB, 0, IntPtr.Zero); int code = sqlite3_open_v2(filename, out DB, 0x2, IntPtr.Zero);
if (code > 0) throw new NativeException(code); 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); static extern int sqlite3_open_v2(byte[] filename, out IntPtr db, int flags, IntPtr vfs);
[DllImport("sqlite3.dll")] [DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int sqlite3_close_v2(IntPtr db); static extern int sqlite3_close(IntPtr db);
} }
} }

View File

@ -27,6 +27,8 @@ namespace MCGalaxy.SQL.Native {
public NativeException(int errorCode) { public NativeException(int errorCode) {
ErrorCode = errorCode; ErrorCode = errorCode;
} }
public override string Message { get { return ToString(); } }
public override string ToString() { public override string ToString() {
byte primaryCode = (byte)ErrorCode; byte primaryCode = (byte)ErrorCode;

View File

@ -44,14 +44,16 @@ namespace MCGalaxy.SQL.Native {
} }
} }
sealed class NativeParameter : IDataParameter { sealed class NativeParameter : IDataParameter {
public DbType DbType { get; set; } public DbType DbType { get { return type; } set { type = value; } }
public ParameterDirection Direction { get; set; } public ParameterDirection Direction { get; set; }
public bool IsNullable { get { return false; } } public bool IsNullable { get { return false; } }
public string ParameterName { get; set; } public string ParameterName { get; set; }
public string SourceColumn { get; set; } public string SourceColumn { get; set; }
public DataRowVersion SourceVersion { get; set; } public DataRowVersion SourceVersion { get; set; }
public object Value { get; set; } public object Value { get; set; }
public DbType type;
public int Index = -1; public int Index = -1;
} }

View File

@ -21,7 +21,7 @@ using System.Data;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public abstract class DatabaseParameterisedQuery { public abstract class ParameterisedQuery {
protected Dictionary<string, object> parameters = new Dictionary<string, object>(); protected Dictionary<string, object> parameters = new Dictionary<string, object>();
public void AddParam(string name, object param) { public void AddParam(string name, object param) {
@ -36,7 +36,7 @@ namespace MCGalaxy.SQL {
public abstract void Fill(string query, DataTable results); public abstract void Fill(string query, DataTable results);
public static DatabaseParameterisedQuery Create() { public static ParameterisedQuery Create() {
if (Server.useMySQL) return new MySQLParameterisedQuery(); if (Server.useMySQL) return new MySQLParameterisedQuery();
else return new SQLiteParameterisedQuery(); else return new SQLiteParameterisedQuery();
} }

View File

@ -22,9 +22,9 @@ using System.Data.SQLite;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public sealed class BulkSQLiteTransaction : BulkDatabaseTransaction { public sealed class SQLiteBulkTransaction : BulkTransaction {
private BulkSQLiteTransaction(string connString) { private SQLiteBulkTransaction(string connString) {
Init(connString); Init(connString);
} }
@ -35,9 +35,9 @@ namespace MCGalaxy.SQL {
transaction = connection.BeginTransaction(); transaction = connection.BeginTransaction();
} }
public static BulkDatabaseTransaction Create(string connString) { public static BulkTransaction Create(string connString) {
try { try {
return new BulkSQLiteTransaction(connString); return new SQLiteBulkTransaction(connString);
} catch (Exception ex) { } catch (Exception ex) {
Server.ErrorLog(ex); Server.ErrorLog(ex);
return null; return null;

View File

@ -21,7 +21,7 @@ using System.Data.SQLite;
namespace MCGalaxy.SQL { namespace MCGalaxy.SQL {
public sealed class SQLiteParameterisedQuery : DatabaseParameterisedQuery { public sealed class SQLiteParameterisedQuery : ParameterisedQuery {
public override void Execute(string query, bool createDB = false) { public override void Execute(string query, bool createDB = false) {
using (var conn = new SQLiteConnection(SQLite.connString)) { using (var conn = new SQLiteConnection(SQLite.connString)) {

View File

@ -113,7 +113,7 @@ namespace MCGalaxy {
public static EcoStats RetrieveEcoStats(string playername) { public static EcoStats RetrieveEcoStats(string playername) {
EcoStats es; EcoStats es;
es.playerName = playername; es.playerName = playername;
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", playername); query.AddParam("@Name", playername);
using (DataTable eco = Database.fillData(query, "SELECT * FROM Economy WHERE player=@Name")) { using (DataTable eco = Database.fillData(query, "SELECT * FROM Economy WHERE player=@Name")) {
if (eco.Rows.Count >= 1) { if (eco.Rows.Count >= 1) {
@ -136,7 +136,7 @@ namespace MCGalaxy {
} }
public static void UpdateEcoStats(EcoStats es) { public static void UpdateEcoStats(EcoStats es) {
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", es.playerName); query.AddParam("@Name", es.playerName);
query.AddParam("@Money", es.money); query.AddParam("@Money", es.money);
query.AddParam("@Total", es.totalSpent); query.AddParam("@Total", es.totalSpent);

View File

@ -431,7 +431,7 @@ namespace MCGalaxy.Games
{ {
const string syntax = "UPDATE CTF SET Points=@Points, Captures=@Captures, tags=@Tags WHERE Name=@Name"; const string syntax = "UPDATE CTF SET Points=@Points, Captures=@Captures, tags=@Tags WHERE Name=@Name";
d.hasflag = false; d.hasflag = false;
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Points", d.points); query.AddParam("@Points", d.points);
query.AddParam("@Captures", d.cap); query.AddParam("@Captures", d.cap);
query.AddParam("@Tags", d.tag); query.AddParam("@Tags", d.tag);

View File

@ -366,7 +366,7 @@ namespace MCGalaxy
List<BlockPos> tempCache = blockCache; List<BlockPos> tempCache = blockCache;
string date = new String('-', 19); //yyyy-mm-dd hh:mm:ss 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) { fixed (char* ptr = date) {
ptr[4] = '-'; ptr[7] = '-'; ptr[10] = ' '; ptr[13] = ':'; ptr[16] = ':'; ptr[4] = '-'; ptr[7] = '-'; ptr[10] = ' '; ptr[13] = ':'; ptr[16] = ':';
DoSaveChanges(tempCache, ptr, date, transaction); DoSaveChanges(tempCache, ptr, date, transaction);
@ -378,7 +378,7 @@ namespace MCGalaxy
} }
unsafe bool DoSaveChanges(List<BlockPos> tempCache, char* ptr, string date, unsafe bool DoSaveChanges(List<BlockPos> tempCache, char* ptr, string date,
BulkDatabaseTransaction transaction) { BulkTransaction transaction) {
string template = "INSERT INTO `Block" + name + string template = "INSERT INTO `Block" + name +
"` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@Name, @Time, @X, @Y, @Z, @Tile, @Del)"; "` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@Name, @Time, @X, @Y, @Z, @Tile, @Del)";
ushort x, y, z; ushort x, y, z;
@ -405,7 +405,7 @@ namespace MCGalaxy
tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawType; tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawType;
delP.Value = (bP.flags & 1) != 0; delP.Value = (bP.flags & 1) != 0;
if (!BulkDatabaseTransaction.Execute(template, cmd)) { if (!BulkTransaction.Execute(template, cmd)) {
cmd.Dispose(); cmd.Dispose();
transaction.Rollback(); return false; transaction.Rollback(); return false;
} }

View File

@ -391,11 +391,11 @@
<Compile Include="Commands\World\CmdTexture.cs" /> <Compile Include="Commands\World\CmdTexture.cs" />
<Compile Include="Commands\World\CmdUnflood.cs" /> <Compile Include="Commands\World\CmdUnflood.cs" />
<Compile Include="Commands\World\CmdUnload.cs" /> <Compile Include="Commands\World\CmdUnload.cs" />
<Compile Include="Database\DatabaseParameterisedQuery.cs" /> <Compile Include="Database\ParameterisedQuery.cs" />
<Compile Include="Database\MySQLParameterisedQuery.cs" /> <Compile Include="Database\MySQLParameterisedQuery.cs" />
<Compile Include="Database\Native\NativeConnection.cs" /> <Compile Include="Database\Native\NativeConnection.cs" />
<Compile Include="Database\Native\Utils.cs" /> <Compile Include="Database\Native\Utils.cs" />
<Compile Include="Database\Native\BulkNativeTransaction.cs" /> <Compile Include="Database\Native\NativeBulkTransaction.cs" />
<Compile Include="Database\Native\NativeCommand.cs" /> <Compile Include="Database\Native\NativeCommand.cs" />
<Compile Include="Database\Native\NativeException.cs" /> <Compile Include="Database\Native\NativeException.cs" />
<Compile Include="Database\SQLiteParameterisedQuery.cs" /> <Compile Include="Database\SQLiteParameterisedQuery.cs" />
@ -541,7 +541,7 @@
<Compile Include="GUI\Win32\Margins.cs" /> <Compile Include="GUI\Win32\Margins.cs" />
<Compile Include="GUI\Win32\Natives.cs" /> <Compile Include="GUI\Win32\Natives.cs" />
<Compile Include="GUI\Win32\RECT.cs" /> <Compile Include="GUI\Win32\RECT.cs" />
<Compile Include="Database\BulkDatabaseTransaction.cs" /> <Compile Include="Database\BulkTransaction.cs" />
<Compile Include="Database\Database.cs" /> <Compile Include="Database\Database.cs" />
<Compile Include="Games\CTF\Auto_CTF.cs" /> <Compile Include="Games\CTF\Auto_CTF.cs" />
<Compile Include="IRC\GlobalChatBot.cs" /> <Compile Include="IRC\GlobalChatBot.cs" />
@ -553,13 +553,13 @@
<DependentUpon>EditText.cs</DependentUpon> <DependentUpon>EditText.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Levels\BlockQueue.cs" /> <Compile Include="Levels\BlockQueue.cs" />
<Compile Include="Database\BulkMySQLTransaction.cs" /> <Compile Include="Database\MySQLBulkTransaction.cs" />
<Compile Include="Player\Player.Events.cs" /> <Compile Include="Player\Player.Events.cs" />
<Compile Include="ScriptingUtil\ScriptingVB.cs" /> <Compile Include="ScriptingUtil\ScriptingVB.cs" />
<Compile Include="Server\Extra\Checktimer.cs" /> <Compile Include="Server\Extra\Checktimer.cs" />
<Compile Include="Server\Extra\UPnP.cs" /> <Compile Include="Server\Extra\UPnP.cs" />
<Compile Include="Database\SQLite.cs" /> <Compile Include="Database\SQLite.cs" />
<Compile Include="Database\BulkSQLiteTransaction.cs" /> <Compile Include="Database\SQLiteBulkTransaction.cs" />
<Compile Include="Drawing\ImagePalette.cs" /> <Compile Include="Drawing\ImagePalette.cs" />
<Compile Include="Server\Colors.cs" /> <Compile Include="Server\Colors.cs" />
<Compile Include="GlobalSuppressions.cs" /> <Compile Include="GlobalSuppressions.cs" />

View File

@ -402,7 +402,7 @@ namespace MCGalaxy {
onWhitelist = true; onWhitelist = true;
} else { } else {
// Verify Names is off. Gotta check the hard way. // Verify Names is off. Gotta check the hard way.
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@IP", ip); query.AddParam("@IP", ip);
DataTable ipQuery = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP"); DataTable ipQuery = Database.fillData(query, "SELECT Name FROM Players WHERE IP = @IP");
@ -458,7 +458,7 @@ namespace MCGalaxy {
//OpenClassic Client Check //OpenClassic Client Check
SendBlockchange(0, 0, 0, 0); SendBlockchange(0, 0, 0, 0);
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", name); query.AddParam("@Name", name);
DataTable playerDb = Database.fillData(query, "SELECT * FROM Players WHERE 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) try { //opstats patch (since 5.5.11)
if (Server.opstats.Contains(cmd) || (cmd == "review" && message.ToLower() == "next" && Server.reviewlist.Count > 0)) { 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("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
query.AddParam("@Name", name); query.AddParam("@Name", name);
query.AddParam("@Cmd", cmd); query.AddParam("@Cmd", cmd);

View File

@ -163,7 +163,7 @@ namespace MCGalaxy {
public static OfflinePlayer FindOffline(string name, bool fullStats = false) { public static OfflinePlayer FindOffline(string name, bool fullStats = false) {
OfflinePlayer pl = new OfflinePlayer(); OfflinePlayer pl = new OfflinePlayer();
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", name); query.AddParam("@Name", name);
string syntax = Server.useMySQL ? "SELECT * FROM Players WHERE Name=@Name COLLATE utf8_general_ci" : string syntax = Server.useMySQL ? "SELECT * FROM Players WHERE Name=@Name COLLATE utf8_general_ci" :
"SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"; "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE";
@ -195,7 +195,7 @@ namespace MCGalaxy {
} }
public static string FindOfflineName(string name) { public static string FindOfflineName(string name) {
DatabaseParameterisedQuery query = DatabaseParameterisedQuery.Create(); ParameterisedQuery query = ParameterisedQuery.Create();
query.AddParam("@Name", name); query.AddParam("@Name", name);
string syntax = Server.useMySQL ? "SELECT Name FROM Players WHERE Name=@Name COLLATE utf8_general_ci" : string syntax = Server.useMySQL ? "SELECT Name FROM Players WHERE Name=@Name COLLATE utf8_general_ci" :
"SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE"; "SELECT * FROM Players WHERE Name=@Name COLLATE NOCASE";

View File

@ -22,7 +22,6 @@ using System.Threading;
namespace MCGalaxy namespace MCGalaxy
{ {
//I
public sealed class AutoSaver public sealed class AutoSaver
{ {
static int _interval; static int _interval;