using FluentValidation.Results; namespace zero.Stores; public partial class StoreOperations : IStoreOperations { /// public virtual Task> Create(T model, Func> validate = null) where T : ZeroIdEntity, new() => Save(model, validate); /// public virtual Task> Update(T model, Func> validate = null) where T : ZeroIdEntity, new() => Save(model, validate); /// protected virtual async Task> Save(T model, Func> validate = null) where T : ZeroIdEntity, new() { if (model == null) { return Result.Fail("@errors.onsave.empty"); } bool isUpdate = false; // check if the Id for a model already exists if (!model.Id.IsNullOrEmpty()) { bool exists = await Session.Advanced.ExistsAsync(model.Id); if (!exists) { return Result.Fail("@errors.onsave.noidmatch"); } isUpdate = true; } // validate flavor if (model is ISupportsFlavors flavorModel && !flavorModel.Flavor.IsNullOrEmpty()) { if (!Flavors.Exists(flavorModel.Flavor)) { return Result.Fail("@errors.onsave.flavornotfound"); } } // prepare model PrepareForSave(model); // run validator if (validate != null) { ValidationResult validation = await validate(model); if (!validation.IsValid) { return Result.Fail(validation); } } // create ID before-hand so interceptors can use it if (!isUpdate) { model.Id = await GenerateId(model); } // run interceptor InterceptorInstruction instruction = isUpdate ? Interceptors.ForUpdate(model) : Interceptors.ForCreate(model); if (!await instruction.Start(this)) { return instruction.Result; } // store our model await Session.StoreAsync(model); await instruction.Complete(); await Session.SaveChangesAsync(); return Result.Success(model); } /// public async Task>> Sort(string[] sortedIds) where T : ZeroIdEntity, ISupportsSorting, new() { Dictionary items = await Load(sortedIds); uint index = 10; // contains multiple parents, therefore fail if (typeof(ISupportsTrees).IsAssignableFrom(typeof(T)) && items.Select(x => (x.Value as ISupportsTrees)?.ParentId).Distinct().Count() > 1) { return Result>.Fail("@errors.treeentity.sortingmultipleparents"); } foreach (var item in items) { item.Value.Sort = index; index += 10; await Update(item.Value); } return Result>.Success(items.Select(x => x.Value).OrderByDescending(x => x.Sort)); } }