mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-27 07:11:04 -04:00
More work on native sqlite backend.
This commit is contained in:
parent
67dabbf819
commit
18ba121b88
@ -48,7 +48,7 @@ namespace MCGalaxy.SQL.Native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override IDbCommand CreateCommand(string query) {
|
public override IDbCommand CreateCommand(string query) {
|
||||||
IDbCommand cmd = new NativeSQLiteCommand();
|
IDbCommand cmd = new NativeCommand();
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
cmd.Connection = connection;
|
cmd.Connection = connection;
|
||||||
cmd.Transaction = transaction;
|
cmd.Transaction = transaction;
|
||||||
@ -61,11 +61,5 @@ namespace MCGalaxy.SQL.Native {
|
|||||||
param.DbType = type;
|
param.DbType = type;
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("sqlite3.dll")]
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,22 +16,23 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace MCGalaxy.SQL.Native {
|
namespace MCGalaxy.SQL.Native {
|
||||||
|
|
||||||
sealed class NativeSQLiteCommand : IDbCommand {
|
sealed class NativeCommand : IDbCommand {
|
||||||
IntPtr statement;
|
public IntPtr Statement;
|
||||||
|
NativeParamsList args = new NativeParamsList();
|
||||||
|
|
||||||
public IDbConnection Connection { get; set; }
|
public IDbConnection Connection { get; set; }
|
||||||
public IDbTransaction Transaction { get; set; }
|
public IDbTransaction Transaction { get; set; }
|
||||||
public string CommandText { get; set; }
|
public string CommandText { get; set; }
|
||||||
public int CommandTimeout { get; set; }
|
public int CommandTimeout { get; set; }
|
||||||
public CommandType CommandType { get; set; }
|
public CommandType CommandType { get; set; }
|
||||||
public IDataParameterCollection Parameters { get; private set; }
|
public IDataParameterCollection Parameters { get { return args; } }
|
||||||
public UpdateRowSource UpdatedRowSource { get; set; }
|
public UpdateRowSource UpdatedRowSource { get; set; }
|
||||||
|
|
||||||
public IDbDataParameter CreateParameter() { return null; }
|
public IDbDataParameter CreateParameter() { return null; }
|
||||||
public void Cancel() { }
|
public void Cancel() { }
|
||||||
public IDataReader ExecuteReader() { return ExecuteReader(CommandBehavior.Default); }
|
public IDataReader ExecuteReader() { return ExecuteReader(CommandBehavior.Default); }
|
||||||
@ -39,21 +40,70 @@ namespace MCGalaxy.SQL.Native {
|
|||||||
public object ExecuteScalar() { return null; }
|
public object ExecuteScalar() { return null; }
|
||||||
|
|
||||||
public void Prepare() {
|
public void Prepare() {
|
||||||
|
byte[] sql = NativeUtils.MakeUTF8(CommandText);
|
||||||
|
IntPtr db = ((NativeConnection)Connection).DB;
|
||||||
|
IntPtr tail;
|
||||||
|
int code = sqlite3_prepare_v2(db, sql, sql.Length, out Statement, out tail);
|
||||||
|
if (code > 0) throw new NativeException(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ExecuteNonQuery() {
|
public int ExecuteNonQuery() {
|
||||||
int code = sqlite3_step(statement);
|
foreach (IDataParameter param in args)
|
||||||
|
BindParam(param);
|
||||||
|
|
||||||
|
int code = sqlite3_step(Statement);
|
||||||
if (code > 0) throw new NativeException(code);
|
if (code > 0) 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BindParam(IDataParameter param) {
|
||||||
|
NativeParameter nParam = (NativeParameter)param;
|
||||||
|
if (nParam.Index == -1) BindIndex(nParam);
|
||||||
|
|
||||||
|
DbType type = param.DbType;
|
||||||
|
int code = 0;
|
||||||
|
switch (type) {
|
||||||
|
case DbType.AnsiStringFixedLength:
|
||||||
|
byte[] data = NativeUtils.MakeUTF8((string)nParam.Value);
|
||||||
|
code = sqlite3_bind_text(Statement, nParam.Index, data, data.Length - 1, IntPtr.Zero);
|
||||||
|
break;
|
||||||
|
case DbType.UInt16:
|
||||||
|
ushort value_u16 = (ushort)nParam.Value;
|
||||||
|
code = sqlite3_bind_int(Statement, nParam.Index, value_u16);
|
||||||
|
break;
|
||||||
|
case DbType.Byte:
|
||||||
|
byte value_u8 = (byte)nParam.Value;
|
||||||
|
code = sqlite3_bind_int(Statement, nParam.Index, value_u8);
|
||||||
|
break;
|
||||||
|
case DbType.Boolean:
|
||||||
|
bool value_bool = (bool)nParam.Value;
|
||||||
|
code = sqlite3_bind_int(Statement, nParam.Index, value_bool ? 1 : 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code > 0) throw new NativeException(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindIndex(NativeParameter nParam) {
|
||||||
|
byte[] name = NativeUtils.MakeUTF8(nParam.ParameterName);
|
||||||
|
nParam.Index = sqlite3_bind_parameter_index(Statement, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("sqlite3.dll")]
|
||||||
|
static extern int sqlite3_bind_int(IntPtr stmt, int index, int value);
|
||||||
|
|
||||||
|
[DllImport("sqlite3.dll")]
|
||||||
|
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")]
|
[DllImport("sqlite3.dll")]
|
||||||
static extern int sqlite3_finalize(IntPtr stmt);
|
static extern int sqlite3_finalize(IntPtr stmt);
|
||||||
|
|
||||||
|
69
Database/Native/NativeConnection.cs
Normal file
69
Database/Native/NativeConnection.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
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 null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close() {
|
||||||
|
int code = sqlite3_close_v2(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Open() {
|
||||||
|
string[] args = ConnectionString.Split(';');
|
||||||
|
byte[] filename = NativeUtils.MakeUTF8(args[0]);
|
||||||
|
int code = sqlite3_open_v2(filename, out DB, 0, IntPtr.Zero);
|
||||||
|
if (code > 0) throw new NativeException(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("sqlite3.dll")]
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -16,32 +16,32 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace MCGalaxy.SQL.Native {
|
namespace MCGalaxy.SQL.Native {
|
||||||
|
|
||||||
sealed class NativeConnection : IDbConnection {
|
|
||||||
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 IDbTransaction BeginTransaction(IsolationLevel il) { return null; }
|
|
||||||
public void Close() { }
|
|
||||||
public void ChangeDatabase(string databaseName) { }
|
|
||||||
public IDbCommand CreateCommand() { return null; }
|
|
||||||
public void Open() { }
|
|
||||||
public void Dispose() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class NativeTransaction : IDbTransaction {
|
sealed class NativeTransaction : IDbTransaction {
|
||||||
public IDbConnection Connection { get; set; }
|
public IDbConnection Connection { get; set; }
|
||||||
public IsolationLevel IsolationLevel { get { return IsolationLevel.Unspecified; } }
|
public IsolationLevel IsolationLevel { get { return IsolationLevel.Unspecified; } }
|
||||||
public void Commit() { }
|
|
||||||
public void Rollback() { }
|
public NativeTransaction(IDbConnection connection) {
|
||||||
|
Connection = connection;
|
||||||
|
DoCommand("BEGIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Commit() { DoCommand("COMMIT"); }
|
||||||
|
public void Rollback() { DoCommand("ROLLBACK"); }
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
|
|
||||||
|
void DoCommand(string query) {
|
||||||
|
using (IDbCommand cmd = Connection.CreateCommand()) {
|
||||||
|
cmd.CommandText = query;
|
||||||
|
cmd.Prepare();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class NativeParameter : IDataParameter {
|
sealed class NativeParameter : IDataParameter {
|
||||||
@ -52,6 +52,31 @@ namespace MCGalaxy.SQL.Native {
|
|||||||
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 int Index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class NativeParamsList : List<IDataParameter>, IDataParameterCollection {
|
||||||
|
|
||||||
|
public object this[string parameterName] {
|
||||||
|
get { return this[IndexOf(parameterName)]; }
|
||||||
|
set { this[IndexOf(parameterName)] = (IDbDataParameter)value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(string parameterName) {
|
||||||
|
return IndexOf(parameterName) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf(string parameterName) {
|
||||||
|
for (int i = 0; i < Count; i++) {
|
||||||
|
if (this[i].ParameterName == parameterName) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAt(string parameterName) {
|
||||||
|
int index = IndexOf(parameterName);
|
||||||
|
if (index >= 0) RemoveAt(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NativeUtils {
|
static class NativeUtils {
|
||||||
|
@ -393,6 +393,7 @@
|
|||||||
<Compile Include="Commands\World\CmdUnload.cs" />
|
<Compile Include="Commands\World\CmdUnload.cs" />
|
||||||
<Compile Include="Database\DatabaseParameterisedQuery.cs" />
|
<Compile Include="Database\DatabaseParameterisedQuery.cs" />
|
||||||
<Compile Include="Database\MySQLParameterisedQuery.cs" />
|
<Compile Include="Database\MySQLParameterisedQuery.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\BulkNativeTransaction.cs" />
|
||||||
<Compile Include="Database\Native\NativeCommand.cs" />
|
<Compile Include="Database\Native\NativeCommand.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user