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(); 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 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; } } }