Skip to content

Commit

Permalink
Added support for query filters
Browse files Browse the repository at this point in the history
  • Loading branch information
klaasvandeweerdt committed Jun 25, 2023
1 parent 0352b7b commit 1000ce6
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 15 deletions.
10 changes: 10 additions & 0 deletions Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal sealed class ExecutionQuery
private List<ExecutionQuery> queries = new();
private HashSet<string> filters = new();
private HashSet<string> customFilters = new();
private string queryFilter = string.Empty;
private string endCursor = string.Empty;
private bool onlyQueryID = false;

Expand Down Expand Up @@ -138,6 +139,15 @@ internal HashSet<string> Filters
set => filters = value;
}

/// <summary>
/// Get or set the query filter.
/// </summary>
internal string QueryFilter
{
get => queryFilter;
set => queryFilter = value;
}

/// <summary>
/// Get or set all custom filters.
/// </summary>
Expand Down
47 changes: 36 additions & 11 deletions Scr/Sdk4me.GraphQL/Helpers/ExecutionQueryBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using Newtonsoft.Json.Linq;
using System.Reflection;
using System.Text;

namespace Sdk4me.GraphQL
Expand Down Expand Up @@ -76,10 +77,14 @@ internal static string GetGraphQLQuery(ExecutionQuery executionQuery)

if (executionQuery.Depth.Equals(0))
{
if (executionQuery.Filters.Count > 0 || executionQuery.CustomFilters.Count > 0)
if (executionQuery.Filters.Count > 0 || executionQuery.CustomFilters.Count > 0 || executionQuery.QueryFilter != string.Empty)
{
builder.Append($" filter:{{");
builder.Append(string.Join(" ", executionQuery.Filters));

if (executionQuery.Filters.Count > 0)
{
builder.Append(string.Join(" ", executionQuery.Filters));
}

if (executionQuery.CustomFilters.Count > 0)
{
Expand All @@ -89,6 +94,14 @@ internal static string GetGraphQLQuery(ExecutionQuery executionQuery)
builder.Append(string.Join(" ", executionQuery.CustomFilters));
builder.Append(']');
}

if (executionQuery.QueryFilter != string.Empty)
{
if (executionQuery.Filters.Count > 0 || executionQuery.CustomFilters.Count > 0)
builder.Append(' ');
builder.Append(executionQuery.QueryFilter);
}

builder.Append('}');
}

Expand Down Expand Up @@ -163,6 +176,7 @@ private static ExecutionQuery BuildQuery(IQuery query, int depth, int defaultIte
OrderByOrder = query.SelectedOrderByOrder,
ItemsPerRequest = query.SelectedItemsPerRequest ?? defaultItemsPerRequest,
Filters = query.Filters.ToHashSet(),
QueryFilter = query.QueryFilter,
CustomFilters = query.CustomFilters.ToHashSet(),
Fields = GetExecutionQueryFields(query.DataType, query.SelectedFields),
IsConnection = query.IsConnection,
Expand Down Expand Up @@ -300,7 +314,7 @@ private static List<ExecutionQueryField> GetExecutionQueryFields(Type dataType,
return retval;
}

internal static string BuildDateTimeFilter(string field, FilterOperator filterOperator, params DateTime[] values)
internal static string BuildDateTimeFilter(string field, FilterOperator filterOperator, params DateTime?[] values)
{
string[] serializedValue = SerializeObject(values);

Expand Down Expand Up @@ -344,6 +358,11 @@ internal static string BuildBooleanFilter(string field, FilterOperator filterOpe
throw new Sdk4meFilterException("Invalid boolean filter operator");
}

internal static string BuildQueryFilter(string? value)
{
return value == null ? string.Empty : $"query:{SerializeObject(value)}";
}

internal static string BuildCustomFilter(string name, FilterOperator filterOperator, params string?[] values)
{
if (filterOperator == FilterOperator.In || filterOperator == FilterOperator.NotIn || filterOperator == FilterOperator.Equals || filterOperator == FilterOperator.NotEquals)
Expand All @@ -359,7 +378,7 @@ internal static string BuildCustomFilter(string name, FilterOperator filterOpera
builder.Append(serializedValues.Length switch
{
0 => "[null]",
1 => $"[{string.Join(',', serializedValues)}]",
1 => $"[{serializedValues[0]}]",
_ => $"[{string.Join(',', serializedValues)}]"
});
builder.Append('}');
Expand All @@ -371,15 +390,15 @@ internal static string BuildCustomFilter(string name, FilterOperator filterOpera
}
else if (filterOperator == FilterOperator.Empty)
{
return $"customFilters:{{name:{SerializeObject(name)} values:[null]}}";
return $"{{name:{SerializeObject(name)} values:[null]}}";
}
else
{
throw new Sdk4meFilterException("Invalid custom filter operator");
}
}

internal static string BuildStringFilter(string field, FilterOperator filterOperator, params string[] values)
internal static string BuildStringFilter(string field, FilterOperator filterOperator, params string?[] values)
{
if (filterOperator == FilterOperator.In || filterOperator == FilterOperator.NotIn || filterOperator == FilterOperator.Equals || filterOperator == FilterOperator.NotEquals)
{
Expand All @@ -394,7 +413,7 @@ internal static string BuildStringFilter(string field, FilterOperator filterOper
builder.Append(serializedValues.Length switch
{
0 => "[]",
1 => $"{serializedValues[0]}",
1 => $"[{serializedValues[0]}]",
_ => $"[{string.Join(',', serializedValues)}]"
});
builder.Append('}');
Expand Down Expand Up @@ -429,11 +448,17 @@ private static string[] SerializeObject(params string?[] values)
return retval.ToArray();
}

private static string[] SerializeObject(params DateTime[] values)
private static string[] SerializeObject(params DateTime?[] values)
{
List<string> retval = new();
foreach (DateTime value in values)
retval.Add(JsonConvert.SerializeObject(value));
foreach (DateTime? value in values)
{
if (value == null)
retval.Add("null");
else
retval.Add(JsonConvert.SerializeObject(value));
}

return retval.ToArray();
}
}
Expand Down
5 changes: 5 additions & 0 deletions Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public interface IQuery
/// </summary>
public ImmutableHashSet<string> Filters { get; }

/// <summary>
/// Get the free format search query filter.
/// </summary>
public string QueryFilter { get; }

/// <summary>
/// Get all custom filters.
/// </summary>
Expand Down
29 changes: 25 additions & 4 deletions Scr/Sdk4me.GraphQL/Queries/Base/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public abstract class Query<TEntity, TFields, TView, TOrderBy> : IQuery
private readonly Dictionary<string, IQuery> queries = new();
private readonly HashSet<string> filters = new();
private readonly HashSet<string> customFilters = new();
private string queryFilter = string.Empty;
private string fieldName = string.Empty;
private string view = string.Empty;
private string orderByOrder = string.Empty;
Expand Down Expand Up @@ -110,6 +111,14 @@ public ImmutableHashSet<string> Filters
get => filters.ToImmutableHashSet();
}

/// <summary>
/// Get the free format search query filter.
/// </summary>
public string QueryFilter
{
get => queryFilter;
}

/// <summary>
/// Get all custom filters.
/// </summary>
Expand Down Expand Up @@ -263,7 +272,7 @@ internal protected TEntity Select(IQuery query)
/// <param name="values">The filter values.</param>
/// <returns>The current <see cref="IQuery"/>.</returns>
/// <exception cref="NullReferenceException"></exception>
public TEntity Filter(string field, FilterOperator filterOperator, params string[] values)
public TEntity Filter(string field, FilterOperator filterOperator, params string?[] values)
{
filters.Add(ExecutionQueryBuilder.BuildStringFilter(field, filterOperator, values));
return this as TEntity ?? throw new NullReferenceException(nameof(TEntity));
Expand All @@ -277,7 +286,7 @@ public TEntity Filter(string field, FilterOperator filterOperator, params string
/// <param name="values">The filter values.</param>
/// <returns>The current <see cref="IQuery"/>.</returns>
/// <exception cref="NullReferenceException"></exception>
public TEntity Filter(TFields field, FilterOperator filterOperator, params string[] values)
public TEntity Filter(TFields field, FilterOperator filterOperator, params string?[] values)
{
return Filter(GetEnumStringValue(field), filterOperator, values);
}
Expand All @@ -290,7 +299,7 @@ public TEntity Filter(TFields field, FilterOperator filterOperator, params strin
/// <param name="values">The filter values.</param>
/// <returns>The current <see cref="IQuery"/>.</returns>
/// <exception cref="NullReferenceException"></exception>
public TEntity Filter(string field, FilterOperator filterOperator, params DateTime[] values)
public TEntity Filter(string field, FilterOperator filterOperator, params DateTime?[] values)
{
filters.Add(ExecutionQueryBuilder.BuildDateTimeFilter(field, filterOperator, values));
return this as TEntity ?? throw new NullReferenceException(nameof(TEntity));
Expand All @@ -304,7 +313,7 @@ public TEntity Filter(string field, FilterOperator filterOperator, params DateTi
/// <param name="values">The filter values.</param>
/// <returns>The current <see cref="IQuery"/>.</returns>
/// <exception cref="NullReferenceException"></exception>
public TEntity Filter(TFields field, FilterOperator filterOperator, params DateTime[] values)
public TEntity Filter(TFields field, FilterOperator filterOperator, params DateTime?[] values)
{
return Filter(GetEnumStringValue(field), filterOperator, values);
}
Expand Down Expand Up @@ -336,6 +345,18 @@ public TEntity Filter(TFields field, FilterOperator filterOperator, bool value)
return Filter(GetEnumStringValue(field), filterOperator, value);
}

/// <summary>
/// Set the free format search query filter.
/// </summary>
/// <param name="value">The filter value.</param>
/// <returns>The current <see cref="IQuery"/>.</returns>
/// <exception cref="NullReferenceException"></exception>
public TEntity FreeFormatFilter(string? value)
{
queryFilter = ExecutionQueryBuilder.BuildQueryFilter(value);
return this as TEntity ?? throw new NullReferenceException(nameof(TEntity));
}

/// <summary>
/// Add a custom filter to the query.
/// </summary>
Expand Down

0 comments on commit 1000ce6

Please sign in to comment.