mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Simplify database API
This commit is contained in:
parent
cabe47f26f
commit
33561ee9d4
@ -30,13 +30,6 @@ namespace MCGalaxy.Commands.Fun {
|
|||||||
public override CommandPerm[] ExtraPerms {
|
public override CommandPerm[] ExtraPerms {
|
||||||
get { return new[] { new CommandPerm(LevelPermission.Operator, "can manage CTF") }; }
|
get { return new[] { new CommandPerm(LevelPermission.Operator, "can manage CTF") }; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: avoid code duplication with CTFLevelPicker
|
|
||||||
static List<string> GetCtfMaps() {
|
|
||||||
if (!File.Exists("CTF/maps.config")) return new List<string>();
|
|
||||||
string[] lines = File.ReadAllLines("CTF/maps.config");
|
|
||||||
return new List<string>(lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void HandleSetCore(Player p, RoundsGame game, string[] args) {
|
protected override void HandleSetCore(Player p, RoundsGame game, string[] args) {
|
||||||
string prop = args[1];
|
string prop = args[1];
|
||||||
@ -64,31 +57,6 @@ namespace MCGalaxy.Commands.Fun {
|
|||||||
Help(p, "set");
|
Help(p, "set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleAdd(Player p, Level lvl) {
|
|
||||||
if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");
|
|
||||||
List<string> maps = GetCtfMaps();
|
|
||||||
|
|
||||||
if (maps.CaselessContains(lvl.name)) {
|
|
||||||
Player.Message(p, "{0} %Sis already in the list of CTF maps", lvl.ColoredName);
|
|
||||||
} else {
|
|
||||||
Player.Message(p, "Added {0} %Sto the list of CTF maps", lvl.ColoredName);
|
|
||||||
maps.Add(p.level.name);
|
|
||||||
File.WriteAllLines("CTF/maps.config", maps.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HandleRemove(Player p, Level lvl) {
|
|
||||||
if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");
|
|
||||||
List<string> maps = GetCtfMaps();
|
|
||||||
|
|
||||||
if (!maps.CaselessRemove(lvl.name)) {
|
|
||||||
Player.Message(p, "{0} %Swas not in the list of CTF maps", lvl.ColoredName);
|
|
||||||
} else {
|
|
||||||
Player.Message(p, "Removed {0} %Sfrom the list of CTF maps", lvl.ColoredName);
|
|
||||||
File.WriteAllLines("CTF/maps.config", maps.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool BlueFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
|
static bool BlueFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
|
||||||
CTFMapConfig cfg = RetrieveConfig(p);
|
CTFMapConfig cfg = RetrieveConfig(p);
|
||||||
|
@ -26,21 +26,29 @@ using MySql.Data.MySqlClient;
|
|||||||
namespace MCGalaxy.SQL {
|
namespace MCGalaxy.SQL {
|
||||||
|
|
||||||
public sealed class MySQLBackend : IDatabaseBackend {
|
public sealed class MySQLBackend : IDatabaseBackend {
|
||||||
|
|
||||||
public static IDatabaseBackend Instance = new MySQLBackend();
|
public static IDatabaseBackend Instance = new MySQLBackend();
|
||||||
static ParameterisedQuery queryInstance = new MySQLParameterisedQuery();
|
|
||||||
|
|
||||||
static string connFormat = "Data Source={0};Port={1};User ID={2};Password={3};Pooling={4};Treat Tiny As Boolean=false;";
|
|
||||||
public override string ConnectionString {
|
|
||||||
get { return string.Format(connFormat, ServerConfig.MySQLHost, ServerConfig.MySQLPort,
|
|
||||||
ServerConfig.MySQLUsername, ServerConfig.MySQLPassword, ServerConfig.DatabasePooling); }
|
|
||||||
}
|
|
||||||
public override bool EnforcesTextLength { get { return true; } }
|
|
||||||
|
|
||||||
public MySQLBackend() {
|
public MySQLBackend() {
|
||||||
CaselessWhereSuffix = " COLLATE utf8_general_ci";
|
CaselessWhereSuffix = " COLLATE utf8_general_ci";
|
||||||
CaselessLikeSuffix = "";
|
CaselessLikeSuffix = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool EnforcesTextLength { get { return true; } }
|
||||||
|
public override bool MultipleSchema { get { return true; } }
|
||||||
|
|
||||||
|
internal override IDbConnection CreateConnection() {
|
||||||
|
const string format = "Data Source={0};Port={1};User ID={2};Password={3};Pooling={4};Treat Tiny As Boolean=false;";
|
||||||
|
string str = string.Format(format, ServerConfig.MySQLHost, ServerConfig.MySQLPort,
|
||||||
|
ServerConfig.MySQLUsername, ServerConfig.MySQLPassword, ServerConfig.DatabasePooling);
|
||||||
|
return new MySqlConnection(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override IDbCommand CreateCommand(string sql, IDbConnection conn) {
|
||||||
|
return new MySqlCommand(sql, (MySqlConnection)conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override IDbDataParameter CreateParameter() {
|
||||||
|
return new MySqlParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void CreateDatabase() {
|
public override void CreateDatabase() {
|
||||||
@ -48,18 +56,6 @@ namespace MCGalaxy.SQL {
|
|||||||
Database.Do(sql, true, null, null);
|
Database.Do(sql, true, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BulkTransaction CreateBulk() {
|
|
||||||
return new MySQLBulkTransaction(ConnectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ParameterisedQuery CreateParameterised() {
|
|
||||||
return new MySQLParameterisedQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected internal override ParameterisedQuery GetStaticParameterised() {
|
|
||||||
return queryInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string RawGetDateTime(IDataRecord record, int col) {
|
public override string RawGetDateTime(IDataRecord record, int col) {
|
||||||
DateTime date = record.GetDateTime(col);
|
DateTime date = record.GetDateTime(col);
|
||||||
return date.ToString(Database.DateFormat);
|
return date.ToString(Database.DateFormat);
|
||||||
@ -138,7 +134,7 @@ namespace MCGalaxy.SQL {
|
|||||||
string pri = "";
|
string pri = "";
|
||||||
|
|
||||||
for (int i = 0; i < fields.Count; i++) {
|
for (int i = 0; i < fields.Count; i++) {
|
||||||
string[] field = fields[i];
|
string[] field = fields[i];
|
||||||
if (field[i_key].CaselessEq("pri")) pri = field[i_name];
|
if (field[i_key].CaselessEq("pri")) pri = field[i_name];
|
||||||
|
|
||||||
string meta = field[i_null].CaselessEq("no") ? "NOT NULL" : "DEFAULT NULL";
|
string meta = field[i_null].CaselessEq("no") ? "NOT NULL" : "DEFAULT NULL";
|
||||||
@ -165,42 +161,4 @@ namespace MCGalaxy.SQL {
|
|||||||
DoInsert("REPLACE INTO", table, columns, args);
|
DoInsert("REPLACE INTO", table, columns, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class MySQLBulkTransaction : BulkTransaction {
|
|
||||||
|
|
||||||
public MySQLBulkTransaction(string connString) {
|
|
||||||
connection = new MySqlConnection(connString);
|
|
||||||
connection.Open();
|
|
||||||
connection.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
|
||||||
|
|
||||||
transaction = connection.BeginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IDbCommand CreateCommand(string sql) {
|
|
||||||
return new MySqlCommand(sql, (MySqlConnection)connection, (MySqlTransaction)transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IDataParameter CreateParam(string paramName, DbType type) {
|
|
||||||
MySqlParameter arg = new MySqlParameter(paramName, null);
|
|
||||||
arg.DbType = type;
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class MySQLParameterisedQuery : ParameterisedQuery {
|
|
||||||
protected override bool MultipleSchema { get { return true; } }
|
|
||||||
|
|
||||||
protected override IDbConnection CreateConnection(string connString) {
|
|
||||||
return new MySqlConnection(connString);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IDbCommand CreateCommand(string sql, IDbConnection conn) {
|
|
||||||
return new MySqlCommand(sql, (MySqlConnection)conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IDbDataParameter CreateParameter() {
|
|
||||||
return new MySqlParameter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,36 +26,32 @@ using System.Text;
|
|||||||
namespace MCGalaxy.SQL {
|
namespace MCGalaxy.SQL {
|
||||||
|
|
||||||
public sealed class SQLiteBackend : IDatabaseBackend {
|
public sealed class SQLiteBackend : IDatabaseBackend {
|
||||||
|
|
||||||
public static IDatabaseBackend Instance = new SQLiteBackend();
|
public static IDatabaseBackend Instance = new SQLiteBackend();
|
||||||
static ParameterisedQuery queryInstance = new SQLiteParameterisedQuery();
|
|
||||||
|
|
||||||
static string connFormat = "Data Source =" + Utils.FolderPath + "/MCGalaxy.db; Version =3; Pooling ={0}; Max Pool Size =300;";
|
|
||||||
public override string ConnectionString {
|
|
||||||
get { return string.Format(connFormat, ServerConfig.DatabasePooling); }
|
|
||||||
}
|
|
||||||
public override bool EnforcesTextLength { get { return false; } }
|
|
||||||
|
|
||||||
public SQLiteBackend() {
|
public SQLiteBackend() {
|
||||||
CaselessWhereSuffix = " COLLATE NOCASE";
|
CaselessWhereSuffix = " COLLATE NOCASE";
|
||||||
CaselessLikeSuffix = " COLLATE NOCASE";
|
CaselessLikeSuffix = " COLLATE NOCASE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool EnforcesTextLength { get { return false; } }
|
||||||
|
public override bool MultipleSchema { get { return false; } }
|
||||||
|
|
||||||
|
internal override IDbConnection CreateConnection() {
|
||||||
|
const string format = "Data Source={0}/MCGalaxy.db;Version=3;Pooling={1};Max Pool Size=300;";
|
||||||
|
string str = string.Format(format, Utils.FolderPath, ServerConfig.DatabasePooling);
|
||||||
|
return new SQLiteConnection(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override IDbCommand CreateCommand(string sql, IDbConnection conn) {
|
||||||
|
return new SQLiteCommand(sql, (SQLiteConnection)conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override IDbDataParameter CreateParameter() {
|
||||||
|
return new SQLiteParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void CreateDatabase() { }
|
public override void CreateDatabase() { }
|
||||||
|
|
||||||
public override BulkTransaction CreateBulk() {
|
|
||||||
return new SQLiteBulkTransaction(ConnectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ParameterisedQuery CreateParameterised() {
|
|
||||||
return new SQLiteParameterisedQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected internal override ParameterisedQuery GetStaticParameterised() {
|
|
||||||
return queryInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string RawGetDateTime(IDataRecord record, int col) {
|
public override string RawGetDateTime(IDataRecord record, int col) {
|
||||||
return record.GetString(col); // reader.GetDateTime is extremely slow so avoid it
|
return record.GetString(col); // reader.GetDateTime is extremely slow so avoid it
|
||||||
}
|
}
|
||||||
@ -104,12 +100,7 @@ namespace MCGalaxy.SQL {
|
|||||||
for (int i = 0; i < columns.Length; i++) {
|
for (int i = 0; i < columns.Length; i++) {
|
||||||
ColumnDesc col = columns[i];
|
ColumnDesc col = columns[i];
|
||||||
sql.Append(col.Column).Append(' ');
|
sql.Append(col.Column).Append(' ');
|
||||||
|
sql.Append(col.FormatType());
|
||||||
if (col.Type == ColumnType.Bool) {
|
|
||||||
sql.Append("TINYINT");
|
|
||||||
} else {
|
|
||||||
sql.Append(col.FormatType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the primary key isn't autoincrement, we use the same form as mysql
|
// When the primary key isn't autoincrement, we use the same form as mysql
|
||||||
// Otherwise we have to use sqlite's 'PRIMARY KEY AUTO_INCREMENT' form
|
// Otherwise we have to use sqlite's 'PRIMARY KEY AUTO_INCREMENT' form
|
||||||
@ -151,38 +142,4 @@ namespace MCGalaxy.SQL {
|
|||||||
DoInsert("INSERT OR REPLACE INTO", table, columns, args);
|
DoInsert("INSERT OR REPLACE INTO", table, columns, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class SQLiteBulkTransaction : BulkTransaction {
|
|
||||||
|
|
||||||
public SQLiteBulkTransaction(string connString) {
|
|
||||||
connection = new SQLiteConnection(connString);
|
|
||||||
connection.Open();
|
|
||||||
transaction = connection.BeginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IDbCommand CreateCommand(string sql) {
|
|
||||||
return new SQLiteCommand(sql, (SQLiteConnection)connection, (SQLiteTransaction)transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IDataParameter CreateParam(string paramName, DbType type) {
|
|
||||||
return new SQLiteParameter(paramName, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class SQLiteParameterisedQuery : ParameterisedQuery {
|
|
||||||
protected override bool MultipleSchema { get { return false; } }
|
|
||||||
|
|
||||||
protected override IDbConnection CreateConnection(string connString) {
|
|
||||||
return new SQLiteConnection(connString);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IDbCommand CreateCommand(string sql, IDbConnection conn) {
|
|
||||||
return new SQLiteCommand(sql, (SQLiteConnection)conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IDbDataParameter CreateParameter() {
|
|
||||||
return new SQLiteParameter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -53,13 +53,13 @@ namespace MCGalaxy.SQL {
|
|||||||
static string[] colTypes = new string[] {
|
static string[] colTypes = new string[] {
|
||||||
"TINYINT UNSIGNED", "SMALLINT UNSIGNED", "MEDIUMINT UNSIGNED",
|
"TINYINT UNSIGNED", "SMALLINT UNSIGNED", "MEDIUMINT UNSIGNED",
|
||||||
"INT UNSIGNED", "BIGINT UNSIGNED", "TINYINT", "SMALLINT",
|
"INT UNSIGNED", "BIGINT UNSIGNED", "TINYINT", "SMALLINT",
|
||||||
"MEDIUMINT", "INT", "BIGINT", "INTEGER", "BOOL", "DATETIME",
|
"MEDIUMINT", "INT", "BIGINT", "INTEGER", "DATETIME",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ColumnType {
|
public enum ColumnType {
|
||||||
UInt8, UInt16, UInt24, UInt32, UInt64,
|
UInt8, UInt16, UInt24, UInt32, UInt64,
|
||||||
Int8, Int16, Int24, Int32, Int64,
|
Int8, Int16, Int24, Int32, Int64,
|
||||||
Integer, Bool, DateTime, Char, VarChar
|
Integer, DateTime, Char, VarChar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,33 +76,21 @@ namespace MCGalaxy.SQL {
|
|||||||
|
|
||||||
internal static object Do(string sql, bool createDB, object arg,
|
internal static object Do(string sql, bool createDB, object arg,
|
||||||
ReaderCallback callback, params object[] args) {
|
ReaderCallback callback, params object[] args) {
|
||||||
ParameterisedQuery query;
|
Exception e = null;
|
||||||
if (args == null || args.Length == 0) {
|
|
||||||
query = Backend.GetStaticParameterised();
|
|
||||||
} else {
|
|
||||||
query = Backend.CreateParameterised();
|
|
||||||
}
|
|
||||||
|
|
||||||
query.parameters = args;
|
|
||||||
string connString = Backend.ConnectionString;
|
|
||||||
Exception e = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
try {
|
try {
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
arg = query.Iterate(sql, connString, arg, callback);
|
arg = SqlQuery.Iterate(sql, args, arg, callback);
|
||||||
} else {
|
} else {
|
||||||
query.Execute(sql, connString, createDB);
|
SqlQuery.Execute(sql, args, createDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
query.parameters = null;
|
|
||||||
return arg;
|
return arg;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
e = ex; // try yet again
|
e = ex; // try yet again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query.parameters = null;
|
|
||||||
File.AppendAllText("MySQL_error.log", DateTime.Now + " " + sql + "\r\n");
|
File.AppendAllText("MySQL_error.log", DateTime.Now + " " + sql + "\r\n");
|
||||||
Logger.LogError(e);
|
Logger.LogError(e);
|
||||||
return arg;
|
return arg;
|
||||||
|
@ -26,16 +26,17 @@ namespace MCGalaxy.SQL {
|
|||||||
/// <summary> Simple abstraction for a database management system. </summary>
|
/// <summary> Simple abstraction for a database management system. </summary>
|
||||||
public abstract class IDatabaseBackend {
|
public abstract class IDatabaseBackend {
|
||||||
|
|
||||||
/// <summary> Describes the arguments for a database connection
|
|
||||||
/// (such as database name or file location) </summary>
|
|
||||||
public abstract string ConnectionString { get; }
|
|
||||||
|
|
||||||
/// <summary> Whether this backend enforces the character length in VARCHAR columns. </summary>
|
/// <summary> Whether this backend enforces the character length in VARCHAR columns. </summary>
|
||||||
public abstract bool EnforcesTextLength { get; }
|
public abstract bool EnforcesTextLength { get; }
|
||||||
|
/// <summary> Whether this backend supports multiple database schemas. </summary>
|
||||||
|
public abstract bool MultipleSchema { get; }
|
||||||
|
|
||||||
|
internal abstract IDbConnection CreateConnection();
|
||||||
|
internal abstract IDbCommand CreateCommand(string sql, IDbConnection conn);
|
||||||
|
internal abstract IDbDataParameter CreateParameter();
|
||||||
|
|
||||||
/// <summary> Suffix required after a WHERE clause for caseless string comparison. </summary>
|
/// <summary> Suffix required after a WHERE clause for caseless string comparison. </summary>
|
||||||
public string CaselessWhereSuffix { get; protected set; }
|
public string CaselessWhereSuffix { get; protected set; }
|
||||||
|
|
||||||
/// <summary> Suffix required after a LIKE clause for caseless string comparison. </summary>
|
/// <summary> Suffix required after a LIKE clause for caseless string comparison. </summary>
|
||||||
public string CaselessLikeSuffix { get; protected set; }
|
public string CaselessLikeSuffix { get; protected set; }
|
||||||
|
|
||||||
@ -43,18 +44,6 @@ namespace MCGalaxy.SQL {
|
|||||||
/// <summary> Creates the schema for this database (if required). </summary>
|
/// <summary> Creates the schema for this database (if required). </summary>
|
||||||
public abstract void CreateDatabase();
|
public abstract void CreateDatabase();
|
||||||
|
|
||||||
/// <summary> Returns a new BulkTransaction instance, which can be used to execute
|
|
||||||
/// many sql statements as one single transaction. </summary>
|
|
||||||
public abstract BulkTransaction CreateBulk();
|
|
||||||
|
|
||||||
/// <summary> Returns a new ParameterisedQuery instance, which executes sql statements
|
|
||||||
/// and manages binding of parameters for sql queries. </summary>
|
|
||||||
public abstract ParameterisedQuery CreateParameterised();
|
|
||||||
|
|
||||||
/// <summary> Returns the shared static ParamterisedQuery instance, that is only used
|
|
||||||
/// for sql queries with no parameters. </summary>
|
|
||||||
protected internal abstract ParameterisedQuery GetStaticParameterised();
|
|
||||||
|
|
||||||
public abstract string RawGetDateTime(IDataRecord record, int col);
|
public abstract string RawGetDateTime(IDataRecord record, int col);
|
||||||
|
|
||||||
protected internal virtual void ParseCreate(ref string cmd) { }
|
protected internal virtual void ParseCreate(ref string cmd) { }
|
||||||
@ -161,7 +150,7 @@ namespace MCGalaxy.SQL {
|
|||||||
sql.Append(" `").Append(table).Append("` ");
|
sql.Append(" `").Append(table).Append("` ");
|
||||||
sql.Append('(').Append(columns).Append(')');
|
sql.Append('(').Append(columns).Append(')');
|
||||||
|
|
||||||
string[] names = ParameterisedQuery.GetNames(args.Length);
|
string[] names = SqlQuery.GetNames(args.Length);
|
||||||
sql.Append(" VALUES (");
|
sql.Append(" VALUES (");
|
||||||
for (int i = 0; i < args.Length; i++) {
|
for (int i = 0; i < args.Length; i++) {
|
||||||
sql.Append(names[i]);
|
sql.Append(names[i]);
|
||||||
|
@ -20,26 +20,19 @@ using System.Data;
|
|||||||
|
|
||||||
namespace MCGalaxy.SQL {
|
namespace MCGalaxy.SQL {
|
||||||
|
|
||||||
/// <summary> Represents an SQL command or query, that takes named parameters/arguments. </summary>
|
/// <summary> Executes an SQL command or query, that takes named parameters/arguments. </summary>
|
||||||
public abstract class ParameterisedQuery {
|
public static class SqlQuery {
|
||||||
|
|
||||||
internal object[] parameters;
|
|
||||||
protected abstract bool MultipleSchema { get; }
|
|
||||||
|
|
||||||
protected abstract IDbConnection CreateConnection(string connString);
|
|
||||||
protected abstract IDbCommand CreateCommand(string sql, IDbConnection conn);
|
|
||||||
protected abstract IDbDataParameter CreateParameter();
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Executes an SQL command that does not return any results. </summary>
|
/// <summary> Executes an SQL command that does not return any results. </summary>
|
||||||
public void Execute(string sql, string connString, bool createDB = false) {
|
public static void Execute(string sql, object[] parameters, bool createDB) {
|
||||||
using (IDbConnection conn = CreateConnection(connString)) {
|
IDatabaseBackend db = Database.Backend;
|
||||||
|
using (IDbConnection conn = db.CreateConnection()) {
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (!createDB && MultipleSchema)
|
if (!createDB && db.MultipleSchema)
|
||||||
conn.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
conn.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
||||||
|
|
||||||
using (IDbCommand cmd = CreateCommand(sql, conn)) {
|
using (IDbCommand cmd = db.CreateCommand(sql, conn)) {
|
||||||
FillParams(cmd);
|
FillParams(cmd, parameters);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
conn.Close();
|
conn.Close();
|
||||||
@ -47,14 +40,15 @@ namespace MCGalaxy.SQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Excecutes an SQL query, invoking a callback on the returned rows one by one. </summary>
|
/// <summary> Excecutes an SQL query, invoking a callback on the returned rows one by one. </summary>
|
||||||
public object Iterate(string sql, string connString, object arg, ReaderCallback callback) {
|
public static object Iterate(string sql, object[] parameters, object arg, ReaderCallback callback) {
|
||||||
using (IDbConnection conn = CreateConnection(connString)) {
|
IDatabaseBackend db = Database.Backend;
|
||||||
|
using (IDbConnection conn = db.CreateConnection()) {
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (MultipleSchema)
|
if (db.MultipleSchema)
|
||||||
conn.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
conn.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
||||||
|
|
||||||
using (IDbCommand cmd = CreateCommand(sql, conn)) {
|
using (IDbCommand cmd = db.CreateCommand(sql, conn)) {
|
||||||
FillParams(cmd);
|
FillParams(cmd, parameters);
|
||||||
using (IDataReader reader = cmd.ExecuteReader()) {
|
using (IDataReader reader = cmd.ExecuteReader()) {
|
||||||
while (reader.Read()) { arg = callback(reader, arg); }
|
while (reader.Read()) { arg = callback(reader, arg); }
|
||||||
}
|
}
|
||||||
@ -65,16 +59,16 @@ namespace MCGalaxy.SQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FillParams(IDbCommand cmd) {
|
internal static void FillParams(IDbCommand cmd, object[] parameters) {
|
||||||
object[] args = parameters;
|
if (parameters == null || parameters.Length == 0) return;
|
||||||
if (args == null || args.Length == 0) return;
|
IDatabaseBackend db = Database.Backend;
|
||||||
|
|
||||||
string[] names = GetNames(args.Length);
|
string[] names = GetNames(parameters.Length);
|
||||||
for (int i = 0; i < args.Length; i++) {
|
for (int i = 0; i < parameters.Length; i++) {
|
||||||
IDbDataParameter dbParam = CreateParameter();
|
IDbDataParameter arg = db.CreateParameter();
|
||||||
dbParam.ParameterName = names[i];
|
arg.ParameterName = names[i];
|
||||||
dbParam.Value = args[i];
|
arg.Value = parameters[i];
|
||||||
cmd.Parameters.Add(dbParam);
|
cmd.Parameters.Add(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,12 +20,18 @@ using System.Data;
|
|||||||
|
|
||||||
namespace MCGalaxy.SQL {
|
namespace MCGalaxy.SQL {
|
||||||
|
|
||||||
public abstract class BulkTransaction : IDisposable {
|
public sealed class SqlTransaction : IDisposable {
|
||||||
protected IDbConnection connection;
|
internal IDbConnection conn;
|
||||||
protected IDbTransaction transaction;
|
internal IDbTransaction transaction;
|
||||||
|
|
||||||
public abstract IDbCommand CreateCommand(string sql);
|
public SqlTransaction() {
|
||||||
public abstract IDataParameter CreateParam(string paramName, DbType type);
|
IDatabaseBackend db = Database.Backend;
|
||||||
|
conn = db.CreateConnection();
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
if (db.MultipleSchema) conn.ChangeDatabase(ServerConfig.MySQLDatabaseName);
|
||||||
|
transaction = conn.BeginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
public void Commit() {
|
public void Commit() {
|
||||||
try {
|
try {
|
||||||
@ -34,7 +40,7 @@ namespace MCGalaxy.SQL {
|
|||||||
Logger.LogError(ex);
|
Logger.LogError(ex);
|
||||||
Rollback();
|
Rollback();
|
||||||
} finally {
|
} finally {
|
||||||
connection.Close();
|
conn.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,14 +56,17 @@ namespace MCGalaxy.SQL {
|
|||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
transaction.Dispose();
|
transaction.Dispose();
|
||||||
connection.Dispose();
|
conn.Dispose();
|
||||||
transaction = null;
|
transaction = null;
|
||||||
connection = null;
|
conn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Execute(string sql) {
|
public bool Execute(string sql, params object[] args) {
|
||||||
|
IDatabaseBackend db = Database.Backend;
|
||||||
try {
|
try {
|
||||||
using (IDbCommand cmd = CreateCommand(sql)) {
|
using (IDbCommand cmd = db.CreateCommand(sql, conn)) {
|
||||||
|
cmd.Transaction = transaction;
|
||||||
|
SqlQuery.FillParams(cmd, args);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
@ -408,7 +408,7 @@
|
|||||||
<Compile Include="Database\ColumnDesc.cs" />
|
<Compile Include="Database\ColumnDesc.cs" />
|
||||||
<Compile Include="Database\IDatabaseBackend.cs" />
|
<Compile Include="Database\IDatabaseBackend.cs" />
|
||||||
<Compile Include="Database\Backends\MySQL.cs" />
|
<Compile Include="Database\Backends\MySQL.cs" />
|
||||||
<Compile Include="Database\ParameterisedQuery.cs" />
|
<Compile Include="Database\SqlQuery.cs" />
|
||||||
<Compile Include="Database\PlayerData.cs" />
|
<Compile Include="Database\PlayerData.cs" />
|
||||||
<Compile Include="Database\Stats\OfflineStat.cs" />
|
<Compile Include="Database\Stats\OfflineStat.cs" />
|
||||||
<Compile Include="Database\Stats\OnlineStat.cs" />
|
<Compile Include="Database\Stats\OnlineStat.cs" />
|
||||||
@ -612,7 +612,7 @@
|
|||||||
<Compile Include="Plugins\PluginManager.cs" />
|
<Compile Include="Plugins\PluginManager.cs" />
|
||||||
<Compile Include="Scripting\Scripting.cs" />
|
<Compile Include="Scripting\Scripting.cs" />
|
||||||
<Compile Include="Player\Ban.cs" />
|
<Compile Include="Player\Ban.cs" />
|
||||||
<Compile Include="Database\BulkTransaction.cs" />
|
<Compile Include="Database\SqlTransaction.cs" />
|
||||||
<Compile Include="Database\Database.cs" />
|
<Compile Include="Database\Database.cs" />
|
||||||
<Compile Include="Games\CTF\CtfGame.cs" />
|
<Compile Include="Games\CTF\CtfGame.cs" />
|
||||||
<Compile Include="Levels\BlockQueue.cs" />
|
<Compile Include="Levels\BlockQueue.cs" />
|
||||||
|
@ -98,8 +98,7 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
void SaveEntries(StreamWriter w) {
|
void SaveEntries(StreamWriter w) {
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
foreach (string l in lines)
|
foreach (string line in lines) w.WriteLine(line);
|
||||||
w.WriteLine(l);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ namespace MCGalaxy {
|
|||||||
readonly object saveLocker = new object();
|
readonly object saveLocker = new object();
|
||||||
|
|
||||||
public PlayerList() { }
|
public PlayerList() { }
|
||||||
public PlayerList(string path) { Path = path; }
|
|
||||||
|
|
||||||
/// <summary> Returns a copy of all names in the list. </summary>
|
/// <summary> Returns a copy of all names in the list. </summary>
|
||||||
public List<string> All() {
|
public List<string> All() {
|
||||||
@ -82,22 +81,21 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
void SaveEntries(StreamWriter w) {
|
void SaveEntries(StreamWriter w) {
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
foreach (string p in names)
|
foreach (string p in names) w.WriteLine(p);
|
||||||
w.WriteLine(p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerList Load(string file) {
|
public static PlayerList Load(string path) {
|
||||||
PlayerList list = new PlayerList(file);
|
PlayerList list = new PlayerList();
|
||||||
list.Path = file;
|
list.Path = path;
|
||||||
|
|
||||||
if (!File.Exists(list.Path)) {
|
if (!File.Exists(path)) {
|
||||||
File.Create(list.Path).Close();
|
File.Create(path).Close();
|
||||||
Logger.Log(LogType.SystemActivity, "CREATED NEW: " + list.Path);
|
Logger.Log(LogType.SystemActivity, "CREATED NEW: " + path);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (StreamReader r = new StreamReader(list.Path, Encoding.UTF8)) {
|
using (StreamReader r = new StreamReader(path, Encoding.UTF8)) {
|
||||||
string line = null;
|
string line = null;
|
||||||
while ((line = r.ReadLine()) != null) {
|
while ((line = r.ReadLine()) != null) {
|
||||||
list.names.Add(line);
|
list.names.Add(line);
|
||||||
|
@ -78,11 +78,11 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ImportBulk(StreamReader reader) {
|
static void ImportBulk(StreamReader reader) {
|
||||||
BulkTransaction helper = null;
|
SqlTransaction bulk = null;
|
||||||
List<string> buffer = new List<string>();
|
List<string> buffer = new List<string>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
helper = Database.Backend.CreateBulk();
|
bulk = new SqlTransaction();
|
||||||
while (!reader.EndOfStream) {
|
while (!reader.EndOfStream) {
|
||||||
string cmd = NextStatement(reader, buffer);
|
string cmd = NextStatement(reader, buffer);
|
||||||
if (cmd == null || cmd.Length == 0) continue;
|
if (cmd == null || cmd.Length == 0) continue;
|
||||||
@ -95,17 +95,17 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Run the command in the transaction.
|
//Run the command in the transaction.
|
||||||
if (helper.Execute(cmd)) continue;
|
if (bulk.Execute(cmd, null)) continue;
|
||||||
|
|
||||||
// Something went wrong.. commit what we've imported so far.
|
// Something went wrong.. commit what we've imported so far.
|
||||||
// We need to recreate connection otherwise every helper.Execute fails
|
// We need to recreate connection otherwise every helper.Execute fails
|
||||||
helper.Commit();
|
bulk.Commit();
|
||||||
helper.Dispose();
|
bulk.Dispose();
|
||||||
helper = Database.Backend.CreateBulk();
|
bulk = new SqlTransaction();
|
||||||
}
|
}
|
||||||
helper.Commit();
|
bulk.Commit();
|
||||||
} finally {
|
} finally {
|
||||||
if (helper != null) helper.Dispose();
|
if (bulk != null) bulk.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,13 +49,12 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void LoadPlayerLists(SchedulerTask task) {
|
static void LoadPlayerLists(SchedulerTask task) {
|
||||||
agreed = new PlayerList("ranks/agreed.txt");
|
|
||||||
try {
|
try {
|
||||||
UpgradeTasks.UpgradeOldAgreed();
|
UpgradeTasks.UpgradeOldAgreed();
|
||||||
agreed = PlayerList.Load("ranks/agreed.txt");
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.LogError("Error upgrading agreed list", ex);
|
Logger.LogError("Error upgrading agreed list", ex);
|
||||||
}
|
}
|
||||||
|
agreed = PlayerList.Load("ranks/agreed.txt");
|
||||||
|
|
||||||
bannedIP = PlayerList.Load("ranks/banned-ip.txt");
|
bannedIP = PlayerList.Load("ranks/banned-ip.txt");
|
||||||
ircControllers = PlayerList.Load("ranks/IRC_Controllers.txt");
|
ircControllers = PlayerList.Load("ranks/IRC_Controllers.txt");
|
||||||
|
@ -178,7 +178,6 @@ namespace MCGalaxy.Tasks {
|
|||||||
static List<long> playerSeconds;
|
static List<long> playerSeconds;
|
||||||
static int playerCount, playerFailed = 0;
|
static int playerCount, playerFailed = 0;
|
||||||
|
|
||||||
|
|
||||||
static void DumpPlayerTimeSpents() {
|
static void DumpPlayerTimeSpents() {
|
||||||
playerIds = new List<int>();
|
playerIds = new List<int>();
|
||||||
playerSeconds = new List<long>();
|
playerSeconds = new List<long>();
|
||||||
@ -200,19 +199,10 @@ namespace MCGalaxy.Tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void UpgradePlayerTimeSpents() {
|
static void UpgradePlayerTimeSpents() {
|
||||||
using (BulkTransaction bulk = Database.Backend.CreateBulk()) {
|
using (SqlTransaction bulk = new SqlTransaction()) {
|
||||||
IDataParameter idParam = bulk.CreateParam("@0", DbType.Int32);
|
|
||||||
IDataParameter secsParam = bulk.CreateParam("@1", DbType.Int64);
|
|
||||||
|
|
||||||
for (int i = 0; i < playerIds.Count; i++) {
|
for (int i = 0; i < playerIds.Count; i++) {
|
||||||
idParam.Value = playerIds[i];
|
bulk.Execute("UPDATE Players SET TimeSpent=@1 WHERE ID=@0",
|
||||||
secsParam.Value = playerSeconds[i];
|
playerIds[i], playerSeconds[i]);
|
||||||
|
|
||||||
using (IDbCommand cmd = bulk.CreateCommand("UPDATE Players SET TimeSpent=@1 WHERE ID=@0")) {
|
|
||||||
cmd.Parameters.Add(idParam);
|
|
||||||
cmd.Parameters.Add(secsParam);
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bulk.Commit();
|
bulk.Commit();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user