Skip to content

Commit 2dfff16

Browse files
author
Viktor Tochonov
committed
Implemented IN case for ObjectListFilter and formatted files
1 parent c9dd83e commit 2dfff16

File tree

3 files changed

+68
-28
lines changed

3 files changed

+68
-28
lines changed

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

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type ObjectListFilter =
1313
| Equals of FieldFilter<System.IComparable>
1414
| GreaterThan of FieldFilter<System.IComparable>
1515
| LessThan of FieldFilter<System.IComparable>
16+
| In of FieldFilter<System.IComparable list>
1617
| StartsWith of FieldFilter<string>
1718
| EndsWith of FieldFilter<string>
1819
| Contains of FieldFilter<string>
@@ -25,10 +26,6 @@ open System.Linq.Expressions
2526
open System.Runtime.InteropServices
2627
open System.Reflection
2728

28-
/// <remarks>
29-
/// Represents a value that can be either None or Some.
30-
/// </remarks>
31-
3229
/// <summary>
3330
/// Allows to specify discriminator comparison or discriminator getter
3431
/// and a function that return discriminator value depending on entity type
@@ -62,32 +59,25 @@ open System.Reflection
6259
[<Struct>]
6360
type ObjectListFilterLinqOptions<'T, 'D> (
6461
[<Optional>] compareDiscriminator : Expression<Func<'T, 'D, bool>> | null,
65-
[<Optional>] getDiscriminatorValue : (Type -> 'D) | null,
66-
[<Optional>] serializeMemberName : (MemberInfo -> string) | null
62+
[<Optional>] getDiscriminatorValue : (Type -> 'D) | null
6763
) =
6864

6965
member _.CompareDiscriminator = compareDiscriminator |> ValueOption.ofObj
7066
member _.GetDiscriminatorValue = getDiscriminatorValue |> ValueOption.ofObj
71-
//member _.SerializeMemberName = serializeMemberName |> ValueOption.ofObj
7267

73-
static member None = ObjectListFilterLinqOptions<'T, 'D> (null, null, null)
68+
static member None = ObjectListFilterLinqOptions<'T, 'D> (null, null)
7469

7570
static member GetCompareDiscriminator (getDiscriminatorValue : Expression<Func<'T, 'D>>) =
7671
let tParam = Expression.Parameter (typeof<'T>, "x")
7772
let dParam = Expression.Parameter (typeof<'D>, "d")
7873
let body = Expression.Equal(Expression.Invoke(getDiscriminatorValue, tParam), dParam)
7974
Expression.Lambda<Func<'T, 'D, bool>> (body, tParam, dParam)
8075

81-
new (getDiscriminator : Expression<Func<'T, 'D>>) = ObjectListFilterLinqOptions<'T, 'D> (ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, null, null)
82-
new (compareDiscriminator : Expression<Func<'T, 'D, bool>>) = ObjectListFilterLinqOptions<'T, 'D> (compareDiscriminator, null, null)
83-
new (getDiscriminatorValue : Type -> 'D) = ObjectListFilterLinqOptions<'T, 'D> (null, getDiscriminatorValue, null)
84-
//new (serializeMemberName : MemberInfo -> string) = ObjectListFilterLinqOptions<'T, 'D> (null, null, serializeMemberName)
85-
86-
new (getDiscriminator : Expression<Func<'T, 'D>>, getDiscriminatorValue : Type -> 'D) = ObjectListFilterLinqOptions<'T, 'D> (ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, getDiscriminatorValue, null)
76+
new (getDiscriminator : Expression<Func<'T, 'D>>) = ObjectListFilterLinqOptions<'T, 'D> (ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, null)
77+
new (compareDiscriminator : Expression<Func<'T, 'D, bool>>) = ObjectListFilterLinqOptions<'T, 'D> (compareDiscriminator, null)
78+
new (getDiscriminatorValue : Type -> 'D) = ObjectListFilterLinqOptions<'T, 'D> (compareDiscriminator = null , getDiscriminatorValue = getDiscriminatorValue)
8779

88-
//new (getDiscriminator : Expression<Func<'T, 'D>>, serializeMemberName : MemberInfo -> string) = ObjectListFilterLinqOptions<'T, 'D> (ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, null, serializeMemberName)
89-
//new (compareDiscriminator : Expression<Func<'T, 'D, bool>>, serializeMemberName : MemberInfo -> string) = ObjectListFilterLinqOptions<'T, 'D> (compareDiscriminator, null, serializeMemberName)
90-
//new (getDiscriminatorValue : Type -> 'D, serializeMemberName : MemberInfo -> string) = ObjectListFilterLinqOptions<'T, 'D> (null, getDiscriminatorValue, serializeMemberName)
80+
new (getDiscriminator : Expression<Func<'T, 'D>>, getDiscriminatorValue : Type -> 'D) = ObjectListFilterLinqOptions<'T, 'D> (ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, getDiscriminatorValue)
9181

9282
/// Contains tooling for working with ObjectListFilter.
9383
module ObjectListFilter =
@@ -190,6 +180,11 @@ module ObjectListFilter =
190180
Expression.Call (getEnumerableContainsMethod field.FieldType, Expression.PropertyOrField (param, f.FieldName), Expression.Constant (f.Value))
191181
| _ ->
192182
Expression.Call (``member``, StringContainsMethod, Expression.Constant (f.Value))
183+
| In f ->
184+
let ``member`` = Expression.PropertyOrField (param, f.FieldName)
185+
let values = f.Value |> List.map (fun v -> Expression.Equal(``member``, Expression.Constant(v)))
186+
(values |> List.reduce (fun acc expr -> Expression.OrElse(acc, expr))) :> Expression
187+
193188
| OfTypes types ->
194189
types
195190
|> Seq.map (fun t -> buildTypeDiscriminatorCheck param t)
@@ -208,19 +203,19 @@ module ObjectListFilter =
208203
| ValueNone, ValueNone ->
209204
// use __typename from filter and do type.ToSting() for values
210205
let typename = t.FullName
211-
Expression.Equal(Expression.PropertyOrField(param, "__typename"), Expression.Constant(typename)) :> Expression
206+
Expression.Equal (Expression.PropertyOrField (param, "__typename"), Expression.Constant (typename)) :> Expression
212207
| ValueSome discExpr, ValueNone ->
213208
// use discriminator and do type.ToSting() for values
214209
let typename = t.FullName
215-
Expression.Invoke(discExpr, param, Expression.Constant(typename)) :> Expression
210+
Expression.Invoke (discExpr, param, Expression.Constant (typename)) :> Expression
216211
| ValueNone, ValueSome discValueFn ->
217212
// use __typename from filter and execute discValueFn for values
218213
let discriminatorValue = discValueFn t
219-
Expression.Equal(Expression.PropertyOrField(param, "__typename"), Expression.Constant(discriminatorValue)) :> Expression
214+
Expression.Equal (Expression.PropertyOrField (param, "__typename"), Expression.Constant (discriminatorValue)) :> Expression
220215
| ValueSome discExpr, ValueSome discValueFn ->
221216
// use discriminator and execute discValueFn for values
222217
let discriminatorValue = discValueFn t
223-
Expression.Invoke(discExpr, param, Expression.Constant (discriminatorValue))
218+
Expression.Invoke (discExpr, param, Expression.Constant (discriminatorValue))
224219

225220
let queryExpr =
226221
let param = Expression.Parameter (typeof<'T>, "x")

tests/FSharp.Data.GraphQL.Tests/ObjectListFilterLinqTests.fs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,40 @@ let ``ObjectListFilter works with OR operator``() =
119119
result.Contact |> equals { Email = "[email protected]" }
120120
result.Friends |> equals [ { Email = "[email protected]" }; { Email = "[email protected]" } ]
121121

122+
[<Fact>]
123+
let ``ObjectListFilter works with IN operator for string type field``() =
124+
let filter =
125+
In { FieldName = "firstName"; Value = ["Jeneffer"; "Ben"] }
126+
let queryable = data.AsQueryable()
127+
let filteredData = queryable.Apply(filter) |> Seq.toList
128+
List.length filteredData |> equals 2
129+
let result = List.head filteredData
130+
result.ID |> equals 4
131+
result.FirstName |> equals "Ben"
132+
result.LastName |> equals "Adams"
133+
result.Contact |> equals { Email = "[email protected]" }
134+
result.Friends |> equals [ { Email = "[email protected]" }; { Email = "[email protected]" } ]
135+
let result2 = List.last filteredData
136+
result2.ID |> equals 7
137+
result2.FirstName |> equals "Jeneffer"
138+
result2.LastName |> equals "Trif"
139+
result2.Contact |> equals { Email = "[email protected]" }
140+
result2.Friends |> equals [ { Email = "[email protected]" } ]
141+
142+
[<Fact>]
143+
let ``ObjectListFilter works with IN operator for int type field``() =
144+
let filter =
145+
In { FieldName = "id"; Value = [4; 2; 7] }
146+
let queryable = data.AsQueryable()
147+
let filteredData = queryable.Apply(filter) |> Seq.toList
148+
List.length filteredData |> equals 3
149+
let result = List.head filteredData
150+
result.ID |> equals 4
151+
result.FirstName |> equals "Ben"
152+
result.LastName |> equals "Adams"
153+
result.Contact |> equals { Email = "[email protected]" }
154+
result.Friends |> equals [ { Email = "[email protected]" }; { Email = "[email protected]" } ]
155+
122156
[<Fact>]
123157
let ``ObjectListFilter works with FilterField operator``() =
124158
let filter =

tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,24 @@ let linqArgs =
7171
Define.Input("after", Nullable StringType) ]
7272

7373
let schema =
74-
Schema(Define.Object("RootQuery",
75-
[ Define.Field("people", ListOf Person, "", linqArgs,
76-
fun ctx () ->
77-
let info = ctx.ExecutionInfo
78-
let queryable = data.AsQueryable()
79-
let result = queryable.Apply(info) |> Seq.toList
80-
result) ]))
74+
Schema (
75+
Define.Object (
76+
"RootQuery",
77+
[
78+
Define.Field (
79+
"people",
80+
ListOf Person,
81+
"",
82+
linqArgs,
83+
fun ctx () ->
84+
let info = ctx.ExecutionInfo
85+
let queryable = data.AsQueryable ()
86+
let result = queryable.Apply (info) |> Seq.toList
87+
result
88+
)
89+
]
90+
)
91+
)
8192

8293
let schemaProcessor = Executor(schema)
8394

0 commit comments

Comments
 (0)