diff --git a/ChaosBot/Attribute/AssemblyController.cs b/ChaosBot/Attribute/AssemblyController.cs
index 8d02727..2532b88 100644
--- a/ChaosBot/Attribute/AssemblyController.cs
+++ b/ChaosBot/Attribute/AssemblyController.cs
@@ -74,7 +74,7 @@ namespace ChaosBot.Attribute
{
string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}"));
string query = $"CREATE TABLE {table} ({columnDefs})";
- Controller.RawQuery(query, false);
+ Controller.RawQuery(query, readOutput: false);
}
else
{
@@ -84,7 +84,7 @@ namespace ChaosBot.Attribute
{
string query =
$"ALTER TABLE {table} ADD COLUMN {column.Item1} {column.Item2} {column.Item4}";
- Controller.RawQuery(query, false, true);
+ Controller.RawQuery(query, readOutput: false, throwError: true);
}
catch
{
diff --git a/ChaosBot/Database/Controller.cs b/ChaosBot/Database/Controller.cs
index 2117ba2..b9f5d3a 100644
--- a/ChaosBot/Database/Controller.cs
+++ b/ChaosBot/Database/Controller.cs
@@ -26,7 +26,7 @@ namespace ChaosBot.Database
/// Whether to read the output and return it as a DataFrame
/// Whether to throw any exceptions or to log and shrug.
///
- public static DataTable RawQuery(string query, bool readOutput = true, bool throwError = false)
+ public static DataTable RawQuery(string query, Dictionary parameters = null, bool readOutput = true, bool throwError = false)
{
DataTable dt = new DataTable();
@@ -40,11 +40,24 @@ namespace ChaosBot.Database
// Start creating the command and assign the query given
SqliteCommand cmd = _conn.CreateCommand();
cmd.CommandText = query;
+
+ // Add parameters if they exist
+ if (parameters != null)
+ {
+ foreach (var parameter in parameters)
+ {
+ cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
+ }
+ }
+
+ // Prepare the statement
+ _logger.Trace($"Database.Controller.RawQuery: Running query {cmd.CommandText}");
+ cmd.Prepare();
if (readOutput)
{
// output needs to be read, make a reader and fill the datatable with the data
- SqliteDataReader executeReader = cmd.ExecuteReader(CommandBehavior.SingleResult);
+ SqliteDataReader executeReader = cmd.ExecuteReader();
dt.Load(executeReader);
}
else
@@ -71,321 +84,5 @@ namespace ChaosBot.Database
return dt;
}
-
- ///
- /// Insert a list of parameters into a table in the database
- ///
- ///
- /// string table = "SomeTable";
- /// Dictionary<string, object> parameters = new Dictionary<string, object>
- /// {
- /// { "someInt", 123 },
- /// { "someString", "asdf" },
- /// { "someChar", 'x' }
- /// }
- ///
- /// Controller.InsertQuery(table, parameters);
- ///
- /// Table to insert into
- /// List of parameters to insert to the row. Every type is a key
- public static void InsertQuery(string table, Dictionary parameters)
- {
- try
- {
- using (_conn)
- {
- // Open the SQLite connection
- _conn.Open();
-
- // Start the command creation
- SqliteCommand cmd = _conn.CreateCommand();
-
- // Build the command bit by bit
- // INSERT INTO {table} (key1, key2, key3) VALUES (@key1,@key2,@key3)
- StringBuilder commandText = new StringBuilder();
- commandText.Append("INSERT INTO ");
- commandText.Append(table);
- commandText.Append(" (");
-
- foreach (string key in parameters.Keys)
- {
- commandText.Append($"{key}, ");
- }
-
- commandText.Remove(commandText.Length - 2, 2);
- commandText.Append(") VALUES (");
-
- foreach (string key in parameters.Keys)
- {
- // We use @key to indicate the parameter placeholder
- commandText.Append($"@{key},");
- }
-
- // Remove the trailing comma
- commandText.Remove(commandText.Length - 1, 1);
- commandText.Append(")");
-
- // Assign onto QueryCommand
- cmd.CommandText = commandText.ToString();
-
- // Replace all the parameters to the query
- foreach (string key in parameters.Keys)
- {
- cmd.Parameters.AddWithValue($"@{key}", parameters.GetValueOrDefault(key));
- }
-
- // Prepare the parameters
- cmd.Prepare();
-
- // Execute, do not return anything
- cmd.ExecuteNonQuery();
-
- _conn.Close();
- }
- }
- catch (Exception ex)
- {
- _logger.Fatal($"Database.Controller.InsertQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
- }
- }
-
- ///
- /// Update rows in the database
- ///
- ///
- /// string table = "SomeTable";
- /// Dictionary<string, object> values = new Dictionary<string, object>
- /// {
- /// {"key", "newValue"}
- /// };
- /// Dictionary<string, object> parameters = new Dictionary<string, object>
- /// {
- /// {"key", "oldValue"}
- /// };
- /// Controller.UpdateQuery(table, values, parameters);
- ///
- /// Table to update data in
- /// List of keys to set. Equivalent of SQL: SET {key} = {value}
- /// List of filters to apply in the SQL WHERE condition
- public static void UpdateQuery(string table, Dictionary values, Dictionary parameters)
- {
- try
- {
- using (_conn)
- {
- // Open SQLite connection
- _conn.Open();
-
- // Create the command
- SqliteCommand cmd = _conn.CreateCommand();
-
- // Build the commandtext
- // UPDATE {table} SET {key}=@val_{key} WHERE {key}=@fil_{key}
- StringBuilder commandText = new StringBuilder();
- commandText.Append("UPDATE ");
- commandText.Append(table);
- commandText.Append(" SET ");
-
- // Build the list of values
- List updateList = new List();
- foreach (string key in values.Keys)
- {
- updateList.Add($"{key}=@val_{key} ");
- cmd.Parameters.AddWithValue($@"val_{key}", values.GetValueOrDefault(key));
- }
-
- // Append the list of values, comma-separated
- commandText.Append(string.Join(", ", updateList));
-
- // Build the list of filters
- List filterList = new List();
- foreach (string key in parameters.Keys)
- {
- filterList.Add($"{key}=@fil_{key} ");
- cmd.Parameters.AddWithValue($"@fil_{key}", parameters.GetValueOrDefault(key));
- }
-
- if (filterList.Count > 0)
- {
- // Prepend with WHERE if there are parameters
- commandText.Append("WHERE ");
- // Append the list of filters AND separated
- commandText.Append(string.Join("AND ", filterList));
- }
-
- // Assign the command
- cmd.CommandText = commandText.ToString();
-
- // Prepare the parameters
- cmd.Prepare();
-
- // Execute, do not return
- cmd.ExecuteNonQuery();
-
- // Close connection
- _conn.Close();
- }
- }
- catch (Exception ex)
- {
- _logger.Fatal($"Database.Controller.UpdateQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
- }
- }
-
- public static int TransactionQuery(List cmds)
- {
- SqliteCommand command = _conn.CreateCommand();
- SqliteTransaction transaction;
-
- _conn.Open();
-
- // Start a local transaction.
- transaction = _conn.BeginTransaction();
-
- // Must assign both transaction object and connection
- // to Command object for a pending local transaction
- command.Connection = _conn;
- command.Transaction = transaction;
-
- try
- {
- foreach (var cmd in cmds)
- {
- command.CommandText = cmd.CommandText;
- command.ExecuteNonQuery();
- }
-
- // Attempt to commit the transaction.
- transaction.Commit();
- _logger.Info($"{cmds.Count} record(s) are written to database.");
- }
- catch (Exception ex)
- {
- _logger.Warn("Commit Exception Type: {0}", ex.GetType());
- _logger.Warn(" Message: {0}", ex.Message);
-
- // Attempt to roll back the transaction.
- try
- {
- transaction.Rollback();
- }
- catch (Exception ex2)
- {
- // This catch block will handle any errors that may have occurred
- // on the server that would cause the rollback to fail, such as
- // a closed connection.
- _logger.Warn("Rollback Exception Type: {0}", ex2.GetType());
- _logger.Warn(" Message: {0}", ex2.Message);
- }
-
- return 0;
- }
-
- _conn.Close();
- return cmds.Count;
- }
-
- public static DataTable SelectQuery(string table, string selectColumns = "*", Dictionary filterColumns = null, string orderByKey = null)
- {
- DataTable dt = new DataTable();
-
- try
- {
- using (_conn)
- {
- _conn.Open();
- SqliteCommand cmd = _conn.CreateCommand();
-
- string filter = null;
- if (filterColumns != null)
- {
- List filterList = new List();
- foreach (string key in filterColumns.Keys)
- {
- filterList.Add($"{key} = @{key}");
- }
-
- filter = $"WHERE {Strings.Join(filterList.ToArray(), " AND ")}";
-
- foreach (string key in filterColumns.Keys)
- {
- cmd.Parameters.AddWithValue($@"{key}", filterColumns.GetValueOrDefault(key));
- }
- }
-
- string order = null;
- if (orderByKey != null)
- {
- order = $"ORDER BY {orderByKey}";
- }
-
- string query = $"SELECT {selectColumns} FROM {table} {filter} {order}";
-
- cmd.CommandText = query;
- cmd.Prepare();
- SqliteDataReader executeReader = cmd.ExecuteReader();
-
- dt.Load(executeReader);
-
- _conn.Close();
- }
- }
- catch (Exception ex)
- {
- _logger.Fatal($"Database.Controller.SelectQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
- }
-
- return dt;
- }
-
- public static void DeleteQuery(string table, Dictionary filterColumns = null, string orderByKey = null, int limit = -1, int offset = -1)
- {
- try
- {
- using (_conn)
- {
- _conn.Open();
- SqliteCommand cmd = _conn.CreateCommand();
-
- string filter = null;
- if (filterColumns != null)
- {
- List filterList = new List();
- foreach (string key in filterColumns.Keys)
- {
- filterList.Add($"{key} = @{key}");
- }
-
- filter = $"WHERE {Strings.Join(filterList.ToArray(), " AND ")}";
-
- foreach (string key in filterColumns.Keys)
- {
- cmd.Parameters.AddWithValue($@"{key}", filterColumns.GetValueOrDefault(key));
- }
- }
-
- string order = null;
- if (orderByKey != null)
- {
- order = $"ORDER BY {orderByKey}";
- }
-
- string limitString = limit > 0 ? $"LIMIT {limit}" : null;
- string offsetString = offset > 0 ? $"OFFSET {offset}" : null;
-
- string query = $"DELETE FROM {table} {filter} {order} {limitString} {offsetString}";
-
- cmd.CommandText = query;
- cmd.Prepare();
- cmd.ExecuteNonQuery();
-
- _conn.Close();
- }
- }
- catch (Exception ex)
- {
- _logger.Fatal($"Database.Controller.DeleteQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
- }
- }
}
}
\ No newline at end of file
diff --git a/ChaosBot/Database/Entity/BaseEntity.cs b/ChaosBot/Database/Entity/BaseEntity.cs
new file mode 100644
index 0000000..8451e7b
--- /dev/null
+++ b/ChaosBot/Database/Entity/BaseEntity.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Data;
+using System.Linq;
+using ChaosBot.Attribute;
+using ChaosBot.Database;
+
+namespace ChaosBot.Database.Entity
+{
+ public abstract class BaseEntity
+ {
+ protected BaseEntity() {}
+
+ public abstract void SetFromRow(DataRow row);
+
+
+ protected static QueryBuilder Query() where T : BaseEntity, new()
+ {
+ var dbEntityAttribute = typeof(T).GetCustomAttributes(
+ typeof(DBEntity),
+ true
+ ).FirstOrDefault() as DBEntity;
+ if (dbEntityAttribute != null)
+ {
+ return new QueryBuilder(dbEntityAttribute.Table);
+ }
+
+ throw new SystemException($"Class {typeof(T)} does not have an attribute of {typeof(DBEntity)} set");
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Database/Entity/Points.cs b/ChaosBot/Database/Entity/Points.cs
index a51a027..c074d88 100644
--- a/ChaosBot/Database/Entity/Points.cs
+++ b/ChaosBot/Database/Entity/Points.cs
@@ -1,19 +1,22 @@
+using System.Data;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("PointsTable")]
- public class Points
+ public class Points : BaseEntity
{
[DBPrimaryKey]
[DBAutoIncrement]
[DBNotNull]
[DBUnique]
- public int id { get; }
+ public int id { get; private set; }
public int points { get; private set; }
public string userId { get; private set; }
public string guildId { get; private set; }
+ public Points() {}
+
public Points(int id, string userId, string guildId, int points)
{
this.id = id;
@@ -28,5 +31,18 @@ namespace ChaosBot.Database.Entity
this.userId = userId;
this.guildId = guildId;
}
+
+ public static QueryBuilder Query()
+ {
+ return BaseEntity.Query();
+ }
+
+ public override void SetFromRow(DataRow row)
+ {
+ id = (int)row["id"];
+ userId = (string)row["userId"];
+ guildId = (string)row["guildId"];
+ points = (int)row["points"];
+ }
}
}
\ No newline at end of file
diff --git a/ChaosBot/Database/Entity/Raffle.cs b/ChaosBot/Database/Entity/Raffle.cs
index d230177..4be0ade 100644
--- a/ChaosBot/Database/Entity/Raffle.cs
+++ b/ChaosBot/Database/Entity/Raffle.cs
@@ -1,18 +1,21 @@
+using System.Data;
using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("RaffleTable")]
- public class Raffle
+ public class Raffle : BaseEntity
{
[DBPrimaryKey]
[DBAutoIncrement]
[DBNotNull]
[DBUnique]
- public int id { get; }
+ public int id { get; private set; }
public string userId { get; private set; }
public string guildId { get; private set; }
+ public Raffle() {}
+
public Raffle(int id, string userId, string guildId)
{
this.id = id;
@@ -25,5 +28,17 @@ namespace ChaosBot.Database.Entity
this.userId = userId;
this.guildId = guildId;
}
+
+ public static QueryBuilder Query()
+ {
+ return BaseEntity.Query();
+ }
+
+ public override void SetFromRow(DataRow row)
+ {
+ id = (int)row["id"];
+ userId = (string)row["userid"];
+ guildId = (string) row["guildid"];
+ }
}
}
\ No newline at end of file
diff --git a/ChaosBot/Database/Entity/ServerConfigurationFlag.cs b/ChaosBot/Database/Entity/ServerConfigurationFlag.cs
index f8d1ab7..01f79e0 100644
--- a/ChaosBot/Database/Entity/ServerConfigurationFlag.cs
+++ b/ChaosBot/Database/Entity/ServerConfigurationFlag.cs
@@ -1,4 +1,5 @@
using System;
+using System.Data;
using System.IO;
using System.Text;
using System.Text.Json;
@@ -8,13 +9,15 @@ using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity
{
[DBEntity("ServerConfigurationFlags")]
- public class ServerConfigurationFlag
+ public class ServerConfigurationFlag : BaseEntity
{
- public string key { get; }
+ public string key { get; private set; }
- public string serializedValue { get; }
+ public string serializedValue { get; set; }
- public long guildId { get; }
+ public long guildId { get; private set; }
+
+ public ServerConfigurationFlag() {}
public ServerConfigurationFlag(string key, T value, ulong guildId)
{
@@ -22,6 +25,29 @@ namespace ChaosBot.Database.Entity
this.key = key;
this.guildId = Convert.ToInt64(guildId);
}
+ public ServerConfigurationFlag(string key, T value, long guildId)
+ {
+ this.serializedValue = Serialize(value);
+ this.key = key;
+ this.guildId = guildId;
+ }
+ public ServerConfigurationFlag(string key, long guildId)
+ {
+ this.key = key;
+ this.guildId = guildId;
+ }
+
+ public static QueryBuilder> Query()
+ {
+ return BaseEntity.Query>();
+ }
+
+ public override void SetFromRow(DataRow row)
+ {
+ key = (string)row["key"];
+ serializedValue = (string)row["serializedValue"];
+ guildId = (long)row["guildId"];
+ }
public T GetValue()
{
diff --git a/ChaosBot/Database/Entity/TestEntity.cs b/ChaosBot/Database/Entity/TestEntity.cs
new file mode 100644
index 0000000..195d59e
--- /dev/null
+++ b/ChaosBot/Database/Entity/TestEntity.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Data;
+using ChaosBot.Attribute;
+
+namespace ChaosBot.Database.Entity
+{
+ [DBEntity("TestTable")]
+ public class TestEntity : BaseEntity
+ {
+ public long id { get; private set; }
+
+ public TestEntity() {}
+
+ public TestEntity(int id)
+ {
+ this.id = id;
+ }
+
+ public static QueryBuilder Query()
+ {
+ return BaseEntity.Query();
+ }
+
+ public override void SetFromRow(DataRow row)
+ {
+ id = (long)row["id"];
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Database/FilterValue.cs b/ChaosBot/Database/FilterValue.cs
new file mode 100644
index 0000000..23968af
--- /dev/null
+++ b/ChaosBot/Database/FilterValue.cs
@@ -0,0 +1,16 @@
+using NLog.Filters;
+
+namespace ChaosBot.Database
+{
+ public struct FilterValue
+ {
+ public object Value;
+ public string Comparison;
+
+ public FilterValue(object value, string comparison = null)
+ {
+ this.Value = value;
+ this.Comparison = comparison;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Database/QueryBuilder.cs b/ChaosBot/Database/QueryBuilder.cs
new file mode 100644
index 0000000..e970161
--- /dev/null
+++ b/ChaosBot/Database/QueryBuilder.cs
@@ -0,0 +1,278 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using System.Text;
+using ChaosBot.Attribute;
+using ChaosBot.Database.Entity;
+
+namespace ChaosBot.Database
+{
+ public class QueryBuilder where T : BaseEntity, new()
+ {
+ private string _table;
+ private bool _distinct;
+ private Dictionary _whereConditions;
+ private Dictionary _setList;
+ private List _orderKeys;
+ private List _groupByList;
+ private int _limit;
+ private int _offset;
+ public QueryBuilder(string table)
+ {
+ _table = table;
+ _distinct = false;
+ _whereConditions = new Dictionary();
+ _setList = new Dictionary();
+ _orderKeys = new List();
+ _groupByList = new List();
+ _limit = -1;
+ _offset = -1;
+ }
+
+ /*
+ * Fetch all records from a database
+ */
+ public List All()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ DataTable dt = query
+ .Select()
+ .Append("*")
+ .FromTable(_table)
+ .Run();
+
+ List returnList = new List();
+ foreach (DataRow row in dt.Rows)
+ {
+ T newObject = new T();
+ newObject.SetFromRow(row);
+ returnList.Add(newObject);
+ }
+
+ return returnList;
+ }
+
+ /*
+ * Set a where condition
+ */
+ public QueryBuilder Where(string key, object value, string comparison = null)
+ {
+ _whereConditions.Add(key, new FilterValue(value, comparison));
+ return this;
+ }
+
+ /*
+ * Set distinct
+ */
+ public QueryBuilder Distinct()
+ {
+ _distinct = true;
+ return this;
+ }
+
+ /*
+ * Set SET field
+ */
+ public QueryBuilder Set(string key, object value)
+ {
+ _setList.Add(key, value);
+ return this;
+ }
+
+ /*
+ * Set an order key
+ */
+ public QueryBuilder OrderBy(string key)
+ {
+ _orderKeys.Add(key);
+ return this;
+ }
+
+ /*
+ * Set a groupBy key
+ */
+ public QueryBuilder GroupBy(string key)
+ {
+ _groupByList.Add(key);
+ return this;
+ }
+
+ /*
+ * Limit amount of responses
+ */
+ public QueryBuilder Limit(int amount)
+ {
+ _limit = amount;
+ return this;
+ }
+
+ public QueryBuilder Offset(int amount)
+ {
+ _offset = amount;
+ return this;
+ }
+
+ public QueryBuilder Limit(int limit, int offset)
+ {
+ Limit(limit);
+ return Offset(offset);
+ }
+
+ /*
+ * Basic mathematical operations
+ */
+ public int Count()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ long amount = (long)query
+ .Select()
+ .Append("COUNT(*) as count")
+ .FromTable(_table)
+ .Run().Rows[0]["count"];
+ return Convert.ToInt32(amount);
+ }
+
+ /*
+ * Basic logical operations
+ */
+ public bool Exists()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ return (bool)query
+ .Select()
+ .Append("COUNT(*)>0 as present")
+ .FromTable(_table)
+ .Run().Rows[0]["present"];
+ }
+
+ public bool DoesNotExist()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ return (bool)query
+ .Select()
+ .Append("COUNT(*)=0 as notPresent")
+ .FromTable(_table)
+ .Run().Rows[0]["notPresent"];
+ }
+
+ /*
+ * Actions
+ */
+ public List Get()
+ {
+ List returnList = new List();
+
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ query
+ .Select();
+
+ if (_distinct)
+ query.Distinct();
+
+ query
+ .Append("*")
+ .FromTable(_table);
+
+ if (_whereConditions.Keys.Count > 0)
+ query.Where(_whereConditions);
+
+ if (_groupByList.Count > 0)
+ query.GroupBy(_groupByList);
+
+ if (_orderKeys.Count > 0)
+ query.OrderBy(_orderKeys);
+
+ if (_limit >= 0)
+ {
+ if (_offset >= 0)
+ {
+ query.Limit(_limit, _offset);
+ }
+ else
+ {
+ query.Limit(_limit);
+ }
+ }
+
+ DataTable dt = query.Run();
+ foreach (DataRow row in dt.Rows)
+ {
+ T newObject = new T();
+ newObject.SetFromRow(row);
+ returnList.Add(newObject);
+ }
+
+ return returnList;
+ }
+
+ public T First()
+ {
+ Limit(1);
+ List list = Get();
+
+ if (list.Count > 0)
+ return list[0];
+ return null;
+ }
+
+ public void Insert(T obj)
+ {
+ Dictionary objectKeysAndValues = GetObjectKeysAndValues(obj);
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ query
+ .Insert()
+ .IntoTable(_table)
+ .Columns(new List(objectKeysAndValues.Keys))
+ .Values(objectKeysAndValues);
+
+ query.Run();
+ }
+
+ public void Update()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ query
+ .Update()
+ .Table(_table)
+ .Set(_setList);
+
+ if (_whereConditions.Keys.Count > 0)
+ query.Where(_whereConditions);
+
+ query.Run();
+ }
+
+ public void Delete()
+ {
+ QueryBuilderRaw query = new QueryBuilderRaw();
+ query
+ .Delete()
+ .FromTable(_table);
+
+ if (_whereConditions.Keys.Count > 0)
+ query.Where(_whereConditions);
+
+ query.Run();
+ }
+
+ /*
+ * Helpers
+ */
+ private Dictionary GetObjectKeysAndValues(T obj)
+ {
+ var returnValue = new Dictionary();
+
+ foreach (PropertyInfo prop in typeof(T).GetProperties())
+ {
+ string columnName = prop.Name;
+ object value = prop.GetValue(obj);
+
+ if (value != null)
+ returnValue.Add(columnName, value);
+ }
+
+ return returnValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Database/QueryBuilderRaw.cs b/ChaosBot/Database/QueryBuilderRaw.cs
new file mode 100644
index 0000000..78e915d
--- /dev/null
+++ b/ChaosBot/Database/QueryBuilderRaw.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+
+namespace ChaosBot.Database
+{
+ public class QueryBuilderRaw
+ {
+ private StringBuilder _query;
+ private Dictionary _parameters;
+ private int keyIndex = 0;
+
+ public QueryBuilderRaw()
+ {
+ _query = new StringBuilder();
+ _parameters = new Dictionary();
+ }
+
+ public QueryBuilderRaw Append(string text)
+ {
+ _query.Append(text);
+ if (!text.EndsWith(" "))
+ _query.Append(" ");
+ return this;
+ }
+
+ public DataTable Run()
+ {
+ return Controller.RawQuery(_query.ToString(), _parameters);
+ }
+
+ public QueryBuilderRaw Select()
+ {
+ return Append("SELECT");
+ }
+
+ public QueryBuilderRaw Insert(string alternativeAction = null)
+ {
+ Append("INSERT");
+ if (alternativeAction != null)
+ Append(alternativeAction);
+ return this;
+ }
+
+ public QueryBuilderRaw Update(string alternativeAction = null)
+ {
+ Append("UPDATE");
+ if (alternativeAction != null)
+ Append(alternativeAction);
+ return this;
+ }
+
+ public QueryBuilderRaw Delete()
+ {
+ return Append("DELETE");
+ }
+
+ public QueryBuilderRaw Distinct()
+ {
+ return Append("DISTINCT");
+ }
+
+ public QueryBuilderRaw Table(string table)
+ {
+ return Append(table);
+ }
+
+ public QueryBuilderRaw FromTable(string table)
+ {
+ Append("FROM");
+ return Table(table);
+ }
+
+ public QueryBuilderRaw IntoTable(string table)
+ {
+ Append("INTO");
+ return Table(table);
+ }
+
+ public QueryBuilderRaw Columns(List columnList)
+ {
+ Append("(");
+ Append(String.Join(", ", columnList));
+ Append(")");
+ return this;
+ }
+
+ public QueryBuilderRaw Values(Dictionary keyValueList)
+ {
+ Append("VALUES (");
+ List parameterKeys = new List();
+ foreach (KeyValuePair pair in keyValueList)
+ {
+ string parameterName = AddParameterAndReturnKey(pair.Key, pair.Value);
+ parameterKeys.Add(parameterName);
+ }
+ Append(string.Join(", ", parameterKeys));
+ Append(")");
+ return this;
+ }
+
+ public QueryBuilderRaw Set(Dictionary keyValueList)
+ {
+ Append("SET");
+ List parameterKeys = new List();
+ foreach (KeyValuePair pair in keyValueList)
+ {
+ string parameterName = AddParameterAndReturnKey(pair.Key, pair.Value);
+ parameterKeys.Add($"{pair.Key} = {parameterName}");
+ }
+ Append(string.Join(", ", parameterKeys));
+ return this;
+ }
+
+ public QueryBuilderRaw Where(Dictionary whereCondition)
+ {
+ Append("WHERE");
+ foreach (string key in whereCondition.Keys)
+ {
+ FilterValue value = whereCondition.GetValueOrDefault(key);
+ string parameterName = AddParameterAndReturnKey(key, value.Value);
+ Append($"{key} {value.Comparison ?? "="} {parameterName}");
+ }
+
+ return this;
+ }
+
+ public QueryBuilderRaw GroupBy(List groupByList)
+ {
+ Append("GROUP BY");
+ return Append(string.Join(", ", groupByList));
+ }
+
+ public QueryBuilderRaw OrderBy(List orderKeys)
+ {
+ Append("ORDER BY");
+ return Append(string.Join(", ", orderKeys));
+ }
+
+ public QueryBuilderRaw Limit(int limit)
+ {
+ return Append($"LIMIT {limit}");
+ }
+
+ public QueryBuilderRaw Limit(int limit, int offset)
+ {
+ return Append($"LIMIT {limit} OFFSET {offset}");
+ }
+
+ private void AddParameter(string parameterName, object value)
+ {
+ _parameters.Add(parameterName, value);
+ }
+
+ private string AddParameterAndReturnKey(string key, object value)
+ {
+ string parameterKey = GetUniqueParameterName(key);
+ AddParameter(parameterKey, value);
+ return parameterKey;
+ }
+
+ private string GetStaticParameterName(string key)
+ {
+ return $"@databasevalue{key}";
+ }
+
+ private string GetUniqueParameterName(string key)
+ {
+ return $"{GetStaticParameterName(key)}_{keyIndex++}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Database/Repository/ConfigurationRepository.cs b/ChaosBot/Database/Repository/ConfigurationRepository.cs
index 70b5c6b..3f0ce88 100644
--- a/ChaosBot/Database/Repository/ConfigurationRepository.cs
+++ b/ChaosBot/Database/Repository/ConfigurationRepository.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Data;
using ChaosBot.Database.Entity;
using Microsoft.Extensions.Configuration;
-using NLog;
namespace ChaosBot.Database.Repository
{
@@ -43,13 +42,13 @@ namespace ChaosBot.Database.Repository
public static string GetValueRaw(string configurationFlag, long guildId)
{
- Dictionary filterColumns = new Dictionary();
- filterColumns.Add("key", configurationFlag);
- filterColumns.Add("guildId", guildId);
- DataTable valueTable = Controller.SelectQuery(ServersTable, filterColumns: filterColumns);
- if (valueTable.Rows.Count == 1)
+ Dictionary filterColumns = new Dictionary();
+ filterColumns.Add("key", new FilterValue(configurationFlag));
+ filterColumns.Add("guildId", new FilterValue(guildId));
+ ServerConfigurationFlag serverConfigurationFlag = ServerConfigurationFlag.Query().Where("key", configurationFlag).Where("guildId", guildId).First();
+ if (serverConfigurationFlag != null)
{
- return valueTable.Rows[0]["serializedValue"].ToString();
+ return serverConfigurationFlag.serializedValue;
}
return null;
@@ -81,23 +80,22 @@ namespace ChaosBot.Database.Repository
{
try
{
- Dictionary filterColumns = new Dictionary();
- filterColumns.Add("key", configurationFlag);
- filterColumns.Add("guildId", guildId);
-
- Dictionary newValue = new Dictionary();
- newValue.Add("key", configurationFlag);
- newValue.Add("guildId", guildId);
- newValue.Add("serializedValue", serializedValue);
-
- DataTable valueTable = Controller.SelectQuery(ServersTable, "COUNT(*)", filterColumns);
- if ((long) valueTable.Rows[0]["COUNT(*)"] == 1)
+ int matchCount = ServerConfigurationFlag.Query().Where("key", configurationFlag).Where("guildId", guildId).Count();
+ if (matchCount > 0)
{
- Controller.UpdateQuery(ServersTable, newValue, filterColumns);
+ ServerConfigurationFlag.Query()
+ .Where("key", configurationFlag)
+ .Where("guildId", guildId)
+ .Set("key", configurationFlag)
+ .Set("guildId", guildId)
+ .Set("serializedValue", serializedValue)
+ .Update();
return;
}
- Controller.InsertQuery(ServersTable, newValue);
+ ServerConfigurationFlag newValue = new ServerConfigurationFlag(configurationFlag, guildId);
+ newValue.serializedValue = serializedValue;
+ ServerConfigurationFlag.Query().Insert(newValue);
}
catch (Exception ex)
{
diff --git a/ChaosBot/Database/Repository/PointsRepository.cs b/ChaosBot/Database/Repository/PointsRepository.cs
index d6145bf..3d7a068 100644
--- a/ChaosBot/Database/Repository/PointsRepository.cs
+++ b/ChaosBot/Database/Repository/PointsRepository.cs
@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
-using System.Drawing;
-using System.Linq;
using ChaosBot.Database.Entity;
-using Microsoft.Data.Sqlite;
namespace ChaosBot.Database.Repository
{
@@ -14,136 +11,66 @@ namespace ChaosBot.Database.Repository
public static Points[] All()
{
- DataTable dataTable = Controller.SelectQuery(Table);
+ List pointsList = Points.Query().All();
- List pointslist = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int id = Convert.ToInt32((long)row["id"]);
- int points = Convert.ToInt32(row["points"]);
- string userId = row["userId"].ToString();
- string guildId = row["guildId"].ToString();
-
- pointslist.Add(new Points(id, userId, guildId, points));
- }
-
- return pointslist.ToArray();
+ return pointsList.ToArray();
}
public static Points[] All(string guildId)
{
- Dictionary filterDict = new Dictionary();
- filterDict.Add("guildId", guildId);
+ List pointsList = Points.Query().Where("guildId", guildId).All();
- DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
-
- List pointslist = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int idFetch = Convert.ToInt32((long)row["id"]);
- int pointsFetch = Convert.ToInt32(row["points"]);
- string userIdFetch = row["userId"].ToString();
- string guildIdFetch = row["guildId"].ToString();
-
- pointslist.Add(new Points(idFetch, userIdFetch, guildIdFetch, pointsFetch));
- }
-
- return pointslist.ToArray();
+ return pointsList.ToArray();
}
public static int Total(string userId, string guildId)
{
- Dictionary selectfilterDict = new Dictionary();
- selectfilterDict.Add("userId", userId);
- selectfilterDict.Add("guildId", guildId);
-
- DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict);
-
- if (Convert.ToInt32(dt.Rows.Count) != 0)
- return Convert.ToInt32(dt.Rows[0]["points"]);
- else
- {
- Dictionary dict = new Dictionary();
- dict.Add("userId", userId);
- dict.Add("guildId", guildId);
- dict.Add("points", 0);
-
- Controller.InsertQuery(Table, dict);
- }
+ Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
+ if (userPoints != null)
+ return userPoints.points;
+
+ Points emptyUserPoints = new Points(userId, guildId, 0);
+ Points.Query().Insert(emptyUserPoints);
return 0;
}
public static int Count(string userId, string guildId)
{
- Dictionary selectfilterDict = new Dictionary();
- selectfilterDict.Add("userId", userId);
- selectfilterDict.Add("guildId", guildId);
-
- DataTable dt = Controller.SelectQuery(Table, "COUNT(*)", selectfilterDict);
-
- return Convert.ToInt32(dt.Rows[0]["COUNT(*)"]);
+ return Points.Query().Where("userId", userId).Where("guildId", guildId).Count();
}
public static int Add(string userId, int points, string guildId)
{
- Dictionary selectfilterDict = new Dictionary();
- selectfilterDict.Add("userId", userId);
- selectfilterDict.Add("guildId", guildId);
- DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict);
- if (Convert.ToInt32(dt.Rows.Count) != 0)
+ Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
+ if (userPoints != null)
{
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
- filterDict.Add("guildId", guildId);
-
- Dictionary updateDict = new Dictionary();
- updateDict.Add("points", Convert.ToInt32(dt.Rows[0]["points"]) + points);
- Controller.UpdateQuery(Table, updateDict, filterDict);
- return Convert.ToInt32(dt.Rows[0]["points"]) + points;
+ Points.Query().Where("userId", userId).Where("guildId", guildId).Set("points", userPoints.points + points).Update();
+ return userPoints.points + points;
}
- else
- {
- Dictionary dict = new Dictionary();
- dict.Add("userId", userId);
- dict.Add("guildId", guildId);
- dict.Add("points", points);
+
+ Points newUserPoints = new Points(userId, guildId, points);
- Controller.InsertQuery(Table, dict);
- return points;
- }
+ Points.Query().Insert(newUserPoints);
+ return points;
}
public static int Remove(string userId, int points, string guildId)
{
- Dictionary selectfilterDict = new Dictionary();
- selectfilterDict.Add("userId", userId);
- selectfilterDict.Add("guildId", guildId);
- DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict);
-
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
- filterDict.Add("guildId", guildId);
-
- Dictionary updateDict = new Dictionary();
- updateDict.Add("points", Convert.ToInt32(dt.Rows[0]["points"]) - points);
- Controller.UpdateQuery(Table, updateDict, filterDict);
- return Convert.ToInt32(dt.Rows[0]["points"]) - points;
+ Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
+ Points.Query().Where("userId", userId).Where("guildId", guildId).Set("points", userPoints.points - points).Update();
+ return userPoints.points - points;
}
public static void Delete(int userId)
{
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
-
- Controller.DeleteQuery(Table, filterDict);
+ Points.Query().Where("userId", userId).Delete();
}
-
}
}
diff --git a/ChaosBot/Database/Repository/RaffleRepository.cs b/ChaosBot/Database/Repository/RaffleRepository.cs
index 5cc87f1..bae7c01 100644
--- a/ChaosBot/Database/Repository/RaffleRepository.cs
+++ b/ChaosBot/Database/Repository/RaffleRepository.cs
@@ -17,17 +17,7 @@ namespace ChaosBot.Database.Repository
/// List of raffles
public static Raffle[] All()
{
- DataTable dataTable = Controller.SelectQuery(Table);
-
- List raffles = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int id = Convert.ToInt32((long) row["id"]);
- string userId = row["userId"].ToString();
- string guildId = row["guildId"].ToString();
-
- raffles.Add(new Raffle(id, userId, guildId));
- }
+ var raffles = Raffle.Query().All();
return raffles.ToArray();
}
@@ -38,21 +28,8 @@ namespace ChaosBot.Database.Repository
///
/// List of raffles
public static Raffle[] All(string guildId)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("guildId", guildId);
-
- DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
-
- List raffles = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int idFetch = Convert.ToInt32((long) row["id"]);
- string userIdFetch = row["userId"].ToString();
- string guildIdFetch = row["guildId"].ToString();
-
- raffles.Add(new Raffle(idFetch, userIdFetch, guildIdFetch));
- }
+ {
+ var raffles = Raffle.Query().Where("guildId", guildId).All();
return raffles.ToArray();
}
@@ -62,10 +39,8 @@ namespace ChaosBot.Database.Repository
///
/// Amount of raffles
public static int Count()
- {
- DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)");
-
- return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
+ {
+ return Raffle.Query().Count();
}
///
@@ -74,13 +49,8 @@ namespace ChaosBot.Database.Repository
///
/// Amount of raffles
public static int Count(string guildId)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("guildId", guildId);
-
- DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)", filterDict);
-
- return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
+ {
+ return Raffle.Query().Where("guildId", guildId).Count();
}
///
@@ -90,14 +60,8 @@ namespace ChaosBot.Database.Repository
///
/// Amount of raffles
public static int Count(string userId, string guildId)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
- filterDict.Add("guildId", guildId);
-
- DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)", filterDict);
-
- return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
+ {
+ return Raffle.Query().Where("userId", userId).Where("guildId", guildId).Count();
}
///
@@ -106,22 +70,9 @@ namespace ChaosBot.Database.Repository
///
/// List of raffles
public static Raffle[] SelectUser(string userId)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
+ {
+ List raffles = Raffle.Query().Where("userId", userId).Get();
- DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
-
- List raffles = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int id = Convert.ToInt32((long) row["id"]);
- string userIdFetch = row["userId"].ToString();
- string guildIdFetch = row["guildId"].ToString();
-
- raffles.Add(new Raffle(id, userIdFetch, guildIdFetch));
- }
-
return raffles.ToArray();
}
@@ -132,22 +83,8 @@ namespace ChaosBot.Database.Repository
///
/// List of raffles
public static Raffle[] SelectUser(string userId, string guildId)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("userId", userId);
- filterDict.Add("guildId", guildId);
-
- DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
-
- List raffles = new List();
- foreach (DataRow row in dataTable.Rows)
- {
- int id = Convert.ToInt32((long) row["id"]);
- string userIdFetch = row["userId"].ToString();
- string guildIdFetch = row["guildId"].ToString();
-
- raffles.Add(new Raffle(id, userIdFetch, guildIdFetch));
- }
+ {
+ List raffles = Raffle.Query().Where("userId", userId).Where("guildId", guildId).Get();
return raffles.ToArray();
}
@@ -158,12 +95,7 @@ namespace ChaosBot.Database.Repository
///
public static void Insert(Raffle raffle)
{
- Dictionary dict = new Dictionary();
-
- dict.Add("userId", raffle.userId);
- dict.Add("guildId", raffle.guildId);
-
- Controller.InsertQuery(Table, dict);
+ Raffle.Query().Insert(raffle);
}
///
@@ -174,12 +106,7 @@ namespace ChaosBot.Database.Repository
{
foreach (var raf in raffles)
{
- Dictionary dict = new Dictionary();
-
- dict.Add("userId", raf.userId);
- dict.Add("guildId", raf.guildId);
-
- Controller.InsertQuery(Table, dict);
+ Raffle.Query().Insert(raf);
}
}
@@ -190,17 +117,7 @@ namespace ChaosBot.Database.Repository
/// Random raffle
public static Raffle PickRandom(string guildId)
{
- Dictionary filterDict = new Dictionary();
- filterDict.Add("guildId", guildId);
-
- DataTable dataTable = Controller.SelectQuery(Table, "*", filterDict, "RANDOM()");
-
- if (dataTable.Rows.Count == 0) return null;
- DataRow row = dataTable.Rows[0];
- int idFetch = Convert.ToInt32((long)row["id"]);
- string userIdFetch = row["userId"].ToString();
- string guildIdFetch = row["guildId"].ToString();
- return new Raffle(idFetch, userIdFetch, guildIdFetch);
+ return Raffle.Query().Where("guildId", guildId).OrderBy("RANDOM()").First();
}
///
@@ -209,11 +126,7 @@ namespace ChaosBot.Database.Repository
///
public static void ClearRaffle(string guildId)
{
- Dictionary filterDict = new Dictionary();
-
- filterDict.Add("guildId", guildId);
-
- Controller.DeleteQuery(Table, filterDict);
+ Raffle.Query().Where("guildId", guildId).Delete();
}
///
@@ -221,11 +134,8 @@ namespace ChaosBot.Database.Repository
///
///
public static void Delete(int id)
- {
- Dictionary filterDict = new Dictionary();
- filterDict.Add("id", id);
-
- Controller.DeleteQuery(Table, filterDict);
+ {
+ Raffle.Query().Where("id", id).Delete();
}
}
}
\ No newline at end of file
diff --git a/ChaosBot/Discord/Modules/PointsCommands.cs b/ChaosBot/Discord/Modules/PointsCommands.cs
index 6c5beb7..b67c733 100644
--- a/ChaosBot/Discord/Modules/PointsCommands.cs
+++ b/ChaosBot/Discord/Modules/PointsCommands.cs
@@ -97,20 +97,15 @@ namespace ChaosBot.Discord.Modules
public async Task DeletePoints(string userMention)
{
ulong userId = Convert.ToUInt64(userMention.Substring(3, userMention.Length - 4));
- Dictionary filterColumns = new Dictionary
- {
- { "userId", userId },
- { "guildId", Context.Guild.Id }
- };
int matches = PointsRepository.Count(userId.ToString(), Context.Guild.Id.ToString());
if (matches > 0)
{
- Controller.DeleteQuery("PointsTable", filterColumns);
+ Points.Query().Where("userId", userId).Where("guildId", Context.Guild.Id).Delete();
- string message = $"{Context.User.Mention} has removed <@{userId}> from the database.";
- await ReplyAsync(message, false);
- _logger.Info($"PointsCommands.DeletePoints: {message}");
+ string message = $"{Context.User.Mention} has removed <@{userId}> from the database.";
+ await ReplyAsync(message, false);
+ _logger.Info($"PointsCommands.DeletePoints: {message}");
}
else
{
diff --git a/ChaosBot/Program.cs b/ChaosBot/Program.cs
index 3ec4c58..9338aec 100644
--- a/ChaosBot/Program.cs
+++ b/ChaosBot/Program.cs
@@ -36,7 +36,6 @@ namespace ChaosBot
*/
_logger = Logging.GenLog();
-
/*
* Attempt to load our custom assemblies
*/
@@ -46,7 +45,7 @@ namespace ChaosBot
* Initialize the Discord Client and Login
*/
_logger.Info($"Starting Up {ConfigurationRepository.GetValue("Bot:Name")} v{ConfigurationRepository.GetValue("Bot:Version")}");
-
+
var discordBot = DiscordConnect.StartUp();
WebServer.WebServer.Start(new string[]{});
await discordBot;