Skip to content

Commit 952757e

Browse files
author
Viktor Tochonov
committed
Implement test Must parse all filter operations and join parse field conditions
1 parent e788d7d commit 952757e

File tree

5 files changed

+198
-27
lines changed

5 files changed

+198
-27
lines changed

src/FSharp.Data.GraphQL.Server.Middleware/ObjectListFilter.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ type ObjectListFilter =
1212
| Not of ObjectListFilter
1313
| Equals of FieldFilter<System.IComparable>
1414
| GreaterThan of FieldFilter<System.IComparable>
15+
| GreaterThanOrEqual of FieldFilter<System.IComparable>
1516
| LessThan of FieldFilter<System.IComparable>
17+
| LessThanOrEqual of FieldFilter<System.IComparable>
1618
| In of FieldFilter<System.IComparable list>
1719
| StartsWith of FieldFilter<string>
1820
| EndsWith of FieldFilter<string>
@@ -159,6 +161,8 @@ module ObjectListFilter =
159161
| Equals f -> Expression.Equal (Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
160162
| GreaterThan f -> Expression.GreaterThan (Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
161163
| LessThan f -> Expression.LessThan (Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
164+
| GreaterThanOrEqual f -> Expression.GreaterThanOrEqual(Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
165+
| LessThanOrEqual f -> Expression.LessThanOrEqual (Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
162166
| StartsWith f ->
163167
Expression.Call (Expression.PropertyOrField (param, f.FieldName), StringStartsWithMethod, Expression.Constant (f.Value))
164168
| EndsWith f ->
@@ -182,7 +186,6 @@ module ObjectListFilter =
182186
let ``member`` = Expression.PropertyOrField (param, f.FieldName)
183187
let values = f.Value |> List.map (fun v -> Expression.Equal(``member``, Expression.Constant(v)))
184188
(values |> List.reduce (fun acc expr -> Expression.OrElse(acc, expr))) :> Expression
185-
186189
| OfTypes types ->
187190
types
188191
|> Seq.map (fun t -> buildTypeDiscriminatorCheck param t)

src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,35 @@ open FSharp.Data.GraphQL.Ast
1212

1313
let internal removeNoFilter = Seq.where (fun filter -> filter <> NoFilter)
1414

15+
type private ComparisonOperator =
16+
| EndsWith of string
17+
| StartsWith of string
18+
| Contains of string
19+
| Equals of string
20+
| GreaterThan of string
21+
| GreaterThanOrEqual of string
22+
| LessThan of string
23+
| LessThanOrEqual of string
24+
1525
let rec private coerceObjectListFilterInput x : Result<ObjectListFilter, IGQLError list> =
1626

17-
let (|EndsWith|StartsWith|GreaterThan|LessThan|Contains|Equals|) (s : string) =
27+
let parseFieldCondition (s : string) =
1828
let s = s.ToLowerInvariant ()
1929
let prefix (suffix : string) (s : string) = s.Substring (0, s.Length - suffix.Length)
2030
match s with
2131
| s when s.EndsWith ("_ends_with") && s.Length > "_ends_with".Length -> EndsWith (prefix "_ends_with" s)
2232
| s when s.EndsWith ("_ew") && s.Length > "_ew".Length -> EndsWith (prefix "_ew" s)
2333
| s when s.EndsWith ("_starts_with") && s.Length > "_starts_with".Length -> StartsWith (prefix "_starts_with" s)
2434
| s when s.EndsWith ("_sw") && s.Length > "_sw".Length -> StartsWith (prefix "_sw" s)
35+
| s when s.EndsWith ("_contains") && s.Length > "_contains".Length -> Contains (prefix "_contains" s)
2536
| s when s.EndsWith ("_greater_than") && s.Length > "_greater_than".Length -> GreaterThan (prefix "_greater_than" s)
2637
| s when s.EndsWith ("_gt") && s.Length > "_gt".Length -> GreaterThan (prefix "_gt" s)
38+
| s when s.EndsWith ("_greater_than_or_equal") && s.Length > "_greater_than_or_equal".Length -> GreaterThanOrEqual (prefix "_greater_than_or_equal" s)
39+
| s when s.EndsWith ("_gte") && s.Length > "_gte".Length -> GreaterThanOrEqual (prefix "_gte" s)
2740
| s when s.EndsWith ("_less_than") && s.Length > "_less_than".Length -> LessThan (prefix "_less_than" s)
2841
| s when s.EndsWith ("_lt") && s.Length > "_lt".Length -> LessThan (prefix "_lt" s)
29-
| s when s.EndsWith ("_contains") && s.Length > "_contains".Length -> Contains (prefix "_contains" s)
42+
| s when s.EndsWith ("_less_than_or_equal") && s.Length > "_less_than_or_equal".Length -> LessThanOrEqual (prefix "_less_than_or_equal" s)
43+
| s when s.EndsWith ("_lte") && s.Length > "_lte".Length -> LessThanOrEqual (prefix "_lte" s)
3044
| s -> Equals s
3145

3246
let (|EquatableValue|Other|) v =
@@ -76,25 +90,27 @@ let rec private coerceObjectListFilterInput x : Result<ObjectListFilter, IGQLErr
7690
match coerceResults with
7791
| Error errs -> Error errs
7892
| Ok coerced -> coerced |> removeNoFilter |> Seq.toList |> Ok
79-
match name, value with
93+
match parseFieldCondition name, value with
8094
| Equals "and", ListValue fields -> fields |> mapFilters |> Result.map buildAnd
8195
| Equals "or", ListValue fields -> fields |> mapFilters |> Result.map buildOr
8296
| Equals "not", ObjectValue value ->
8397
match mapInput value with
8498
| Error errs -> Error errs
8599
| Ok NoFilter -> Ok NoFilter
86100
| Ok filter -> Ok (Not filter)
87-
| EndsWith fname, StringValue value -> Ok (EndsWith { FieldName = fname; Value = value })
88-
| StartsWith fname, StringValue value -> Ok (StartsWith { FieldName = fname; Value = value })
89-
| Contains fname, StringValue value -> Ok (Contains { FieldName = fname; Value = value })
101+
| EndsWith fname, StringValue value -> Ok (ObjectListFilter.EndsWith { FieldName = fname; Value = value })
102+
| StartsWith fname, StringValue value -> Ok (ObjectListFilter.StartsWith { FieldName = fname; Value = value })
103+
| Contains fname, StringValue value -> Ok (ObjectListFilter.Contains { FieldName = fname; Value = value })
90104
| Equals fname, ObjectValue value ->
91105
match mapInput value with
92106
| Error errs -> Error errs
93107
| Ok NoFilter -> Ok NoFilter
94108
| Ok filter -> Ok (FilterField { FieldName = fname; Value = filter })
95-
| Equals fname, EquatableValue value -> Ok (Equals { FieldName = fname; Value = value })
96-
| GreaterThan fname, ComparableValue value -> Ok (GreaterThan { FieldName = fname; Value = value })
97-
| LessThan fname, ComparableValue value -> Ok (LessThan { FieldName = fname; Value = value })
109+
| Equals fname, EquatableValue value -> Ok (ObjectListFilter.Equals { FieldName = fname; Value = value })
110+
| GreaterThan fname, ComparableValue value -> Ok (ObjectListFilter.GreaterThan { FieldName = fname; Value = value })
111+
| GreaterThanOrEqual fname, ComparableValue value -> Ok (ObjectListFilter.GreaterThanOrEqual { FieldName = fname; Value = value })
112+
| LessThan fname, ComparableValue value -> Ok (ObjectListFilter.LessThan { FieldName = fname; Value = value })
113+
| LessThanOrEqual fname, ComparableValue value -> Ok (ObjectListFilter.LessThanOrEqual { FieldName = fname; Value = value })
98114
| _ -> Ok NoFilter
99115

100116
and mapInput value =

src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace rec FSharp.Data.GraphQL
22

33
open System.Linq
4+
open System.Collections.Generic
45
open FsToolkit.ErrorHandling
56

67
module internal ValueOption =
@@ -11,6 +12,12 @@ module internal Option =
1112

1213
let mapValueOption mapping voption = voption |> ValueOption.map mapping |> ValueOption.toOption
1314

15+
[<AutoOpen>]
16+
module KeyValuePair =
17+
18+
let inline kvp key value = KeyValuePair (key, value)
19+
let inline kvpObj key (value : obj) = KeyValuePair (key, value)
20+
1421
[<AutoOpen>]
1522
module internal ValueTuple =
1623

0 commit comments

Comments
 (0)