mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 03:55:18 -04:00
Completely remove the obsolete MySQL, SQLite3, and Native sqlite backend classes.
This commit is contained in:
parent
65561ad2ea
commit
8bc3fe0675
@ -18,7 +18,7 @@
|
||||
using System;
|
||||
|
||||
namespace MCGalaxy.SQL {
|
||||
|
||||
|
||||
public abstract class IDatabaseBackend {
|
||||
|
||||
/// <summary> Describes the arguments for a database connection
|
||||
@ -36,5 +36,11 @@ namespace MCGalaxy.SQL {
|
||||
/// <summary> Returns the shared static ParamterisedQuery instance, that is only used
|
||||
/// for sql queries with no parameters. </summary>
|
||||
internal abstract ParameterisedQuery GetStaticParameterised();
|
||||
|
||||
|
||||
// == Higher level functions ==
|
||||
|
||||
/// <summary> Returns whether a table (case sensitive) exists by that name. </summary>
|
||||
public abstract bool TableExists(string table);
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,12 @@ namespace MCGalaxy.SQL {
|
||||
internal override ParameterisedQuery GetStaticParameterised() {
|
||||
return queryInstance;
|
||||
}
|
||||
|
||||
public override bool TableExists(string table) {
|
||||
const string syntax = "SELECT * FROM information_schema.tables WHERE table_schema = @1 AND table_name = @0";
|
||||
using (DataTable results = Database.Fill(syntax, table, Server.MySQLDatabaseName))
|
||||
return results.Rows.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MySQLBulkTransaction : BulkTransaction {
|
||||
@ -69,8 +75,8 @@ namespace MCGalaxy.SQL {
|
||||
|
||||
public sealed class MySQLParameterisedQuery : ParameterisedQuery {
|
||||
|
||||
public override void Execute(string queryString, bool createDB = false) {
|
||||
using (var conn = new MySqlConnection(MySQL.connString)) {
|
||||
public override void Execute(string queryString, string connString, bool createDB = false) {
|
||||
using (var conn = new MySqlConnection(connString)) {
|
||||
conn.Open();
|
||||
if (!createDB) conn.ChangeDatabase(Server.MySQLDatabaseName);
|
||||
|
||||
@ -83,8 +89,8 @@ namespace MCGalaxy.SQL {
|
||||
}
|
||||
}
|
||||
|
||||
public override void Fill(string queryString, DataTable toReturn) {
|
||||
using (var conn = new MySqlConnection(MySQL.connString)) {
|
||||
public override void Fill(string queryString, string connString, DataTable toReturn) {
|
||||
using (var conn = new MySqlConnection(connString)) {
|
||||
conn.Open();
|
||||
conn.ChangeDatabase(Server.MySQLDatabaseName);
|
||||
using (MySqlDataAdapter da = new MySqlDataAdapter(queryString, conn)) {
|
||||
|
@ -42,6 +42,12 @@ namespace MCGalaxy.SQL {
|
||||
internal override ParameterisedQuery GetStaticParameterised() {
|
||||
return queryInstance;
|
||||
}
|
||||
|
||||
public override bool TableExists(string table) {
|
||||
const string syntax = "SELECT name FROM sqlite_master WHERE type='table' AND name=@0";
|
||||
using (DataTable results = Database.Fill(syntax, table))
|
||||
return results.Rows.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SQLiteBulkTransaction : BulkTransaction {
|
||||
@ -63,8 +69,8 @@ namespace MCGalaxy.SQL {
|
||||
|
||||
public sealed class SQLiteParameterisedQuery : ParameterisedQuery {
|
||||
|
||||
public override void Execute(string query, bool createDB = false) {
|
||||
using (var conn = new SQLiteConnection(SQLite.connString)) {
|
||||
public override void Execute(string query, string connString, bool createDB = false) {
|
||||
using (var conn = new SQLiteConnection(connString)) {
|
||||
conn.Open();
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, conn)) {
|
||||
foreach (var param in parameters)
|
||||
@ -75,8 +81,8 @@ namespace MCGalaxy.SQL {
|
||||
}
|
||||
}
|
||||
|
||||
public override void Fill(string query, DataTable results) {
|
||||
using (var conn = new SQLiteConnection(SQLite.connString)) {
|
||||
public override void Fill(string query, string connString, DataTable results) {
|
||||
using (var conn = new SQLiteConnection(connString)) {
|
||||
conn.Open();
|
||||
|
||||
using (SQLiteDataAdapter da = new SQLiteDataAdapter(query, conn)) {
|
||||
|
@ -32,17 +32,6 @@ namespace MCGalaxy.SQL {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static BulkTransaction CreateNative() {
|
||||
try {
|
||||
return Database.Backend.CreateBulk();
|
||||
// TODO: Use NativeTransaction once I can figure out how to synchronise
|
||||
// System.Data.Sqlite and Native sqlite connection/command disposing.
|
||||
} catch (Exception ex) {
|
||||
Server.ErrorLog(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract IDbCommand CreateCommand(string query);
|
||||
|
||||
|
@ -25,9 +25,7 @@ namespace MCGalaxy.SQL {
|
||||
public static IDatabaseBackend Backend;
|
||||
|
||||
public static bool TableExists(string table) {
|
||||
string syntax = Server.useMySQL ? MySQL.TableExists : SQLite.TableExists;
|
||||
using (DataTable results = Fill(syntax, table, Server.MySQLDatabaseName))
|
||||
return results.Rows.Count > 0;
|
||||
return Backend.TableExists(table);
|
||||
}
|
||||
|
||||
[Obsolete("Use Execute() method instead.")]
|
||||
@ -35,11 +33,6 @@ namespace MCGalaxy.SQL {
|
||||
ParameterisedQuery query = Backend.GetStaticParameterised();
|
||||
Execute(query, queryString, createDB, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Execute() method instead.")]
|
||||
public static void executeQuery(ParameterisedQuery query, string queryString, bool createDB = false) {
|
||||
Execute(query, queryString, createDB, null);
|
||||
}
|
||||
|
||||
public static void Execute(string queryString) {
|
||||
ParameterisedQuery query = Backend.GetStaticParameterised();
|
||||
@ -57,11 +50,6 @@ namespace MCGalaxy.SQL {
|
||||
return Fill(query, queryString, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Fill() method instead.")]
|
||||
public static DataTable fillData(ParameterisedQuery query, string queryString, bool skipError = false) {
|
||||
return Fill(query, queryString, null);
|
||||
}
|
||||
|
||||
public static DataTable Fill(string queryString) {
|
||||
ParameterisedQuery query = Backend.GetStaticParameterised();
|
||||
return Fill(query, queryString, null);
|
||||
@ -76,10 +64,12 @@ namespace MCGalaxy.SQL {
|
||||
static void Execute(ParameterisedQuery query, string queryString,
|
||||
bool createDB, params object[] args) {
|
||||
BindParams(query, args);
|
||||
string connString = Backend.ConnectionString;
|
||||
Exception e = null;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
query.Execute(queryString, createDB);
|
||||
query.Execute(queryString, connString, createDB);
|
||||
query.ClearParams();
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
@ -95,11 +85,13 @@ namespace MCGalaxy.SQL {
|
||||
static DataTable Fill(ParameterisedQuery query, string queryString,
|
||||
params object[] args) {
|
||||
BindParams(query, args);
|
||||
string connString = Backend.ConnectionString;
|
||||
Exception e = null;
|
||||
|
||||
using (DataTable results = new DataTable("toReturn")) {
|
||||
Exception e = null;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
try {
|
||||
query.Fill(queryString, results);
|
||||
query.Fill(queryString, connString, results);
|
||||
query.ClearParams();
|
||||
return results;
|
||||
} catch (Exception ex) {
|
||||
@ -134,16 +126,4 @@ namespace MCGalaxy.SQL {
|
||||
query.AddParam(names[i], args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySQL {
|
||||
static string connStringFormat = "Data Source={0};Port={1};User ID={2};Password={3};Pooling={4}";
|
||||
public static string connString { get { return String.Format(connStringFormat, Server.MySQLHost, Server.MySQLPort, Server.MySQLUsername, Server.MySQLPassword, Server.DatabasePooling); } }
|
||||
public const string TableExists = "SELECT * FROM information_schema.tables WHERE table_schema = @1 AND table_name = @0";
|
||||
}
|
||||
|
||||
public static class SQLite {
|
||||
static string connStringFormat = "Data Source =" + Server.apppath + "/MCGalaxy.db; Version =3; Pooling ={0}; Max Pool Size =300;";
|
||||
public static string connString { get { return String.Format(connStringFormat, Server.DatabasePooling); } }
|
||||
public const string TableExists = "SELECT name FROM sqlite_master WHERE type='table' AND name=@0";
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
public partial class NativeBulkTransaction : BulkTransaction {
|
||||
|
||||
public NativeBulkTransaction() {
|
||||
connection = new NativeConnection();
|
||||
connection.ConnectionString = SQLite.connString;
|
||||
connection.Open();
|
||||
transaction = connection.BeginTransaction();
|
||||
}
|
||||
|
||||
public override IDbCommand CreateCommand(string query) {
|
||||
IDbCommand cmd = new NativeCommand();
|
||||
cmd.CommandText = query;
|
||||
cmd.Connection = connection;
|
||||
cmd.Transaction = transaction;
|
||||
cmd.Prepare();
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public override IDataParameter CreateParam(string paramName, DbType type) {
|
||||
IDataParameter param = new NativeParameter();
|
||||
param.ParameterName = paramName;
|
||||
param.DbType = type;
|
||||
return param;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
unsafe sealed class NativeCommand : IDbCommand {
|
||||
public IntPtr Statement;
|
||||
internal NativeParamsList args = new NativeParamsList();
|
||||
|
||||
public IDbConnection Connection { get; set; }
|
||||
public IDbTransaction Transaction { get; set; }
|
||||
public string CommandText { get; set; }
|
||||
public int CommandTimeout { get; set; }
|
||||
public CommandType CommandType { get; set; }
|
||||
public IDataParameterCollection Parameters { get { return args; } }
|
||||
public UpdateRowSource UpdatedRowSource { get; set; }
|
||||
public IDbDataParameter CreateParameter() { return null; }
|
||||
public void Cancel() { }
|
||||
public IDataReader ExecuteReader() { return ExecuteReader(CommandBehavior.Default); }
|
||||
public IDataReader ExecuteReader(CommandBehavior behavior) { return null; }
|
||||
public object ExecuteScalar() { return null; }
|
||||
|
||||
public void Prepare() {
|
||||
byte[] sql = Interop.MakeUTF8(CommandText);
|
||||
IntPtr db = ((NativeConnection)Connection).DB;
|
||||
IntPtr tail;
|
||||
int code = Interop.sqlite3_prepare_v2(db, sql, sql.Length, out Statement, out tail);
|
||||
if (code > 0) throw new NativeException(code);
|
||||
}
|
||||
|
||||
public int ExecuteNonQuery() {
|
||||
List<NativeParameter> args = this.args.args;
|
||||
for (int i = 0; i < args.Count; i++)
|
||||
BindParam(args[i]);
|
||||
|
||||
int code = Interop.sqlite3_step(Statement);
|
||||
WaitUntilFree(ref code, false);
|
||||
if (code > 0 && code != Interop.Done) throw new NativeException(code);
|
||||
|
||||
code = Interop.sqlite3_reset(Statement);
|
||||
WaitUntilFree(ref code, true);
|
||||
if (code > 0) throw new NativeException(code);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WaitUntilFree(ref int code, bool reset) {
|
||||
DateTime start = DateTime.UtcNow;
|
||||
while (code == Interop.Busy || code == Interop.Locked) {
|
||||
Thread.Sleep(100);
|
||||
TimeSpan delta = DateTime.UtcNow - start;
|
||||
if (delta.TotalSeconds > 30) break;
|
||||
code = reset ? Interop.sqlite3_reset(Statement)
|
||||
: Interop.sqlite3_step(Statement);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
int code = Interop.sqlite3_finalize(Statement);
|
||||
if (code > 0) throw new NativeException(code);
|
||||
}
|
||||
|
||||
void BindParam(IDataParameter param) {
|
||||
NativeParameter nParam = (NativeParameter)param;
|
||||
if (nParam.Index == -1) BindIndex(nParam);
|
||||
|
||||
int code = 0;
|
||||
switch (nParam.type) {
|
||||
case DbType.AnsiStringFixedLength:
|
||||
code = Interop.sqlite3_bind_text(Statement, nParam.Index, nParam.StringPtr,
|
||||
nParam.StringCount - 1, IntPtr.Zero); break;
|
||||
case DbType.Int32:
|
||||
code = Interop.sqlite3_bind_int(Statement, nParam.Index, nParam.I32Value); break;
|
||||
case DbType.UInt16:
|
||||
code = Interop.sqlite3_bind_int(Statement, nParam.Index, nParam.U16Value); break;
|
||||
case DbType.Byte:
|
||||
code = Interop.sqlite3_bind_int(Statement, nParam.Index, nParam.U8Value); break;
|
||||
case DbType.Boolean:
|
||||
code = Interop.sqlite3_bind_int(Statement, nParam.Index, nParam.BoolValue ? 1 : 0); break;
|
||||
}
|
||||
if (code > 0) throw new NativeException(code);
|
||||
}
|
||||
|
||||
void BindIndex(NativeParameter nParam) {
|
||||
byte[] name = Interop.MakeUTF8(nParam.ParameterName);
|
||||
nParam.Index = Interop.sqlite3_bind_parameter_index(Statement, name);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
sealed class NativeConnection : IDbConnection {
|
||||
public IntPtr DB;
|
||||
|
||||
public string ConnectionString { get; set; }
|
||||
public int ConnectionTimeout { get { return 0; } }
|
||||
public string Database { get { return ""; } }
|
||||
public ConnectionState State { get { return ConnectionState.Open; } }
|
||||
public IDbTransaction BeginTransaction() { return BeginTransaction(IsolationLevel.Unspecified); }
|
||||
public void ChangeDatabase(string databaseName) { }
|
||||
|
||||
public IDbTransaction BeginTransaction(IsolationLevel il) {
|
||||
return new NativeTransaction(this);
|
||||
}
|
||||
|
||||
public void Close() {
|
||||
IntPtr stmt = IntPtr.Zero;
|
||||
do {
|
||||
stmt = Interop.sqlite3_next_stmt(DB, stmt);
|
||||
if (stmt != IntPtr.Zero) Interop.sqlite3_reset(stmt);
|
||||
} while (stmt != IntPtr.Zero);
|
||||
|
||||
int code = Interop.sqlite3_close(DB);
|
||||
DB = IntPtr.Zero;
|
||||
if (code > 0) throw new NativeException(code);
|
||||
}
|
||||
|
||||
public IDbCommand CreateCommand() {
|
||||
IDbCommand cmd = new NativeCommand();
|
||||
cmd.Connection = this;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (DB == IntPtr.Zero) return;
|
||||
Close();
|
||||
}
|
||||
|
||||
string path;
|
||||
public void Open() {
|
||||
ParseConnectionString();
|
||||
byte[] filename = Interop.MakeUTF8(path);
|
||||
int code = Interop.sqlite3_open_v2(filename, out DB, 0x2, IntPtr.Zero);
|
||||
if (code > 0) throw new NativeException(code);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
sealed class NativeException : Exception {
|
||||
public readonly int ErrorCode;
|
||||
|
||||
public NativeException(int errorCode) {
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public override string Message { get { return ToString(); } }
|
||||
|
||||
public override string ToString() {
|
||||
byte primaryCode = (byte)ErrorCode;
|
||||
string desc = errors[primaryCode] ?? "SQL error";
|
||||
return desc + " (" + ErrorCode + ")";
|
||||
}
|
||||
|
||||
static string[] errors = new string[256];
|
||||
static NativeException() {
|
||||
errors[0] = "Successful result";
|
||||
errors[1] = "SQL error or missing database";
|
||||
errors[2] = "Internal logic error in SQLite";
|
||||
errors[3] = "Access permission denied";
|
||||
errors[4] = "Callback routine requested an abort";
|
||||
errors[5] = "The database file is locked";
|
||||
errors[6] = "A table in the database is locked";
|
||||
errors[7] = "A malloc() failed";
|
||||
errors[8] = "Attempt to write a readonly database";
|
||||
errors[9] = "Operation terminated by sqlite3_interrupt()";
|
||||
errors[10] = "Some kind of disk I/O error occurred";
|
||||
errors[11] = "The database disk image is malformed";
|
||||
errors[12] = "Unknown opcode in sqlite3_file_control()";
|
||||
errors[13] = "Insertion failed because database is full";
|
||||
errors[14] = "Unable to open the database file";
|
||||
errors[15] = "Database lock protocol error";
|
||||
errors[16] = "Database is empty";
|
||||
errors[17] = "The database schema changed";
|
||||
errors[18] = "String or BLOB exceeds size limit";
|
||||
errors[19] = "Abort due to constraint violation";
|
||||
errors[20] = "Data type mismatch";
|
||||
errors[21] = "Library used incorrectly";
|
||||
errors[22] = "Uses OS features not supported on host";
|
||||
errors[23] = "Authorization denied";
|
||||
errors[24] = "Auxiliary database format error";
|
||||
errors[25] = "2nd parameter to sqlite3_bind out of range";
|
||||
errors[26] = "File opened that is not a database file";
|
||||
errors[27] = "Notifications from sqlite3_log()";
|
||||
errors[28] = "Warnings from sqlite3_log()";
|
||||
errors[100] = "sqlite3_step() has another row ready";
|
||||
errors[101] = "sqlite3_step() has finished executing";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
sealed class NativeParamsList : IDataParameterCollection {
|
||||
|
||||
internal List<NativeParameter> args = new List<NativeParameter>();
|
||||
|
||||
public void Clear() {
|
||||
foreach (var param in args)
|
||||
param.Dispose();
|
||||
args.Clear();
|
||||
}
|
||||
|
||||
// Boilerplate code for all the interfaces
|
||||
public object this[string parameterName] {
|
||||
get { return args[IndexOf(parameterName)]; }
|
||||
set { args[IndexOf(parameterName)] = (NativeParameter)value; }
|
||||
}
|
||||
|
||||
public bool Contains(string parameterName) {
|
||||
return IndexOf(parameterName) >= 0;
|
||||
}
|
||||
|
||||
public int IndexOf(string parameterName) {
|
||||
for (int i = 0; i < Count; i++) {
|
||||
if (args[i].ParameterName == parameterName) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void RemoveAt(string parameterName) {
|
||||
int index = IndexOf(parameterName);
|
||||
if (index >= 0) args.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
||||
public bool IsSynchronized { get { return false; } }
|
||||
|
||||
public object SyncRoot { get { return this; } }
|
||||
|
||||
public int Count { get { return args.Count; } }
|
||||
|
||||
public void CopyTo(Array array, int index) { }
|
||||
|
||||
|
||||
public object this[int index] {
|
||||
get { return args[index]; }
|
||||
set { args[index] = (NativeParameter)value; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly { get { return false; } }
|
||||
|
||||
public bool IsFixedSize { get { return false; } }
|
||||
|
||||
public int Add(object value) { return ((IList)args).Add(value); }
|
||||
|
||||
public bool Contains(object value) { return ((IList)args).Contains(value); }
|
||||
|
||||
public int IndexOf(object value) { return ((IList)args).IndexOf(value); }
|
||||
|
||||
public void Insert(int index, object value) { ((IList)args).Insert(index, value); }
|
||||
|
||||
public void Remove(object value) { ((IList)args).Remove(value); }
|
||||
|
||||
public void RemoveAt(int index) { args.RemoveAt(index); }
|
||||
|
||||
public IEnumerator GetEnumerator() { return args.GetEnumerator(); }
|
||||
|
||||
|
||||
public void AddWithValue(string key, object value) {
|
||||
NativeParameter arg = new NativeParameter();
|
||||
arg.ParameterName = key;
|
||||
Type type = value.GetType();
|
||||
|
||||
if (type == typeof(string)) {
|
||||
arg.SetString((string)value);
|
||||
arg.DbType = DbType.String;
|
||||
} else if (type == typeof(byte)) {
|
||||
arg.U8Value = (byte)value;
|
||||
arg.DbType = DbType.Byte;
|
||||
} else if (type == typeof(ushort)) {
|
||||
arg.U16Value = (ushort)value;
|
||||
arg.DbType = DbType.UInt16;
|
||||
} else if (type == typeof(int)) {
|
||||
arg.I32Value = (ushort)value;
|
||||
arg.DbType = DbType.Int32;
|
||||
} else {
|
||||
throw new NotSupportedException("Unsupported type: " + type);
|
||||
}
|
||||
args.Add(arg);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace MCGalaxy.SQL.Native {
|
||||
|
||||
sealed class NativeTransaction : IDbTransaction {
|
||||
public IDbConnection Connection { get; set; }
|
||||
public IsolationLevel IsolationLevel { get { return IsolationLevel.Unspecified; } }
|
||||
|
||||
public NativeTransaction(IDbConnection connection) {
|
||||
Connection = connection;
|
||||
DoCommand("BEGIN");
|
||||
}
|
||||
|
||||
public void Commit() { DoCommand("COMMIT"); }
|
||||
public void Rollback() { DoCommand("ROLLBACK"); }
|
||||
public void Dispose() { }
|
||||
|
||||
void DoCommand(string query) {
|
||||
using (IDbCommand cmd = Connection.CreateCommand()) {
|
||||
cmd.CommandText = query;
|
||||
cmd.Prepare();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe 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;
|
||||
// Avoid boxing primitive types
|
||||
public int I32Value;
|
||||
public ushort U16Value;
|
||||
public byte U8Value;
|
||||
public bool BoolValue;
|
||||
public byte* StringPtr;
|
||||
public int StringCount;
|
||||
|
||||
public void SetString(string value) {
|
||||
if ((value.Length + 1) > StringCount) {
|
||||
if (StringCount > 0)
|
||||
Marshal.FreeHGlobal((IntPtr)StringPtr);
|
||||
StringCount = value.Length + 1;
|
||||
StringPtr = (byte*)Marshal.AllocHGlobal(StringCount);
|
||||
}
|
||||
|
||||
// Reset all bytes to 0, then replace them.
|
||||
for (int i = 0; i < StringCount; i++)
|
||||
StringPtr[i] = 0;
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
StringPtr[i] = (byte)value[i];
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (StringCount != 0) return;
|
||||
Marshal.FreeHGlobal((IntPtr)StringPtr);
|
||||
StringCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe static class Interop {
|
||||
static Encoding encoding = Encoding.UTF8;
|
||||
const CallingConvention conv = CallingConvention.Cdecl;
|
||||
|
||||
public const int Busy = 5, Locked = 6;
|
||||
public const int RowReady = 100, Done = 101;
|
||||
|
||||
public static byte[] MakeUTF8(string input) {
|
||||
int count = encoding.GetByteCount(input) + 1; // null terminator
|
||||
byte[] chars = new byte[count];
|
||||
encoding.GetBytes(input, 0, input.Length, chars, 0);
|
||||
return chars;
|
||||
}
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_open_v2(byte[] filename, out IntPtr db, int flags, IntPtr vfs);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_close(IntPtr db);
|
||||
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_bind_int(IntPtr stmt, int index, int value);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] name);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_bind_text(IntPtr stmt, int index, byte* text, int textLen, IntPtr reserved);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_finalize(IntPtr stmt);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_prepare_v2(IntPtr db, byte[] sql, int nBytes, out IntPtr stmt, out IntPtr sqlTail);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_reset(IntPtr stmt);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int sqlite3_step(IntPtr stmt);
|
||||
|
||||
[DllImport("sqlite3", CallingConvention = conv), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr sqlite3_next_stmt(IntPtr db, IntPtr stmt);
|
||||
}
|
||||
}
|
@ -29,9 +29,9 @@ namespace MCGalaxy.SQL {
|
||||
|
||||
public void ClearParams() { parameters.Clear(); }
|
||||
|
||||
public abstract void Execute(string query, bool createDB = false);
|
||||
public abstract void Execute(string query, string connString, bool createDB = false);
|
||||
|
||||
public abstract void Fill(string query, DataTable results);
|
||||
public abstract void Fill(string query, string connString, DataTable results);
|
||||
|
||||
public static ParameterisedQuery Create() {
|
||||
return Database.Backend.CreateParameterised();
|
||||
|
@ -19,7 +19,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using MCGalaxy.SQL;
|
||||
using MCGalaxy.SQL.Native;
|
||||
|
||||
namespace MCGalaxy {
|
||||
public static class LevelDB {
|
||||
@ -32,7 +31,7 @@ namespace MCGalaxy {
|
||||
|
||||
fixed (char* ptr = date) {
|
||||
ptr[4] = '-'; ptr[7] = '-'; ptr[10] = ' '; ptr[13] = ':'; ptr[16] = ':';
|
||||
using (BulkTransaction bulk = BulkTransaction.CreateNative())
|
||||
using (BulkTransaction bulk = BulkTransaction.Create())
|
||||
DoSaveChanges(tempCache, ptr, lvl, date, bulk);
|
||||
}
|
||||
tempCache.Clear();
|
||||
@ -56,7 +55,6 @@ namespace MCGalaxy {
|
||||
IDataParameter zP = transaction.CreateParam("@Z", DbType.UInt16); cmd.Parameters.Add(zP);
|
||||
IDataParameter tileP = transaction.CreateParam("@Tile", DbType.Byte); cmd.Parameters.Add(tileP);
|
||||
IDataParameter delP = transaction.CreateParam("@Del", DbType.Boolean); cmd.Parameters.Add(delP);
|
||||
bool isNative = transaction is NativeBulkTransaction;
|
||||
|
||||
for (int i = 0; i < tempCache.Count; i++) {
|
||||
Level.BlockPos bP = tempCache[i];
|
||||
@ -65,22 +63,11 @@ namespace MCGalaxy {
|
||||
MakeInt(time.Year, 4, 0, ptr); MakeInt(time.Month, 2, 5, ptr); MakeInt(time.Day, 2, 8, ptr);
|
||||
MakeInt(time.Hour, 2, 11, ptr); MakeInt(time.Minute, 2, 14, ptr); MakeInt(time.Second, 2, 17, ptr);
|
||||
|
||||
// For NativeParameter, we make the optimisation of avoiding boxing primitive types.
|
||||
if (!isNative) {
|
||||
nameP.Value = bP.name;
|
||||
timeP.Value = date;
|
||||
xP.Value = x; yP.Value = y; zP.Value = z;
|
||||
tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawBlock;
|
||||
delP.Value = (bP.flags & 1) != 0;
|
||||
} else {
|
||||
((NativeParameter)nameP).SetString(bP.name);
|
||||
((NativeParameter)timeP).SetString(date);
|
||||
((NativeParameter)xP).U16Value = x;
|
||||
((NativeParameter)yP).U16Value = y;
|
||||
((NativeParameter)zP).U16Value = z;
|
||||
((NativeParameter)tileP).U8Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawBlock;
|
||||
((NativeParameter)delP).BoolValue = (bP.flags & 1) != 0;
|
||||
}
|
||||
nameP.Value = bP.name;
|
||||
timeP.Value = date;
|
||||
xP.Value = x; yP.Value = y; zP.Value = z;
|
||||
tileP.Value = (bP.flags & 2) != 0 ? Block.custom_block : bP.rawBlock;
|
||||
delP.Value = (bP.flags & 1) != 0;
|
||||
|
||||
if (!BulkTransaction.Execute(template, cmd)) {
|
||||
cmd.Dispose();
|
||||
|
@ -409,13 +409,7 @@
|
||||
<Compile Include="Database\Backends\SQLiteBackend.cs" />
|
||||
<Compile Include="Database\Backends\MySQLBackend.cs" />
|
||||
<Compile Include="Database\BlockDB.cs" />
|
||||
<Compile Include="Database\Native\NativeParamsList.cs" />
|
||||
<Compile Include="Database\ParameterisedQuery.cs" />
|
||||
<Compile Include="Database\Native\NativeConnection.cs" />
|
||||
<Compile Include="Database\Native\Utils.cs" />
|
||||
<Compile Include="Database\Native\NativeBulkTransaction.cs" />
|
||||
<Compile Include="Database\Native\NativeCommand.cs" />
|
||||
<Compile Include="Database\Native\NativeException.cs" />
|
||||
<Compile Include="Drawing\Brushes\Brush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CloudyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\PasteBrush.cs" />
|
||||
@ -700,7 +694,6 @@
|
||||
<Folder Include="Commands\Scripting" />
|
||||
<Folder Include="Commands\World" />
|
||||
<Folder Include="Commands\other" />
|
||||
<Folder Include="Database\Native" />
|
||||
<Folder Include="Database\Backends" />
|
||||
<Folder Include="Drawing\DrawOps" />
|
||||
<Folder Include="Drawing\Brushes" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user