using System; using System.Collections.Generic; using System.Data; using FluentValidation.Results; using Microsoft.Extensions.DependencyInjection; using System.Linq.Expressions; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using ServiceStack.OrmLite; using zero.Context; using zero.Models; using zero.Utils; using zero.Validation; namespace zero.Sqlite; public partial class DbOperations : IDbOperations { protected IZeroContext Context { get; private set; } protected FlavorOptions Flavors { get; private set; } protected IServiceProvider Services { get; private set; } protected IDbConnection Db { get; private set; } protected ILogger Logger { get; private set; } public DbOperations(StoreContext context, IDbConnection db, ILogger logger) { Context = context.Context; Services = context.Services; Flavors = context.Options.For(); Db = db; Logger = logger; } /// public bool EnsureTableExists() where T : ZeroIdEntity { return Db.CreateTableIfNotExists(); } /// public Task GenerateId(T model) where T : ZeroIdEntity { return Task.FromResult(IdGenerator.Create(12)); } /// public T AutoSetIds(T model) { return IdGenerator.Autofill(model); } /// public T PrepareForSave(T model) where T : ZeroIdEntity { // set IDs AutoSetIds(model); if (model is not ZeroEntity zeroModel) { return model; } // set default properties if (zeroModel.CreatedDate == default) { zeroModel.CreatedDate = DateTimeOffset.Now; } // update name alias and last modified zeroModel.Alias = Safenames.Alias(zeroModel.Name); zeroModel.LastModifiedDate = DateTimeOffset.Now; zeroModel.Hash ??= IdGenerator.Create(); return model; } /// public async Task Validate(T model) where T : ZeroIdEntity, new() { IZeroMergedValidator validator = Services.GetService>(); if (validator == null) { return new(); } return await validator.ValidateAsync(model); } /// public virtual T WhenActive(T model) where T : ZeroIdEntity, new() { return model; // TODO should we really use this? I tried to get data in a custom backend but couldn't because of this //return model != null && (model is not ZeroEntity || (model as ZeroEntity).IsActive) && (model is not ISupportsSoftDelete || !(model as ISupportsSoftDelete).IsDeleted) ? model : default; } } public interface IDbOperations { /// /// Create a table if not existing /// bool EnsureTableExists() where T : ZeroIdEntity; /// /// Generate model Id by using configured document store conventions /// Task GenerateId(T model) where T : ZeroIdEntity; /// /// Do only return the model when it is set to active or inactive entities are included with IncludeInactive() /// T WhenActive(T model) where T : ZeroIdEntity, new(); /// /// Validates an entity /// Task Validate(T model) where T : ZeroIdEntity, new(); /// /// 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 ids /// Task> LoadAsList(IEnumerable ids) where T : ZeroIdEntity, new(); /// /// Check if any items exist in this collection (with optional query) /// Task Any(Expression> querySelector = null) where T : ZeroIdEntity, new(); /// /// Get entities by query /// Task> Load(Expression> querySelector) where T : ZeroIdEntity, new(); /// /// Get entities by sql query /// Task> LoadBySql(Func, SqlExpression> querySelector) where T : ZeroIdEntity, 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(); /// /// 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 an entity /// Task> Delete(string id) where T : ZeroIdEntity, new(); }