chaosbot/ChaosBot/Attribute/AssemblyController.cs

107 lines
5.3 KiB
C#

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<DBEntity>().First();
// Generate columns
// name, type, constraintName, constraints,
List<Tuple<string, string, string, string>> columnList = new List<Tuple<string, string, string, string>>();
// 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<string> constraintsList = new List<string>();
// 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<string, string, string, string>(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}]>.");
}
}
}
}
}
}
}
}