First version of new database system

This commit is contained in:
Daniel_I_Am 2020-06-08 20:21:14 +02:00
parent a06c6d5e91
commit 155c9b4e77
No known key found for this signature in database
GPG Key ID: 80C428FCC9743E84
15 changed files with 674 additions and 564 deletions

View File

@ -74,7 +74,7 @@ namespace ChaosBot.Attribute
{ {
string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}")); string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}"));
string query = $"CREATE TABLE {table} ({columnDefs})"; string query = $"CREATE TABLE {table} ({columnDefs})";
Controller.RawQuery(query, false); Controller.RawQuery(query, readOutput: false);
} }
else else
{ {
@ -84,7 +84,7 @@ namespace ChaosBot.Attribute
{ {
string query = string query =
$"ALTER TABLE {table} ADD COLUMN {column.Item1} {column.Item2} {column.Item4}"; $"ALTER TABLE {table} ADD COLUMN {column.Item1} {column.Item2} {column.Item4}";
Controller.RawQuery(query, false, true); Controller.RawQuery(query, readOutput: false, throwError: true);
} }
catch catch
{ {

View File

@ -26,7 +26,7 @@ namespace ChaosBot.Database
/// <param name="readOutput">Whether to read the output and return it as a <c>DataFrame</c></param> /// <param name="readOutput">Whether to read the output and return it as a <c>DataFrame</c></param>
/// <param name="throwError">Whether to throw any exceptions or to log and shrug.</param> /// <param name="throwError">Whether to throw any exceptions or to log and shrug.</param>
/// <returns></returns> /// <returns></returns>
public static DataTable RawQuery(string query, bool readOutput = true, bool throwError = false) public static DataTable RawQuery(string query, Dictionary<string, object> parameters = null, bool readOutput = true, bool throwError = false)
{ {
DataTable dt = new DataTable(); DataTable dt = new DataTable();
@ -41,10 +41,23 @@ namespace ChaosBot.Database
SqliteCommand cmd = _conn.CreateCommand(); SqliteCommand cmd = _conn.CreateCommand();
cmd.CommandText = query; 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) if (readOutput)
{ {
// output needs to be read, make a reader and fill the datatable with the data // 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); dt.Load(executeReader);
} }
else else
@ -71,321 +84,5 @@ namespace ChaosBot.Database
return dt; return dt;
} }
/// <summary>
/// Insert a list of parameters into a table in the database
/// </summary>
/// <code>
/// string table = "SomeTable";
/// Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;
/// {
/// { "someInt", 123 },
/// { "someString", "asdf" },
/// { "someChar", 'x' }
/// }
///
/// Controller.InsertQuery(table, parameters);
/// </code>
/// <param name="table">Table to insert into</param>
/// <param name="parameters">List of parameters to insert to the row. Every type is a key</param>
public static void InsertQuery(string table, Dictionary<string, object> 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}]>.");
}
}
/// <summary>
/// Update rows in the database
/// </summary>
/// <code>
/// string table = "SomeTable";
/// Dictionary&lt;string, object&gt; values = new Dictionary&lt;string, object&gt;
/// {
/// {"key", "newValue"}
/// };
/// Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;
/// {
/// {"key", "oldValue"}
/// };
/// Controller.UpdateQuery(table, values, parameters);
/// </code>
/// <param name="table">Table to update data in</param>
/// <param name="values">List of keys to set. Equivalent of SQL: SET {key} = {value}</param>
/// <param name="parameters">List of filters to apply in the SQL WHERE condition</param>
public static void UpdateQuery(string table, Dictionary<string, object> values, Dictionary<string, object> 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<string> updateList = new List<string>();
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<string> filterList = new List<string>();
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<SqliteCommand> 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<string, object> 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<string> filterList = new List<string>();
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<string, object> 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<string> filterList = new List<string>();
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}]>.");
}
}
} }
} }

View File

@ -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<T> Query<T>() where T : BaseEntity, new()
{
var dbEntityAttribute = typeof(T).GetCustomAttributes(
typeof(DBEntity),
true
).FirstOrDefault() as DBEntity;
if (dbEntityAttribute != null)
{
return new QueryBuilder<T>(dbEntityAttribute.Table);
}
throw new SystemException($"Class {typeof(T)} does not have an attribute of {typeof(DBEntity)} set");
}
}
}

View File

@ -1,19 +1,22 @@
using System.Data;
using ChaosBot.Attribute; using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity namespace ChaosBot.Database.Entity
{ {
[DBEntity("PointsTable")] [DBEntity("PointsTable")]
public class Points public class Points : BaseEntity
{ {
[DBPrimaryKey] [DBPrimaryKey]
[DBAutoIncrement] [DBAutoIncrement]
[DBNotNull] [DBNotNull]
[DBUnique] [DBUnique]
public int id { get; } public int id { get; private set; }
public int points { get; private set; } public int points { get; private set; }
public string userId { get; private set; } public string userId { get; private set; }
public string guildId { get; private set; } public string guildId { get; private set; }
public Points() {}
public Points(int id, string userId, string guildId, int points) public Points(int id, string userId, string guildId, int points)
{ {
this.id = id; this.id = id;
@ -28,5 +31,18 @@ namespace ChaosBot.Database.Entity
this.userId = userId; this.userId = userId;
this.guildId = guildId; this.guildId = guildId;
} }
public static QueryBuilder<Points> Query()
{
return BaseEntity.Query<Points>();
}
public override void SetFromRow(DataRow row)
{
id = (int)row["id"];
userId = (string)row["userId"];
guildId = (string)row["guildId"];
points = (int)row["points"];
}
} }
} }

View File

@ -1,18 +1,21 @@
using System.Data;
using ChaosBot.Attribute; using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity namespace ChaosBot.Database.Entity
{ {
[DBEntity("RaffleTable")] [DBEntity("RaffleTable")]
public class Raffle public class Raffle : BaseEntity
{ {
[DBPrimaryKey] [DBPrimaryKey]
[DBAutoIncrement] [DBAutoIncrement]
[DBNotNull] [DBNotNull]
[DBUnique] [DBUnique]
public int id { get; } public int id { get; private set; }
public string userId { get; private set; } public string userId { get; private set; }
public string guildId { get; private set; } public string guildId { get; private set; }
public Raffle() {}
public Raffle(int id, string userId, string guildId) public Raffle(int id, string userId, string guildId)
{ {
this.id = id; this.id = id;
@ -25,5 +28,17 @@ namespace ChaosBot.Database.Entity
this.userId = userId; this.userId = userId;
this.guildId = guildId; this.guildId = guildId;
} }
public static QueryBuilder<Raffle> Query()
{
return BaseEntity.Query<Raffle>();
}
public override void SetFromRow(DataRow row)
{
id = (int)row["id"];
userId = (string)row["userid"];
guildId = (string) row["guildid"];
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Data;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@ -8,13 +9,15 @@ using ChaosBot.Attribute;
namespace ChaosBot.Database.Entity namespace ChaosBot.Database.Entity
{ {
[DBEntity("ServerConfigurationFlags")] [DBEntity("ServerConfigurationFlags")]
public class ServerConfigurationFlag<T> public class ServerConfigurationFlag<T> : 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) public ServerConfigurationFlag(string key, T value, ulong guildId)
{ {
@ -22,6 +25,29 @@ namespace ChaosBot.Database.Entity
this.key = key; this.key = key;
this.guildId = Convert.ToInt64(guildId); 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<ServerConfigurationFlag<T>> Query()
{
return BaseEntity.Query<ServerConfigurationFlag<T>>();
}
public override void SetFromRow(DataRow row)
{
key = (string)row["key"];
serializedValue = (string)row["serializedValue"];
guildId = (long)row["guildId"];
}
public T GetValue() public T GetValue()
{ {

View File

@ -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<TestEntity> Query()
{
return BaseEntity.Query<TestEntity>();
}
public override void SetFromRow(DataRow row)
{
id = (long)row["id"];
}
}
}

View File

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

View File

@ -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<T> where T : BaseEntity, new()
{
private string _table;
private bool _distinct;
private Dictionary<string, FilterValue> _whereConditions;
private Dictionary<string, object> _setList;
private List<string> _orderKeys;
private List<string> _groupByList;
private int _limit;
private int _offset;
public QueryBuilder(string table)
{
_table = table;
_distinct = false;
_whereConditions = new Dictionary<string, FilterValue>();
_setList = new Dictionary<string, object>();
_orderKeys = new List<string>();
_groupByList = new List<string>();
_limit = -1;
_offset = -1;
}
/*
* Fetch all records from a database
*/
public List<T> All()
{
QueryBuilderRaw query = new QueryBuilderRaw();
DataTable dt = query
.Select()
.Append("*")
.FromTable(_table)
.Run();
List<T> returnList = new List<T>();
foreach (DataRow row in dt.Rows)
{
T newObject = new T();
newObject.SetFromRow(row);
returnList.Add(newObject);
}
return returnList;
}
/*
* Set a where condition
*/
public QueryBuilder<T> Where(string key, object value, string comparison = null)
{
_whereConditions.Add(key, new FilterValue(value, comparison));
return this;
}
/*
* Set distinct
*/
public QueryBuilder<T> Distinct()
{
_distinct = true;
return this;
}
/*
* Set SET field
*/
public QueryBuilder<T> Set(string key, object value)
{
_setList.Add(key, value);
return this;
}
/*
* Set an order key
*/
public QueryBuilder<T> OrderBy(string key)
{
_orderKeys.Add(key);
return this;
}
/*
* Set a groupBy key
*/
public QueryBuilder<T> GroupBy(string key)
{
_groupByList.Add(key);
return this;
}
/*
* Limit amount of responses
*/
public QueryBuilder<T> Limit(int amount)
{
_limit = amount;
return this;
}
public QueryBuilder<T> Offset(int amount)
{
_offset = amount;
return this;
}
public QueryBuilder<T> 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<T> Get()
{
List<T> returnList = new List<T>();
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<T> list = Get();
if (list.Count > 0)
return list[0];
return null;
}
public void Insert(T obj)
{
Dictionary<string, object> objectKeysAndValues = GetObjectKeysAndValues(obj);
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Insert()
.IntoTable(_table)
.Columns(new List<string>(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<string, object> GetObjectKeysAndValues(T obj)
{
var returnValue = new Dictionary<string, object>();
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;
}
}
}

View File

@ -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<string, object> _parameters;
private int keyIndex = 0;
public QueryBuilderRaw()
{
_query = new StringBuilder();
_parameters = new Dictionary<string, object>();
}
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<string> columnList)
{
Append("(");
Append(String.Join(", ", columnList));
Append(")");
return this;
}
public QueryBuilderRaw Values(Dictionary<string, object> keyValueList)
{
Append("VALUES (");
List<string> parameterKeys = new List<string>();
foreach (KeyValuePair<string, object> pair in keyValueList)
{
string parameterName = AddParameterAndReturnKey(pair.Key, pair.Value);
parameterKeys.Add(parameterName);
}
Append(string.Join(", ", parameterKeys));
Append(")");
return this;
}
public QueryBuilderRaw Set(Dictionary<string, object> keyValueList)
{
Append("SET");
List<string> parameterKeys = new List<string>();
foreach (KeyValuePair<string, object> 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<string, FilterValue> 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<string> groupByList)
{
Append("GROUP BY");
return Append(string.Join(", ", groupByList));
}
public QueryBuilderRaw OrderBy(List<string> 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++}";
}
}
}

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using ChaosBot.Database.Entity; using ChaosBot.Database.Entity;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using NLog;
namespace ChaosBot.Database.Repository namespace ChaosBot.Database.Repository
{ {
@ -43,13 +42,13 @@ namespace ChaosBot.Database.Repository
public static string GetValueRaw(string configurationFlag, long guildId) public static string GetValueRaw(string configurationFlag, long guildId)
{ {
Dictionary<string, object> filterColumns = new Dictionary<string, object>(); Dictionary<string, FilterValue> filterColumns = new Dictionary<string, FilterValue>();
filterColumns.Add("key", configurationFlag); filterColumns.Add("key", new FilterValue(configurationFlag));
filterColumns.Add("guildId", guildId); filterColumns.Add("guildId", new FilterValue(guildId));
DataTable valueTable = Controller.SelectQuery(ServersTable, filterColumns: filterColumns); ServerConfigurationFlag<string> serverConfigurationFlag = ServerConfigurationFlag<string>.Query().Where("key", configurationFlag).Where("guildId", guildId).First();
if (valueTable.Rows.Count == 1) if (serverConfigurationFlag != null)
{ {
return valueTable.Rows[0]["serializedValue"].ToString(); return serverConfigurationFlag.serializedValue;
} }
return null; return null;
@ -81,23 +80,22 @@ namespace ChaosBot.Database.Repository
{ {
try try
{ {
Dictionary<string, object> filterColumns = new Dictionary<string, object>(); int matchCount = ServerConfigurationFlag<string>.Query().Where("key", configurationFlag).Where("guildId", guildId).Count();
filterColumns.Add("key", configurationFlag); if (matchCount > 0)
filterColumns.Add("guildId", guildId);
Dictionary<string, object> newValue = new Dictionary<string, object>();
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)
{ {
Controller.UpdateQuery(ServersTable, newValue, filterColumns); ServerConfigurationFlag<string>.Query()
.Where("key", configurationFlag)
.Where("guildId", guildId)
.Set("key", configurationFlag)
.Set("guildId", guildId)
.Set("serializedValue", serializedValue)
.Update();
return; return;
} }
Controller.InsertQuery(ServersTable, newValue); ServerConfigurationFlag<string> newValue = new ServerConfigurationFlag<string>(configurationFlag, guildId);
newValue.serializedValue = serializedValue;
ServerConfigurationFlag<string>.Query().Insert(newValue);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -1,10 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Drawing;
using System.Linq;
using ChaosBot.Database.Entity; using ChaosBot.Database.Entity;
using Microsoft.Data.Sqlite;
namespace ChaosBot.Database.Repository namespace ChaosBot.Database.Repository
{ {
@ -14,136 +11,66 @@ namespace ChaosBot.Database.Repository
public static Points[] All() public static Points[] All()
{ {
DataTable dataTable = Controller.SelectQuery(Table); List<Points> pointsList = Points.Query().All();
List<Points> pointslist = new List<Points>(); return pointsList.ToArray();
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();
} }
public static Points[] All(string guildId) public static Points[] All(string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); List<Points> pointsList = Points.Query().Where("guildId", guildId).All();
filterDict.Add("guildId", guildId);
DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict); return pointsList.ToArray();
List<Points> pointslist = new List<Points>();
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();
} }
public static int Total(string userId, string guildId) public static int Total(string userId, string guildId)
{ {
Dictionary<string, object> selectfilterDict = new Dictionary<string, object>(); Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
selectfilterDict.Add("userId", userId);
selectfilterDict.Add("guildId", guildId);
DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict); if (userPoints != null)
return userPoints.points;
if (Convert.ToInt32(dt.Rows.Count) != 0)
return Convert.ToInt32(dt.Rows[0]["points"]);
else
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("userId", userId);
dict.Add("guildId", guildId);
dict.Add("points", 0);
Controller.InsertQuery(Table, dict);
}
Points emptyUserPoints = new Points(userId, guildId, 0);
Points.Query().Insert(emptyUserPoints);
return 0; return 0;
} }
public static int Count(string userId, string guildId) public static int Count(string userId, string guildId)
{ {
Dictionary<string, object> selectfilterDict = new Dictionary<string, object>(); return Points.Query().Where("userId", userId).Where("guildId", guildId).Count();
selectfilterDict.Add("userId", userId);
selectfilterDict.Add("guildId", guildId);
DataTable dt = Controller.SelectQuery(Table, "COUNT(*)", selectfilterDict);
return Convert.ToInt32(dt.Rows[0]["COUNT(*)"]);
} }
public static int Add(string userId, int points, string guildId) public static int Add(string userId, int points, string guildId)
{ {
Dictionary<string, object> selectfilterDict = new Dictionary<string, object>(); Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
selectfilterDict.Add("userId", userId); if (userPoints != null)
selectfilterDict.Add("guildId", guildId);
DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict);
if (Convert.ToInt32(dt.Rows.Count) != 0)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); Points.Query().Where("userId", userId).Where("guildId", guildId).Set("points", userPoints.points + points).Update();
filterDict.Add("userId", userId); return userPoints.points + points;
filterDict.Add("guildId", guildId);
Dictionary<string, object> updateDict = new Dictionary<string, object>();
updateDict.Add("points", Convert.ToInt32(dt.Rows[0]["points"]) + points);
Controller.UpdateQuery(Table, updateDict, filterDict);
return Convert.ToInt32(dt.Rows[0]["points"]) + points;
} }
else
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("userId", userId);
dict.Add("guildId", guildId);
dict.Add("points", points);
Controller.InsertQuery(Table, dict); Points newUserPoints = new Points(userId, guildId, points);
return points;
} Points.Query().Insert(newUserPoints);
return points;
} }
public static int Remove(string userId, int points, string guildId) public static int Remove(string userId, int points, string guildId)
{ {
Dictionary<string, object> selectfilterDict = new Dictionary<string, object>(); Points userPoints = Points.Query().Where("userId", userId).Where("guildId", guildId).First();
selectfilterDict.Add("userId", userId);
selectfilterDict.Add("guildId", guildId);
DataTable dt = Controller.SelectQuery(Table, "points", selectfilterDict);
Dictionary<string, object> filterDict = new Dictionary<string, object>();
filterDict.Add("userId", userId);
filterDict.Add("guildId", guildId);
Dictionary<string, object> updateDict = new Dictionary<string, object>();
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;
} }
public static void Delete(int userId) public static void Delete(int userId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); Points.Query().Where("userId", userId).Delete();
filterDict.Add("userId", userId);
Controller.DeleteQuery(Table, filterDict);
} }
} }
} }

View File

@ -17,17 +17,7 @@ namespace ChaosBot.Database.Repository
/// <returns>List of raffles</returns> /// <returns>List of raffles</returns>
public static Raffle[] All() public static Raffle[] All()
{ {
DataTable dataTable = Controller.SelectQuery(Table); var raffles = Raffle.Query().All();
List<Raffle> raffles = new List<Raffle>();
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));
}
return raffles.ToArray(); return raffles.ToArray();
} }
@ -39,20 +29,7 @@ namespace ChaosBot.Database.Repository
/// <returns>List of raffles</returns> /// <returns>List of raffles</returns>
public static Raffle[] All(string guildId) public static Raffle[] All(string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); var raffles = Raffle.Query().Where("guildId", guildId).All();
filterDict.Add("guildId", guildId);
DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
List<Raffle> raffles = new List<Raffle>();
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));
}
return raffles.ToArray(); return raffles.ToArray();
} }
@ -63,9 +40,7 @@ namespace ChaosBot.Database.Repository
/// <returns>Amount of raffles</returns> /// <returns>Amount of raffles</returns>
public static int Count() public static int Count()
{ {
DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)"); return Raffle.Query().Count();
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary> /// <summary>
@ -75,12 +50,7 @@ namespace ChaosBot.Database.Repository
/// <returns>Amount of raffles</returns> /// <returns>Amount of raffles</returns>
public static int Count(string guildId) public static int Count(string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); return Raffle.Query().Where("guildId", guildId).Count();
filterDict.Add("guildId", guildId);
DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)", filterDict);
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary> /// <summary>
@ -91,13 +61,7 @@ namespace ChaosBot.Database.Repository
/// <returns>Amount of raffles</returns> /// <returns>Amount of raffles</returns>
public static int Count(string userId, string guildId) public static int Count(string userId, string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); return Raffle.Query().Where("userId", userId).Where("guildId", guildId).Count();
filterDict.Add("userId", userId);
filterDict.Add("guildId", guildId);
DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)", filterDict);
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary> /// <summary>
@ -107,20 +71,7 @@ namespace ChaosBot.Database.Repository
/// <returns>List of raffles</returns> /// <returns>List of raffles</returns>
public static Raffle[] SelectUser(string userId) public static Raffle[] SelectUser(string userId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); List<Raffle> raffles = Raffle.Query().Where("userId", userId).Get();
filterDict.Add("userId", userId);
DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
List<Raffle> raffles = new List<Raffle>();
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(); return raffles.ToArray();
} }
@ -133,21 +84,7 @@ namespace ChaosBot.Database.Repository
/// <returns>List of raffles</returns> /// <returns>List of raffles</returns>
public static Raffle[] SelectUser(string userId, string guildId) public static Raffle[] SelectUser(string userId, string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); List<Raffle> raffles = Raffle.Query().Where("userId", userId).Where("guildId", guildId).Get();
filterDict.Add("userId", userId);
filterDict.Add("guildId", guildId);
DataTable dataTable = Controller.SelectQuery(Table, filterColumns: filterDict);
List<Raffle> raffles = new List<Raffle>();
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(); return raffles.ToArray();
} }
@ -158,12 +95,7 @@ namespace ChaosBot.Database.Repository
/// <param name="raffle"></param> /// <param name="raffle"></param>
public static void Insert(Raffle raffle) public static void Insert(Raffle raffle)
{ {
Dictionary<string, object> dict = new Dictionary<string, object>(); Raffle.Query().Insert(raffle);
dict.Add("userId", raffle.userId);
dict.Add("guildId", raffle.guildId);
Controller.InsertQuery(Table, dict);
} }
/// <summary> /// <summary>
@ -174,12 +106,7 @@ namespace ChaosBot.Database.Repository
{ {
foreach (var raf in raffles) foreach (var raf in raffles)
{ {
Dictionary<string, object> dict = new Dictionary<string, object>(); Raffle.Query().Insert(raf);
dict.Add("userId", raf.userId);
dict.Add("guildId", raf.guildId);
Controller.InsertQuery(Table, dict);
} }
} }
@ -190,17 +117,7 @@ namespace ChaosBot.Database.Repository
/// <returns>Random raffle</returns> /// <returns>Random raffle</returns>
public static Raffle PickRandom(string guildId) public static Raffle PickRandom(string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); return Raffle.Query().Where("guildId", guildId).OrderBy("RANDOM()").First();
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);
} }
/// <summary> /// <summary>
@ -209,11 +126,7 @@ namespace ChaosBot.Database.Repository
/// <param name="guildId"></param> /// <param name="guildId"></param>
public static void ClearRaffle(string guildId) public static void ClearRaffle(string guildId)
{ {
Dictionary<string,object> filterDict = new Dictionary<string, object>(); Raffle.Query().Where("guildId", guildId).Delete();
filterDict.Add("guildId", guildId);
Controller.DeleteQuery(Table, filterDict);
} }
/// <summary> /// <summary>
@ -222,10 +135,7 @@ namespace ChaosBot.Database.Repository
/// <param name="id"></param> /// <param name="id"></param>
public static void Delete(int id) public static void Delete(int id)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); Raffle.Query().Where("id", id).Delete();
filterDict.Add("id", id);
Controller.DeleteQuery(Table, filterDict);
} }
} }
} }

View File

@ -97,20 +97,15 @@ namespace ChaosBot.Discord.Modules
public async Task DeletePoints(string userMention) public async Task DeletePoints(string userMention)
{ {
ulong userId = Convert.ToUInt64(userMention.Substring(3, userMention.Length - 4)); ulong userId = Convert.ToUInt64(userMention.Substring(3, userMention.Length - 4));
Dictionary<string, object> filterColumns = new Dictionary<string, object>
{
{ "userId", userId },
{ "guildId", Context.Guild.Id }
};
int matches = PointsRepository.Count(userId.ToString(), Context.Guild.Id.ToString()); int matches = PointsRepository.Count(userId.ToString(), Context.Guild.Id.ToString());
if (matches > 0) 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."; string message = $"{Context.User.Mention} has removed <@{userId}> from the database.";
await ReplyAsync(message, false); await ReplyAsync(message, false);
_logger.Info($"PointsCommands.DeletePoints: {message}"); _logger.Info($"PointsCommands.DeletePoints: {message}");
} }
else else
{ {

View File

@ -36,7 +36,6 @@ namespace ChaosBot
*/ */
_logger = Logging.GenLog(); _logger = Logging.GenLog();
/* /*
* Attempt to load our custom assemblies * Attempt to load our custom assemblies
*/ */