Simplify database API

This commit is contained in:
UnknownShadow200 2018-07-02 17:03:14 +10:00
parent cabe47f26f
commit 33561ee9d4
14 changed files with 117 additions and 268 deletions

View File

@ -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);

View File

@ -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();
}
}
} }

View File

@ -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();
}
}
} }

View File

@ -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
} }
} }

View File

@ -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;

View File

@ -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]);

View File

@ -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);
} }
} }

View File

@ -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;
} }

View File

@ -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" />

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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();
} }
} }

View File

@ -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");

View File

@ -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();
} }