using System; using System.Collections.Generic; using System.Linq; using System.Reflection; 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) { // type == all classes that have [DBEntity(...)] // Get a reference to the attribute DBEntity dbEntity = type.GetCustomAttributes(typeof(DBEntity)).Cast().First(); string table = dbEntity.Table; // 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)"); foreach (MethodInfo field in type.GetMethods()) { if (field.Name.StartsWith("get_")) { try { // TODO: Use an attribute to detect primary autoincrement key if (field.Name == "id") { Controller.RawQuery($"CREATE UNIQUE INDEX {table}_id_uindex ON {table} (id)", false, true); continue; } string fieldname = field.Name.Substring(4); string fieldType = DBEntity.DataTypes.GetValueOrDefault(field.ReturnType).ToString(); string fieldModifiers = null; string query = $"ALTER TABLE {table} ADD COLUMN {fieldname} {fieldType} {fieldModifiers}"; Controller.RawQuery(query, false, true); } 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}]>."); } } } } } } } } } }