First cut of BT operator (#3)
This commit is contained in:
@@ -63,17 +63,29 @@ module Parameters =
|
||||
let jsonParam (name: string) (it: 'TJson) =
|
||||
name, Sql.jsonb (Configuration.serializer().Serialize it)
|
||||
|
||||
/// Create a JSON field parameter (name "@field")
|
||||
/// Create a JSON field parameter
|
||||
[<CompiledName "FSharpAddField">]
|
||||
let addFieldParam name field parameters =
|
||||
match field.Op with
|
||||
| EX | NEX -> parameters
|
||||
| BT ->
|
||||
let values = field.Value :?> obj list
|
||||
List.concat
|
||||
[ parameters
|
||||
[ ($"{name}min", Sql.parameter (NpgsqlParameter($"{name}min", List.head values)))
|
||||
($"{name}max", Sql.parameter (NpgsqlParameter($"{name}max", List.last values))) ] ]
|
||||
| _ -> (name, Sql.parameter (NpgsqlParameter(name, field.Value))) :: parameters
|
||||
|
||||
/// Create a JSON field parameter (name "@field")
|
||||
/// Create a JSON field parameter
|
||||
let AddField name field parameters =
|
||||
match field.Op with
|
||||
| EX | NEX -> parameters
|
||||
| BT ->
|
||||
let values = field.Value :?> obj list
|
||||
ResizeArray
|
||||
[ ($"{name}min", Sql.parameter (NpgsqlParameter($"{name}min", List.head values)))
|
||||
($"{name}max", Sql.parameter (NpgsqlParameter($"{name}max", List.last values))) ]
|
||||
|> Seq.append parameters
|
||||
| _ -> (name, Sql.parameter (NpgsqlParameter(name, field.Value))) |> Seq.singleton |> Seq.append parameters
|
||||
|
||||
/// Append JSON field name parameters for the given field names to the given parameters
|
||||
@@ -97,6 +109,25 @@ module Parameters =
|
||||
[<RequireQualifiedAccess>]
|
||||
module Query =
|
||||
|
||||
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
|
||||
[<CompiledName "WhereByField">]
|
||||
let whereByField field paramName =
|
||||
match field.Op with
|
||||
| EX | NEX -> $"data->>'{field.Name}' {field.Op}"
|
||||
| BT ->
|
||||
let names = $"{paramName}min AND {paramName}max"
|
||||
let values = field.Value :?> obj list
|
||||
match values[0] with
|
||||
| :? int8 | :? uint8 | :? int16 | :? uint16 | :? int | :? uint32 | :? int64 | :? uint64
|
||||
| :? decimal | :? single | :? double -> $"(data->>'{field.Name}')::numeric {field.Op} {names}"
|
||||
| _ -> $"data->>'{field.Name}' {field.Op} {names}"
|
||||
| _ -> $"data->>'{field.Name}' {field.Op} %s{paramName}"
|
||||
|
||||
/// Create a WHERE clause fragment to implement an ID-based query
|
||||
[<CompiledName "WhereById">]
|
||||
let whereById paramName =
|
||||
whereByField (Field.EQ (Configuration.idField ()) 0) paramName
|
||||
|
||||
/// Table and index definition queries
|
||||
module Definition =
|
||||
|
||||
@@ -112,6 +143,11 @@ 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 =
|
||||
@@ -125,6 +161,16 @@ module Query =
|
||||
/// 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 a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
$"""SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByField field "@field"}"""
|
||||
|
||||
/// Query to count matching documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
@@ -138,6 +184,16 @@ module Query =
|
||||
/// 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 a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
$"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereByField field "@field"}) AS it"""
|
||||
|
||||
/// Query to determine if documents exist using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
@@ -151,6 +207,16 @@ module Query =
|
||||
/// Queries for retrieving documents
|
||||
module Find =
|
||||
|
||||
/// Query to retrieve a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to retrieve documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereByField field "@field"}"""
|
||||
|
||||
/// Query to retrieve documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
@@ -171,12 +237,12 @@ module Query =
|
||||
/// Query to patch a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
Query.whereById "@id" |> update tableName
|
||||
whereById "@id" |> update tableName
|
||||
|
||||
/// Query to patch documents match a JSON field comparison (->> =)
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
Query.whereByField field "@field" |> update tableName
|
||||
whereByField field "@field" |> update tableName
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
@@ -198,12 +264,12 @@ module Query =
|
||||
/// Query to remove fields from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
Query.whereById "@id" |> update tableName
|
||||
whereById "@id" |> update tableName
|
||||
|
||||
/// Query to remove fields from documents via a comparison on a JSON field within the document
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
Query.whereByField field "@field" |> update tableName
|
||||
whereByField field "@field" |> update tableName
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
@@ -218,6 +284,16 @@ module Query =
|
||||
/// Queries to delete documents
|
||||
module Delete =
|
||||
|
||||
/// Query to delete a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to delete documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName field =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereByField field "@field"}"""
|
||||
|
||||
/// Query to delete documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
|
||||
Reference in New Issue
Block a user