diff --git a/src/Common/Library.fs b/src/Common/Library.fs index 3ae755a..a1cc7a2 100644 --- a/src/Common/Library.fs +++ b/src/Common/Library.fs @@ -209,6 +209,11 @@ module Configuration = [] module Query = + /// Combine a query (select, update, etc.) and a WHERE clause + [] + let statementWhere statement where = + $"%s{statement} WHERE %s{where}" + /// Create a SELECT clause to retrieve the document data from the given table [] let selectFromTable tableName = @@ -258,15 +263,17 @@ module Query = "INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data" tableName (Configuration.idField ()) - /// Queries for counting documents - module Count = - - /// Query to count all documents in a table - [] - let all tableName = - $"SELECT COUNT(*) AS it FROM %s{tableName}" - - /// Query to count matching documents using a text comparison on JSON fields - [] - let byFields (whereByFields: FieldMatch -> Field seq -> string) tableName howMatched fields = - $"SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByFields howMatched fields}" + /// Query to update a document (no WHERE clause) + [] + let update tableName = + $"UPDATE %s{tableName} SET data = @data" + + /// Query to count documents in a table (no WHERE clause) + [] + let count tableName = + $"SELECT COUNT(*) AS it FROM %s{tableName}" + + /// Query to check for document existence in a table + [] + let exists tableName where = + $"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it" diff --git a/src/Postgres/Library.fs b/src/Postgres/Library.fs index 9138811..69f86e0 100644 --- a/src/Postgres/Library.fs +++ b/src/Postgres/Library.fs @@ -160,11 +160,6 @@ module Query = let tableName = name.Split '.' |> Array.last $"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})" - /// Query to update a document - [] - let update tableName = - $"""UPDATE %s{tableName} SET data = @data WHERE {whereById "@id"}""" - /// Create a WHERE clause fragment to implement a @> (JSON contains) condition [] let whereDataContains paramName = @@ -175,58 +170,17 @@ module Query = let whereJsonPathMatches paramName = $"data @? %s{paramName}::jsonpath" - /// Queries for counting documents - module Count = - - /// Query to count matching documents using a text comparison on JSON fields - [] - let byFields tableName howMatched fields = - Query.Count.byFields whereByFields tableName howMatched fields - - /// Query to count matching documents using a text comparison on a JSON field - [] - [] - let byField tableName field = - byFields tableName Any [ field ] - - /// Query to count matching documents using a JSON containment query (@>) - [] - let byContains tableName = - $"""{Query.Count.all tableName} WHERE {whereDataContains "@criteria"}""" - - /// Query to count matching documents using a JSON Path match (@?) - [] - let byJsonPath tableName = - $"""{Query.Count.all tableName} WHERE {whereJsonPathMatches "@path"}""" + /// Create a query on JSON fields + let fieldQuery statement howMatched fields = + Query.statementWhere statement (whereByFields howMatched fields) - /// Queries for determining document existence - module Exists = - - /// Query to determine if a document exists for the given ID - [] - 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 = - byFields tableName Any [ field ] - - /// Query to determine if documents exist using a JSON containment query (@>) - [] - let byContains tableName = - $"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereDataContains "@criteria"}) AS it""" - - /// Query to determine if documents exist using a JSON Path match (@?) - [] - let byJsonPath tableName = - $"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereJsonPathMatches "@path"}) AS it""" + /// Create a JSON containment query + let containQuery statement = + Query.statementWhere statement (whereDataContains "@criteria") + + /// Create a JSON Path match query + let pathMatchQuery statement = + Query.statementWhere statement (whereJsonPathMatches "@path") /// Queries for retrieving documents module Find = @@ -474,28 +428,25 @@ module WithProps = /// Count all documents in a table [] let all tableName sqlProps = - Custom.scalar (Query.Count.all tableName) [] toCount sqlProps + Custom.scalar (Query.count 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 = - byFields tableName Any [ field ] sqlProps + Custom.scalar + (Query.fieldQuery (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount sqlProps /// Count matching documents using a JSON containment query (@>) [] let byContains tableName (criteria: 'TContains) sqlProps = - Custom.scalar (Query.Count.byContains tableName) [ jsonParam "@criteria" criteria ] toCount sqlProps + Custom.scalar + (Query.containQuery (Query.count tableName)) [ jsonParam "@criteria" criteria ] toCount sqlProps /// Count matching documents using a JSON Path match query (@?) [] let byJsonPath tableName jsonPath sqlProps = - Custom.scalar (Query.Count.byJsonPath tableName) [ "@path", Sql.string jsonPath ] toCount sqlProps + Custom.scalar + (Query.pathMatchQuery (Query.count tableName)) [ "@path", Sql.string jsonPath ] toCount sqlProps /// Commands to determine if documents exist [] @@ -504,29 +455,34 @@ module WithProps = /// Determine if a document exists for the given ID [] let byId tableName (docId: 'TKey) sqlProps = - Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists sqlProps + Custom.scalar (Query.exists tableName (Query.whereById "@id")) [ 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 + (Query.exists tableName (Query.whereByFields howMatched fields)) + (addFieldParams fields []) + toExists + sqlProps - /// Determine if a document exists using a JSON field comparison (->> =) - [] - [] - let byField tableName field sqlProps = - byFields tableName Any [ field ] sqlProps - /// Determine if a document exists using a JSON containment query (@>) [] let byContains tableName (criteria: 'TContains) sqlProps = - Custom.scalar (Query.Exists.byContains tableName) [ jsonParam "@criteria" criteria ] toExists sqlProps + Custom.scalar + (Query.exists tableName (Query.whereDataContains "@criteria")) + [ jsonParam "@criteria" criteria ] + toExists + sqlProps /// Determine if a document exists using a JSON Path match query (@?) [] let byJsonPath tableName jsonPath sqlProps = - Custom.scalar (Query.Exists.byJsonPath tableName) [ "@path", Sql.string jsonPath ] toExists sqlProps + Custom.scalar + (Query.exists tableName (Query.whereJsonPathMatches "@path")) + [ "@path", Sql.string jsonPath ] + toExists + sqlProps /// Commands to determine if documents exist [] @@ -657,7 +613,10 @@ module WithProps = /// Update an entire document by its ID [] let byId tableName (docId: 'TKey) (document: 'TDoc) sqlProps = - Custom.nonQuery (Query.update tableName) [ idParam docId; jsonParam "@data" document ] sqlProps + Custom.nonQuery + (Query.statementWhere (Query.update tableName) (Query.whereById "@id")) + [ idParam docId; jsonParam "@data" document ] + sqlProps /// Update an entire document by its ID, using the provided function to obtain the ID from the document [] diff --git a/src/Sqlite/Library.fs b/src/Sqlite/Library.fs index b716fa0..a0d861a 100644 --- a/src/Sqlite/Library.fs +++ b/src/Sqlite/Library.fs @@ -64,44 +64,6 @@ module Query = let ensureTable name = Query.Definition.ensureTableFor name "TEXT" - /// Query to update a document - [] - let update tableName = - $"""UPDATE %s{tableName} SET data = @data WHERE {whereById "@id"}""" - - /// Queries for counting documents - module Count = - - /// Query to count matching documents using a text comparison on JSON fields - [] - let byFields tableName howMatched fields = - Query.Count.byFields whereByFields tableName howMatched fields - - /// Query to count matching documents using a text comparison on a JSON field - [] - [] - let byField tableName field = - byFields tableName Any [ field ] - - /// Queries for determining document existence - module Exists = - - /// Query to determine if a document exists for the given ID - [] - 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 = - byFields tableName Any [ field ] - /// Queries for retrieving documents module Find = @@ -381,18 +343,16 @@ module WithConn = /// Count all documents in a table [] let all tableName conn = - Custom.scalar (Query.Count.all tableName) [] toCount conn + Custom.scalar (Query.count tableName) [] toCount conn /// Count matching documents using a comparison on JSON fields [] let byFields tableName howMatched fields conn = - Custom.scalar (Query.Count.byFields tableName howMatched fields) (addFieldParams fields []) toCount conn - - /// Count matching documents using a comparison on a JSON field - [] - [] - let byField tableName field conn = - byFields tableName Any [ field ] conn + Custom.scalar + (Query.statementWhere (Query.count tableName) (Query.whereByFields howMatched fields)) + (addFieldParams fields []) + toCount + conn /// Commands to determine if documents exist [] @@ -401,18 +361,16 @@ module WithConn = /// Determine if a document exists for the given ID [] let byId tableName (docId: 'TKey) conn = - Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists conn + Custom.scalar (Query.exists tableName (Query.whereById "@id")) [ idParam docId ] toExists conn /// Determine if a document exists using a comparison on JSON fields [] let byFields tableName howMatched fields conn = - Custom.scalar (Query.Exists.byFields tableName howMatched fields) (addFieldParams fields []) toExists conn - - /// Determine if a document exists using a comparison on a JSON field - [] - [] - let byField tableName field conn = - byFields tableName Any [ field ] conn + Custom.scalar + (Query.exists tableName (Query.whereByFields howMatched fields)) + (addFieldParams fields []) + toExists + conn /// Commands to retrieve documents [] @@ -493,7 +451,10 @@ module WithConn = /// Update an entire document by its ID [] let byId tableName (docId: 'TKey) (document: 'TDoc) conn = - Custom.nonQuery (Query.update tableName) [ idParam docId; jsonParam "@data" document ] conn + Custom.nonQuery + (Query.statementWhere (Query.update tableName) (Query.whereById "@id")) + [ idParam docId; jsonParam "@data" document ] + conn /// Update an entire document by its ID, using the provided function to obtain the ID from the document [] diff --git a/src/Tests.CSharp/CommonCSharpTests.cs b/src/Tests.CSharp/CommonCSharpTests.cs index e823508..d1ed8cd 100644 --- a/src/Tests.CSharp/CommonCSharpTests.cs +++ b/src/Tests.CSharp/CommonCSharpTests.cs @@ -285,15 +285,7 @@ public static class CommonCSharpTests Expect.equal(Query.Save("tbl"), "INSERT INTO tbl VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data", "INSERT ON CONFLICT UPDATE statement not correct"); - }), - TestList("Count", - [ - TestCase("All succeeds", () => - { - Expect.equal(Query.Count.All("a_table"), $"SELECT COUNT(*) AS it FROM a_table", - "Count query not correct"); - }), - ]) + }) ]) ]); } diff --git a/src/Tests.CSharp/PostgresCSharpTests.cs b/src/Tests.CSharp/PostgresCSharpTests.cs index d3c239b..cc115fd 100644 --- a/src/Tests.CSharp/PostgresCSharpTests.cs +++ b/src/Tests.CSharp/PostgresCSharpTests.cs @@ -270,11 +270,6 @@ public static class PostgresCSharpTests "CREATE INDEX statement not constructed correctly"); }) ]), - TestCase("Update succeeds", () => - { - Expect.equal(Postgres.Query.Update("tbl"), "UPDATE tbl SET data = @data WHERE data->>'Id' = @id", - "UPDATE full statement not correct"); - }), TestCase("WhereDataContains succeeds", () => { Expect.equal(Postgres.Query.WhereDataContains("@test"), "data @> @test", @@ -285,74 +280,6 @@ public static class PostgresCSharpTests Expect.equal(Postgres.Query.WhereJsonPathMatches("@path"), "data @? @path::jsonpath", "WHERE clause not correct"); }), - TestList("Count", - [ - TestCase("ByFields succeeds", () => - { - Expect.equal( - Postgres.Query.Count.ByFields("x", FieldMatch.All, - [Field.EQ("thatField", 0), Field.EQ("anotherField", 8)]), - $"SELECT COUNT(*) AS it FROM x WHERE data->>'thatField' = @field0 AND data->>'anotherField' = @field1", - "JSON field text comparison count query not correct"); - }), -#pragma warning disable CS0618 - 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' = @field0", - "JSON field text comparison count query not correct"); - }), -#pragma warning restore CS0618 - TestCase("ByContains succeeds", () => - { - Expect.equal(Postgres.Query.Count.ByContains(PostgresDb.TableName), - $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data @> @criteria", - "JSON containment count query not correct"); - }), - TestCase("ByJsonPath succeeds", () => - { - Expect.equal(Postgres.Query.Count.ByJsonPath(PostgresDb.TableName), - $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath", - "JSON Path match count query not correct"); - }) - ]), - TestList("Exists", - [ - TestCase("ById succeeds", () => - { - Expect.equal(Postgres.Query.Exists.ById(PostgresDb.TableName), - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Id' = @id) AS it", - "ID existence query not correct"); - }), - TestCase("ByFields succeeds", () => - { - Expect.equal( - Postgres.Query.Exists.ByFields("q", FieldMatch.Any, - [Field.LT("Test", 0).WithParameterName("@a"), Field.LT("Unit", "x").WithParameterName("@b")]), - $"SELECT EXISTS (SELECT 1 FROM q WHERE data->>'Test' < @a OR data->>'Unit' < @b) AS it", - "JSON field text comparison exists query not correct"); - }), -#pragma warning disable CS0618 - 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' < @field0) AS it", - "JSON field text comparison exists query not correct"); - }), -#pragma warning restore CS0618 - TestCase("ByContains succeeds", () => - { - Expect.equal(Postgres.Query.Exists.ByContains(PostgresDb.TableName), - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data @> @criteria) AS it", - "JSON containment exists query not correct"); - }), - TestCase("byJsonPath succeeds", () => - { - Expect.equal(Postgres.Query.Exists.ByJsonPath(PostgresDb.TableName), - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath) AS it", - "JSON Path match existence query not correct"); - }) - ]), TestList("Find", [ TestCase("ById succeeds", () => diff --git a/src/Tests.CSharp/SqliteCSharpTests.cs b/src/Tests.CSharp/SqliteCSharpTests.cs index ca57e8b..be07d87 100644 --- a/src/Tests.CSharp/SqliteCSharpTests.cs +++ b/src/Tests.CSharp/SqliteCSharpTests.cs @@ -92,39 +92,6 @@ public static class SqliteCSharpTests Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"), "CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)", "CREATE TABLE statement not correct"); }), - TestCase("Update succeeds", () => - { - Expect.equal(Sqlite.Query.Update("tbl"), "UPDATE tbl SET data = @data WHERE data->>'Id' = @id", - "UPDATE full statement not correct"); - }), - TestList("Count", - [ -#pragma warning disable CS0618 - TestCase("ByField succeeds", () => - { - Expect.equal(Sqlite.Query.Count.ByField("tbl", Field.EQ("thatField", 0)), - "SELECT COUNT(*) AS it FROM tbl WHERE data->>'thatField' = @field0", - "JSON field text comparison count query not correct"); - }) -#pragma warning restore CS0618 - ]), - TestList("Exists", - [ - TestCase("ById succeeds", () => - { - Expect.equal(Sqlite.Query.Exists.ById("tbl"), - "SELECT EXISTS (SELECT 1 FROM tbl WHERE data->>'Id' = @id) AS it", - "ID existence query not correct"); - }), -#pragma warning disable CS0618 - TestCase("ByField succeeds", () => - { - Expect.equal(Sqlite.Query.Exists.ByField("tbl", Field.LT("Test", 0)), - "SELECT EXISTS (SELECT 1 FROM tbl WHERE data->>'Test' < @field0) AS it", - "JSON field text comparison exists query not correct"); - }) -#pragma warning restore CS0618 - ]), TestList("Find", [ TestCase("ById succeeds", () => diff --git a/src/Tests/CommonTests.fs b/src/Tests/CommonTests.fs index 5020d26..4e2eab0 100644 --- a/src/Tests/CommonTests.fs +++ b/src/Tests/CommonTests.fs @@ -213,18 +213,8 @@ let all = $"INSERT INTO {tbl} VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data" "INSERT ON CONFLICT UPDATE statement not correct" } - testList "Count" [ - test "all succeeds" { - Expect.equal (Query.Count.all "a_table") "SELECT COUNT(*) AS it FROM a_table" - "Count query not correct" - } - test "byFields succeeds" { - let test = fun _ _ -> "howdy" - Expect.equal - (Query.Count.byFields test "over_here" Any []) - "SELECT COUNT(*) AS it FROM over_here WHERE howdy" - "Count by fields query not correct" - } - ] + test "count succeeds" { + Expect.equal (Query.count "a_table") "SELECT COUNT(*) AS it FROM a_table" "Count query not correct" + } ] ] diff --git a/src/Tests/PostgresTests.fs b/src/Tests/PostgresTests.fs index 81d5052..d217a2b 100644 --- a/src/Tests/PostgresTests.fs +++ b/src/Tests/PostgresTests.fs @@ -246,78 +246,12 @@ let unitTests = "CREATE INDEX statement not constructed correctly" } ] - test "update succeeds" { - Expect.equal - (Query.update PostgresDb.TableName) - $"UPDATE {PostgresDb.TableName} SET data = @data WHERE data->>'Id' = @id" - "UPDATE full statement not correct" - } test "whereDataContains succeeds" { Expect.equal (Query.whereDataContains "@test") "data @> @test" "WHERE clause not correct" } test "whereJsonPathMatches succeeds" { Expect.equal (Query.whereJsonPathMatches "@path") "data @? @path::jsonpath" "WHERE clause not correct" } - testList "Count" [ - test "byFields succeeds" { - Expect.equal - (Query.Count.byFields "tbl" All [ Field.EQ "thatField" 0; Field.EQ "anotherField" 8]) - $"SELECT COUNT(*) AS it FROM tbl WHERE data->>'thatField' = @field0 AND data->>'anotherField' = @field1" - "JSON field text comparison count query not correct" - } - test "byField succeeds" { - Expect.equal - (Query.Count.byField PostgresDb.TableName (Field.EQ "thatField" 0)) - $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data->>'thatField' = @field0" - "JSON field text comparison count query not correct" - } - test "byContains succeeds" { - Expect.equal - (Query.Count.byContains PostgresDb.TableName) - $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data @> @criteria" - "JSON containment count query not correct" - } - test "byJsonPath succeeds" { - Expect.equal - (Query.Count.byJsonPath PostgresDb.TableName) - $"SELECT COUNT(*) AS it FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath" - "JSON Path match count query not correct" - } - ] - testList "Exists" [ - test "byId succeeds" { - Expect.equal - (Query.Exists.byId PostgresDb.TableName) - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Id' = @id) AS it" - "ID existence query not correct" - } - test "byFields succeeds" { - Expect.equal - (Query.Exists.byFields "tbl" Any - [ { Field.LT "Test" 0 with ParameterName = Some "@a" } - { Field.GT "Unit" "x" with ParameterName = Some "@b" } ]) - $"SELECT EXISTS (SELECT 1 FROM tbl WHERE data->>'Test' < @a OR data->>'Unit' > @b) AS it" - "JSON field text comparison exists query not correct" - } - test "byField succeeds" { - Expect.equal - (Query.Exists.byField PostgresDb.TableName (Field.LT "Test" 0)) - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data->>'Test' < @field0) AS it" - "JSON field text comparison exists query not correct" - } - test "byContains succeeds" { - Expect.equal - (Query.Exists.byContains PostgresDb.TableName) - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data @> @criteria) AS it" - "JSON containment exists query not correct" - } - test "byJsonPath succeeds" { - Expect.equal - (Query.Exists.byJsonPath PostgresDb.TableName) - $"SELECT EXISTS (SELECT 1 FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath) AS it" - "JSON Path match existence query not correct" - } - ] testList "Find" [ test "byId succeeds" { Expect.equal diff --git a/src/Tests/SqliteTests.fs b/src/Tests/SqliteTests.fs index 709f50a..a916473 100644 --- a/src/Tests/SqliteTests.fs +++ b/src/Tests/SqliteTests.fs @@ -81,34 +81,6 @@ let unitTests = "CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)" "CREATE TABLE statement not correct" } - test "update succeeds" { - Expect.equal - (Query.update "tbl") - "UPDATE tbl SET data = @data WHERE data->>'Id' = @id" - "UPDATE full statement not correct" - } - testList "Count" [ - test "byField succeeds" { - Expect.equal - (Query.Count.byField "tbl" (Field.EQ "thatField" 0)) - "SELECT COUNT(*) AS it FROM tbl WHERE data->>'thatField' = @field0" - "JSON field text comparison count query not correct" - } - ] - testList "Exists" [ - test "byId succeeds" { - Expect.equal - (Query.Exists.byId "tbl") - "SELECT EXISTS (SELECT 1 FROM tbl WHERE data->>'Id' = @id) AS it" - "ID existence query not correct" - } - test "byField succeeds" { - Expect.equal - (Query.Exists.byField "tbl" (Field.LT "Test" 0)) - "SELECT EXISTS (SELECT 1 FROM tbl WHERE data->>'Test' < @field0) AS it" - "JSON field text comparison exists query not correct" - } - ] testList "Find" [ test "byId succeeds" { Expect.equal