/// <inheritdoc/> public Task <Maybe <IEnumerable <T> > > ExecuteAsync <T>( IWpDb db, IUnitOfWork w, GetPostsOptions opt, params IContentFilter[] filters ) where T : IWithId <WpPostId> => QueryPostsF.ExecuteAsync <T>(db, w, opt, filters);
/// <inheritdoc/> public Task <Maybe <IPagedList <T> > > ExecuteAsync <T>( IWpDb db, IUnitOfWork w, ulong page, GetPostsOptions opt, params IContentFilter[] filters ) where T : IWithId <WpPostId> => QueryPostsF.ExecuteAsync <T>(db, w, page, opt, filters);
/// <summary> /// Get query parts using the specific options /// </summary> /// <typeparam name="TModel">Return value type</typeparam> /// <param name="db">IWpDb</param> /// <param name="opt">Function to return query options</param> internal static Maybe <IQueryParts> GetQueryParts <TModel>(IWpDb db, GetPostsOptions opt) where TModel : IWithId <WpPostId> => F.Some( () => opt(new PostsOptions(db.Schema)), e => new M.ErrorGettingQueryPostsOptionsMsg(e) ) .Bind( x => x.ToParts <TModel>() );
/// <summary> /// Execute Terms query /// </summary> /// <typeparam name="TModel">Return Model type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="opt">Function to return query options</param> public static Task <Maybe <IEnumerable <TModel> > > ExecuteAsync <TModel>(IWpDb db, IUnitOfWork w, GetTermsOptions opt) where TModel : IWithId <WpTermId> => F.Some( () => opt(new TermsOptions(db.Schema)), e => new M.ErrorGettingQueryTermsOptionsMsg(e) ) .Bind( x => x.ToParts <TModel>() ) .BindAsync( x => db.Query.QueryAsync <TModel>(x, w.Transaction) );
/// <summary> /// Get attached files /// </summary> /// <typeparam name="T"></typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="opt">Function to return query options</param> internal static Task <Maybe <IEnumerable <T> > > ExecuteAsync <T>(IWpDb db, IUnitOfWork w, GetAttachmentsOptions opt) where T : IPostAttachment => F.Some( () => opt(new AttachmentsOptions()), e => new M.ErrorGettingQueryAttachmentsOptionsMsg(e) ) .Bind( x => GetQuery(db.Schema, x.Ids, db.WpConfig.VirtualUploadsUrl) ) .BindAsync( x => db.QueryAsync <T>(x, null, System.Data.CommandType.Text, w.Transaction) );
/// <inheritdoc cref="ExecuteAsync{TModel}(IWpDb, IUnitOfWork, ulong, GetPostsOptions, IContentFilter[])"/> internal static Task <Maybe <IEnumerable <TModel> > > ExecuteAsync <TModel>( IWpDb db, IUnitOfWork w, GetPostsOptions opt, params IContentFilter[] filters ) where TModel : IWithId <WpPostId> => GetQueryParts <TModel>( db, opt ) .BindAsync( x => db.Query.QueryAsync <TModel>(x, w.Transaction) ) .BindAsync(
/// <summary> /// Hydrate the custom fields for the list of posts /// </summary> /// <typeparam name="TList">List type</typeparam> /// <typeparam name="TModel">Model type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="posts">Posts</param> /// <param name="meta">Meta property</param> /// <param name="fields">Custom Fields</param> internal static async Task <Maybe <TList> > HydrateAsync <TList, TModel>( IWpDb db, IUnitOfWork w, TList posts, Meta <TModel> meta, List <PropertyInfo> fields ) where TList : IEnumerable <TModel> where TModel : IWithId <WpPostId> { // Hydrate all custom fields for all posts foreach (var post in posts) { // Get meta var metaDict = meta.Get(post); // Add each custom field foreach (var info in fields) { // Whether or not the field is required var required = info.GetValue(post) is not null; // Get custom field if (GetCustomField(post, info) is ICustomField customField) { // Hydrate the field var result = await customField.HydrateAsync(db, w, metaDict, required).ConfigureAwait(false); // If it failed and it's required, return None if (result.IsNone(out var reason) && required) { return(F.None <TList>(reason)); } // Set the value if (result.IsSome(out var set) && set) { info.SetValue(post, customField); } } } } return(posts); }
/// <summary> /// Add meta dictionary to posts /// </summary> /// <typeparam name="TList">List type</typeparam> /// <typeparam name="TModel">Model type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="posts">Posts</param> internal static Task <Maybe <TList> > AddMetaAsync <TList, TModel>(IWpDb db, IUnitOfWork w, TList posts) where TList : IEnumerable <TModel> where TModel : IWithId <WpPostId> { // If there are no posts, do nothing if (!posts.Any()) { return(F.Some(posts).AsTask()); } // Get Meta values return(GetMetaDictionary <TModel>() .SwitchAsync( some: x => from postMeta in QueryPostsMetaF.ExecuteAsync <PostMeta>(db, w, opt => opt with { PostIds = posts.Select(p => p.Id).ToImmutableList() })
/// <summary> /// Process a list of posts, adding meta / taxonomies / custom fields as required /// </summary> /// <typeparam name="TList">List type</typeparam> /// <typeparam name="TModel">Model type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="posts">Posts</param> /// <param name="filters">Optional content filters</param> internal static Task <Maybe <TList> > Process <TList, TModel>(IWpDb db, IUnitOfWork w, TList posts, params IContentFilter[] filters) where TList : IEnumerable <TModel> where TModel : IWithId <WpPostId> => F.Some( posts ) .BindAsync( x => AddMetaAsync <TList, TModel>(db, w, x) ) .BindAsync( x => AddCustomFieldsAsync <TList, TModel>(db, w, x) ) .BindAsync( x => AddTaxonomiesAsync <TList, TModel>(db, w, x) ) .SwitchIfAsync( _ => filters.Length > 0, ifTrue : x => ApplyContentFilters <TList, TModel>(x, filters) );
/// <summary> /// Add Taxonomies to posts /// </summary> /// <typeparam name="TList">List type</typeparam> /// <typeparam name="TModel">Post type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="posts">Posts</param> internal static Task <Maybe <TList> > AddTaxonomiesAsync <TList, TModel>(IWpDb db, IUnitOfWork w, TList posts) where TList : IEnumerable <TModel> where TModel : IWithId <WpPostId> { // If there are no posts, do nothing if (!posts.Any()) { return(F.Some(posts).AsTask()); } // Only proceed if there is at least one term list in this model var termLists = GetTermLists <TModel>(); if (termLists.Count == 0) { return(F.Some(posts).AsTask()); } // Get terms and add them to the posts return(QueryPostsTaxonomyF .ExecuteAsync <Term>(db, w, opt => opt with { PostIds = posts.Select(p => p.Id).ToImmutableList() })
/// <summary> /// Add custom fields to posts /// </summary> /// <typeparam name="TList">List type</typeparam> /// <typeparam name="TModel">Model type</typeparam> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="posts">Posts</param> internal static Task <Maybe <TList> > AddCustomFieldsAsync <TList, TModel>(IWpDb db, IUnitOfWork w, TList posts) where TList : IEnumerable <TModel> where TModel : IWithId <WpPostId> { // If there are no posts, do nothing if (!posts.Any()) { return(F.Some(posts).AsTask()); } // Only proceed if there are custom fields, and a meta property for this model var fields = GetCustomFields <TModel>(); if (fields.Count == 0) { return(F.Some(posts).AsTask()); } // Get terms and add them to the posts return(GetMetaDictionary <TModel>() .BindAsync( x => HydrateAsync(db, w, posts, x, fields) )); }
/// <summary> /// Get Previous and Next posts, if they exist, for the specified query options /// </summary> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="currentId">Current Post ID</param> /// <param name="opt">Function to return query options</param> internal static Task <Maybe <(WpPostId?prev, WpPostId?next)> > GetPreviousAndNextAsync( IWpDb db, IUnitOfWork w, WpPostId currentId, GetPostsOptions opt ) =>
/// <inheritdoc/> public Task <Maybe <IEnumerable <T> > > ExecuteAsync <T>(IWpDb db, IUnitOfWork w, GetTermsOptions opt) where T : IWithId <WpTermId> => QueryTermsF.ExecuteAsync <T>(db, w, opt);
/// <summary> /// Get the filesystem path to the specified Attachment /// </summary> /// <param name="db">IWpDb</param> /// <param name="w">IUnitOfWork</param> /// <param name="fileId">File (Post) ID</param> internal static Task <Maybe <string> > GetFilePathAsync(IWpDb db, IUnitOfWork w, WpPostId fileId) => ExecuteAsync <Attachment>( db, w, opt => opt with {