Skip to content

Commit

Permalink
Add caching methods and refactor query execution
Browse files Browse the repository at this point in the history
- Add `ExecutePageQuery` and `ExecuteContentQuery` methods to `BaseRepository.cs` for query execution with caching and preview mode handling.
- Introduce `CacheDependencyHelper.cs` to provide static methods for creating cache keys and dependencies.
- Refactor `PageTypeRepository.cs` to use `ExecutePageQuery` from `BaseRepository`, simplifying query execution and caching logic.
- Adjust formatting of package references in `XperienceCommunity.DataRepository.csproj`.
  • Loading branch information
brandonhenricks committed Jan 8, 2025
1 parent 98f499b commit 668f7be
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 210 deletions.
62 changes: 62 additions & 0 deletions src/XperienceCommunity.DataRepository/BaseRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CMS.ContentEngine;
using CMS.Helpers;
using CMS.Websites;
using CMS.Websites.Routing;

using XperienceCommunity.DataRepository.Models;
Expand Down Expand Up @@ -32,5 +33,66 @@ protected ContentQueryExecutionOptions GetQueryExecutionOptions()
return queryOptions;
}

protected async Task<IEnumerable<T>> ExecutePageQuery<T>(ContentItemQueryBuilder builder, Func<CMSCacheDependency> dependencyFunc, CancellationToken cancellationToken = default,
params object[] cacheNameParts)
{
var queryOptions = GetQueryExecutionOptions();

if (WebsiteChannelContext.IsPreview)
{
return await Executor.GetMappedWebPageResult<T>(builder, queryOptions, cancellationToken);
}

var cacheSettings =
new CacheSettings(CacheMinutes, cacheNameParts);

return await Cache.LoadAsync(async (cs, ct) =>
{
var result = (await Executor.GetMappedWebPageResult<T>(builder, queryOptions,
cancellationToken: ct))?.ToList() ?? [];

cs.BoolCondition = result.Count > 0;

if (!cs.Cached)
{
return result;
}

cs.CacheDependency = dependencyFunc.Invoke();

return result;
}, cacheSettings, cancellationToken);
}
protected async Task<IEnumerable<T>> ExecuteContentQuery<T>(ContentItemQueryBuilder builder, Func<CMSCacheDependency> dependencyFunc, CancellationToken cancellationToken = default,
params object[] cacheNameParts)
{
var queryOptions = GetQueryExecutionOptions();

if (WebsiteChannelContext.IsPreview)
{
return await Executor.GetMappedWebPageResult<T>(builder, queryOptions, cancellationToken);
}

var cacheSettings =
new CacheSettings(CacheMinutes, cacheNameParts);

return await Cache.LoadAsync(async (cs, ct) =>
{
var result = (await Executor.GetMappedResult<T>(builder, queryOptions,
cancellationToken: ct))?.ToList() ?? [];

cs.BoolCondition = result.Count > 0;

if (!cs.Cached)
{
return result;
}

cs.CacheDependency = dependencyFunc.Invoke();

return result;
}, cacheSettings, cancellationToken);
}

public virtual string CachePrefix => "base|data";
}
144 changes: 144 additions & 0 deletions src/XperienceCommunity.DataRepository/Helpers/CacheDependencyHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
using CMS.ContentEngine;
using CMS.Helpers;
using CMS.Websites;

namespace XperienceCommunity.DataRepository.Helpers
{
/// <summary>
/// Provides helper methods for creating cache dependencies for content and web page items.
/// </summary>
public static class CacheDependencyHelper
{
/// <summary>
/// Creates cache keys for web page items by their GUIDs.
/// </summary>
/// <param name="itemGuids">The GUIDs of the web page items.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateWebPageItemGUIDKeys(IEnumerable<Guid>? itemGuids) => itemGuids?.Select(x => CreateWebPageItemGUIDKey(x))?.ToArray() ?? Array.Empty<string>();

/// <summary>
/// Creates a cache key for a web page item by its GUID.
/// </summary>
/// <param name="itemGuid">The GUID of the web page item.</param>
/// <returns>A cache key.</returns>
public static string CreateWebPageItemGUIDKey(Guid? itemGuid) => $"webpageitem|byguid|{itemGuid}";

/// <summary>
/// Creates a cache key for a web page item by its ID.
/// </summary>
/// <param name="itemId">The ID of the web page item.</param>
/// <returns>A cache key.</returns>
public static string CreateWebPageItemIdKey(int? itemId) => $"webpageitem|byid|{itemId}";

/// <summary>
/// Creates cache keys for web page items by their IDs.
/// </summary>
/// <param name="itemIdList">The IDs of the web page items.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateWebPageItemIdKeys(IEnumerable<int>? itemIdList) =>
itemIdList?.Select(x => CreateWebPageItemIdKey(x))?.ToArray() ?? [];

/// <summary>
/// Creates cache keys for web page items by content type and channel name.
/// </summary>
/// <param name="contentTypes">The content types.</param>
/// <param name="channelName">The channel name.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateWebPageItemTypeKeys(IEnumerable<string>? contentTypes, string channelName) => contentTypes?.Select(x => $"webpageitem|bychannel|{channelName}|bycontenttype|{x}")?.ToArray() ?? [];

/// <summary>
/// Creates cache keys for content items by content type.
/// </summary>
/// <param name="contentTypes">The content types.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateContentItemTypeKeys(IEnumerable<string>? contentTypes) => contentTypes?.Select(x => $"contentitem|bycontenttype|{x}")?.ToArray() ?? [];

/// <summary>
/// Creates cache keys for content items by their GUIDs.
/// </summary>
/// <typeparam name="T">The type of the content items.</typeparam>
/// <param name="items">The content items.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateContentItemKeys<T>(IEnumerable<T>? items) where T : IContentItemFieldsSource => items?.Select(x => $"contentitem|byid|{x.SystemFields.ContentItemGUID}")?.ToArray() ?? [];

/// <summary>
/// Creates cache keys for web page items by their IDs.
/// </summary>
/// <typeparam name="T">The type of the web page items.</typeparam>
/// <param name="items">The web page items.</param>
/// <returns>An array of cache keys.</returns>
public static string[] CreateWebPageItemKeys<T>(IEnumerable<T>? items) where T : IWebPageFieldsSource => items?.Select(x => $"webpageitem|byid|{x.SystemFields.WebPageItemID}")?.ToArray() ?? [];

/// <summary>
/// Creates a cache dependency for the specified content items.
/// </summary>
/// <typeparam name="T">The type of the content items.</typeparam>
/// <param name="items">The content items.</param>
/// <returns>A cache dependency for the specified content items.</returns>
public static CMSCacheDependency CreateContentItemCacheDependency<T>(IEnumerable<T>? items)
where T : IContentItemFieldsSource
{
string[] contentItemKeys = CreateContentItemKeys(items);

return CacheHelper.GetCacheDependency(contentItemKeys);
}

/// <summary>
/// Creates a cache dependency for the specified web page items.
/// </summary>
/// <typeparam name="T">The type of the web page items.</typeparam>
/// <param name="items">The web page items.</param>
/// <returns>A cache dependency for the specified web page items.</returns>
public static CMSCacheDependency CreateWebPageItemCacheDependency<T>(IEnumerable<T>? items)
where T : IWebPageFieldsSource
{
string[] webPageItemKeys = CreateWebPageItemKeys(items);
return CacheHelper.GetCacheDependency(webPageItemKeys);
}

/// <summary>
/// Creates a cache dependency for web page items by content type and channel name.
/// </summary>
/// <param name="contentTypes">The content types.</param>
/// <param name="channelName">The channel name.</param>
/// <returns>A cache dependency for the specified web page items.</returns>
public static CMSCacheDependency CreateWebPageItemTypeCacheDependency(IEnumerable<string>? contentTypes, string channelName)
{
string[] webPageItemTypeKeys = CreateWebPageItemTypeKeys(contentTypes, channelName);
return CacheHelper.GetCacheDependency(webPageItemTypeKeys);
}

/// <summary>
/// Creates a cache dependency for content items by content type.
/// </summary>
/// <param name="contentTypes">The content types.</param>
/// <returns>A cache dependency for the specified content items.</returns>
public static CMSCacheDependency CreateContentItemTypeCacheDependency(IEnumerable<string>? contentTypes)
{
string[] contentItemTypeKeys = CreateContentItemTypeKeys(contentTypes);
return CacheHelper.GetCacheDependency(contentItemTypeKeys);
}

/// <summary>
/// Creates a cache dependency for web page items by their GUIDs.
/// </summary>
/// <param name="itemGuids">The GUIDs of the web page items.</param>
/// <returns>A cache dependency for the specified web page items.</returns>
public static CMSCacheDependency CreateWebPageItemGUIDCacheDependency(IEnumerable<Guid>? itemGuids)
{
string[] webPageItemGUIDKeys = CreateWebPageItemGUIDKeys(itemGuids);
return CacheHelper.GetCacheDependency(webPageItemGUIDKeys);
}

/// <summary>
/// Creates a cache dependency for web page items by their IDs.
/// </summary>
/// <param name="itemIdList"></param>
/// <returns></returns>
public static CMSCacheDependency CreateWebPageItemIDCacheDependency(IEnumerable<int>? itemIdList)
{
string[] webPageItemIdKeys = CreateWebPageItemIdKeys(itemIdList);
return CacheHelper.GetCacheDependency(webPageItemIdKeys);
}
}
}
Loading

0 comments on commit 668f7be

Please # to comment.