chaosbot/ChaosBot/Database/QueryBuilder.cs

290 lines
7.4 KiB
C#

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();
query
.Select()
.Append("COUNT(*) as count")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
long amount = (long)query.Run().Rows[0]["count"];
return Convert.ToInt32(amount);
}
/*
* Basic logical operations
*/
public bool Exists()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select()
.Append("COUNT(*)>0 as present")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
return (bool)query.Run().Rows[0]["present"];
}
public bool DoesNotExist()
{
QueryBuilderRaw query = new QueryBuilderRaw();
query
.Select()
.Append("COUNT(*)=0 as notPresent")
.FromTable(_table);
if (_whereConditions.Count > 0)
query.Where(_whereConditions);
return (bool)query.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;
}
}
}