chaosbot/ChaosBot/Database/Controller.cs

200 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualBasic;
using NLog;
namespace ChaosBot.Database
{
public static class Controller
{
static SqliteConnection _conn = new SqliteConnection($"Data Source={System.IO.Directory.GetCurrentDirectory()}/{Program.Cfg.GetValue<string>("Bot:Database")}");
private static Logger _logger = Program._logger;
public static DataTable RawQuery(string query)
{
DataTable dt = new DataTable();
try
{
using (_conn)
{
_conn.Open();
SqliteCommand cmd = _conn.CreateCommand();
cmd.CommandText = query;
SqliteDataReader executeReader = cmd.ExecuteReader(CommandBehavior.SingleResult);
dt.Load(executeReader);
_conn.Close();
}
}
catch (Exception ex)
{
_logger.Fatal($"Controllers.DBWork.RawQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
}
return dt;
}
public static void InsertQuery(string table, Dictionary<string, object> parameters)
{
try
{
using (_conn)
{
_conn.Open();
SqliteCommand cmd = _conn.CreateCommand();
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)
{
commandText.Append($"@{key},");
}
commandText.Remove(commandText.Length - 1, 1);
commandText.Append(")");
cmd.CommandText = commandText.ToString();
foreach (string key in parameters.Keys)
{
cmd.Parameters.AddWithValue($"@{key}", parameters.GetValueOrDefault(key));
}
cmd.Prepare();
cmd.ExecuteNonQuery();
_conn.Close();
}
}
catch (Exception ex)
{
_logger.Fatal($"Controllers.DBWork.RawQuery: 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($"Controllers.DBWork.RawQuery: Exception [{ex}] thrown, <[{ex.Message}]>.");
}
return dt;
}
}
}