From 1000ce630713309df08bef6460dadebd332b3857 Mon Sep 17 00:00:00 2001 From: Klaas Vandeweerdt Date: Sun, 25 Jun 2023 05:37:20 +0200 Subject: [PATCH] Added support for query filters --- Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs | 10 ++++ .../Helpers/ExecutionQueryBuilder.cs | 47 ++++++++++++++----- Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs | 5 ++ Scr/Sdk4me.GraphQL/Queries/Base/Query.cs | 29 ++++++++++-- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs b/Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs index c0b4461..a44d196 100644 --- a/Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs +++ b/Scr/Sdk4me.GraphQL/Helpers/ExecutionQuery.cs @@ -17,6 +17,7 @@ internal sealed class ExecutionQuery private List queries = new(); private HashSet filters = new(); private HashSet customFilters = new(); + private string queryFilter = string.Empty; private string endCursor = string.Empty; private bool onlyQueryID = false; @@ -138,6 +139,15 @@ internal HashSet Filters set => filters = value; } + /// + /// Get or set the query filter. + /// + internal string QueryFilter + { + get => queryFilter; + set => queryFilter = value; + } + /// /// Get or set all custom filters. /// diff --git a/Scr/Sdk4me.GraphQL/Helpers/ExecutionQueryBuilder.cs b/Scr/Sdk4me.GraphQL/Helpers/ExecutionQueryBuilder.cs index 774616d..47813d9 100644 --- a/Scr/Sdk4me.GraphQL/Helpers/ExecutionQueryBuilder.cs +++ b/Scr/Sdk4me.GraphQL/Helpers/ExecutionQueryBuilder.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using Newtonsoft.Json.Linq; +using System.Reflection; using System.Text; namespace Sdk4me.GraphQL @@ -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) { @@ -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('}'); } @@ -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, @@ -300,7 +314,7 @@ private static List 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); @@ -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) @@ -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('}'); @@ -371,7 +390,7 @@ 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 { @@ -379,7 +398,7 @@ internal static string BuildCustomFilter(string name, FilterOperator filterOpera } } - 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) { @@ -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('}'); @@ -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 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(); } } diff --git a/Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs b/Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs index 5236c9f..d494e0d 100644 --- a/Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs +++ b/Scr/Sdk4me.GraphQL/Interfaces/IQuery.cs @@ -58,6 +58,11 @@ public interface IQuery /// public ImmutableHashSet Filters { get; } + /// + /// Get the free format search query filter. + /// + public string QueryFilter { get; } + /// /// Get all custom filters. /// diff --git a/Scr/Sdk4me.GraphQL/Queries/Base/Query.cs b/Scr/Sdk4me.GraphQL/Queries/Base/Query.cs index b480f3b..5670dc6 100644 --- a/Scr/Sdk4me.GraphQL/Queries/Base/Query.cs +++ b/Scr/Sdk4me.GraphQL/Queries/Base/Query.cs @@ -18,6 +18,7 @@ public abstract class Query : IQuery private readonly Dictionary queries = new(); private readonly HashSet filters = new(); private readonly HashSet customFilters = new(); + private string queryFilter = string.Empty; private string fieldName = string.Empty; private string view = string.Empty; private string orderByOrder = string.Empty; @@ -110,6 +111,14 @@ public ImmutableHashSet Filters get => filters.ToImmutableHashSet(); } + /// + /// Get the free format search query filter. + /// + public string QueryFilter + { + get => queryFilter; + } + /// /// Get all custom filters. /// @@ -263,7 +272,7 @@ internal protected TEntity Select(IQuery query) /// The filter values. /// The current . /// - 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)); @@ -277,7 +286,7 @@ public TEntity Filter(string field, FilterOperator filterOperator, params string /// The filter values. /// The current . /// - 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); } @@ -290,7 +299,7 @@ public TEntity Filter(TFields field, FilterOperator filterOperator, params strin /// The filter values. /// The current . /// - 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)); @@ -304,7 +313,7 @@ public TEntity Filter(string field, FilterOperator filterOperator, params DateTi /// The filter values. /// The current . /// - 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); } @@ -336,6 +345,18 @@ public TEntity Filter(TFields field, FilterOperator filterOperator, bool value) return Filter(GetEnumStringValue(field), filterOperator, value); } + /// + /// Set the free format search query filter. + /// + /// The filter value. + /// The current . + /// + public TEntity FreeFormatFilter(string? value) + { + queryFilter = ExecutionQueryBuilder.BuildQueryFilter(value); + return this as TEntity ?? throw new NullReferenceException(nameof(TEntity)); + } + /// /// Add a custom filter to the query. ///