Version 4 #6

Merged
danieljsummers merged 30 commits from version-four into main 2024-08-19 23:30:39 +00:00
9 changed files with 75 additions and 366 deletions
Showing only changes of commit 98bc83ac17 - Show all commits

View File

@ -209,6 +209,11 @@ module Configuration =
[<RequireQualifiedAccess>]
module Query =
/// Combine a query (select, update, etc.) and a WHERE clause
[<CompiledName "StatementWhere">]
let statementWhere statement where =
$"%s{statement} WHERE %s{where}"
/// Create a SELECT clause to retrieve the document data from the given table
[<CompiledName "SelectFromTable">]
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
[<CompiledName "All">]
let all tableName =
$"SELECT COUNT(*) AS it FROM %s{tableName}"
/// Query to count matching documents using a text comparison on JSON fields
[<CompiledName "ByFields">]
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)
[<CompiledName "Update">]
let update tableName =
$"UPDATE %s{tableName} SET data = @data"
/// Query to count documents in a table (no WHERE clause)
[<CompiledName "Count">]
let count tableName =
$"SELECT COUNT(*) AS it FROM %s{tableName}"
/// Query to check for document existence in a table
[<CompiledName "Exists">]
let exists tableName where =
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it"

View File

@ -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
[<CompiledName "Update">]
let update tableName =
$"""UPDATE %s{tableName} SET data = @data WHERE {whereById "@id"}"""
/// Create a WHERE clause fragment to implement a @> (JSON contains) condition
[<CompiledName "WhereDataContains">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field =
byFields tableName Any [ field ]
/// Query to count matching documents using a JSON containment query (@>)
[<CompiledName "ByContains">]
let byContains tableName =
$"""{Query.Count.all tableName} WHERE {whereDataContains "@criteria"}"""
/// Query to count matching documents using a JSON Path match (@?)
[<CompiledName "ByJsonPath">]
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
[<CompiledName "ById">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field =
byFields tableName Any [ field ]
/// Query to determine if documents exist using a JSON containment query (@>)
[<CompiledName "ByContains">]
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 (@?)
[<CompiledName "ByJsonPath">]
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
[<CompiledName "All">]
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 (->> =)
[<CompiledName "ByFields">]
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 (->> =)
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
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 (@>)
[<CompiledName "ByContains">]
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 (@?)
[<CompiledName "ByJsonPath">]
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
[<RequireQualifiedAccess>]
@ -504,29 +455,34 @@ module WithProps =
/// Determine if a document exists for the given ID
[<CompiledName "ById">]
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 (->> =)
[<CompiledName "ByFields">]
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 (->> =)
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
let byField tableName field sqlProps =
byFields tableName Any [ field ] sqlProps
/// Determine if a document exists using a JSON containment query (@>)
[<CompiledName "ByContains">]
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 (@?)
[<CompiledName "ByJsonPath">]
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
[<RequireQualifiedAccess>]
@ -657,7 +613,10 @@ module WithProps =
/// Update an entire document by its ID
[<CompiledName "ById">]
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
[<CompiledName "FSharpByFunc">]

View File

@ -64,44 +64,6 @@ module Query =
let ensureTable name =
Query.Definition.ensureTableFor name "TEXT"
/// Query to update a document
[<CompiledName "Update">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
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
[<CompiledName "ById">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
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
[<CompiledName "All">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
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
[<RequireQualifiedAccess>]
@ -401,18 +361,16 @@ module WithConn =
/// Determine if a document exists for the given ID
[<CompiledName "ById">]
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
[<CompiledName "ByFields">]
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
[<CompiledName "ByField">]
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
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
[<RequireQualifiedAccess>]
@ -493,7 +451,10 @@ module WithConn =
/// Update an entire document by its ID
[<CompiledName "ById">]
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
[<CompiledName "FSharpByFunc">]

View File

@ -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");
}),
])
})
])
]);
}

View File

@ -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", () =>

View File

@ -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", () =>

View File

@ -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"
}
]
]

View File

@ -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

View File

@ -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