Skip to content

Commit

Permalink
Refactor for common methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ManhOptimizely committed Dec 10, 2024
1 parent 85cced4 commit 6fac62e
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using EPiServer.ContentGraph.Helpers;
using EPiServer.ContentGraph.Helpers.Reflection;
using EPiServer.ContentGraph.Helpers.Text;
using GraphQL.Transport;
using System;
using System.Linq.Expressions;

namespace EPiServer.ContentGraph.Api.Querying
{
Expand Down Expand Up @@ -157,7 +159,42 @@ public virtual BaseTypeQueryBuilder Children(ITypeQueryBuilder children)

return this;
}
public virtual BaseTypeQueryBuilder AddFragments(params FragmentBuilder[] fragments)
protected virtual void AppendItem(string item)
{
if (!item.IsNullOrEmpty())
{
graphObject.SelectItems.Append(graphObject.SelectItems.Length > 0 ? $" {item}": item);
}
}
}

public class BaseTypeQueryBuilder<T> : BaseTypeQueryBuilder
{
public BaseTypeQueryBuilder():base() { }
public BaseTypeQueryBuilder(GraphQLRequest query): base(query) { }
/// <summary>
/// Select properties of an IEnumerable of <typeparamref name="TField"/>
/// </summary>
/// <typeparam name="TField"></typeparam>
/// <param name="enumSelector">IEnumerable property of <typeparamref name="T"/></param>
/// <param name="fieldSelectors">Fields of type <typeparamref name="TField"/></param>
/// <returns></returns>
public virtual BaseTypeQueryBuilder<T> NestedFields<TField>(Expression<Func<T, IEnumerable<TField>>> enumSelector, params Expression<Func<TField, object>>[] fieldSelectors)
{
enumSelector.ValidateNotNullArgument("fieldSelector");
fieldSelectors.ValidateNotNullArgument("fields");
var enumPath = enumSelector.GetFieldPath();
string fields = string.Empty;
foreach (var fieldSelector in fieldSelectors)
{
fields += fields.IsNullOrEmpty() ? fieldSelector.GetFieldPath() : $" {fieldSelector.GetFieldPath()}";
}
var combinedPath = ConvertNestedFieldToString.ConvertNestedFieldForQuery($"{enumPath}.{fields}");
Field(combinedPath);
return this;
}

public virtual BaseTypeQueryBuilder<T> AddFragments(params IFragmentBuilder[] fragments)
{
fragments.ValidateNotNullArgument("fragments");
foreach (var fragment in fragments)
Expand All @@ -166,12 +203,12 @@ public virtual BaseTypeQueryBuilder AddFragments(params FragmentBuilder[] fragme
}
return this;
}
protected virtual BaseTypeQueryBuilder AddFragment(FragmentBuilder fragment)
protected virtual BaseTypeQueryBuilder<T> AddFragment(IFragmentBuilder fragment)
{
AddFragment(null, fragment);
return this;
}
public virtual BaseTypeQueryBuilder AddFragment(string fieldPath, FragmentBuilder fragment)
public virtual BaseTypeQueryBuilder<T> AddFragment(string fieldPath, IFragmentBuilder fragment)
{
fragment.ValidateNotNullArgument("fragment");
string propName;
Expand Down Expand Up @@ -200,11 +237,11 @@ public virtual BaseTypeQueryBuilder AddFragment(string fieldPath, FragmentBuilde
}
return this;
}
private IEnumerable<FragmentBuilder> GetAllChildren(FragmentBuilder fragment)
private IEnumerable<IFragmentBuilder> GetAllChildren(IFragmentBuilder fragment)
{
if (fragment.HasChildren)
{
foreach (var child in fragment.ChildrenFragments)
foreach (var child in fragment.GetChildren())
{
if (Parent.HasFragment(child.GetName()))
{
Expand All @@ -226,12 +263,5 @@ private IEnumerable<FragmentBuilder> GetAllChildren(FragmentBuilder fragment)
}
}

protected virtual void AppendItem(string item)
{
if (!item.IsNullOrEmpty())
{
graphObject.SelectItems.Append(graphObject.SelectItems.Length > 0 ? $" {item}": item);
}
}
}
}
46 changes: 25 additions & 21 deletions APIs/src/EpiServer.ContentGraph/Api/Querying/FragmentBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

namespace EPiServer.ContentGraph.Api.Querying
{
public interface IFragmentBuilder
{
public string GetName();
public GraphQLRequest GetQuery();
public bool HasChildren { get; }
public IEnumerable<IFragmentBuilder> GetChildren();
}
public class Recursion
{
public string FieldName { get; set; }
Expand All @@ -25,14 +32,13 @@ public override string ToString()
return ConvertNestedFieldToString.ConvertNestedFieldForQuery($"{FieldName} @recursive(depth:{RecursiveDepth.Value})");
}
}
}
public class FragmentBuilder : BaseTypeQueryBuilder
}
public class FragmentBuilder<T> : BaseTypeQueryBuilder<T>, IFragmentBuilder
{
private List<FragmentBuilder> _childrenFragments;
public IEnumerable<FragmentBuilder> ChildrenFragments => _childrenFragments;
private List<IFragmentBuilder> _childrenFragments;
public IEnumerable<IFragmentBuilder> GetChildren() => _childrenFragments;
public bool HasChildren => _childrenFragments != null && _childrenFragments.Any();
public FragmentBuilder() : base()
{
public FragmentBuilder() : base() {
_query.OperationName = "sampleFragment";
}
public void OperationName(string name)
Expand All @@ -43,40 +49,38 @@ public void OperationName(string name)
_query.OperationName = name;
}
}
public FragmentBuilder(string name)
{
OperationName(name);
}
public string GetName()
{
return _query.OperationName;
}
public override FragmentBuilder AddFragments(params FragmentBuilder[] fragments)
public override FragmentBuilder<T> AddFragments(params IFragmentBuilder[] fragments)
{
if (fragments.IsNotNull() && fragments.Length > 0)
{
if (_childrenFragments.IsNull())
{
_childrenFragments = new List<FragmentBuilder>();
_childrenFragments = new List<IFragmentBuilder>();
}
base.AddFragments(fragments);
_childrenFragments.AddRange(fragments);
}
return this;
}
public override FragmentBuilder AddFragment(string path, FragmentBuilder fragment)
public override FragmentBuilder<T> AddFragment(string path, IFragmentBuilder fragment)
{
_childrenFragments ??= new List<FragmentBuilder>();
if (_childrenFragments.IsNull())
{
_childrenFragments = new List<IFragmentBuilder>();
}
base.AddFragment(path, fragment);
_childrenFragments.Add(fragment);

return this;
}
}

public class FragmentBuilder<T> : FragmentBuilder
{
public FragmentBuilder() : base() { }
public FragmentBuilder(string name)
{
base.OperationName(name);
}
private FragmentBuilder<T> Field(Expression<Func<T, object>> fieldSelector)
{
fieldSelector.ValidateNotNullArgument("fieldSelector");
Expand Down Expand Up @@ -109,7 +113,7 @@ public FragmentBuilder<T> Children<TChildren>(TypeQueryBuilder<TChildren> childr
base.Children(children);
return this;
}
private FragmentBuilder Recursive<TSub>(params Recursion[] recursives) where TSub : T
private FragmentBuilder<T> Recursive<TSub>(params Recursion[] recursives) where TSub : T
{
recursives.ValidateNotNullArgument("recursives");
if (!recursives.Any()) throw new ArgumentException("recursives can not be empty");
Expand Down Expand Up @@ -203,7 +207,7 @@ public FragmentBuilder<T> AddFragment<TProp>(Expression<Func<T, TProp>> fieldSel
fragment.ValidateNotNullArgument(nameof(fragment));

var fieldPath = fieldSelector.GetFieldPath();
base.AddFragment(fieldPath, fragment);
AddFragment(fieldPath, fragment);
return this;
}
public override GraphQLRequest GetQuery()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class GraphQueryBuilder : IQuery
private readonly OptiGraphOptions _optiGraphOptions;
private const string RequestMethod = "POST";
private const string UnCachedPath = "?cache=false";
private Dictionary<string, FragmentBuilder> _fragmentBuilders;
private Dictionary<string, IFragmentBuilder> _fragmentBuilders;
private readonly List<string> typeQueries = new List<string>();
public GraphQueryBuilder()
{
Expand Down Expand Up @@ -92,15 +92,15 @@ public TypeQueryBuilder<T> ForType<T>(TypeQueryBuilder<T> typeQueryBuilder)
typeQueryBuilder.Parent = this;
return typeQueryBuilder;
}
public void AddFragment(FragmentBuilder fragmentBuilder)
public void AddFragment(IFragmentBuilder fragmentBuilder)
{
if (_fragmentBuilders == null)
{
_fragmentBuilders = new Dictionary<string, FragmentBuilder>();
_fragmentBuilders = new Dictionary<string, IFragmentBuilder>();
}
_fragmentBuilders.TryAdd(fragmentBuilder.GetName(), fragmentBuilder);
}
public IEnumerable<FragmentBuilder> GetFragments()
public IEnumerable<IFragmentBuilder> GetFragments()
{
return _fragmentBuilders?.Values;
}
Expand Down Expand Up @@ -136,12 +136,12 @@ private string GetHmacHeader(byte[] requestBody)
DefaultHmacDeclarationFactory hmacDeclarationFactory =
new DefaultHmacDeclarationFactory(new Sha256HmacAlgorithm(Convert.FromBase64String(_optiGraphOptions.Secret)));
HmacMessage hmacMessage = GetHmacMessage(requestBody);
HmacDeclaration? hmacDeclaration = hmacDeclarationFactory.Create(hmacMessage);
HmacDeclaration hmacDeclaration = hmacDeclarationFactory.Create(hmacMessage);
return $"{hmacDeclaration}";
}
private HmacMessage GetHmacMessage(byte[] requestBody)
{
DefaultHmacMessageBuilder? messageBuilder = new DefaultHmacMessageBuilder()
DefaultHmacMessageBuilder messageBuilder = new DefaultHmacMessageBuilder()
.AddApplicationKey(_optiGraphOptions.AppKey)
.AddTarget(new Uri(GetServiceUrl()).PathAndQuery)
.AddMethod(RequestMethod)
Expand Down
2 changes: 1 addition & 1 deletion APIs/src/EpiServer.ContentGraph/Api/Querying/IQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ public interface IQuery
{
public Task<ContentGraphResult<TResult>> GetResultAsync<TResult>();
public Task<ContentGraphResult> GetResultAsync();
internal void AddFragment(FragmentBuilder fragmentBuilder);
internal bool HasFragment(string fragmentName);
internal void AddFragment(IFragmentBuilder fragmentBuilder);
internal void AddQuery(string typeQuery);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace EPiServer.ContentGraph.Api.Querying
{
public class SubTypeQueryBuilder<T> : BaseTypeQueryBuilder
public class SubTypeQueryBuilder<T> : BaseTypeQueryBuilder<T>
{
public SubTypeQueryBuilder():base()
{
Expand Down Expand Up @@ -68,12 +68,12 @@ public SubTypeQueryBuilder<T> Children<TChildren>(TypeQueryBuilder<TChildren> ch
base.Children(children);
return this;
}
public override SubTypeQueryBuilder<T> AddFragments(params FragmentBuilder[] fragments)
public override SubTypeQueryBuilder<T> AddFragments(params IFragmentBuilder[] fragments)
{
base.AddFragments(fragments);
return this;
}
protected override SubTypeQueryBuilder<T> AddFragment(FragmentBuilder fragment)
protected override SubTypeQueryBuilder<T> AddFragment(IFragmentBuilder fragment)
{
base.AddFragment(fragment);
return this;
Expand Down
44 changes: 8 additions & 36 deletions APIs/src/EpiServer.ContentGraph/Api/Querying/TypeQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

namespace EPiServer.ContentGraph.Api.Querying
{
public partial class TypeQueryBuilder<T> : TypeQueryBuilder
public partial class TypeQueryBuilder<T> : BaseTypeQueryBuilder<T>
{
private static IEnumerable<IFilterForVisitor>? _filters;
private static IEnumerable<IFilterForVisitor> _filters;
public TypeQueryBuilder(GraphQLRequest request) : base(request)
{
}
Expand Down Expand Up @@ -52,23 +52,23 @@ public TypeQueryBuilder<T> Children<TChildren>(TypeQueryBuilder<TChildren> child
return this;
}
[Obsolete("Use AddFragments method instead")]
public TypeQueryBuilder<T> Fragments(params FragmentBuilder[] fragments)
public TypeQueryBuilder<T> Fragments(params IFragmentBuilder[] fragments)
{
base.AddFragments(fragments);
return this;
}
public override TypeQueryBuilder<T> AddFragments(params FragmentBuilder[] fragments)
public override TypeQueryBuilder<T> AddFragments(params IFragmentBuilder[] fragments)
{
base.AddFragments(fragments);
return this;
}
[Obsolete("Use AddFragment method instead")]
public TypeQueryBuilder<T> Fragment(FragmentBuilder fragment)
public TypeQueryBuilder<T> Fragment(IFragmentBuilder fragment)
{
base.AddFragment(fragment);
return this;
}
protected override TypeQueryBuilder<T> AddFragment(FragmentBuilder fragment)
protected override TypeQueryBuilder<T> AddFragment(IFragmentBuilder fragment)
{
base.AddFragment(fragment);
return this;
Expand Down Expand Up @@ -125,26 +125,9 @@ public TypeQueryBuilder<T> Fields(params Expression<Func<T, object>>[] fieldSele
}
return this;
}
/// <summary>
/// Select properties of an IEnumerable of <typeparamref name="TField"/>
/// </summary>
/// <typeparam name="TField"></typeparam>
/// <param name="enumSelector">IEnumerable property of <typeparamref name="T"/></param>
/// <param name="fieldSelectors">Fields of type <typeparamref name="TField"/></param>
/// <returns></returns>
public TypeQueryBuilder<T> NestedFields<TField>(Expression<Func<T, IEnumerable<TField>>> enumSelector, params Expression<Func<TField, object>>[] fieldSelectors )
public override TypeQueryBuilder<T> NestedFields<TField>(Expression<Func<T, IEnumerable<TField>>> enumSelector, params Expression<Func<TField, object>>[] fieldSelectors)
{
enumSelector.ValidateNotNullArgument("fieldSelector");
fieldSelectors.ValidateNotNullArgument("fields");
var enumPath = enumSelector.GetFieldPath();
string fields = string.Empty;
foreach (var fieldSelector in fieldSelectors)
{
fields += fields.IsNullOrEmpty() ? fieldSelector.GetFieldPath(): $" {fieldSelector.GetFieldPath()}";
}
var combinedPath = ConvertNestedFieldToString.ConvertNestedFieldForQuery($"{enumPath}.{fields}");
Field(combinedPath);
return this;
return (TypeQueryBuilder<T>)base.NestedFields(enumSelector, fieldSelectors);
}
[Obsolete("Obsoleted. Use InlineFragment instead")]
/// <summary>
Expand Down Expand Up @@ -896,15 +879,4 @@ public override GraphQueryBuilder ToQuery()
return this.Parent != null ? (GraphQueryBuilder)this.Parent : new GraphQueryBuilder(_query, this);
}
}

public class TypeQueryBuilder : BaseTypeQueryBuilder
{
public TypeQueryBuilder(GraphQLRequest request) : base(request)
{
}
public TypeQueryBuilder() : base()
{
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,15 @@ public static GraphQueryBuilder EndType<T>(this TypeQueryBuilder<T> typeQueryBui
#endregion

#region Get results
public static async Task<ContentGraphResult<TResult>> GetResultAsync<TResult>(this TypeQueryBuilder typeQueryBuilder)
public static async Task<ContentGraphResult<TResult>> GetResultAsync<T,TResult>(this TypeQueryBuilder<T> typeQueryBuilder)
{
return await typeQueryBuilder.ToQuery().BuildQueries().GetResultAsync<TResult>();
}
public static async Task<ContentGraphResult> GetResultAsync(this TypeQueryBuilder typeQueryBuilder)
return await typeQueryBuilder.ToQuery().BuildQueries().GetResultAsync<TResult>();
}
public static async Task<ContentGraphResult> GetResultAsync<T>(this TypeQueryBuilder<T> typeQueryBuilder)
{
return await typeQueryBuilder.ToQuery().BuildQueries().GetResultAsync();
}
public static async Task<string> GetRawResultAsync(this TypeQueryBuilder typeQueryBuilder)
public static async Task<string> GetRawResultAsync<T>(this TypeQueryBuilder<T> typeQueryBuilder)
{
return await typeQueryBuilder.ToQuery().BuildQueries().GetRawResultAsync();
}
Expand Down
Loading

0 comments on commit 6fac62e

Please sign in to comment.