using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using ChaosBot.Database; 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()) { try { 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; if (!tableExists) { string columnDefs = String.Join(", ", columnList.Select(c => $"{c.Item1} {c.Item2} {c.Item4}")); string query = $"CREATE TABLE {table} ({columnDefs})"; Controller.RawQuery(query, readOutput: false); } else { foreach (Tuple column in columnList) { try { string query = $"ALTER TABLE {table} ADD COLUMN {column.Item1} {column.Item2} {column.Item4}"; Controller.RawQuery(query, readOutput: false, throwError: true); } catch { // ignored } } } } } catch (Exception ex) { _logger.Error($"AssemblyController.Register: Exception [{ex}] thrown, <[{ex.Message}]>."); } } } } } }