Merge branch 'cleanup'

This commit is contained in:
Daniel_I_Am 2020-06-06 02:53:07 +02:00
commit f5488995f5
No known key found for this signature in database
GPG Key ID: 80C428FCC9743E84
2 changed files with 139 additions and 4 deletions

View File

@ -14,6 +14,17 @@ namespace ChaosBot.Database
static SqliteConnection _conn = new SqliteConnection($"Data Source={System.IO.Directory.GetCurrentDirectory()}/{Program.Cfg.GetValue<string>("Bot:Database")}"); static SqliteConnection _conn = new SqliteConnection($"Data Source={System.IO.Directory.GetCurrentDirectory()}/{Program.Cfg.GetValue<string>("Bot:Database")}");
private static Logger _logger = Program._logger; private static Logger _logger = Program._logger;
/// <summary>
/// Run a raw query on the database
/// </summary>
/// <code>
/// string query = "TRUNCATE SomeTable";
/// Controller.RawQuery(query);
/// </code>
/// <param name="query">Raw query to execute</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>
/// <returns></returns>
public static DataTable RawQuery(string query, bool readOutput = true, bool throwError = false) public static DataTable RawQuery(string query, bool readOutput = true, bool throwError = false)
{ {
DataTable dt = new DataTable(); DataTable dt = new DataTable();
@ -22,21 +33,26 @@ namespace ChaosBot.Database
{ {
using (_conn) using (_conn)
{ {
// Open the SQLite connection
_conn.Open(); _conn.Open();
// Start creating the command and assign the query given
SqliteCommand cmd = _conn.CreateCommand(); SqliteCommand cmd = _conn.CreateCommand();
cmd.CommandText = query; cmd.CommandText = query;
if (readOutput) 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(CommandBehavior.SingleResult);
dt.Load(executeReader); dt.Load(executeReader);
} }
else else
{ {
// output does not need to be read, just run the query without reading
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
// Clean up after ourselves
_conn.Close(); _conn.Close();
} }
} }
@ -44,24 +60,47 @@ namespace ChaosBot.Database
{ {
if (throwError) if (throwError)
{ {
// If we throw any exception, just throw it so other code can handle it
throw; throw;
} }
// We handle the exception, log it and be done
_logger.Fatal($"Database.Controller.RawQuery: Exception [{ex}] thrown, <[{ex.Message}]>."); _logger.Fatal($"Database.Controller.RawQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
} }
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) public static void InsertQuery(string table, Dictionary<string, object> parameters)
{ {
try try
{ {
using (_conn) using (_conn)
{ {
// Open the SQLite connection
_conn.Open(); _conn.Open();
// Start the command creation
SqliteCommand cmd = _conn.CreateCommand(); SqliteCommand cmd = _conn.CreateCommand();
// Build the command bit by bit
// INSERT INTO {table} (key1, key2, key3) VALUES (@key1,@key2,@key3)
StringBuilder commandText = new StringBuilder(); StringBuilder commandText = new StringBuilder();
commandText.Append("INSERT INTO "); commandText.Append("INSERT INTO ");
commandText.Append(table); commandText.Append(table);
@ -77,20 +116,27 @@ namespace ChaosBot.Database
foreach (string key in parameters.Keys) foreach (string key in parameters.Keys)
{ {
// We use @key to indicate the parameter placeholder
commandText.Append($"@{key},"); commandText.Append($"@{key},");
} }
// Remove the trailing comma
commandText.Remove(commandText.Length - 1, 1); commandText.Remove(commandText.Length - 1, 1);
commandText.Append(")"); commandText.Append(")");
// Assign onto QueryCommand
cmd.CommandText = commandText.ToString(); cmd.CommandText = commandText.ToString();
// Replace all the parameters to the query
foreach (string key in parameters.Keys) foreach (string key in parameters.Keys)
{ {
cmd.Parameters.AddWithValue($"@{key}", parameters.GetValueOrDefault(key)); cmd.Parameters.AddWithValue($"@{key}", parameters.GetValueOrDefault(key));
} }
// Prepare the parameters
cmd.Prepare(); cmd.Prepare();
// Execute, do not return anything
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
_conn.Close(); _conn.Close();
@ -102,20 +148,44 @@ namespace ChaosBot.Database
} }
} }
/// <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) public static void UpdateQuery(string table, Dictionary<string, object> values, Dictionary<string, object> parameters)
{ {
try try
{ {
using (_conn) using (_conn)
{ {
// Open SQLite connection
_conn.Open(); _conn.Open();
// Create the command
SqliteCommand cmd = _conn.CreateCommand(); SqliteCommand cmd = _conn.CreateCommand();
// Build the commandtext
// UPDATE {table} SET {key}=@val_{key} WHERE {key}=@fil_{key}
StringBuilder commandText = new StringBuilder(); StringBuilder commandText = new StringBuilder();
commandText.Append("UPDATE "); commandText.Append("UPDATE ");
commandText.Append(table); commandText.Append(table);
commandText.Append(" SET "); commandText.Append(" SET ");
// Build the list of values
List<string> updateList = new List<string>(); List<string> updateList = new List<string>();
foreach (string key in values.Keys) foreach (string key in values.Keys)
{ {
@ -123,8 +193,10 @@ namespace ChaosBot.Database
cmd.Parameters.AddWithValue($@"val_{key}", values.GetValueOrDefault(key)); cmd.Parameters.AddWithValue($@"val_{key}", values.GetValueOrDefault(key));
} }
// Append the list of values, comma-separated
commandText.Append(string.Join(", ", updateList)); commandText.Append(string.Join(", ", updateList));
// Build the list of filters
List<string> filterList = new List<string>(); List<string> filterList = new List<string>();
foreach (string key in parameters.Keys) foreach (string key in parameters.Keys)
{ {
@ -134,15 +206,22 @@ namespace ChaosBot.Database
if (filterList.Count > 0) if (filterList.Count > 0)
{ {
// Prepend with WHERE if there are parameters
commandText.Append("WHERE "); commandText.Append("WHERE ");
// Append the list of filters AND separated
commandText.Append(string.Join("AND ", filterList)); commandText.Append(string.Join("AND ", filterList));
} }
// Assign the command
cmd.CommandText = commandText.ToString(); cmd.CommandText = commandText.ToString();
Console.WriteLine(commandText.ToString());
// Prepare the parameters
cmd.Prepare(); cmd.Prepare();
// Execute, do not return
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
// Close connection
_conn.Close(); _conn.Close();
} }
} }

View File

@ -11,6 +11,10 @@ namespace ChaosBot.Database.Repository
{ {
private static readonly string Table = "RaffleTable"; private static readonly string Table = "RaffleTable";
/// <summary>
/// Fetch all <c>Raffle</c>s
/// </summary>
/// <returns>List of raffles</returns>
public static Raffle[] All() public static Raffle[] All()
{ {
DataTable dataTable = Controller.SelectQuery(Table); DataTable dataTable = Controller.SelectQuery(Table);
@ -28,6 +32,11 @@ namespace ChaosBot.Database.Repository
return raffles.ToArray(); return raffles.ToArray();
} }
/// <summary>
/// Fetch all <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="guildId"></param>
/// <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>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -48,6 +57,10 @@ namespace ChaosBot.Database.Repository
return raffles.ToArray(); return raffles.ToArray();
} }
/// <summary>
/// Count amount of <c>Raffle</c>s
/// </summary>
/// <returns>Amount of raffles</returns>
public static int Count() public static int Count()
{ {
DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)"); DataTable dataTable = Controller.SelectQuery(Table, "COUNT(*)");
@ -55,6 +68,11 @@ namespace ChaosBot.Database.Repository
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]); return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary>
/// Count amount of <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="guildId"></param>
/// <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>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -65,6 +83,12 @@ namespace ChaosBot.Database.Repository
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]); return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary>
/// Count amount of <c>Raffle</c>s filtered by guildId
/// </summary>
/// <param name="userId"></param>
/// <param name="guildId"></param>
/// <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>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -76,6 +100,11 @@ namespace ChaosBot.Database.Repository
return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]); return Convert.ToInt32(dataTable.Rows[0]["COUNT(*)"]);
} }
/// <summary>
/// Get all <c>Raffle</c>s from a user
/// </summary>
/// <param name="userId"></param>
/// <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>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -96,6 +125,12 @@ namespace ChaosBot.Database.Repository
return raffles.ToArray(); return raffles.ToArray();
} }
/// <summary>
/// Get all <c>Raffle</c>s from a user filtered by guild
/// </summary>
/// <param name="userId"></param>
/// <param name="guildId"></param>
/// <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>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -117,6 +152,10 @@ namespace ChaosBot.Database.Repository
return raffles.ToArray(); return raffles.ToArray();
} }
/// <summary>
/// Insert a <c>Raffle</c> into the database
/// </summary>
/// <param name="raffle"></param>
public static void Insert(Raffle raffle) public static void Insert(Raffle raffle)
{ {
Dictionary<string, object> dict = new Dictionary<string, object>(); Dictionary<string, object> dict = new Dictionary<string, object>();
@ -127,6 +166,10 @@ namespace ChaosBot.Database.Repository
Controller.InsertQuery(Table, dict); Controller.InsertQuery(Table, dict);
} }
/// <summary>
/// Insert a <c>List</c> of <c>Raffle</c>s into the database
/// </summary>
/// <param name="raffles"></param>
public static void MassInsert(List<Raffle> raffles) public static void MassInsert(List<Raffle> raffles)
{ {
foreach (var raf in raffles) foreach (var raf in raffles)
@ -140,6 +183,11 @@ namespace ChaosBot.Database.Repository
} }
} }
/// <summary>
/// Pick a random raffle from the database filtered to a guild
/// </summary>
/// <param name="guildId"></param>
/// <returns>Random raffle</returns>
public static Raffle PickRandom(string guildId) public static Raffle PickRandom(string guildId)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();
@ -155,6 +203,10 @@ namespace ChaosBot.Database.Repository
return new Raffle(idFetch, userIdFetch, guildIdFetch); return new Raffle(idFetch, userIdFetch, guildIdFetch);
} }
/// <summary>
/// Clear all <c>Raffle</c>s for a given guild
/// </summary>
/// <param name="guildId"></param>
public static void ClearRaffle(string guildId) public static void ClearRaffle(string guildId)
{ {
Dictionary<string,object> filterDict = new Dictionary<string, object>(); Dictionary<string,object> filterDict = new Dictionary<string, object>();
@ -164,6 +216,10 @@ namespace ChaosBot.Database.Repository
Controller.DeleteQuery(Table, filterDict); Controller.DeleteQuery(Table, filterDict);
} }
/// <summary>
/// Delete a <c>Raffle</c> by id
/// </summary>
/// <param name="id"></param>
public static void Delete(int id) public static void Delete(int id)
{ {
Dictionary<string, object> filterDict = new Dictionary<string, object>(); Dictionary<string, object> filterDict = new Dictionary<string, object>();