Add byFields to PostgreSQL impl

- Swap howMatched and fields throughout
- Existing tests pass; still need new ones for byFields
This commit is contained in:
Daniel J. Summers 2024-08-07 23:23:28 -04:00
parent d131eda56e
commit 8a15bdce2e
7 changed files with 401 additions and 135 deletions

View File

@ -50,6 +50,11 @@ module Extensions =
WithProps.Count.all tableName (Sql.existingConnection conn) WithProps.Count.all tableName (Sql.existingConnection conn)
/// Count matching documents using a JSON field comparison query (->> =) /// Count matching documents using a JSON field comparison query (->> =)
member conn.countByFields tableName howMatched fields =
WithProps.Count.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Count matching documents using a JSON field comparison query (->> =)
[<System.Obsolete "Use countByFields instead; will be removed in v4">]
member conn.countByField tableName field = member conn.countByField tableName field =
WithProps.Count.byField tableName field (Sql.existingConnection conn) WithProps.Count.byField tableName field (Sql.existingConnection conn)
@ -66,6 +71,11 @@ module Extensions =
WithProps.Exists.byId tableName docId (Sql.existingConnection conn) WithProps.Exists.byId tableName docId (Sql.existingConnection conn)
/// Determine if documents exist using a JSON field comparison query (->> =) /// Determine if documents exist using a JSON field comparison query (->> =)
member conn.existsByFields tableName howMatched fields =
WithProps.Exists.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Determine if documents exist using a JSON field comparison query (->> =)
[<System.Obsolete "Use existsByFields instead; will be removed in v4">]
member conn.existsByField tableName field = member conn.existsByField tableName field =
WithProps.Exists.byField tableName field (Sql.existingConnection conn) WithProps.Exists.byField tableName field (Sql.existingConnection conn)
@ -86,6 +96,11 @@ module Extensions =
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn) WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
member conn.findByFields<'TDoc> tableName howMatched fields =
WithProps.Find.byFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =)
[<System.Obsolete "Use findByFields instead; will be removed in v4">]
member conn.findByField<'TDoc> tableName field = member conn.findByField<'TDoc> tableName field =
WithProps.Find.byField<'TDoc> tableName field (Sql.existingConnection conn) WithProps.Find.byField<'TDoc> tableName field (Sql.existingConnection conn)
@ -98,6 +113,11 @@ module Extensions =
WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn) WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
[<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
member conn.findFirstByField<'TDoc> tableName field = member conn.findFirstByField<'TDoc> tableName field =
WithProps.Find.firstByField<'TDoc> tableName field (Sql.existingConnection conn) WithProps.Find.firstByField<'TDoc> tableName field (Sql.existingConnection conn)
@ -122,6 +142,11 @@ module Extensions =
WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn) WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn)
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
member conn.patchByFields tableName howMatched fields (patch: 'TPatch) =
WithProps.Patch.byFields tableName howMatched fields patch (Sql.existingConnection conn)
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<System.Obsolete "Use patchByFields instead; will be removed in v4">]
member conn.patchByField tableName field (patch: 'TPatch) = member conn.patchByField tableName field (patch: 'TPatch) =
WithProps.Patch.byField tableName field patch (Sql.existingConnection conn) WithProps.Patch.byField tableName field patch (Sql.existingConnection conn)
@ -137,7 +162,12 @@ module Extensions =
member conn.removeFieldsById tableName (docId: 'TKey) fieldNames = member conn.removeFieldsById tableName (docId: 'TKey) fieldNames =
WithProps.RemoveFields.byId tableName docId fieldNames (Sql.existingConnection conn) WithProps.RemoveFields.byId tableName docId fieldNames (Sql.existingConnection conn)
/// Remove fields from documents via a comparison on JSON fields in the document
member conn.removeFieldsByFields tableName howMatched fields fieldNames =
WithProps.RemoveFields.byFields tableName howMatched fields fieldNames (Sql.existingConnection conn)
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on a JSON field in the document
[<System.Obsolete "Use removeFieldsByFields instead; will be removed in v4">]
member conn.removeFieldsByField tableName field fieldNames = member conn.removeFieldsByField tableName field fieldNames =
WithProps.RemoveFields.byField tableName field fieldNames (Sql.existingConnection conn) WithProps.RemoveFields.byField tableName field fieldNames (Sql.existingConnection conn)
@ -153,7 +183,11 @@ module Extensions =
member conn.deleteById tableName (docId: 'TKey) = member conn.deleteById tableName (docId: 'TKey) =
WithProps.Delete.byId tableName docId (Sql.existingConnection conn) WithProps.Delete.byId tableName docId (Sql.existingConnection conn)
member conn.deleteByFields tableName howMatched fields =
WithProps.Delete.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Delete documents by matching a JSON field comparison query (->> =) /// Delete documents by matching a JSON field comparison query (->> =)
[<System.Obsolete "Use deleteByFields instead; will be removed in v4">]
member conn.deleteByField tableName field = member conn.deleteByField tableName field =
WithProps.Delete.byField tableName field (Sql.existingConnection conn) WithProps.Delete.byField tableName field (Sql.existingConnection conn)
@ -225,6 +259,12 @@ type NpgsqlConnectionCSharpExtensions =
/// Count matching documents using a JSON field comparison query (->> =) /// Count matching documents using a JSON field comparison query (->> =)
[<Extension>] [<Extension>]
static member inline CountByFields(conn, tableName, howMatched, fields) =
WithProps.Count.ByFields(tableName, howMatched, fields, Sql.existingConnection conn)
/// Count matching documents using a JSON field comparison query (->> =)
[<Extension>]
[<System.Obsolete "Use CountByFields instead; will be removed in v4">]
static member inline CountByField(conn, tableName, field) = static member inline CountByField(conn, tableName, field) =
WithProps.Count.byField tableName field (Sql.existingConnection conn) WithProps.Count.byField tableName field (Sql.existingConnection conn)
@ -245,6 +285,12 @@ type NpgsqlConnectionCSharpExtensions =
/// Determine if documents exist using a JSON field comparison query (->> =) /// Determine if documents exist using a JSON field comparison query (->> =)
[<Extension>] [<Extension>]
static member inline ExistsByFields(conn, tableName, howMatched, fields) =
WithProps.Exists.ByFields(tableName, howMatched, fields, Sql.existingConnection conn)
/// Determine if documents exist using a JSON field comparison query (->> =)
[<Extension>]
[<System.Obsolete "Use ExistsByFields instead; will be removed in v4">]
static member inline ExistsByField(conn, tableName, field) = static member inline ExistsByField(conn, tableName, field) =
WithProps.Exists.byField tableName field (Sql.existingConnection conn) WithProps.Exists.byField tableName field (Sql.existingConnection conn)
@ -270,6 +316,12 @@ type NpgsqlConnectionCSharpExtensions =
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
[<Extension>] [<Extension>]
static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) =
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =)
[<Extension>]
[<System.Obsolete "Use FindByFields instead; will be removed in v4">]
static member inline FindByField<'TDoc>(conn, tableName, field) = static member inline FindByField<'TDoc>(conn, tableName, field) =
WithProps.Find.ByField<'TDoc>(tableName, field, Sql.existingConnection conn) WithProps.Find.ByField<'TDoc>(tableName, field, Sql.existingConnection conn)
@ -283,8 +335,14 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) = static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) =
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn) WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
[<Extension>] [<Extension>]
static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) =
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
[<Extension>]
[<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">]
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) = static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
WithProps.Find.FirstByField<'TDoc>(tableName, field, Sql.existingConnection conn) WithProps.Find.FirstByField<'TDoc>(tableName, field, Sql.existingConnection conn)
@ -315,6 +373,12 @@ type NpgsqlConnectionCSharpExtensions =
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<Extension>] [<Extension>]
static member inline PatchByFields(conn, tableName, howMatched, fields, patch: 'TPatch) =
WithProps.Patch.ByFields(tableName, howMatched, fields, patch, Sql.existingConnection conn)
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<Extension>]
[<System.Obsolete "Use PatchByFields instead; will be removed in v4">]
static member inline PatchByField(conn, tableName, field, patch: 'TPatch) = static member inline PatchByField(conn, tableName, field, patch: 'TPatch) =
WithProps.Patch.byField tableName field patch (Sql.existingConnection conn) WithProps.Patch.byField tableName field patch (Sql.existingConnection conn)
@ -332,9 +396,15 @@ type NpgsqlConnectionCSharpExtensions =
[<Extension>] [<Extension>]
static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) = static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) =
WithProps.RemoveFields.ById(tableName, docId, fieldNames, Sql.existingConnection conn) WithProps.RemoveFields.ById(tableName, docId, fieldNames, Sql.existingConnection conn)
/// Remove fields from documents via a comparison on JSON fields in the document
[<Extension>]
static member inline RemoveFieldsByFields(conn, tableName, howMatched, fields, fieldNames) =
WithProps.RemoveFields.ByFields(tableName, howMatched, fields, fieldNames, Sql.existingConnection conn)
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on a JSON field in the document
[<Extension>] [<Extension>]
[<System.Obsolete "Use RemoveFieldsByFields instead; will be removed in v4">]
static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) = static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) =
WithProps.RemoveFields.ByField(tableName, field, fieldNames, Sql.existingConnection conn) WithProps.RemoveFields.ByField(tableName, field, fieldNames, Sql.existingConnection conn)
@ -352,9 +422,15 @@ type NpgsqlConnectionCSharpExtensions =
[<Extension>] [<Extension>]
static member inline DeleteById(conn, tableName, docId: 'TKey) = static member inline DeleteById(conn, tableName, docId: 'TKey) =
WithProps.Delete.byId tableName docId (Sql.existingConnection conn) WithProps.Delete.byId tableName docId (Sql.existingConnection conn)
/// Delete documents by matching a JSON field comparison query (->> =) /// Delete documents by matching a JSON field comparison query (->> =)
[<Extension>] [<Extension>]
static member inline DeleteByFields(conn, tableName, howMatched, fields) =
WithProps.Delete.ByFields(tableName, howMatched, fields, Sql.existingConnection conn)
/// Delete documents by matching a JSON field comparison query (->> =)
[<Extension>]
[<System.Obsolete "Use DeleteByFields instead; will be removed in v4">]
static member inline DeleteByField(conn, tableName, field) = static member inline DeleteByField(conn, tableName, field) =
WithProps.Delete.byField tableName field (Sql.existingConnection conn) WithProps.Delete.byField tableName field (Sql.existingConnection conn)

View File

@ -127,7 +127,7 @@ module Query =
/// Create a WHERE clause fragment to implement a comparison on fields in a JSON document /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
[<CompiledName "FSharpWhereByFields">] [<CompiledName "FSharpWhereByFields">]
let whereByFields fields howMatched = let whereByFields howMatched fields =
let name = ParameterName() let name = ParameterName()
fields fields
|> List.map (fun it -> |> List.map (fun it ->
@ -145,19 +145,19 @@ module Query =
|> String.concat (match howMatched with Any -> " OR " | All -> " AND ") |> String.concat (match howMatched with Any -> " OR " | All -> " AND ")
/// Create a WHERE clause fragment to implement a comparison on fields in a JSON document /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
let WhereByFields(fields: Field seq, howMatched) = let WhereByFields(howMatched, fields: Field seq) =
whereByFields (List.ofSeq fields) howMatched whereByFields howMatched (List.ofSeq fields)
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
[<CompiledName "WhereByField">] [<CompiledName "WhereByField">]
[<System.Obsolete "Use WhereByFields instead; will be removed in v4">] [<System.Obsolete "Use WhereByFields instead; will be removed in v4">]
let whereByField field paramName = let whereByField field paramName =
whereByFields [ { field with ParameterName = Some paramName } ] Any whereByFields Any [ { field with ParameterName = Some paramName } ]
/// Create a WHERE clause fragment to implement an ID-based query /// Create a WHERE clause fragment to implement an ID-based query
[<CompiledName "WhereById">] [<CompiledName "WhereById">]
let whereById paramName = let whereById paramName =
whereByFields [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ] Any whereByFields Any [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ]
/// Table and index definition queries /// Table and index definition queries
module Definition = module Definition =
@ -197,11 +197,20 @@ module Query =
let all tableName = let all tableName =
$"SELECT COUNT(*) AS it FROM %s{tableName}" $"SELECT COUNT(*) AS it FROM %s{tableName}"
/// Query to count matching documents using a text comparison on JSON fields
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
$"SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByFields howMatched fields}"
/// Query to count matching documents using a text comparison on a JSON field /// Query to count matching documents using a text comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any byFields tableName Any [ field ]
|> sprintf "SELECT COUNT(*) AS it FROM %s WHERE %s" tableName
/// Query to count matching documents using a text comparison on JSON fields
let ByFields tableName howMatched fields =
byFields tableName howMatched (List.ofSeq fields)
/// Query to count matching documents using a JSON containment query (@>) /// Query to count matching documents using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -221,12 +230,21 @@ module Query =
let byId tableName = let byId tableName =
$"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereById "@id"}) AS it""" $"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereById "@id"}) AS it"""
/// Query to determine if documents exist using a comparison on JSON fields
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereByFields howMatched fields}) AS it"
/// Query to determine if documents exist using a comparison on a JSON field /// Query to determine if documents exist using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any byFields tableName Any [ field ]
|> sprintf "SELECT EXISTS (SELECT 1 FROM %s WHERE %s) AS it" tableName
/// Query to determine if documents exist using a comparison on JSON fields
let ByFields tableName howMatched fields =
byFields tableName howMatched (List.ofSeq fields)
/// Query to determine if documents exist using a JSON containment query (@>) /// Query to determine if documents exist using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
let byContains tableName = let byContains tableName =
@ -245,11 +263,20 @@ module Query =
let byId tableName = let byId tableName =
$"""{Query.selectFromTable tableName} WHERE {whereById "@id"}""" $"""{Query.selectFromTable tableName} WHERE {whereById "@id"}"""
/// Query to retrieve documents using a comparison on JSON fields
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
$"{Query.selectFromTable tableName} WHERE {whereByFields howMatched fields}"
/// Query to retrieve documents using a comparison on a JSON field /// Query to retrieve documents using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any byFields tableName Any [ field ]
|> sprintf "%s WHERE %s" (Query.selectFromTable tableName)
/// Query to retrieve documents using a comparison on JSON fields
let ByFields tableName howMatched fields =
byFields tableName howMatched (List.ofSeq fields)
/// Query to retrieve documents using a JSON containment query (@>) /// Query to retrieve documents using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -273,11 +300,21 @@ module Query =
let byId tableName = let byId tableName =
whereById "@id" |> update tableName whereById "@id" |> update tableName
/// Query to patch documents match JSON field comparisons (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
whereByFields howMatched fields |> update tableName
/// Query to patch documents match a JSON field comparison (->> =) /// Query to patch documents match a JSON field comparison (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any |> update tableName byFields tableName Any [ field ]
/// Query to patch documents match JSON field comparisons (->> =)
let ByFields tableName howMatched fields =
whereByFields howMatched (List.ofSeq fields) |> update tableName
/// Query to patch documents matching a JSON containment query (@>) /// Query to patch documents matching a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
let byContains tableName = let byContains tableName =
@ -300,10 +337,20 @@ module Query =
let byId tableName = let byId tableName =
whereById "@id" |> update tableName whereById "@id" |> update tableName
/// Query to remove fields from documents via a comparison on JSON fields within the document
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
whereByFields howMatched fields |> update tableName
/// Query to remove fields from documents via a comparison on a JSON field within the document /// Query to remove fields from documents via a comparison on a JSON field within the document
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any |> update tableName byFields tableName Any [ field ]
/// Query to remove fields from documents via a comparison on JSON fields within the document
let ByFields tableName howMatched fields =
whereByFields howMatched (List.ofSeq fields) |> update tableName
/// Query to patch documents matching a JSON containment query (@>) /// Query to patch documents matching a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -323,11 +370,20 @@ module Query =
let byId tableName = let byId tableName =
$"""DELETE FROM %s{tableName} WHERE {whereById "@id"}""" $"""DELETE FROM %s{tableName} WHERE {whereById "@id"}"""
/// Query to delete documents using a comparison on JSON fields
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
$"DELETE FROM %s{tableName} WHERE {whereByFields howMatched fields}"
/// Query to delete documents using a comparison on a JSON field /// Query to delete documents using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any byFields tableName Any [ field ]
|> sprintf "DELETE FROM %s WHERE %s" tableName
/// Query to delete documents using a comparison on JSON fields
let ByFields tableName howMatched fields =
byFields tableName howMatched (List.ofSeq fields)
/// Query to delete documents using a JSON containment query (@>) /// Query to delete documents using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -461,14 +517,20 @@ module WithProps =
let all tableName sqlProps = let all tableName sqlProps =
Custom.scalar (Query.Count.all tableName) [] toCount sqlProps Custom.scalar (Query.Count.all tableName) [] toCount sqlProps
/// Count matching documents using JSON field comparisons (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields sqlProps =
Custom.scalar (Query.Count.byFields tableName howMatched fields) (addFieldParams fields []) toCount sqlProps
/// Count matching documents using a JSON field comparison (->> =) /// Count matching documents using a JSON field comparison (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field sqlProps = let byField tableName field sqlProps =
Custom.scalar byFields tableName Any [ field ] sqlProps
(Query.Count.byField tableName field)
(addFieldParams [ { field with ParameterName = Some "@field" } ] []) /// Count matching documents using JSON field comparisons (->> =)
toCount let ByFields(tableName, howMatched, fields, sqlProps) =
sqlProps Custom.Scalar(Query.Count.ByFields tableName howMatched fields, AddFields fields [], toCount, sqlProps)
/// Count matching documents using a JSON containment query (@>) /// Count matching documents using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -489,14 +551,21 @@ module WithProps =
let byId tableName (docId: 'TKey) sqlProps = let byId tableName (docId: 'TKey) sqlProps =
Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists sqlProps Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists sqlProps
/// Determine if a document exists using JSON field comparisons (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields sqlProps =
Custom.scalar
(Query.Exists.byFields tableName howMatched fields) (addFieldParams fields []) toExists sqlProps
/// Determine if a document exists using a JSON field comparison (->> =) /// Determine if a document exists using a JSON field comparison (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field sqlProps = let byField tableName field sqlProps =
Custom.scalar byFields tableName Any [ field ] sqlProps
(Query.Exists.byField tableName field)
(addFieldParams [ { field with ParameterName = Some "@field" } ] []) /// Determine if a document exists using JSON field comparisons (->> =)
toExists let ByFields(tableName, howMatched, fields, sqlProps) =
sqlProps Custom.Scalar(Query.Exists.ByFields tableName howMatched fields, AddFields fields [], toExists, sqlProps)
/// Determine if a document exists using a JSON containment query (@>) /// Determine if a document exists using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -530,22 +599,27 @@ module WithProps =
let ById<'TKey, 'TDoc when 'TDoc: null>(tableName, docId: 'TKey, sqlProps) = let ById<'TKey, 'TDoc when 'TDoc: null>(tableName, docId: 'TKey, sqlProps) =
Custom.Single<'TDoc>(Query.Find.byId tableName, [ idParam docId ], fromData<'TDoc>, sqlProps) Custom.Single<'TDoc>(Query.Find.byId tableName, [ idParam docId ], fromData<'TDoc>, sqlProps)
/// Retrieve documents matching JSON field comparisons (->> =)
[<CompiledName "FSharpByFields">]
let byFields<'TDoc> tableName howMatched fields sqlProps =
Custom.list<'TDoc>
(Query.Find.byFields tableName howMatched fields) (addFieldParams fields []) fromData<'TDoc> sqlProps
/// Retrieve documents matching a JSON field comparison (->> =) /// Retrieve documents matching a JSON field comparison (->> =)
[<CompiledName "FSharpByField">] [<CompiledName "FSharpByField">]
[<System.Obsolete "Use byFields instead; will be removed in v4">]
let byField<'TDoc> tableName field sqlProps = let byField<'TDoc> tableName field sqlProps =
Custom.list<'TDoc> byFields<'TDoc> tableName Any [ field ] sqlProps
(Query.Find.byField tableName field)
(addFieldParams [ { field with ParameterName = Some "@field" } ] [])
fromData<'TDoc>
sqlProps
/// Retrieve documents matching a JSON field comparison (->> =) /// Retrieve documents matching JSON field comparisons (->> =)
let ByField<'TDoc>(tableName, field, sqlProps) = let ByFields<'TDoc>(tableName, howMatched, fields, sqlProps) =
Custom.List<'TDoc>( Custom.List<'TDoc>(
Query.Find.byField tableName field, Query.Find.ByFields tableName howMatched fields, AddFields fields [], fromData<'TDoc>, sqlProps)
addFieldParams [ { field with ParameterName = Some "@field" } ] [],
fromData<'TDoc>, /// Retrieve documents matching a JSON field comparison (->> =)
sqlProps) [<System.Obsolete "Use ByFields instead; will be removed in v4">]
let ByField<'TDoc>(tableName, field, sqlProps) =
ByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
/// Retrieve documents matching a JSON containment query (@>) /// Retrieve documents matching a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
@ -569,23 +643,34 @@ module WithProps =
Custom.List<'TDoc>( Custom.List<'TDoc>(
Query.Find.byJsonPath tableName, [ "@path", Sql.string jsonPath ], fromData<'TDoc>, sqlProps) Query.Find.byJsonPath tableName, [ "@path", Sql.string jsonPath ], fromData<'TDoc>, sqlProps)
/// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found /// Retrieve the first document matching JSON field comparisons (->> =); returns None if not found
[<CompiledName "FSharpFirstByField">] [<CompiledName "FSharpFirstByFields">]
let firstByField<'TDoc> tableName field sqlProps = let firstByFields<'TDoc> tableName howMatched fields sqlProps =
Custom.single<'TDoc> Custom.single<'TDoc>
$"{Query.Find.byField tableName field} LIMIT 1" $"{Query.Find.byFields tableName howMatched fields} LIMIT 1"
(addFieldParams [ { field with ParameterName = Some "@field" } ] []) (addFieldParams fields [])
fromData<'TDoc> fromData<'TDoc>
sqlProps sqlProps
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found
let FirstByField<'TDoc when 'TDoc: null>(tableName, field, sqlProps) = [<CompiledName "FSharpFirstByField">]
[<System.Obsolete "Use firstByFields instead; will be removed in v4">]
let firstByField<'TDoc> tableName field sqlProps =
firstByFields<'TDoc> tableName Any [ field ] sqlProps
/// Retrieve the first document matching JSON field comparisons (->> =); returns null if not found
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields, sqlProps) =
Custom.Single<'TDoc>( Custom.Single<'TDoc>(
$"{Query.Find.byField tableName field} LIMIT 1", $"{Query.Find.ByFields tableName howMatched fields} LIMIT 1",
addFieldParams [ { field with ParameterName = Some "@field" } ] [], AddFields fields [],
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
[<System.Obsolete "Use FirstByFields instead; will be removed in v4">]
let FirstByField<'TDoc when 'TDoc: null>(tableName, field, sqlProps) =
FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found /// Retrieve the first document matching a JSON containment query (@>); returns None if not found
[<CompiledName "FSharpFirstByContains">] [<CompiledName "FSharpFirstByContains">]
let firstByContains<'TDoc> tableName (criteria: obj) sqlProps = let firstByContains<'TDoc> tableName (criteria: obj) sqlProps =
@ -642,13 +727,26 @@ module WithProps =
Custom.nonQuery (Query.Patch.byId tableName) [ idParam docId; jsonParam "@data" patch ] sqlProps Custom.nonQuery (Query.Patch.byId tableName) [ idParam docId; jsonParam "@data" patch ] sqlProps
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "ByField">] [<CompiledName "FSharpByFields">]
let byField tableName field (patch: 'TPatch) sqlProps = let byFields tableName howMatched fields (patch: 'TPatch) sqlProps =
Custom.nonQuery Custom.nonQuery
(Query.Patch.byField tableName field) (Query.Patch.byFields tableName howMatched fields)
(addFieldParams [ { field with ParameterName = Some "@field" } ] [ jsonParam "@data" patch ]) (addFieldParams fields [ jsonParam "@data" patch ])
sqlProps sqlProps
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field (patch: 'TPatch) sqlProps =
byFields tableName Any [ field ] patch sqlProps
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
let ByFields(tableName, howMatched, fields, patch: 'TPatch, sqlProps) =
Custom.nonQuery
(Query.Patch.ByFields tableName howMatched fields)
(AddFields fields [ jsonParam "@data" patch ])
sqlProps
/// Patch documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON containment query in the WHERE clause (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps = let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps =
@ -674,17 +772,31 @@ module WithProps =
let ById(tableName, docId: 'TKey, fieldNames, sqlProps) = let ById(tableName, docId: 'TKey, fieldNames, sqlProps) =
byId tableName docId (List.ofSeq fieldNames) sqlProps byId tableName docId (List.ofSeq fieldNames) sqlProps
/// Remove fields from documents via a comparison on JSON fields in the document
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields fieldNames sqlProps =
Custom.nonQuery
(Query.RemoveFields.byFields tableName howMatched fields)
(addFieldParams fields [ fieldNameParam fieldNames ])
sqlProps
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on a JSON field in the document
[<CompiledName "FSharpByField">] [<CompiledName "FSharpByField">]
[<System.Obsolete "Use byFields instead; will be removed in v4">]
let byField tableName field fieldNames sqlProps = let byField tableName field fieldNames sqlProps =
Custom.nonQuery byFields tableName Any [ field ] fieldNames sqlProps
(Query.RemoveFields.byField tableName field)
(addFieldParams [ { field with ParameterName = Some "@field" } ] [ fieldNameParam fieldNames ])
sqlProps
/// Remove fields from documents via a comparison on JSON fields in the document
let ByFields(tableName, howMatched, fields, fieldNames, sqlProps) =
Custom.nonQuery
(Query.RemoveFields.ByFields tableName howMatched fields)
(AddFields fields [ FieldName fieldNames ])
sqlProps
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on a JSON field in the document
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let ByField(tableName, field, fieldNames, sqlProps) = let ByField(tableName, field, fieldNames, sqlProps) =
byField tableName field (List.ofSeq fieldNames) sqlProps ByFields(tableName, Any, Seq.singleton field, fieldNames, sqlProps)
/// Remove fields from documents via a JSON containment query (@>) /// Remove fields from documents via a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
@ -719,13 +831,19 @@ module WithProps =
let byId tableName (docId: 'TKey) sqlProps = let byId tableName (docId: 'TKey) sqlProps =
Custom.nonQuery (Query.Delete.byId tableName) [ idParam docId ] sqlProps Custom.nonQuery (Query.Delete.byId tableName) [ idParam docId ] sqlProps
/// Delete documents by matching a JSON field comparison query (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields sqlProps =
Custom.nonQuery (Query.Delete.byFields tableName howMatched fields) (addFieldParams fields []) sqlProps
/// Delete documents by matching a JSON field comparison query (->> =) /// Delete documents by matching a JSON field comparison query (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field sqlProps = let byField tableName field sqlProps =
Custom.nonQuery byFields tableName Any [ field ] sqlProps
(Query.Delete.byField tableName field)
(addFieldParams [ { field with ParameterName = Some "@field" } ] []) let ByFields(tableName, howMatched, fields, sqlProps) =
sqlProps Custom.nonQuery (Query.Delete.ByFields tableName howMatched fields) (AddFields fields []) sqlProps
/// Delete documents by matching a JSON contains query (@>) /// Delete documents by matching a JSON contains query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -819,10 +937,20 @@ module Count =
let all tableName = let all tableName =
WithProps.Count.all tableName (fromDataSource ()) WithProps.Count.all tableName (fromDataSource ())
/// Count matching documents using a JSON field comparison query (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
WithProps.Count.byFields tableName howMatched fields (fromDataSource ())
/// Count matching documents using a JSON field comparison query (->> =) /// Count matching documents using a JSON field comparison query (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
WithProps.Count.byField tableName field (fromDataSource ()) byFields tableName Any [ field ]
/// Count matching documents using a JSON field comparison query (->> =)
let ByFields(tableName, howMatched, fields) =
WithProps.Count.ByFields(tableName, howMatched, fields, fromDataSource ())
/// Count matching documents using a JSON containment query (@>) /// Count matching documents using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -844,10 +972,20 @@ module Exists =
let byId tableName docId = let byId tableName docId =
WithProps.Exists.byId tableName docId (fromDataSource ()) WithProps.Exists.byId tableName docId (fromDataSource ())
/// Determine if documents exist using a JSON field comparison query (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
WithProps.Exists.byFields tableName howMatched fields (fromDataSource ())
/// Determine if documents exist using a JSON field comparison query (->> =) /// Determine if documents exist using a JSON field comparison query (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
WithProps.Exists.byField tableName field (fromDataSource ()) byFields tableName Any [ field ]
/// Determine if documents exist using a JSON field comparison query (->> =)
let ByFields(tableName, howMatched, fields) =
WithProps.Exists.ByFields(tableName, howMatched, fields, fromDataSource ())
/// Determine if documents exist using a JSON containment query (@>) /// Determine if documents exist using a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -883,13 +1021,24 @@ module Find =
WithProps.Find.ById<'TKey, 'TDoc>(tableName, docId, fromDataSource ()) WithProps.Find.ById<'TKey, 'TDoc>(tableName, docId, fromDataSource ())
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
[<CompiledName "FSharpByField">] [<CompiledName "FSharpByFields">]
let byField<'TDoc> tableName field = let byFields<'TDoc> tableName howMatched fields =
WithProps.Find.byField<'TDoc> tableName field (fromDataSource ()) WithProps.Find.byFields<'TDoc> tableName howMatched fields (fromDataSource ())
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
[<CompiledName "FSharpByField">]
[<System.Obsolete "Use byFields instead; will be removed in v4">]
let byField<'TDoc> tableName field =
byFields<'TDoc> tableName Any [ field ]
/// Retrieve documents matching a JSON field comparison query (->> =)
let ByFields<'TDoc>(tableName, howMatched, fields) =
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
/// Retrieve documents matching a JSON field comparison query (->> =)
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let ByField<'TDoc>(tableName, field) = let ByField<'TDoc>(tableName, field) =
WithProps.Find.ByField<'TDoc>(tableName, field, fromDataSource ()) ByFields<'TDoc>(tableName, Any, Seq.singleton field)
/// Retrieve documents matching a JSON containment query (@>) /// Retrieve documents matching a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
@ -909,14 +1058,25 @@ module Find =
let ByJsonPath<'TDoc>(tableName, jsonPath) = let ByJsonPath<'TDoc>(tableName, jsonPath) =
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ()) WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
[<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields =
WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
[<CompiledName "FSharpFirstByField">] [<CompiledName "FSharpFirstByField">]
[<System.Obsolete "Use firstByFields instead; will be removed in v4">]
let firstByField<'TDoc> tableName field = let firstByField<'TDoc> tableName field =
WithProps.Find.firstByField<'TDoc> tableName field (fromDataSource ()) firstByFields<'TDoc> tableName Any [ field ]
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields) =
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
[<System.Obsolete "Use FirstByFields instead; will be removed in v4">]
let FirstByField<'TDoc when 'TDoc: null>(tableName, field) = let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
WithProps.Find.FirstByField<'TDoc>(tableName, field, fromDataSource ()) FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found /// Retrieve the first document matching a JSON containment query (@>); returns None if not found
[<CompiledName "FSharpFirstByContains">] [<CompiledName "FSharpFirstByContains">]
@ -965,10 +1125,20 @@ module Patch =
let byId tableName (docId: 'TKey) (patch: 'TPatch) = let byId tableName (docId: 'TKey) (patch: 'TPatch) =
WithProps.Patch.byId tableName docId patch (fromDataSource ()) WithProps.Patch.byId tableName docId patch (fromDataSource ())
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields (patch: 'TPatch) =
WithProps.Patch.byFields tableName howMatched fields patch (fromDataSource ())
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field (patch: 'TPatch) = let byField tableName field (patch: 'TPatch) =
WithProps.Patch.byField tableName field patch (fromDataSource ()) byFields tableName Any [ field ] patch
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
let ByFields(tableName, howMatched, fields, patch: 'TPatch) =
WithProps.Patch.ByFields(tableName, howMatched, fields, patch, fromDataSource ())
/// Patch documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON containment query in the WHERE clause (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]
@ -994,14 +1164,25 @@ module RemoveFields =
let ById(tableName, docId: 'TKey, fieldNames) = let ById(tableName, docId: 'TKey, fieldNames) =
WithProps.RemoveFields.ById(tableName, docId, fieldNames, fromDataSource ()) WithProps.RemoveFields.ById(tableName, docId, fieldNames, fromDataSource ())
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on JSON fields in the document
[<CompiledName "FSharpByField">] [<CompiledName "FSharpByFields">]
let byField tableName field fieldNames = let byFields tableName howMatched fields fieldNames =
WithProps.RemoveFields.byField tableName field fieldNames (fromDataSource ()) WithProps.RemoveFields.byFields tableName howMatched fields fieldNames (fromDataSource ())
/// Remove fields from documents via a comparison on a JSON field in the document /// Remove fields from documents via a comparison on a JSON field in the document
[<CompiledName "FSharpByField">]
[<System.Obsolete "Use byFields instead; will be removed in v4">]
let byField tableName field fieldNames =
byFields tableName Any [ field ] fieldNames
/// Remove fields from documents via a comparison on JSON fields in the document
let ByFields(tableName, howMatched, fields, fieldNames) =
WithProps.RemoveFields.ByFields(tableName, howMatched, fields, fieldNames, fromDataSource ())
/// Remove fields from documents via a comparison on a JSON field in the document
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let ByField(tableName, field, fieldNames) = let ByField(tableName, field, fieldNames) =
WithProps.RemoveFields.ByField(tableName, field, fieldNames, fromDataSource ()) ByFields(tableName, Any, Seq.singleton field, fieldNames)
/// Remove fields from documents via a JSON containment query (@>) /// Remove fields from documents via a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
@ -1030,11 +1211,21 @@ module Delete =
[<CompiledName "ById">] [<CompiledName "ById">]
let byId tableName (docId: 'TKey) = let byId tableName (docId: 'TKey) =
WithProps.Delete.byId tableName docId (fromDataSource ()) WithProps.Delete.byId tableName docId (fromDataSource ())
/// Delete documents by matching a JSON field comparison query (->> =)
[<CompiledName "FSharpByFields">]
let byFields tableName howMatched fields =
WithProps.Delete.byFields tableName howMatched fields (fromDataSource ())
/// Delete documents by matching a JSON field comparison query (->> =) /// Delete documents by matching a JSON field comparison query (->> =)
[<CompiledName "ByField">] [<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field = let byField tableName field =
WithProps.Delete.byField tableName field (fromDataSource ()) byFields tableName Any [ field ]
/// Delete documents by matching a JSON field comparison query (->> =)
let ByFields(tableName, howMatched, fields) =
WithProps.Delete.ByFields(tableName, howMatched, fields, fromDataSource ())
/// Delete documents by matching a JSON containment query (@>) /// Delete documents by matching a JSON containment query (@>)
[<CompiledName "ByContains">] [<CompiledName "ByContains">]

View File

@ -33,7 +33,7 @@ module Query =
/// Create a WHERE clause fragment to implement a comparison on fields in a JSON document /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
[<CompiledName "FSharpWhereByFields">] [<CompiledName "FSharpWhereByFields">]
let whereByFields fields howMatched = let whereByFields howMatched fields =
let name = ParameterName() let name = ParameterName()
fields fields
|> List.map (fun it -> |> List.map (fun it ->
@ -46,19 +46,19 @@ module Query =
|> String.concat (match howMatched with Any -> " OR " | All -> " AND ") |> String.concat (match howMatched with Any -> " OR " | All -> " AND ")
/// Create a WHERE clause fragment to implement a comparison on fields in a JSON document /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
let WhereByFields(fields: Field seq, howMatched) = let WhereByFields(howMatched, fields: Field seq) =
whereByFields (List.ofSeq fields) howMatched whereByFields howMatched (List.ofSeq fields)
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
[<CompiledName "WhereByField">] [<CompiledName "WhereByField">]
[<System.Obsolete "Use WhereByFields instead; will be removed in v4">] [<System.Obsolete "Use WhereByFields instead; will be removed in v4">]
let whereByField field paramName = let whereByField field paramName =
whereByFields [ { field with ParameterName = Some paramName } ] Any whereByFields Any [ { field with ParameterName = Some paramName } ]
/// Create a WHERE clause fragment to implement an ID-based query /// Create a WHERE clause fragment to implement an ID-based query
[<CompiledName "WhereById">] [<CompiledName "WhereById">]
let whereById paramName = let whereById paramName =
whereByFields [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ] Any whereByFields Any [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ]
/// Data definition /// Data definition
module Definition = module Definition =
@ -84,7 +84,7 @@ module Query =
/// Query to count matching documents using a text comparison on a JSON field /// Query to count matching documents using a text comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any whereByFields Any [ { field with ParameterName = Some "@field" } ]
|> sprintf "SELECT COUNT(*) AS it FROM %s WHERE %s" tableName |> sprintf "SELECT COUNT(*) AS it FROM %s WHERE %s" tableName
/// Queries for determining document existence /// Queries for determining document existence
@ -98,7 +98,7 @@ module Query =
/// Query to determine if documents exist using a comparison on a JSON field /// Query to determine if documents exist using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any whereByFields Any [ { field with ParameterName = Some "@field" } ]
|> sprintf "SELECT EXISTS (SELECT 1 FROM %s WHERE %s) AS it" tableName |> sprintf "SELECT EXISTS (SELECT 1 FROM %s WHERE %s) AS it" tableName
/// Queries for retrieving documents /// Queries for retrieving documents
@ -112,7 +112,7 @@ module Query =
/// Query to retrieve documents using a comparison on a JSON field /// Query to retrieve documents using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any whereByFields Any [ { field with ParameterName = Some "@field" } ]
|> sprintf "%s WHERE %s" (Query.selectFromTable tableName) |> sprintf "%s WHERE %s" (Query.selectFromTable tableName)
/// Document patching (partial update) queries /// Document patching (partial update) queries
@ -130,7 +130,7 @@ module Query =
/// Query to patch (partially update) a document via a comparison on a JSON field /// Query to patch (partially update) a document via a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any |> update tableName whereByFields Any [ { field with ParameterName = Some "@field" } ] |> update tableName
/// Queries to remove fields from documents /// Queries to remove fields from documents
module RemoveFields = module RemoveFields =
@ -152,7 +152,7 @@ module Query =
/// Query to remove fields from documents via a comparison on a JSON field within the document /// Query to remove fields from documents via a comparison on a JSON field within the document
[<CompiledName "FSharpByField">] [<CompiledName "FSharpByField">]
let byField tableName field parameters = let byField tableName field parameters =
whereByFields [ { field with ParameterName = Some "@field" } ] Any |> update tableName parameters whereByFields Any [ { field with ParameterName = Some "@field" } ] |> update tableName parameters
/// Query to remove fields from documents via a comparison on a JSON field within the document /// Query to remove fields from documents via a comparison on a JSON field within the document
let ByField(tableName, field, parameters) = let ByField(tableName, field, parameters) =
@ -169,7 +169,7 @@ module Query =
/// Query to delete documents using a comparison on a JSON field /// Query to delete documents using a comparison on a JSON field
[<CompiledName "ByField">] [<CompiledName "ByField">]
let byField tableName field = let byField tableName field =
whereByFields [ { field with ParameterName = Some "@field" } ] Any whereByFields Any [ { field with ParameterName = Some "@field" } ]
|> sprintf "DELETE FROM %s WHERE %s" tableName |> sprintf "DELETE FROM %s WHERE %s" tableName

View File

@ -64,48 +64,48 @@ public static class PostgresCSharpTests
TestCase("succeeds for a single field when a logical operator is passed", () => TestCase("succeeds for a single field when a logical operator is passed", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.GT("theField", 0).WithParameterName("@test")], Postgres.Query.WhereByFields(FieldMatch.Any,
FieldMatch.Any), [Field.GT("theField", 0).WithParameterName("@test")]),
"data->>'theField' > @test", "WHERE clause not correct"); "data->>'theField' > @test", "WHERE clause not correct");
}), }),
TestCase("succeeds for a single field when an existence operator is passed", () => TestCase("succeeds for a single field when an existence operator is passed", () =>
{ {
Expect.equal(Postgres.Query.WhereByFields([Field.NEX("thatField")], FieldMatch.Any), Expect.equal(Postgres.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField")]),
"data->>'thatField' IS NULL", "WHERE clause not correct"); "data->>'thatField' IS NULL", "WHERE clause not correct");
}), }),
TestCase("succeeds for a single field when a between operator is passed with numeric values", () => TestCase("succeeds for a single field when a between operator is passed with numeric values", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.BT("aField", 50, 99).WithParameterName("@range")], Postgres.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.BT("aField", 50, 99).WithParameterName("@range")]),
"(data->>'aField')::numeric BETWEEN @rangemin AND @rangemax", "WHERE clause not correct"); "(data->>'aField')::numeric BETWEEN @rangemin AND @rangemax", "WHERE clause not correct");
}), }),
TestCase("succeeds for a single field when a between operator is passed with non-numeric values", () => TestCase("succeeds for a single field when a between operator is passed with non-numeric values", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.BT("field0", "a", "b").WithParameterName("@alpha")], Postgres.Query.WhereByFields(FieldMatch.Any,
FieldMatch.Any), [Field.BT("field0", "a", "b").WithParameterName("@alpha")]),
"data->>'field0' BETWEEN @alphamin AND @alphamax", "WHERE clause not correct"); "data->>'field0' BETWEEN @alphamin AND @alphamax", "WHERE clause not correct");
}), }),
TestCase("succeeds for all multiple fields with logical operators", () => TestCase("succeeds for all multiple fields with logical operators", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")], Postgres.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")]),
"data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct"); "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct");
}), }),
TestCase("succeeds for any multiple fields with an existence operator", () => TestCase("succeeds for any multiple fields with an existence operator", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.NEX("thatField"), Field.GE("thisField", 18)], Postgres.Query.WhereByFields(FieldMatch.Any,
FieldMatch.Any), [Field.NEX("thatField"), Field.GE("thisField", 18)]),
"data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct"); "data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct");
}), }),
TestCase("succeeds for all multiple fields with between operators", () => TestCase("succeeds for all multiple fields with between operators", () =>
{ {
Expect.equal( Expect.equal(
Postgres.Query.WhereByFields([Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")], Postgres.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")]),
"(data->>'aField')::numeric BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max", "(data->>'aField')::numeric BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max",
"WHERE clause not correct"); "WHERE clause not correct");
}) })
@ -186,7 +186,7 @@ public static class PostgresCSharpTests
TestCase("ByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.Count.ByField(PostgresDb.TableName, Field.EQ("thatField", 0)), Expect.equal(Postgres.Query.Count.ByField(PostgresDb.TableName, Field.EQ("thatField", 0)),
$"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data->>'thatField' = @field", $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data->>'thatField' = @field0",
"JSON field text comparison count query not correct"); "JSON field text comparison count query not correct");
}), }),
TestCase("ByContains succeeds", () => TestCase("ByContains succeeds", () =>
@ -213,7 +213,7 @@ public static class PostgresCSharpTests
TestCase("ByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.Exists.ByField(PostgresDb.TableName, Field.LT("Test", 0)), Expect.equal(Postgres.Query.Exists.ByField(PostgresDb.TableName, Field.LT("Test", 0)),
$"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Test' < @field) AS it", $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Test' < @field0) AS it",
"JSON field text comparison exists query not correct"); "JSON field text comparison exists query not correct");
}), }),
TestCase("ByContains succeeds", () => TestCase("ByContains succeeds", () =>
@ -240,7 +240,7 @@ public static class PostgresCSharpTests
TestCase("ByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.Find.ByField(PostgresDb.TableName, Field.GE("Golf", 0)), Expect.equal(Postgres.Query.Find.ByField(PostgresDb.TableName, Field.GE("Golf", 0)),
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field", $"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field0",
"SELECT by JSON comparison query not correct"); "SELECT by JSON comparison query not correct");
}), }),
TestCase("byContains succeeds", () => TestCase("byContains succeeds", () =>
@ -267,7 +267,7 @@ public static class PostgresCSharpTests
TestCase("ByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.Patch.ByField(PostgresDb.TableName, Field.LT("Snail", 0)), Expect.equal(Postgres.Query.Patch.ByField(PostgresDb.TableName, Field.LT("Snail", 0)),
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field", $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field0",
"UPDATE partial by ID statement not correct"); "UPDATE partial by ID statement not correct");
}), }),
TestCase("ByContains succeeds", () => TestCase("ByContains succeeds", () =>
@ -294,7 +294,7 @@ public static class PostgresCSharpTests
TestCase("ByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.RemoveFields.ByField(PostgresDb.TableName, Field.LT("Fly", 0)), Expect.equal(Postgres.Query.RemoveFields.ByField(PostgresDb.TableName, Field.LT("Fly", 0)),
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Fly' < @field", $"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Fly' < @field0",
"Remove field by field query not correct"); "Remove field by field query not correct");
}), }),
TestCase("ByContains succeeds", () => TestCase("ByContains succeeds", () =>

View File

@ -25,41 +25,40 @@ public static class SqliteCSharpTests
TestCase("succeeds for a single field when a logical operator is passed", () => TestCase("succeeds for a single field when a logical operator is passed", () =>
{ {
Expect.equal( Expect.equal(
Sqlite.Query.WhereByFields([Field.GT("theField", 0).WithParameterName("@test")], Sqlite.Query.WhereByFields(FieldMatch.Any,
FieldMatch.Any), [Field.GT("theField", 0).WithParameterName("@test")]),
"data->>'theField' > @test", "WHERE clause not correct"); "data->>'theField' > @test", "WHERE clause not correct");
}), }),
TestCase("succeeds for a single field when an existence operator is passed", () => TestCase("succeeds for a single field when an existence operator is passed", () =>
{ {
Expect.equal(Sqlite.Query.WhereByFields([Field.NEX("thatField")], FieldMatch.Any), Expect.equal(Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField")]),
"data->>'thatField' IS NULL", "WHERE clause not correct"); "data->>'thatField' IS NULL", "WHERE clause not correct");
}), }),
TestCase("succeeds for a single field when a between operator is passed", () => TestCase("succeeds for a single field when a between operator is passed", () =>
{ {
Expect.equal( Expect.equal(
Sqlite.Query.WhereByFields([Field.BT("aField", 50, 99).WithParameterName("@range")], Sqlite.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.BT("aField", 50, 99).WithParameterName("@range")]),
"data->>'aField' BETWEEN @rangemin AND @rangemax", "WHERE clause not correct"); "data->>'aField' BETWEEN @rangemin AND @rangemax", "WHERE clause not correct");
}), }),
TestCase("succeeds for all multiple fields with logical operators", () => TestCase("succeeds for all multiple fields with logical operators", () =>
{ {
Expect.equal( Expect.equal(
Sqlite.Query.WhereByFields([Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")], Sqlite.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")]),
"data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct"); "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct");
}), }),
TestCase("succeeds for any multiple fields with an existence operator", () => TestCase("succeeds for any multiple fields with an existence operator", () =>
{ {
Expect.equal( Expect.equal(
Sqlite.Query.WhereByFields([Field.NEX("thatField"), Field.GE("thisField", 18)], Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField"), Field.GE("thisField", 18)]),
FieldMatch.Any),
"data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct"); "data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct");
}), }),
TestCase("succeeds for all multiple fields with between operators", () => TestCase("succeeds for all multiple fields with between operators", () =>
{ {
Expect.equal( Expect.equal(
Sqlite.Query.WhereByFields([Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")], Sqlite.Query.WhereByFields(FieldMatch.All,
FieldMatch.All), [Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")]),
"data->>'aField' BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max", "data->>'aField' BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max",
"WHERE clause not correct"); "WHERE clause not correct");
}) })

View File

@ -61,43 +61,43 @@ let unitTests =
testList "whereByFields" [ testList "whereByFields" [
test "succeeds for a single field when a logical operator is passed" { test "succeeds for a single field when a logical operator is passed" {
Expect.equal Expect.equal
(Query.whereByFields [ { Field.GT "theField" 0 with ParameterName = Some "@test" } ] Any) (Query.whereByFields Any [ { Field.GT "theField" 0 with ParameterName = Some "@test" } ])
"data->>'theField' > @test" "data->>'theField' > @test"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for a single field when an existence operator is passed" { test "succeeds for a single field when an existence operator is passed" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.NEX "thatField" ] Any) (Query.whereByFields Any [ Field.NEX "thatField" ])
"data->>'thatField' IS NULL" "data->>'thatField' IS NULL"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for a single field when a between operator is passed with numeric values" { test "succeeds for a single field when a between operator is passed with numeric values" {
Expect.equal Expect.equal
(Query.whereByFields [ { Field.BT "aField" 50 99 with ParameterName = Some "@range" } ] All) (Query.whereByFields All [ { Field.BT "aField" 50 99 with ParameterName = Some "@range" } ])
"(data->>'aField')::numeric BETWEEN @rangemin AND @rangemax" "(data->>'aField')::numeric BETWEEN @rangemin AND @rangemax"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for a single field when a between operator is passed with non-numeric values" { test "succeeds for a single field when a between operator is passed with non-numeric values" {
Expect.equal Expect.equal
(Query.whereByFields [ { Field.BT "field0" "a" "b" with ParameterName = Some "@alpha" } ] Any) (Query.whereByFields Any [ { Field.BT "field0" "a" "b" with ParameterName = Some "@alpha" } ])
"data->>'field0' BETWEEN @alphamin AND @alphamax" "data->>'field0' BETWEEN @alphamin AND @alphamax"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for all multiple fields with logical operators" { test "succeeds for all multiple fields with logical operators" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.EQ "theFirst" "1"; Field.EQ "numberTwo" "2" ] All) (Query.whereByFields All [ Field.EQ "theFirst" "1"; Field.EQ "numberTwo" "2" ])
"data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1" "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for any multiple fields with an existence operator" { test "succeeds for any multiple fields with an existence operator" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.NEX "thatField"; Field.GE "thisField" 18 ] Any) (Query.whereByFields Any [ Field.NEX "thatField"; Field.GE "thisField" 18 ])
"data->>'thatField' IS NULL OR data->>'thisField' >= @field0" "data->>'thatField' IS NULL OR data->>'thisField' >= @field0"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for all multiple fields with between operators" { test "succeeds for all multiple fields with between operators" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.BT "aField" 50 99; Field.BT "anotherField" "a" "b" ] All) (Query.whereByFields All [ Field.BT "aField" 50 99; Field.BT "anotherField" "a" "b" ])
"(data->>'aField')::numeric BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max" "(data->>'aField')::numeric BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max"
"WHERE clause not correct" "WHERE clause not correct"
} }
@ -174,7 +174,7 @@ let unitTests =
test "byField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.Count.byField PostgresDb.TableName (Field.EQ "thatField" 0)) (Query.Count.byField PostgresDb.TableName (Field.EQ "thatField" 0))
$"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data->>'thatField' = @field" $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data->>'thatField' = @field0"
"JSON field text comparison count query not correct" "JSON field text comparison count query not correct"
} }
test "byContains succeeds" { test "byContains succeeds" {
@ -200,7 +200,7 @@ let unitTests =
test "byField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.Exists.byField PostgresDb.TableName (Field.LT "Test" 0)) (Query.Exists.byField PostgresDb.TableName (Field.LT "Test" 0))
$"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Test' < @field) AS it" $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Test' < @field0) AS it"
"JSON field text comparison exists query not correct" "JSON field text comparison exists query not correct"
} }
test "byContains succeeds" { test "byContains succeeds" {
@ -226,7 +226,7 @@ let unitTests =
test "byField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.Find.byField PostgresDb.TableName (Field.GE "Golf" 0)) (Query.Find.byField PostgresDb.TableName (Field.GE "Golf" 0))
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field" $"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field0"
"SELECT by JSON comparison query not correct" "SELECT by JSON comparison query not correct"
} }
test "byContains succeeds" { test "byContains succeeds" {
@ -252,7 +252,7 @@ let unitTests =
test "byField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.Patch.byField PostgresDb.TableName (Field.LT "Snail" 0)) (Query.Patch.byField PostgresDb.TableName (Field.LT "Snail" 0))
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field" $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field0"
"UPDATE partial by ID statement not correct" "UPDATE partial by ID statement not correct"
} }
test "byContains succeeds" { test "byContains succeeds" {
@ -278,7 +278,7 @@ let unitTests =
test "byField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.RemoveFields.byField "tbl" (Field.LT "Fly" 0)) (Query.RemoveFields.byField "tbl" (Field.LT "Fly" 0))
"UPDATE tbl SET data = data - @name WHERE data->>'Fly' < @field" "UPDATE tbl SET data = data - @name WHERE data->>'Fly' < @field0"
"Remove field by field query not correct" "Remove field by field query not correct"
} }
test "byContains succeeds" { test "byContains succeeds" {

View File

@ -15,37 +15,37 @@ let unitTests =
testList "whereByFields" [ testList "whereByFields" [
test "succeeds for a single field when a logical operator is passed" { test "succeeds for a single field when a logical operator is passed" {
Expect.equal Expect.equal
(Query.whereByFields [ { Field.GT "theField" 0 with ParameterName = Some "@test" } ] Any) (Query.whereByFields Any [ { Field.GT "theField" 0 with ParameterName = Some "@test" } ])
"data->>'theField' > @test" "data->>'theField' > @test"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for a single field when an existence operator is passed" { test "succeeds for a single field when an existence operator is passed" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.NEX "thatField" ] Any) (Query.whereByFields Any [ Field.NEX "thatField" ])
"data->>'thatField' IS NULL" "data->>'thatField' IS NULL"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for a single field when a between operator is passed" { test "succeeds for a single field when a between operator is passed" {
Expect.equal Expect.equal
(Query.whereByFields [ { Field.BT "aField" 50 99 with ParameterName = Some "@range" } ] All) (Query.whereByFields All [ { Field.BT "aField" 50 99 with ParameterName = Some "@range" } ])
"data->>'aField' BETWEEN @rangemin AND @rangemax" "data->>'aField' BETWEEN @rangemin AND @rangemax"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for all multiple fields with logical operators" { test "succeeds for all multiple fields with logical operators" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.EQ "theFirst" "1"; Field.EQ "numberTwo" "2" ] All) (Query.whereByFields All [ Field.EQ "theFirst" "1"; Field.EQ "numberTwo" "2" ])
"data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1" "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for any multiple fields with an existence operator" { test "succeeds for any multiple fields with an existence operator" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.NEX "thatField"; Field.GE "thisField" 18 ] Any) (Query.whereByFields Any [ Field.NEX "thatField"; Field.GE "thisField" 18 ])
"data->>'thatField' IS NULL OR data->>'thisField' >= @field0" "data->>'thatField' IS NULL OR data->>'thisField' >= @field0"
"WHERE clause not correct" "WHERE clause not correct"
} }
test "succeeds for all multiple fields with between operators" { test "succeeds for all multiple fields with between operators" {
Expect.equal Expect.equal
(Query.whereByFields [ Field.BT "aField" 50 99; Field.BT "anotherField" "a" "b" ] All) (Query.whereByFields All [ Field.BT "aField" 50 99; Field.BT "anotherField" "a" "b" ])
"data->>'aField' BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max" "data->>'aField' BETWEEN @field0min AND @field0max AND data->>'anotherField' BETWEEN @field1min AND @field1max"
"WHERE clause not correct" "WHERE clause not correct"
} }