using InABox.Clients; using InABox.Core; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace InABox.DynamicGrid; /// /// Defines a common interface for dealing with grids like /// or , which display s, but do not load them necessarily from the database, /// instead keeping them in memory. ///
/// This interface then allows other functions, like /// , to work based on and manage our column handling better. ///
/// public interface IDynamicMemoryEntityGrid where T : Entity, IRemotable, IPersistent, new() { /// /// A set of columns representing which columns have been loaded from the database. /// /// /// This is used to refresh the data when the columns change.
/// /// It is if no data has been loaded from the database (that is, the data was gotten from /// a page data handler instead.) ///
public HashSet? LoadedColumns { get; } public IEnumerable Items { get; } } public static class DynamicMemoryEntityGridExtensions { public static void EnsureColumns(this IDynamicMemoryEntityGrid grid, Columns columns) where T : Entity, IRemotable, IPersistent, new() { RequireColumns(grid, columns); LoadForeignProperties(grid, columns); } /// /// Load the properties of any s on this where the is not . /// This allows us to populate columns of transient objects, as long as they are linked by the ID. What this actually then does is query each /// linked table with the required columns. /// /// public static void LoadForeignProperties(this IDynamicMemoryEntityGrid grid, Columns columns) where T : Entity, IRemotable, IPersistent, new() { grid.Items.LoadForeignProperties(columns); } public static void RequireColumns(this IDynamicMemoryEntityGrid grid, Columns columns) where T : Entity, IRemotable, IPersistent, new() { if (grid.LoadedColumns is null) return; // Figure out which columns we still need. var newColumns = columns.Where(x => !grid.LoadedColumns.Contains(x.Property)).ToColumns(ColumnTypeFlags.None); if (newColumns.Count > 0 && typeof(T).GetCustomAttribute() is null) { var data = Client.Query( new Filter(x => x.ID).InList(grid.Items.Select(x => x.ID).Where(x => x != Guid.Empty).ToArray()), // We also need to add ID, so we know which item to fill. newColumns.Add(x => x.ID)); foreach (var row in data.Rows) { var item = grid.Items.FirstOrDefault(x => x.ID == row.Get(y => y.ID)); if (item is not null) { row.FillObject(item, overrideExisting: false); } } // Remember that we have now loaded this data. foreach (var column in newColumns) { grid.LoadedColumns.Add(column.Property); } } } }