using InABox.Core; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace InABox.Core { public class SetNullData { public Guid EntityID { get; set; } public Guid ParentID { get; set; } public string Property { get; set; } public SetNullData(Guid entityID, string property, Guid parentID) { EntityID = entityID; ParentID = parentID; Property = property; } } public class DeletionData { public Dictionary> SetNulls { get; set; } = new Dictionary>(); public Dictionary Cascades { get; set; } = new Dictionary(); private static bool IsDeletionColumn(IProperty property) { if (property.IsCalculated) return false; if (property is StandardProperty standardProperty && standardProperty.Property.GetCustomAttribute() != null) return false; if (property.Parent is null) return true; if (property.Parent.IsEntityLink && !property.Name.EndsWith(".ID")) return false; if (property.Parent.HasParentEntityLink()) return false; return true; } public static IColumns DeletionColumns(Type T) { var columns = Columns.None(T); foreach(var property in DatabaseSchema.Properties(T)) { if (IsDeletionColumn(property)) columns.Add(property); } return columns; } public static Columns DeletionColumns() => (DeletionColumns(typeof(T)) as Columns)!; public void DeleteEntity(T entity) where T : Entity, new() { var entityName = typeof(T).EntityName(); if(!Cascades.TryGetValue(entityName, out var table)) { table = new CoreTable(); table.LoadColumns(DeletionColumns()); Cascades.Add(entityName, table); } table.LoadRow(entity); } public void DeleteEntity(CoreRow row) where T : Entity, new() { var entityName = typeof(T).EntityName(); if(!Cascades.TryGetValue(entityName, out var table)) { table = new CoreTable(); table.LoadColumns(DeletionColumns()); Cascades.Add(entityName, table); } table.LoadRows(new CoreRow[] { row }); } public void SetNullEntity(Guid entityID, string property, Guid parentID) where T : Entity, new() { var entityName = typeof(T).EntityName(); if (!SetNulls.TryGetValue(entityName, out var list)) { list = new List(); SetNulls.Add(entityName, list); } list.Add(new SetNullData(entityID, property, parentID)); } } // A Deletion is not IRemotable; *no one* but the database should know about it. public class Deletion : Entity, ILicense, IPersistent { [DateTimeEditor(Editable = Editable.Disabled)] public DateTime DeletionDate { get; set; } [TextBoxEditor(Editable = Editable.Disabled)] public string DeletedBy { get; set; } [TextBoxEditor(Editable = Editable.Disabled)] public string HeadTable { get; set; } [TextBoxEditor(Editable = Editable.Disabled)] public string Description { get; set; } [NullEditor] public string Data { get; set; } } }