From 72f1ccefca0707c440e12bde26d5ec111512b9eb Mon Sep 17 00:00:00 2001 From: Ryan Palmer Date: Sun, 1 Aug 2021 08:49:47 +1000 Subject: [PATCH] Start on QueryBuilder Created: - MySql Type Name Map - Added String Extensions --- Articulate/Attributes/Column.cs | 9 +- Articulate/DBConnection.cs | 26 +++- Articulate/Extensions/StringExtension.cs | 27 ++++ Articulate/Model.cs | 42 +++++- Articulate/MysqlTypeNames.cs | 25 ++++ Articulate/QueryBuilder.cs | 170 +++++++++++++++++++++++ 6 files changed, 288 insertions(+), 11 deletions(-) create mode 100644 Articulate/Extensions/StringExtension.cs create mode 100644 Articulate/MysqlTypeNames.cs create mode 100644 Articulate/QueryBuilder.cs diff --git a/Articulate/Attributes/Column.cs b/Articulate/Attributes/Column.cs index 21d3182..95361e7 100644 --- a/Articulate/Attributes/Column.cs +++ b/Articulate/Attributes/Column.cs @@ -1,4 +1,5 @@ -using System; +using MySql.Data.MySqlClient; +using System; using System.Collections.Generic; using System.Text; @@ -6,6 +7,10 @@ namespace Articulate.Attributes { public class Column : Attribute { - public string Type { get; set; } + public MySqlDbType Type { get; set; } + + public int Size { get; set; } + + public bool Primary { get; set; } } } diff --git a/Articulate/DBConnection.cs b/Articulate/DBConnection.cs index 9457451..974c742 100644 --- a/Articulate/DBConnection.cs +++ b/Articulate/DBConnection.cs @@ -12,7 +12,7 @@ namespace Articulate public string UserName { get; set; } public string Password { get; set; } - private MySqlConnection Connection { get; set; } + public MySqlConnection Connection { get; set; } private static DBConnection _instance = null; public static DBConnection Instance() @@ -28,14 +28,34 @@ namespace Articulate { if (String.IsNullOrEmpty(DatabaseName)) return false; - string connstring = string.Format("Server={0}; database={1}; UID={2}; password={3}", Server, DatabaseName, UserName, Password); + string connstring = string.Format("Server={0}; database={1}; UID={2}; password={3}; SSL Mode=none", Server, DatabaseName, UserName, Password); Connection = new MySqlConnection(connstring); - Connection.Open(); } return true; } + public void SendCommand(MySqlCommand command) + { + Connection.Open(); + + command.ExecuteNonQuery(); + + Connection.Close(); + } + + public void SendQuery(MySqlCommand query) + { + Connection.Open(); + + using (MySqlDataReader reader = query.ExecuteReader()) + { + + } + + Connection.Close(); + } + public void Close() { Connection.Close(); diff --git a/Articulate/Extensions/StringExtension.cs b/Articulate/Extensions/StringExtension.cs new file mode 100644 index 0000000..834636d --- /dev/null +++ b/Articulate/Extensions/StringExtension.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Articulate.Extensions +{ + public static class StringExtension + { + public static string AddUnderscoresToSentence(this string text, bool preserveAcronyms = false) + { + if (string.IsNullOrWhiteSpace(text)) + return string.Empty; + StringBuilder newText = new StringBuilder(text.Length * 2); + newText.Append(text[0]); + for (int i = 1; i < text.Length; i++) + { + if (char.IsUpper(text[i])) + if ((text[i - 1] != ' ' && !char.IsUpper(text[i - 1])) || + (preserveAcronyms && char.IsUpper(text[i - 1]) && + i < text.Length - 1 && !char.IsUpper(text[i + 1]))) + newText.Append('_'); + newText.Append(text[i]); + } + return newText.ToString(); + } + } +} diff --git a/Articulate/Model.cs b/Articulate/Model.cs index 5ee2cc7..786b5a7 100644 --- a/Articulate/Model.cs +++ b/Articulate/Model.cs @@ -1,28 +1,58 @@ -using System; +using MySql.Data.MySqlClient; +using Pluralize.NET; +using System; using System.Collections.Generic; using System.Text; namespace Articulate { - public class Model + public abstract class Model { - protected string Table = string.Empty; + protected virtual string Table => new Pluralizer().Pluralize(this.GetType().Name); - protected string PrimaryKey = "id"; - protected string KeyType = "integer"; + protected virtual string PrimaryKey => "id"; + protected virtual MySqlDbType KeyType => MySqlDbType.Int32; protected bool Incrementing = true; protected bool Timestamps = false; + public Model() + { + } + public bool Insert() { return false; } - public static void Get() + public Model[] Get(params string[][] conditions) { + string query = QueryBuilder.Select(this, conditions); + //DBConnection.Instance() + + return null; + } + + public string GetTable() + { + return Table; + } + + public string GetPrimaryKey() + { + return PrimaryKey; + } + + public MySqlDbType GetKeyType() + { + return KeyType; + } + + public void Save() + { + //Insert into database; } } } diff --git a/Articulate/MysqlTypeNames.cs b/Articulate/MysqlTypeNames.cs new file mode 100644 index 0000000..9c6fad9 --- /dev/null +++ b/Articulate/MysqlTypeNames.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Articulate +{ + public enum MysqlTypeNames + { + INT = 3, + VARCHAR = 253, + TEXT = 752, + DATE = 10, + TINYINT = 1, + SMALLINT = 2, + BIGINT = 8, + FLOAT = 4, + DOUBLE = 5, + DATETIME = 12, + TIMESTAMP = 7, + BLOB = 252, + MEDIUMBLOB = 250, + LONGBLOB = 251 + + } +} diff --git a/Articulate/QueryBuilder.cs b/Articulate/QueryBuilder.cs new file mode 100644 index 0000000..924b0ad --- /dev/null +++ b/Articulate/QueryBuilder.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Linq; +using System.Diagnostics; +using Articulate.Attributes; +using Articulate.Extensions; +using MySql.Data.MySqlClient; + +namespace Articulate +{ + public class QueryBuilder + { + public static string Select(Model model, params string[][] conditions) + { + StringBuilder command = new StringBuilder(); + + command.Append($"SELECT * FROM `{model.GetTable()}`"); + + if (conditions.Length > 0) + { + command.Append(" WHERE "); + + for (int i = 0; i < conditions.Length; i++) + { + string[] condition = conditions[i]; + + if (i > 0) + command.Append(" AND "); + + command.Append(string.Join(" ", condition)); + } + } + + return command.ToString(); + } + + public static MySqlCommand InsertCommand(Model model) + { + using (MySqlCommand cmd = new MySqlCommand("", DBConnection.Instance().Connection)) + { + StringBuilder command = new StringBuilder(); + + command.Append($"INSERT INTO `{model.GetTable()}` ("); + + PropertyInfo[] columns = model.GetType().GetProperties(BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance).Where(p => Attribute.IsDefined(p, typeof(Column))).ToArray(); + + List valRef = new List(); + + for (int i = 0; i < columns.Length; i++) + { + var column = columns[i]; + + var name = column.Name.ToLower(); + var type = column.GetCustomAttribute().Type; + var value = column.GetValue(model); + + cmd.Parameters.Add(new MySqlParameter($"@{name}", type) { Value = value }); + + valRef.Add($"@{name}"); + + command.Append($"`{name}`"); + + if (i + 1 < columns.Length) + command.Append(", "); + } + + command.Append(") VALUES ("); + + for (int i = 0; i < valRef.Count; i++) + { + var value = valRef[i]; + + command.Append($"'{value}'"); + + if (i + 1 < valRef.Count) + command.Append(", "); + } + + command.Append(");"); + } + + return null; + } + + public static string Insert(Model model) + { + StringBuilder command = new StringBuilder(); + + command.Append($"INSERT INTO `{model.GetTable()}` ("); + + PropertyInfo[] columns = model.GetType().GetProperties(BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance).Where(p => Attribute.IsDefined(p, typeof(Column))).ToArray(); + + List values = new List(); + + for (int i = 0; i < columns.Length; i++) + { + var column = columns[i]; + + var name = column.Name.ToLower(); + var value = column.GetValue(model); + + values.Add(value); + + command.Append($"`{name}`"); + + if (i + 1 < columns.Length) + command.Append(", "); + } + + command.Append(") VALUES ("); + + for (int i = 0; i < values.Count; i++) + { + var value = values[i]; + + command.Append($"'{value}'"); + + if (i + 1 < values.Count) + command.Append(", "); + } + + command.Append(");"); + + return command.ToString(); + } + + public static MySqlCommand CreateTable(Type model) + { + var modelInstance = (Model)Activator.CreateInstance(model); + + string tableName = modelInstance.GetTable(); + + PropertyInfo[] columns = model.GetProperties(BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance).Where(p => Attribute.IsDefined(p, typeof(Column))).ToArray(); + + StringBuilder command = new StringBuilder(); + + command.Append($"CREATE TABLE `{tableName}` ("); + + for (int i = 0; i < columns.Length; i++) + { + var column = columns[i]; + Column attr = column.GetCustomAttribute(); + + command.Append($"{column.Name.AddUnderscoresToSentence().ToLower()} "); + command.Append($"{(MysqlTypeNames)attr.Type}"); + + if (attr.Size > 0) + command.Append($"({attr.Size})"); + + if (attr.Primary) + command.Append(" PRIMARY KEY"); + + if (i + 1 < columns.Length) + command.Append(", "); + } + + command.Append(");"); + + return new MySqlCommand(command.ToString(), DBConnection.Instance().Connection); + } + } +}