Created by: Andrew
This commit is contained in:
Andrew
2016-08-27 22:43:23 -04:00
commit 6d74d5b59e
31 changed files with 3002 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
using System;
using System.IO;
using MySql.Data.MySqlClient;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;
using KartExtreme.IO;
namespace KartExtreme.Data
{
public class TemporaryConnection : IDisposable
{
private string oldHost;
private string oldSchema;
private string oldUsername;
private string oldPassword;
internal TemporaryConnection(string host, string schema, string username, string password)
{
this.oldHost = Database.Host;
this.oldSchema = Database.Schema;
this.oldUsername = Database.Username;
this.oldPassword = Database.Password;
Database.Host = host;
Database.Schema = schema;
Database.Username = username;
Database.Password = password;
}
public void Dispose()
{
Database.Host = this.oldHost;
Database.Schema = this.oldSchema;
Database.Username = this.oldUsername;
Database.Password = this.oldPassword;
}
}
public class TemporarySchema : IDisposable
{
private string oldSchema;
internal TemporarySchema(string schema)
{
this.oldSchema = Database.Schema;
Database.Schema = schema;
}
public void Dispose()
{
Database.Schema = this.oldSchema;
}
}
public static class Database
{
public static string Host { get; set; }
public static string Schema { get; set; }
public static string Username { get; set; }
public static string Password { get; set; }
internal static string CorrectFields(string fields)
{
string final = string.Empty;
string[] tokens = fields.Replace(",", " ").Replace(";", " ").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int processed = 0;
foreach (string field in tokens)
{
final += field;
processed++;
if (processed < tokens.Length)
{
final += ", ";
}
}
return final;
}
internal static string ConnectionString
{
get
{
return string.Format("server={0}; database={1}; uid={2}; password={3}; convertzerodatetime=yes;",
Database.Host,
Database.Schema,
Database.Username,
Database.Password);
}
}
internal static void Execute(string nonQuery, params object[] args)
{
MySqlHelper.ExecuteNonQuery(Database.ConnectionString, string.Format(nonQuery, args));
}
public static string DefaultSchema
{
get
{
string name = Assembly.GetEntryAssembly().GetName().Name;
switch (name)
{
case "WvsCenter":
return "wvsmaple-center";
case "WvsLogin":
return "wvsmaple-login";
default:
return "wvsmaple-game";
}
}
}
public static void Test()
{
using (MySqlConnection connection = new MySqlConnection(Database.ConnectionString))
{
connection.Open();
Log.Inform("Able to connect to database '{0}'.", connection.Database);
connection.Close();
}
}
public static void Analyze()
{
using (Database.TemporarySchema("information_schema"))
{
Meta.Initialize();
}
}
public static void Delete(string table, string constraints, params object[] args)
{
Database.Execute("DELETE FROM {0} WHERE {1}", table, string.Format(constraints, args));
}
public static bool Exists(string table, string constraints, params object[] args)
{
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, string.Format("SELECT * FROM {0} WHERE {1}", table, string.Format(constraints, args))))
{
return reader.HasRows;
}
}
public static dynamic Fetch(string table, string field, string constraints, params object[] args)
{
object value = new Datum(table).PopulateWith(field, constraints, args).Dictionary[field];
if (value is DBNull)
{
return null;
}
else if (value is byte && Meta.IsBool(table, field))
{
return (byte)value > 0;
}
else
{
return value;
}
}
public static void ExecuteScript(string host, string username, string password, string query, params object[] args)
{
using (MySqlConnection connection = new MySqlConnection(string.Format("SERVER={0}; UID={1}; PASSWORD={2};", host, username, password)))
{
connection.Open();
new MySqlScript(connection, string.Format(query, args)).Execute();
connection.Close();
}
}
public static void ExecuteFile(string host, string username, string password, string path)
{
using (MySqlConnection connection = new MySqlConnection(string.Format("SERVER={0}; UID={1}; PASSWORD={2};", host, username, password)))
{
connection.Open();
using (TextReader reader = new StreamReader(path))
{
new MySqlScript(connection, reader.ReadToEnd()).Execute();
}
connection.Close();
}
}
public static TemporaryConnection TemporaryConnection(string host, string schema, string username, string password)
{
return new TemporaryConnection(host, schema, username, password);
}
public static TemporarySchema TemporarySchema(string schema)
{
return new TemporarySchema(schema);
}
}
}

307
trunk/Common/Data/Datum.cs Normal file
View File

@@ -0,0 +1,307 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Dynamic;
using MySql.Data.MySqlClient;
namespace KartExtreme.Data
{
public class Datums : IEnumerable<Datum>
{
private List<Datum> Values { get; set; }
private string Table { get; set; }
public Datums(string table = null)
{
this.Table = table;
}
internal void PopulateInternal(string fields, string constraints)
{
this.Values = new List<Datum>();
string query = string.Format("SELECT {0} FROM {1}{2}", fields == null ? "*" : Database.CorrectFields(fields), this.Table, constraints != null ? " WHERE " + constraints : string.Empty);
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
{
while (reader.Read())
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
dictionary.Add(reader.GetName(i), reader.GetValue(i));
}
this.Values.Add(new Datum(this.Table, dictionary));
}
}
}
internal void PopulateInternalFree(string query)
{
this.Values = new List<Datum>();
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
{
while (reader.Read())
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
dictionary.Add(reader.GetName(i), reader.GetValue(i));
}
this.Values.Add(new Datum(this.Table, dictionary));
}
}
}
public dynamic Populate()
{
this.PopulateInternal(null, null);
return this;
}
public dynamic Populate(string constraints, params object[] args)
{
this.PopulateInternal(null, string.Format(constraints, args));
return this;
}
public dynamic PopulateWith(string fields)
{
this.PopulateInternal(fields, null);
return this;
}
public dynamic PopulateWith(string fields, string constraints, params object[] args)
{
this.PopulateInternal(fields, string.Format(constraints, args));
return this;
}
public dynamic PopulateFree(string query)
{
this.PopulateInternalFree(query);
return this;
}
public IEnumerator<Datum> GetEnumerator()
{
foreach (Datum loopDatum in this.Values)
{
yield return loopDatum;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)this.GetEnumerator();
}
}
public class Datum : DynamicObject
{
public string Table { get; private set; }
internal Dictionary<string, object> Dictionary { get; set; }
public Datum(string table)
{
this.Table = table;
this.Dictionary = new Dictionary<string, object>();
}
internal Datum(string table, Dictionary<string, object> values)
{
this.Table = table;
this.Dictionary = values;
}
internal void Populate(string query)
{
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(Database.ConnectionString, query))
{
if (reader.RecordsAffected > 1)
{
throw new RowNotUniqueException();
}
if (!reader.HasRows)
{
throw new RowNotInTableException();
}
reader.Read();
for (int i = 0; i < reader.FieldCount; i++)
{
string name = reader.GetName(i);
object value = reader.GetValue(i);
if (this.Dictionary.ContainsKey(name))
{
this.Dictionary[name] = value;
}
else
{
this.Dictionary.Add(name, value);
}
}
}
}
public dynamic Populate(string constraints, params object[] args)
{
this.Populate(string.Format("SELECT * FROM {0} WHERE {1}", this.Table, string.Format(constraints, args)));
return this;
}
public dynamic PopulateWith(string fields, string constraints, params object[] args)
{
this.Populate(string.Format("SELECT {0} FROM {1} WHERE {2}", Database.CorrectFields(fields), this.Table, string.Format(constraints, args)));
return this;
}
public void Insert()
{
string fields = "( ";
int processed = 0;
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
{
fields += loopPair.Key;
processed++;
if (processed < this.Dictionary.Count)
{
fields += ", ";
}
}
fields += " ) VALUES ( ";
processed = 0;
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
{
fields += string.Format("'{0}'", loopPair.Value is bool ? (((bool)loopPair.Value) ? 1 : 0) : loopPair.Value);
processed++;
if (processed < this.Dictionary.Count)
{
fields += ", ";
}
}
fields += " )";
Database.Execute("INSERT INTO {0} {1}", this.Table, fields);
}
public void Update(string constraints, params object[] args)
{
int processed = 0;
string fields = string.Empty;
foreach (KeyValuePair<string, object> loopPair in this.Dictionary)
{
fields += string.Format("{0}='{1}'", loopPair.Key, loopPair.Value is bool ? (((bool)loopPair.Value) ? 1 : 0) : loopPair.Value);
processed++;
if (processed < this.Dictionary.Count)
{
fields += ", ";
}
}
Database.Execute("UPDATE {0} SET {1} WHERE {2}", this.Table, fields, string.Format(constraints, args));
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (this.Dictionary.ContainsKey(binder.Name))
{
if (this.Dictionary[binder.Name] is DBNull)
{
result = null;
}
else if (this.Dictionary[binder.Name] is byte && Meta.IsBool(this.Table, binder.Name))
{
result = (byte)this.Dictionary[binder.Name] > 0;
}
else
{
result = this.Dictionary[binder.Name];
}
return true;
}
else
{
result = default(object);
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (value is DateTime)
{
if (Meta.IsDate(this.Table, binder.Name))
{
value = ((DateTime)value).ToString("yyyy-MM-dd");
}
else if (Meta.IsDateTime(this.Table, binder.Name))
{
value = ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
}
}
if (this.Dictionary.ContainsKey(binder.Name))
{
this.Dictionary[binder.Name] = value;
}
else
{
this.Dictionary.Add(binder.Name, value);
}
return true;
}
public override string ToString()
{
string result = this.Table + " [ ";
int processed = 0;
foreach (KeyValuePair<string, object> value in this.Dictionary)
{
result += value.Key;
processed++;
if (processed < this.Dictionary.Count)
{
result += ", ";
}
}
result += " ]";
return result;
}
}
}

70
trunk/Common/Data/Meta.cs Normal file
View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
namespace KartExtreme.Data
{
internal static class Meta
{
public static Dictionary<string, Dictionary<string, Column>> Tables = new Dictionary<string, Dictionary<string, Column>>();
public static void Initialize()
{
Meta.Tables.Clear();
foreach (dynamic datum in new Datums("COLUMNS").Populate("TABLE_SCHEMA = '{0}'", Database.DefaultSchema))
{
Meta.Add(datum);
}
}
private static void Add(dynamic datum)
{
Dictionary<string, Column> table;
string tableName = datum.TABLE_NAME;
if (Meta.Tables.ContainsKey(tableName))
{
table = Meta.Tables[tableName];
}
else
{
table = new Dictionary<string, Column>();
Meta.Tables.Add(tableName, table);
}
table.Add(datum.COLUMN_NAME, new Column(datum));
}
public static bool IsBool(String tableName, String fieldName)
{
return Meta.Tables[tableName][fieldName].ColumnType == "tinyint(1) unsigned";
}
public static bool IsDate(String tableName, String fieldName)
{
return Meta.Tables[tableName][fieldName].ColumnType == "date";
}
public static bool IsDateTime(String tableName, String fieldName)
{
return Meta.Tables[tableName][fieldName].ColumnType == "datetime";
}
}
internal class Column
{
public string Name { get; private set; }
public bool IsPrimaryKey { get; private set; }
public bool IsUniqueKey { get; private set; }
public string ColumnType { get; private set; }
public Column(dynamic datum)
{
this.Name = datum.COLUMN_NAME;
this.IsPrimaryKey = datum.COLUMN_KEY == "PRI";
this.IsUniqueKey = datum.COLUMN_KEY == "UNI";
this.ColumnType = datum.COLUMN_TYPE;
}
}
}

View File

@@ -0,0 +1,13 @@
namespace System.Data
{
public class RowNotUniqueException : DataException
{
public override string Message
{
get
{
return "Obtained row is not unique.";
}
}
}
}