Version 4 #6
|
@ -209,6 +209,11 @@ module Configuration =
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Query =
|
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
|
/// Create a SELECT clause to retrieve the document data from the given table
|
||||||
[<CompiledName "SelectFromTable">]
|
[<CompiledName "SelectFromTable">]
|
||||||
let selectFromTable tableName =
|
let selectFromTable tableName =
|
||||||
|
@ -258,15 +263,17 @@ module Query =
|
||||||
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data"
|
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data"
|
||||||
tableName (Configuration.idField ())
|
tableName (Configuration.idField ())
|
||||||
|
|
||||||
/// Queries for counting documents
|
/// Query to update a document (no WHERE clause)
|
||||||
module Count =
|
[<CompiledName "Update">]
|
||||||
|
let update tableName =
|
||||||
/// Query to count all documents in a table
|
$"UPDATE %s{tableName} SET data = @data"
|
||||||
[<CompiledName "All">]
|
|
||||||
let all tableName =
|
/// Query to count documents in a table (no WHERE clause)
|
||||||
$"SELECT COUNT(*) AS it FROM %s{tableName}"
|
[<CompiledName "Count">]
|
||||||
|
let count tableName =
|
||||||
/// Query to count matching documents using a text comparison on JSON fields
|
$"SELECT COUNT(*) AS it FROM %s{tableName}"
|
||||||
[<CompiledName "ByFields">]
|
|
||||||
let byFields (whereByFields: FieldMatch -> Field seq -> string) tableName howMatched fields =
|
/// Query to check for document existence in a table
|
||||||
$"SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByFields howMatched fields}"
|
[<CompiledName "Exists">]
|
||||||
|
let exists tableName where =
|
||||||
|
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it"
|
||||||
|
|
|
@ -160,11 +160,6 @@ module Query =
|
||||||
let tableName = name.Split '.' |> Array.last
|
let tableName = name.Split '.' |> Array.last
|
||||||
$"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})"
|
$"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
|
/// Create a WHERE clause fragment to implement a @> (JSON contains) condition
|
||||||
[<CompiledName "WhereDataContains">]
|
[<CompiledName "WhereDataContains">]
|
||||||
let whereDataContains paramName =
|
let whereDataContains paramName =
|
||||||
|
@ -175,58 +170,17 @@ module Query =
|
||||||
let whereJsonPathMatches paramName =
|
let whereJsonPathMatches paramName =
|
||||||
$"data @? %s{paramName}::jsonpath"
|
$"data @? %s{paramName}::jsonpath"
|
||||||
|
|
||||||
/// Queries for counting documents
|
/// Create a query on JSON fields
|
||||||
module Count =
|
let fieldQuery statement howMatched fields =
|
||||||
|
Query.statementWhere statement (whereByFields howMatched fields)
|
||||||
/// 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"}"""
|
|
||||||
|
|
||||||
/// Queries for determining document existence
|
/// Create a JSON containment query
|
||||||
module Exists =
|
let containQuery statement =
|
||||||
|
Query.statementWhere statement (whereDataContains "@criteria")
|
||||||
/// Query to determine if a document exists for the given ID
|
|
||||||
[<CompiledName "ById">]
|
/// Create a JSON Path match query
|
||||||
let byId tableName =
|
let pathMatchQuery statement =
|
||||||
$"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereById "@id"}) AS it"""
|
Query.statementWhere statement (whereJsonPathMatches "@path")
|
||||||
|
|
||||||
/// 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"""
|
|
||||||
|
|
||||||
/// Queries for retrieving documents
|
/// Queries for retrieving documents
|
||||||
module Find =
|
module Find =
|
||||||
|
@ -474,28 +428,25 @@ module WithProps =
|
||||||
/// Count all documents in a table
|
/// Count all documents in a table
|
||||||
[<CompiledName "All">]
|
[<CompiledName "All">]
|
||||||
let all tableName sqlProps =
|
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 (->> =)
|
/// Count matching documents using JSON field comparisons (->> =)
|
||||||
[<CompiledName "ByFields">]
|
[<CompiledName "ByFields">]
|
||||||
let byFields tableName howMatched fields sqlProps =
|
let byFields tableName howMatched fields sqlProps =
|
||||||
Custom.scalar (Query.Count.byFields tableName howMatched fields) (addFieldParams fields []) toCount sqlProps
|
Custom.scalar
|
||||||
|
(Query.fieldQuery (Query.count 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
|
|
||||||
|
|
||||||
/// Count matching documents using a JSON containment query (@>)
|
/// Count matching documents using a JSON containment query (@>)
|
||||||
[<CompiledName "ByContains">]
|
[<CompiledName "ByContains">]
|
||||||
let byContains tableName (criteria: 'TContains) sqlProps =
|
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 (@?)
|
/// Count matching documents using a JSON Path match query (@?)
|
||||||
[<CompiledName "ByJsonPath">]
|
[<CompiledName "ByJsonPath">]
|
||||||
let byJsonPath tableName jsonPath sqlProps =
|
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
|
/// Commands to determine if documents exist
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@ -504,29 +455,34 @@ module WithProps =
|
||||||
/// Determine if a document exists for the given ID
|
/// Determine if a document exists for the given ID
|
||||||
[<CompiledName "ById">]
|
[<CompiledName "ById">]
|
||||||
let byId tableName (docId: 'TKey) sqlProps =
|
let byId tableName (docId: 'TKey) sqlProps =
|
||||||
Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists sqlProps
|
Custom.scalar (Query.exists tableName (Query.whereById "@id")) [ idParam docId ] toExists sqlProps
|
||||||
|
|
||||||
/// Determine if a document exists using JSON field comparisons (->> =)
|
/// Determine if a document exists using JSON field comparisons (->> =)
|
||||||
[<CompiledName "ByFields">]
|
[<CompiledName "ByFields">]
|
||||||
let byFields tableName howMatched fields sqlProps =
|
let byFields tableName howMatched fields sqlProps =
|
||||||
Custom.scalar
|
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 (@>)
|
/// Determine if a document exists using a JSON containment query (@>)
|
||||||
[<CompiledName "ByContains">]
|
[<CompiledName "ByContains">]
|
||||||
let byContains tableName (criteria: 'TContains) sqlProps =
|
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 (@?)
|
/// Determine if a document exists using a JSON Path match query (@?)
|
||||||
[<CompiledName "ByJsonPath">]
|
[<CompiledName "ByJsonPath">]
|
||||||
let byJsonPath tableName jsonPath sqlProps =
|
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
|
/// Commands to determine if documents exist
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@ -657,7 +613,10 @@ module WithProps =
|
||||||
/// Update an entire document by its ID
|
/// Update an entire document by its ID
|
||||||
[<CompiledName "ById">]
|
[<CompiledName "ById">]
|
||||||
let byId tableName (docId: 'TKey) (document: 'TDoc) sqlProps =
|
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
|
/// Update an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
[<CompiledName "FSharpByFunc">]
|
[<CompiledName "FSharpByFunc">]
|
||||||
|
|
|
@ -64,44 +64,6 @@ module Query =
|
||||||
let ensureTable name =
|
let ensureTable name =
|
||||||
Query.Definition.ensureTableFor name "TEXT"
|
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
|
/// Queries for retrieving documents
|
||||||
module Find =
|
module Find =
|
||||||
|
|
||||||
|
@ -381,18 +343,16 @@ module WithConn =
|
||||||
/// Count all documents in a table
|
/// Count all documents in a table
|
||||||
[<CompiledName "All">]
|
[<CompiledName "All">]
|
||||||
let all tableName conn =
|
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
|
/// Count matching documents using a comparison on JSON fields
|
||||||
[<CompiledName "ByFields">]
|
[<CompiledName "ByFields">]
|
||||||
let byFields tableName howMatched fields conn =
|
let byFields tableName howMatched fields conn =
|
||||||
Custom.scalar (Query.Count.byFields tableName howMatched fields) (addFieldParams fields []) toCount conn
|
Custom.scalar
|
||||||
|
(Query.statementWhere (Query.count tableName) (Query.whereByFields howMatched fields))
|
||||||
/// Count matching documents using a comparison on a JSON field
|
(addFieldParams fields [])
|
||||||
[<CompiledName "ByField">]
|
toCount
|
||||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
conn
|
||||||
let byField tableName field conn =
|
|
||||||
byFields tableName Any [ field ] conn
|
|
||||||
|
|
||||||
/// Commands to determine if documents exist
|
/// Commands to determine if documents exist
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@ -401,18 +361,16 @@ module WithConn =
|
||||||
/// Determine if a document exists for the given ID
|
/// Determine if a document exists for the given ID
|
||||||
[<CompiledName "ById">]
|
[<CompiledName "ById">]
|
||||||
let byId tableName (docId: 'TKey) conn =
|
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
|
/// Determine if a document exists using a comparison on JSON fields
|
||||||
[<CompiledName "ByFields">]
|
[<CompiledName "ByFields">]
|
||||||
let byFields tableName howMatched fields conn =
|
let byFields tableName howMatched fields conn =
|
||||||
Custom.scalar (Query.Exists.byFields tableName howMatched fields) (addFieldParams fields []) toExists conn
|
Custom.scalar
|
||||||
|
(Query.exists tableName (Query.whereByFields howMatched fields))
|
||||||
/// Determine if a document exists using a comparison on a JSON field
|
(addFieldParams fields [])
|
||||||
[<CompiledName "ByField">]
|
toExists
|
||||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
conn
|
||||||
let byField tableName field conn =
|
|
||||||
byFields tableName Any [ field ] conn
|
|
||||||
|
|
||||||
/// Commands to retrieve documents
|
/// Commands to retrieve documents
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@ -493,7 +451,10 @@ module WithConn =
|
||||||
/// Update an entire document by its ID
|
/// Update an entire document by its ID
|
||||||
[<CompiledName "ById">]
|
[<CompiledName "ById">]
|
||||||
let byId tableName (docId: 'TKey) (document: 'TDoc) conn =
|
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
|
/// Update an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
[<CompiledName "FSharpByFunc">]
|
[<CompiledName "FSharpByFunc">]
|
||||||
|
|
|
@ -285,15 +285,7 @@ public static class CommonCSharpTests
|
||||||
Expect.equal(Query.Save("tbl"),
|
Expect.equal(Query.Save("tbl"),
|
||||||
"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data",
|
"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
"INSERT ON CONFLICT UPDATE statement not correct");
|
"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");
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,11 +270,6 @@ public static class PostgresCSharpTests
|
||||||
"CREATE INDEX statement not constructed correctly");
|
"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", () =>
|
TestCase("WhereDataContains succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Postgres.Query.WhereDataContains("@test"), "data @> @test",
|
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",
|
Expect.equal(Postgres.Query.WhereJsonPathMatches("@path"), "data @? @path::jsonpath",
|
||||||
"WHERE clause not correct");
|
"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",
|
TestList("Find",
|
||||||
[
|
[
|
||||||
TestCase("ById succeeds", () =>
|
TestCase("ById succeeds", () =>
|
||||||
|
|
|
@ -92,39 +92,6 @@ public static class SqliteCSharpTests
|
||||||
Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"),
|
Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"),
|
||||||
"CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)", "CREATE TABLE statement not correct");
|
"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",
|
TestList("Find",
|
||||||
[
|
[
|
||||||
TestCase("ById succeeds", () =>
|
TestCase("ById succeeds", () =>
|
||||||
|
|
|
@ -213,18 +213,8 @@ let all =
|
||||||
$"INSERT INTO {tbl} VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data"
|
$"INSERT INTO {tbl} VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data"
|
||||||
"INSERT ON CONFLICT UPDATE statement not correct"
|
"INSERT ON CONFLICT UPDATE statement not correct"
|
||||||
}
|
}
|
||||||
testList "Count" [
|
test "count succeeds" {
|
||||||
test "all succeeds" {
|
Expect.equal (Query.count "a_table") "SELECT COUNT(*) AS it FROM a_table" "Count query not correct"
|
||||||
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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
@ -246,78 +246,12 @@ let unitTests =
|
||||||
"CREATE INDEX statement not constructed correctly"
|
"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" {
|
test "whereDataContains succeeds" {
|
||||||
Expect.equal (Query.whereDataContains "@test") "data @> @test" "WHERE clause not correct"
|
Expect.equal (Query.whereDataContains "@test") "data @> @test" "WHERE clause not correct"
|
||||||
}
|
}
|
||||||
test "whereJsonPathMatches succeeds" {
|
test "whereJsonPathMatches succeeds" {
|
||||||
Expect.equal (Query.whereJsonPathMatches "@path") "data @? @path::jsonpath" "WHERE clause not correct"
|
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" [
|
testList "Find" [
|
||||||
test "byId succeeds" {
|
test "byId succeeds" {
|
||||||
Expect.equal
|
Expect.equal
|
||||||
|
|
|
@ -81,34 +81,6 @@ let unitTests =
|
||||||
"CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)"
|
"CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)"
|
||||||
"CREATE TABLE statement not correct"
|
"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" [
|
testList "Find" [
|
||||||
test "byId succeeds" {
|
test "byId succeeds" {
|
||||||
Expect.equal
|
Expect.equal
|
||||||
|
|
Loading…
Reference in New Issue
Block a user