using FluentValidation.Results; using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Linq; using System.Security.Claims; namespace zero.Collections; public abstract partial class CollectionOperations : ICollectionOperations { /// public IZeroDocumentSession Session => Context.Store.Session(); protected record EntityCollectionOptions(bool IncludeInactive); protected IZeroContext Context { get; private set; } protected EntityCollectionOptions Options { get; set; } protected IInterceptors Interceptors { get; private set; } public CollectionOperations(ICollectionContext collectionContext) { Context = collectionContext.Context; Interceptors = collectionContext.Interceptors; Options = new(true); } /// /// Get new instance of an entity /// public virtual Task Empty() where T : ZeroIdEntity, new() { return Task.FromResult(new T()); } /// public async Task GenerateId(T model) where T : ZeroIdEntity { IZeroDocumentSession session = Context.Store.Session(); return await session.Advanced.DocumentStore.Conventions.GenerateDocumentIdAsync(session.Advanced.DocumentStore.Database, model); } /// public T AutoSetIds(T model) { // find all Raven Ids List> ravenIds = ObjectTraverser.FindAttribute(model); // set unset Raven Ids foreach (ObjectTraverser.Result item in ravenIds) { string id = item.Property.GetValue(item.Parent, null) as string; if (id.IsNullOrWhiteSpace()) { id = item.Item.Length.HasValue ? IdGenerator.Create(item.Item.Length.Value) : IdGenerator.Create(); item.Property.SetValue(item.Parent, id); } } return model; } /// public T PrepareForSave(T model) where T : ZeroIdEntity { // set IDs AutoSetIds(model); if (model is ZeroEntity) { ZeroEntity zeroModel = model as ZeroEntity; // get current user string userId = Context.BackofficeUser.FindFirstValue(Constants.Auth.Claims.UserId); // set default properties if (zeroModel.CreatedDate == default) { zeroModel.CreatedDate = DateTimeOffset.Now; } if (zeroModel.CreatedById.IsNullOrEmpty()) { zeroModel.CreatedById = userId; } if (zeroModel.LanguageId.IsNullOrEmpty()) { zeroModel.LanguageId ??= "languages.1-A"; // TODO correct language id } // update name alias and last modified zeroModel.Alias = Safenames.Alias(zeroModel.Name); zeroModel.LastModifiedById = userId; zeroModel.LastModifiedDate = DateTimeOffset.Now; zeroModel.CreatedById ??= userId; zeroModel.Hash ??= IdGenerator.Create(); } return model; } /// /// Do only return the model when it is set to active or inactive entities are included with IncludeInactive() /// protected virtual T WhenActive(T model) where T : ZeroIdEntity, new() { return model != null && (Options.IncludeInactive || (model is ZeroEntity ? (model as ZeroEntity).IsActive : true)) ? model : default; } } public interface ICollectionOperations { /// /// Get new instance of an entity /// Task Empty() where T : ZeroIdEntity, new(); /// /// Generate model Id by using configured document store conventions /// Task GenerateId(T model) where T : ZeroIdEntity; /// /// Generate values for all properties (incl. nested) which contain the [GenerateId] attribute /// T AutoSetIds(T model); /// /// Automatically fill base properties of a ZeroEntity /// T PrepareForSave(T model) where T : ZeroIdEntity; /// /// Get an entity by Id /// Task Load(string id, string changeVector = null) where T : ZeroIdEntity, new(); /// /// Get entities by ids /// Task> Load(IEnumerable ids) where T : ZeroIdEntity, new(); /// /// Get entities by query /// Task> Load(int pageNumber, int pageSize, Func, IQueryable> expression = default) where T : ZeroIdEntity, new(); /// /// Get entities by query (by using the specified index) /// Task> Load(int pageNumber, int pageSize, Func, IQueryable> expression = default) where T : ZeroIdEntity, new() where TIndex : AbstractCommonApiForIndexes, new(); /// /// Get all entities from this collection. /// Warning: Don't use this method for large collections. Stream the results instead. /// Task> LoadAll() where T : ZeroIdEntity, new(); /// /// Stream the collection /// IAsyncEnumerable Stream() where T : ZeroIdEntity, new(); /// /// Stream the collection /// IAsyncEnumerable Stream(Func, IQueryable> expression) where T : ZeroIdEntity, new(); /// /// Creates an entity with an optional validator /// Task> Create(T model, Func> validate = null) where T : ZeroIdEntity, new(); /// /// Updates an entity with an optional validator /// Task> Update(T model, Func> validate = null) where T : ZeroIdEntity, new(); /// /// Deletes an entity /// Task> Delete(T model) where T : ZeroIdEntity, new(); /// /// Deletes entities /// Task Delete(IEnumerable models) where T : ZeroIdEntity, new(); /// /// Deletes an entity by Id /// Task> Delete(string id) where T : ZeroIdEntity, new(); /// /// Deletes entities by Id /// Task Delete(IEnumerable ids) where T : ZeroIdEntity, new(); }