using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Linq; namespace zero.Stores; public abstract class TreeEntityStore : EntityStore, ITreeEntityStore where T : ZeroIdEntity, ISupportsTrees, ISupportsFlavors, ISupportsSorting, new() { public TreeEntityStore(IStoreContext collectionContext) : base(collectionContext) { } /// public override async Task> Create(T model) { if (!await IsAllowedAsChild(model, model.ParentId)) { return Result.Fail("@errors.treeentity.parentnotallowed"); } return await base.Create(model); } /// public override async Task> Update(T model) { if (!await IsAllowedAsChild(model, model.ParentId)) { return Result.Fail("@errors.treeentity.parentnotallowed"); } return await base.Update(model); } /// public virtual Task IsAllowedAsChild(T model, string parentId) => Task.FromResult(true); /// public virtual Task> LoadChildren(string parentId, int pageNumber, int pageSize, Func, IQueryable> querySelector = null) => Operations.LoadChildren(parentId, pageNumber, pageSize, querySelector); /// public virtual Task> LoadChildren(string parentId, int pageNumber, int pageSize, Func, IQueryable> querySelector = null) where TIndex : AbstractCommonApiForIndexes, new() => Operations.LoadChildren(parentId, pageNumber, pageSize, querySelector); /// public virtual Task GetHierarchy(string id) where TIndex : ZeroTreeHierarchyIndex, new() => Operations.GetHierarchy(id); /// public virtual Task> Copy(string id, string newParentId) => Operations.Copy(id, newParentId, async (model, parentId) => await IsAllowedAsChild(model, parentId)); /// public virtual Task> CopyWithDescendants(string id, string newParentId) => Operations.CopyWithDescendants(id, newParentId, async (model, parentId) => await IsAllowedAsChild(model, parentId)); /// public virtual Task> Move(string id, string newParentId) => Operations.Move(id, newParentId, async (model, parentId) => await IsAllowedAsChild(model, parentId)); /// public virtual Task> DeleteWithDescendants(T model) => Operations.DeleteWithDescendants(model); /// public virtual Task> DeleteWithDescendants(string id) => Operations.DeleteWithDescendants(id); } public interface ITreeEntityStore : IEntityStore where T : ZeroIdEntity, ISupportsTrees, ISupportsFlavors, ISupportsSorting, new() { /// /// Determines whether a model is allowed as a child for a new parent. /// This is primarily used by copy/move operations /// Task IsAllowedAsChild(T model, string parentId); /// /// Loads all children for an entity /// Task> LoadChildren(string parentId, int pageNumber, int pageSize, Func, IQueryable> querySelector = default); /// /// Get descendants by query (by using the specified index) /// Task> LoadChildren(string parentId, int pageNumber, int pageSize, Func, IQueryable> querySelector = default) where TIndex : AbstractCommonApiForIndexes, new(); /// /// Get tree hierarchy for an entity /// Task GetHierarchy(string id) where TIndex : ZeroTreeHierarchyIndex, new(); /// /// Move an entity to a new parent /// Task> Move(string id, string newParentId); /// /// Copies an entity to a new location /// Task> Copy(string id, string newParentId); /// /// Copies an entity with descendants to a new location /// Task> CopyWithDescendants(string id, string newParentId); /// /// Deletes an entity with all descendents /// Task> DeleteWithDescendants(T model); /// /// Deletes an entity by Id with all descendents /// Task> DeleteWithDescendants(string id); }