using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Antlr4.Runtime; using ChaosBot.Database; using Microsoft.Data.Sqlite; using NLog; namespace ChaosBot.Attribute { public static class AssemblyController { private static Logger _logger = Program._logger; public static void Register() { Assembly dbEntityAssembly = Assembly.GetAssembly(typeof(DBEntity)); if (dbEntityAssembly != null) { foreach (Type type in dbEntityAssembly.GetTypes()) { if (type.GetCustomAttributes(typeof(DBEntity), true).Length > 0) { // Get a reference to the attribute DBEntity dbEntity = type.GetCustomAttributes(typeof(DBEntity)).Cast().First(); // Generate columns // name, type, constraintName, constraints, List> columnList = new List>(); // Get the table as an easy variable string table = dbEntity.Table; // Loop through all fields foreach (PropertyInfo prop in type.GetProperties()) { string columnName = prop.Name; string columnType = DBEntity.DataTypes.GetValueOrDefault(prop.PropertyType).ToString(); StringBuilder constraintNameBuilder = new StringBuilder($"{table}_{columnName}"); List constraintsList = new List(); // Go through every attribute foreach (object fieldAttribute in prop.GetCustomAttributes(true)) { if (fieldAttribute is DBFieldAttribute dBFieldAttribute) { string constraintSuffix = DBEntity.ConstrainNames.GetValueOrDefault(dBFieldAttribute.GetType(), null); if (constraintSuffix != null) { constraintNameBuilder.Append($"_{constraintSuffix}"); constraintsList.Add($"{dBFieldAttribute.GetSQLiteQuery()}"); } } } string constraintName = constraintNameBuilder.ToString(); if (constraintsList.Count > 0) { constraintsList.Insert(0, "CONSTRAINT"); constraintsList.Insert(1, constraintName); } string constraints = String.Join(" ", constraintsList); columnList.Add(new Tuple(columnName, columnType, constraintName, constraints)); } // Check table exists bool tableExists = Controller.RawQuery($"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'") .Rows.Count > 0; try { if (!tableExists) { string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}")); string query = $"CREATE TABLE {table} ({columnDefs})"; Controller.RawQuery(query); } // // TODO: Generate this in one go instead of many separate commands // Controller.RawQuery($"CREATE TABLE IF NOT EXISTS {table} (id INTEGER NOT NULL CONSTRAINT {table}_pk PRIMARY KEY AUTOINCREMENT)"); // Controller.RawQuery($"CREATE UNIQUE INDEX {table}_id_uindex ON {table} (id)", false, true); // string query = $"ALTER TABLE {table} ADD COLUMN {fieldname} {fieldType} {fieldModifiers}"; } catch (Exception ex) { if (ex is SqliteException sqliteException) { if (!sqliteException.Message.Contains("duplicate column name")) { _logger.Fatal( $"AssemblyController.Register: Exception [{ex}] thrown, <[{ex.Message}]>."); } } else { _logger.Error( $"AssemblyController.Register: Exception [{ex}] thrown, <[{ex.Message}]>."); } } } } } } } }