From 8a15bdce2ee225456e88cb13dd09ea8398ff3dcb Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Wed, 7 Aug 2024 23:23:28 -0400 Subject: [PATCH] Add byFields to PostgreSQL impl - Swap howMatched and fields throughout - Existing tests pass; still need new ones for byFields --- src/Postgres/Extensions.fs | 82 +++++- src/Postgres/Library.fs | 339 ++++++++++++++++++------ src/Sqlite/Library.fs | 22 +- src/Tests.CSharp/PostgresCSharpTests.cs | 36 +-- src/Tests.CSharp/SqliteCSharpTests.cs | 21 +- src/Tests/PostgresTests.fs | 24 +- src/Tests/SqliteTests.fs | 12 +- 7 files changed, 401 insertions(+), 135 deletions(-) diff --git a/src/Postgres/Extensions.fs b/src/Postgres/Extensions.fs index c2ae2e5..f6ba32e 100644 --- a/src/Postgres/Extensions.fs +++ b/src/Postgres/Extensions.fs @@ -50,6 +50,11 @@ module Extensions = WithProps.Count.all tableName (Sql.existingConnection conn) /// 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 (->> =) + [] member conn.countByField tableName field = WithProps.Count.byField tableName field (Sql.existingConnection conn) @@ -66,6 +71,11 @@ module Extensions = WithProps.Exists.byId tableName docId (Sql.existingConnection conn) /// 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 (->> =) + [] member conn.existsByField tableName field = WithProps.Exists.byField tableName field (Sql.existingConnection conn) @@ -86,6 +96,11 @@ module Extensions = WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn) /// 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 (->> =) + [] member conn.findByField<'TDoc> tableName field = WithProps.Find.byField<'TDoc> tableName field (Sql.existingConnection conn) @@ -98,6 +113,11 @@ module Extensions = WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn) /// 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 + [] member conn.findFirstByField<'TDoc> tableName field = WithProps.Find.firstByField<'TDoc> tableName field (Sql.existingConnection conn) @@ -122,6 +142,11 @@ module Extensions = WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn) /// 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 (->> =) + [] member conn.patchByField tableName field (patch: 'TPatch) = WithProps.Patch.byField tableName field patch (Sql.existingConnection conn) @@ -137,7 +162,12 @@ module Extensions = member conn.removeFieldsById tableName (docId: 'TKey) fieldNames = 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 + [] member conn.removeFieldsByField tableName field fieldNames = WithProps.RemoveFields.byField tableName field fieldNames (Sql.existingConnection conn) @@ -153,7 +183,11 @@ module Extensions = member conn.deleteById tableName (docId: 'TKey) = 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 (->> =) + [] member conn.deleteByField tableName field = WithProps.Delete.byField tableName field (Sql.existingConnection conn) @@ -225,6 +259,12 @@ type NpgsqlConnectionCSharpExtensions = /// Count matching documents using a JSON field comparison query (->> =) [] + 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 (->> =) + [] + [] static member inline CountByField(conn, tableName, field) = WithProps.Count.byField tableName field (Sql.existingConnection conn) @@ -245,6 +285,12 @@ type NpgsqlConnectionCSharpExtensions = /// Determine if documents exist using a JSON field comparison query (->> =) [] + 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 (->> =) + [] + [] static member inline ExistsByField(conn, tableName, field) = WithProps.Exists.byField tableName field (Sql.existingConnection conn) @@ -270,6 +316,12 @@ type NpgsqlConnectionCSharpExtensions = /// Retrieve documents matching a JSON field comparison query (->> =) [] + 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 (->> =) + [] + [] static member inline FindByField<'TDoc>(conn, tableName, field) = WithProps.Find.ByField<'TDoc>(tableName, field, Sql.existingConnection conn) @@ -283,8 +335,14 @@ type NpgsqlConnectionCSharpExtensions = static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) = 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 [] + 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 + [] + [] static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) = 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 (->> =) [] + 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 (->> =) + [] + [] static member inline PatchByField(conn, tableName, field, patch: 'TPatch) = WithProps.Patch.byField tableName field patch (Sql.existingConnection conn) @@ -332,9 +396,15 @@ type NpgsqlConnectionCSharpExtensions = [] static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) = WithProps.RemoveFields.ById(tableName, docId, fieldNames, Sql.existingConnection conn) - + + /// Remove fields from documents via a comparison on JSON fields in the document + [] + 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 [] + [] static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) = WithProps.RemoveFields.ByField(tableName, field, fieldNames, Sql.existingConnection conn) @@ -352,9 +422,15 @@ type NpgsqlConnectionCSharpExtensions = [] static member inline DeleteById(conn, tableName, docId: 'TKey) = WithProps.Delete.byId tableName docId (Sql.existingConnection conn) - + /// Delete documents by matching a JSON field comparison query (->> =) [] + 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 (->> =) + [] + [] static member inline DeleteByField(conn, tableName, field) = WithProps.Delete.byField tableName field (Sql.existingConnection conn) diff --git a/src/Postgres/Library.fs b/src/Postgres/Library.fs index 32aa352..c586168 100644 --- a/src/Postgres/Library.fs +++ b/src/Postgres/Library.fs @@ -127,7 +127,7 @@ module Query = /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document [] - let whereByFields fields howMatched = + let whereByFields howMatched fields = let name = ParameterName() fields |> List.map (fun it -> @@ -145,19 +145,19 @@ module Query = |> String.concat (match howMatched with Any -> " OR " | All -> " AND ") /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document - let WhereByFields(fields: Field seq, howMatched) = - whereByFields (List.ofSeq fields) howMatched + let WhereByFields(howMatched, fields: Field seq) = + whereByFields howMatched (List.ofSeq fields) /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document [] [] 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 [] 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 module Definition = @@ -197,11 +197,20 @@ module Query = let all tableName = $"SELECT COUNT(*) AS it FROM %s{tableName}" + /// Query to count matching documents using a text comparison on JSON fields + [] + 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 [] + [] let byField tableName field = - whereByFields [ { field with ParameterName = Some "@field" } ] Any - |> sprintf "SELECT COUNT(*) AS it FROM %s WHERE %s" tableName + byFields tableName Any [ field ] + + /// 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 (@>) [] @@ -221,12 +230,21 @@ module Query = let byId tableName = $"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereById "@id"}) AS it""" + /// Query to determine if documents exist using a comparison on JSON fields + [] + 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 [] + [] let byField tableName field = - whereByFields [ { field with ParameterName = Some "@field" } ] Any - |> sprintf "SELECT EXISTS (SELECT 1 FROM %s WHERE %s) AS it" tableName + byFields tableName Any [ field ] + /// 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 (@>) [] let byContains tableName = @@ -245,11 +263,20 @@ module Query = let byId tableName = $"""{Query.selectFromTable tableName} WHERE {whereById "@id"}""" + /// Query to retrieve documents using a comparison on JSON fields + [] + let byFields tableName howMatched fields = + $"{Query.selectFromTable tableName} WHERE {whereByFields howMatched fields}" + /// Query to retrieve documents using a comparison on a JSON field [] + [] let byField tableName field = - whereByFields [ { field with ParameterName = Some "@field" } ] Any - |> sprintf "%s WHERE %s" (Query.selectFromTable tableName) + byFields tableName Any [ field ] + + /// 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 (@>) [] @@ -273,11 +300,21 @@ module Query = let byId tableName = whereById "@id" |> update tableName + /// Query to patch documents match JSON field comparisons (->> =) + [] + let byFields tableName howMatched fields = + whereByFields howMatched fields |> update tableName + /// Query to patch documents match a JSON field comparison (->> =) [] + [] 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 (@>) [] let byContains tableName = @@ -300,10 +337,20 @@ module Query = let byId tableName = whereById "@id" |> update tableName + /// Query to remove fields from documents via a comparison on JSON fields within the document + [] + 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 [] + [] 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 (@>) [] @@ -323,11 +370,20 @@ module Query = let byId tableName = $"""DELETE FROM %s{tableName} WHERE {whereById "@id"}""" + /// Query to delete documents using a comparison on JSON fields + [] + let byFields tableName howMatched fields = + $"DELETE FROM %s{tableName} WHERE {whereByFields howMatched fields}" + /// Query to delete documents using a comparison on a JSON field [] + [] let byField tableName field = - whereByFields [ { field with ParameterName = Some "@field" } ] Any - |> sprintf "DELETE FROM %s WHERE %s" tableName + byFields tableName Any [ field ] + + /// 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 (@>) [] @@ -461,14 +517,20 @@ module WithProps = let all tableName sqlProps = Custom.scalar (Query.Count.all tableName) [] toCount sqlProps + /// Count matching documents using JSON field comparisons (->> =) + [] + 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 (->> =) [] + [] let byField tableName field sqlProps = - Custom.scalar - (Query.Count.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] []) - toCount - sqlProps + byFields tableName Any [ field ] sqlProps + + /// Count matching documents using JSON field comparisons (->> =) + let ByFields(tableName, howMatched, fields, sqlProps) = + Custom.Scalar(Query.Count.ByFields tableName howMatched fields, AddFields fields [], toCount, sqlProps) /// Count matching documents using a JSON containment query (@>) [] @@ -489,14 +551,21 @@ module WithProps = let byId tableName (docId: 'TKey) sqlProps = Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists sqlProps + /// Determine if a document exists using JSON field comparisons (->> =) + [] + 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 (->> =) [] + [] let byField tableName field sqlProps = - Custom.scalar - (Query.Exists.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] []) - toExists - sqlProps + byFields tableName Any [ field ] sqlProps + + /// Determine if a document exists using JSON field comparisons (->> =) + let ByFields(tableName, howMatched, fields, sqlProps) = + Custom.Scalar(Query.Exists.ByFields tableName howMatched fields, AddFields fields [], toExists, sqlProps) /// Determine if a document exists using a JSON containment query (@>) [] @@ -530,22 +599,27 @@ module WithProps = let ById<'TKey, 'TDoc when 'TDoc: null>(tableName, docId: 'TKey, sqlProps) = Custom.Single<'TDoc>(Query.Find.byId tableName, [ idParam docId ], fromData<'TDoc>, sqlProps) + /// Retrieve documents matching JSON field comparisons (->> =) + [] + 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 (->> =) [] + [] let byField<'TDoc> tableName field sqlProps = - Custom.list<'TDoc> - (Query.Find.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] []) - fromData<'TDoc> - sqlProps + byFields<'TDoc> tableName Any [ field ] sqlProps - /// Retrieve documents matching a JSON field comparison (->> =) - let ByField<'TDoc>(tableName, field, sqlProps) = + /// Retrieve documents matching JSON field comparisons (->> =) + let ByFields<'TDoc>(tableName, howMatched, fields, sqlProps) = Custom.List<'TDoc>( - Query.Find.byField tableName field, - addFieldParams [ { field with ParameterName = Some "@field" } ] [], - fromData<'TDoc>, - sqlProps) + Query.Find.ByFields tableName howMatched fields, AddFields fields [], fromData<'TDoc>, sqlProps) + + /// Retrieve documents matching a JSON field comparison (->> =) + [] + let ByField<'TDoc>(tableName, field, sqlProps) = + ByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps) /// Retrieve documents matching a JSON containment query (@>) [] @@ -569,23 +643,34 @@ module WithProps = Custom.List<'TDoc>( 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 - [] - let firstByField<'TDoc> tableName field sqlProps = + /// Retrieve the first document matching JSON field comparisons (->> =); returns None if not found + [] + let firstByFields<'TDoc> tableName howMatched fields sqlProps = Custom.single<'TDoc> - $"{Query.Find.byField tableName field} LIMIT 1" - (addFieldParams [ { field with ParameterName = Some "@field" } ] []) + $"{Query.Find.byFields tableName howMatched fields} LIMIT 1" + (addFieldParams fields []) fromData<'TDoc> sqlProps - /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found - let FirstByField<'TDoc when 'TDoc: null>(tableName, field, sqlProps) = + /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found + [] + [] + 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>( - $"{Query.Find.byField tableName field} LIMIT 1", - addFieldParams [ { field with ParameterName = Some "@field" } ] [], + $"{Query.Find.ByFields tableName howMatched fields} LIMIT 1", + AddFields fields [], fromData<'TDoc>, sqlProps) + /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found + [] + 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 [] 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 /// Patch documents using a JSON field comparison query in the WHERE clause (->> =) - [] - let byField tableName field (patch: 'TPatch) sqlProps = + [] + let byFields tableName howMatched fields (patch: 'TPatch) sqlProps = Custom.nonQuery - (Query.Patch.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] [ jsonParam "@data" patch ]) + (Query.Patch.byFields tableName howMatched fields) + (addFieldParams fields [ jsonParam "@data" patch ]) sqlProps + + /// Patch documents using a JSON field comparison query in the WHERE clause (->> =) + [] + [] + 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 (@>) [] let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps = @@ -674,17 +772,31 @@ module WithProps = let ById(tableName, docId: 'TKey, fieldNames, sqlProps) = byId tableName docId (List.ofSeq 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) + (addFieldParams fields [ fieldNameParam fieldNames ]) + sqlProps + /// Remove fields from documents via a comparison on a JSON field in the document [] + [] let byField tableName field fieldNames sqlProps = - Custom.nonQuery - (Query.RemoveFields.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] [ fieldNameParam fieldNames ]) - sqlProps + byFields tableName Any [ field ] 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 + [] 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 (@>) [] @@ -719,13 +831,19 @@ module WithProps = let byId tableName (docId: 'TKey) sqlProps = Custom.nonQuery (Query.Delete.byId tableName) [ idParam docId ] sqlProps + /// Delete documents by matching a JSON field comparison query (->> =) + [] + 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 (->> =) [] + [] let byField tableName field sqlProps = - Custom.nonQuery - (Query.Delete.byField tableName field) - (addFieldParams [ { field with ParameterName = Some "@field" } ] []) - sqlProps + byFields tableName Any [ field ] sqlProps + + let ByFields(tableName, howMatched, fields, sqlProps) = + Custom.nonQuery (Query.Delete.ByFields tableName howMatched fields) (AddFields fields []) sqlProps /// Delete documents by matching a JSON contains query (@>) [] @@ -819,10 +937,20 @@ module Count = let all tableName = WithProps.Count.all tableName (fromDataSource ()) + /// 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 field comparison query (->> =) [] + [] 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 (@>) [] @@ -844,10 +972,20 @@ module Exists = let byId tableName docId = WithProps.Exists.byId tableName docId (fromDataSource ()) + /// 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 field comparison query (->> =) [] + [] 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 (@>) [] @@ -883,13 +1021,24 @@ module Find = WithProps.Find.ById<'TKey, 'TDoc>(tableName, docId, fromDataSource ()) /// Retrieve documents matching a JSON field comparison query (->> =) - [] - let byField<'TDoc> tableName field = - WithProps.Find.byField<'TDoc> tableName field (fromDataSource ()) + [] + let byFields<'TDoc> tableName howMatched fields = + WithProps.Find.byFields<'TDoc> tableName howMatched fields (fromDataSource ()) /// Retrieve documents matching a JSON field comparison query (->> =) + [] + [] + 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 (->> =) + [] 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 (@>) [] @@ -909,14 +1058,25 @@ module Find = let ByJsonPath<'TDoc>(tableName, jsonPath) = WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ()) + /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found + [] + 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 [] + [] 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 + 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 + [] 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 [] @@ -965,10 +1125,20 @@ module Patch = let byId tableName (docId: 'TKey) (patch: 'TPatch) = WithProps.Patch.byId tableName docId patch (fromDataSource ()) + /// 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 field comparison query in the WHERE clause (->> =) [] + [] 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 (@>) [] @@ -994,14 +1164,25 @@ module RemoveFields = let ById(tableName, docId: 'TKey, fieldNames) = WithProps.RemoveFields.ById(tableName, docId, fieldNames, fromDataSource ()) - /// Remove fields from documents via a comparison on a JSON field in the document - [] - let byField tableName field fieldNames = - WithProps.RemoveFields.byField tableName field fieldNames (fromDataSource ()) + /// 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 + [] + [] + 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 + [] 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 (@>) [] @@ -1030,11 +1211,21 @@ module Delete = [] let byId tableName (docId: 'TKey) = WithProps.Delete.byId tableName docId (fromDataSource ()) - + + /// 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 field comparison query (->> =) [] + [] 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 (@>) [] diff --git a/src/Sqlite/Library.fs b/src/Sqlite/Library.fs index 90a8520..3a52534 100644 --- a/src/Sqlite/Library.fs +++ b/src/Sqlite/Library.fs @@ -33,7 +33,7 @@ module Query = /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document [] - let whereByFields fields howMatched = + let whereByFields howMatched fields = let name = ParameterName() fields |> List.map (fun it -> @@ -46,19 +46,19 @@ module Query = |> String.concat (match howMatched with Any -> " OR " | All -> " AND ") /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document - let WhereByFields(fields: Field seq, howMatched) = - whereByFields (List.ofSeq fields) howMatched + let WhereByFields(howMatched, fields: Field seq) = + whereByFields howMatched (List.ofSeq fields) /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document [] [] 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 [] 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 module Definition = @@ -84,7 +84,7 @@ module Query = /// Query to count matching documents using a text comparison on a JSON 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 /// Queries for determining document existence @@ -98,7 +98,7 @@ module Query = /// Query to determine if documents exist using a comparison on a JSON 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 /// Queries for retrieving documents @@ -112,7 +112,7 @@ module Query = /// Query to retrieve documents using a comparison on a JSON 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) /// 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 [] 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 module RemoveFields = @@ -152,7 +152,7 @@ module Query = /// Query to remove fields from documents via a comparison on a JSON field within the document [] 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 let ByField(tableName, field, parameters) = @@ -169,7 +169,7 @@ module Query = /// Query to delete documents using a comparison on a JSON 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 diff --git a/src/Tests.CSharp/PostgresCSharpTests.cs b/src/Tests.CSharp/PostgresCSharpTests.cs index 960ca6e..fb9f551 100644 --- a/src/Tests.CSharp/PostgresCSharpTests.cs +++ b/src/Tests.CSharp/PostgresCSharpTests.cs @@ -64,48 +64,48 @@ public static class PostgresCSharpTests TestCase("succeeds for a single field when a logical operator is passed", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.GT("theField", 0).WithParameterName("@test")], - FieldMatch.Any), + Postgres.Query.WhereByFields(FieldMatch.Any, + [Field.GT("theField", 0).WithParameterName("@test")]), "data->>'theField' > @test", "WHERE clause not correct"); }), 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"); }), TestCase("succeeds for a single field when a between operator is passed with numeric values", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.BT("aField", 50, 99).WithParameterName("@range")], - FieldMatch.All), + Postgres.Query.WhereByFields(FieldMatch.All, + [Field.BT("aField", 50, 99).WithParameterName("@range")]), "(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", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.BT("field0", "a", "b").WithParameterName("@alpha")], - FieldMatch.Any), + Postgres.Query.WhereByFields(FieldMatch.Any, + [Field.BT("field0", "a", "b").WithParameterName("@alpha")]), "data->>'field0' BETWEEN @alphamin AND @alphamax", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with logical operators", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")], - FieldMatch.All), + Postgres.Query.WhereByFields(FieldMatch.All, + [Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")]), "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct"); }), TestCase("succeeds for any multiple fields with an existence operator", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.NEX("thatField"), Field.GE("thisField", 18)], - FieldMatch.Any), + Postgres.Query.WhereByFields(FieldMatch.Any, + [Field.NEX("thatField"), Field.GE("thisField", 18)]), "data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with between operators", () => { Expect.equal( - Postgres.Query.WhereByFields([Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")], - FieldMatch.All), + Postgres.Query.WhereByFields(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", "WHERE clause not correct"); }) @@ -186,7 +186,7 @@ public static class PostgresCSharpTests TestCase("ByField succeeds", () => { 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"); }), TestCase("ByContains succeeds", () => @@ -213,7 +213,7 @@ public static class PostgresCSharpTests TestCase("ByField succeeds", () => { 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"); }), TestCase("ByContains succeeds", () => @@ -240,7 +240,7 @@ public static class PostgresCSharpTests TestCase("ByField succeeds", () => { 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"); }), TestCase("byContains succeeds", () => @@ -267,7 +267,7 @@ public static class PostgresCSharpTests TestCase("ByField succeeds", () => { 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"); }), TestCase("ByContains succeeds", () => @@ -294,7 +294,7 @@ public static class PostgresCSharpTests TestCase("ByField succeeds", () => { 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"); }), TestCase("ByContains succeeds", () => diff --git a/src/Tests.CSharp/SqliteCSharpTests.cs b/src/Tests.CSharp/SqliteCSharpTests.cs index 44c807a..3b9ac72 100644 --- a/src/Tests.CSharp/SqliteCSharpTests.cs +++ b/src/Tests.CSharp/SqliteCSharpTests.cs @@ -25,41 +25,40 @@ public static class SqliteCSharpTests TestCase("succeeds for a single field when a logical operator is passed", () => { Expect.equal( - Sqlite.Query.WhereByFields([Field.GT("theField", 0).WithParameterName("@test")], - FieldMatch.Any), + Sqlite.Query.WhereByFields(FieldMatch.Any, + [Field.GT("theField", 0).WithParameterName("@test")]), "data->>'theField' > @test", "WHERE clause not correct"); }), 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"); }), TestCase("succeeds for a single field when a between operator is passed", () => { Expect.equal( - Sqlite.Query.WhereByFields([Field.BT("aField", 50, 99).WithParameterName("@range")], - FieldMatch.All), + Sqlite.Query.WhereByFields(FieldMatch.All, + [Field.BT("aField", 50, 99).WithParameterName("@range")]), "data->>'aField' BETWEEN @rangemin AND @rangemax", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with logical operators", () => { Expect.equal( - Sqlite.Query.WhereByFields([Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")], - FieldMatch.All), + Sqlite.Query.WhereByFields(FieldMatch.All, + [Field.EQ("theFirst", "1"), Field.EQ("numberTwo", "2")]), "data->>'theFirst' = @field0 AND data->>'numberTwo' = @field1", "WHERE clause not correct"); }), TestCase("succeeds for any multiple fields with an existence operator", () => { Expect.equal( - Sqlite.Query.WhereByFields([Field.NEX("thatField"), Field.GE("thisField", 18)], - FieldMatch.Any), + Sqlite.Query.WhereByFields(FieldMatch.Any, [Field.NEX("thatField"), Field.GE("thisField", 18)]), "data->>'thatField' IS NULL OR data->>'thisField' >= @field0", "WHERE clause not correct"); }), TestCase("succeeds for all multiple fields with between operators", () => { Expect.equal( - Sqlite.Query.WhereByFields([Field.BT("aField", 50, 99), Field.BT("anotherField", "a", "b")], - FieldMatch.All), + Sqlite.Query.WhereByFields(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", "WHERE clause not correct"); }) diff --git a/src/Tests/PostgresTests.fs b/src/Tests/PostgresTests.fs index d25f6ca..d43309b 100644 --- a/src/Tests/PostgresTests.fs +++ b/src/Tests/PostgresTests.fs @@ -61,43 +61,43 @@ let unitTests = testList "whereByFields" [ test "succeeds for a single field when a logical operator is passed" { 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" "WHERE clause not correct" } test "succeeds for a single field when an existence operator is passed" { Expect.equal - (Query.whereByFields [ Field.NEX "thatField" ] Any) + (Query.whereByFields Any [ Field.NEX "thatField" ]) "data->>'thatField' IS NULL" "WHERE clause not correct" } test "succeeds for a single field when a between operator is passed with numeric values" { 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" "WHERE clause not correct" } test "succeeds for a single field when a between operator is passed with non-numeric values" { 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" "WHERE clause not correct" } test "succeeds for all multiple fields with logical operators" { 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" "WHERE clause not correct" } test "succeeds for any multiple fields with an existence operator" { 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" "WHERE clause not correct" } test "succeeds for all multiple fields with between operators" { 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" "WHERE clause not correct" } @@ -174,7 +174,7 @@ let unitTests = test "byField succeeds" { Expect.equal (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" } test "byContains succeeds" { @@ -200,7 +200,7 @@ let unitTests = test "byField succeeds" { Expect.equal (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" } test "byContains succeeds" { @@ -226,7 +226,7 @@ let unitTests = test "byField succeeds" { Expect.equal (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" } test "byContains succeeds" { @@ -252,7 +252,7 @@ let unitTests = test "byField succeeds" { Expect.equal (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" } test "byContains succeeds" { @@ -278,7 +278,7 @@ let unitTests = test "byField succeeds" { Expect.equal (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" } test "byContains succeeds" { diff --git a/src/Tests/SqliteTests.fs b/src/Tests/SqliteTests.fs index 73365e4..0a3b249 100644 --- a/src/Tests/SqliteTests.fs +++ b/src/Tests/SqliteTests.fs @@ -15,37 +15,37 @@ let unitTests = testList "whereByFields" [ test "succeeds for a single field when a logical operator is passed" { 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" "WHERE clause not correct" } test "succeeds for a single field when an existence operator is passed" { Expect.equal - (Query.whereByFields [ Field.NEX "thatField" ] Any) + (Query.whereByFields Any [ Field.NEX "thatField" ]) "data->>'thatField' IS NULL" "WHERE clause not correct" } test "succeeds for a single field when a between operator is passed" { 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" "WHERE clause not correct" } test "succeeds for all multiple fields with logical operators" { 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" "WHERE clause not correct" } test "succeeds for any multiple fields with an existence operator" { 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" "WHERE clause not correct" } test "succeeds for all multiple fields with between operators" { 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" "WHERE clause not correct" }