Version 4 #6
|
@ -98,6 +98,15 @@ type Field = {
|
||||||
{ this with Qualifier = Some alias }
|
{ this with Qualifier = Some alias }
|
||||||
|
|
||||||
|
|
||||||
|
/// How fields should be matched
|
||||||
|
[<Struct>]
|
||||||
|
type FieldMatch =
|
||||||
|
/// Any field matches (OR)
|
||||||
|
| Any
|
||||||
|
/// All fields match (AND)
|
||||||
|
| All
|
||||||
|
|
||||||
|
|
||||||
/// The required document serialization implementation
|
/// The required document serialization implementation
|
||||||
type IDocumentSerializer =
|
type IDocumentSerializer =
|
||||||
|
|
||||||
|
|
|
@ -109,24 +109,46 @@ module Parameters =
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Query =
|
module Query =
|
||||||
|
|
||||||
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
|
/// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
|
||||||
[<CompiledName "WhereByField">]
|
[<CompiledName "WhereByFields">]
|
||||||
let whereByField field paramName =
|
let whereByFields fields howMatched =
|
||||||
match field.Op with
|
let mutable idx = 0
|
||||||
| EX | NEX -> $"data->>'{field.Name}' {field.Op}"
|
let nameField () =
|
||||||
|
let name = $"field{idx}"
|
||||||
|
idx <- idx + 1
|
||||||
|
name
|
||||||
|
fields
|
||||||
|
|> List.map (fun it ->
|
||||||
|
let fieldName = it.Qualifier |> Option.map (fun q -> $"{q}.data") |> Option.defaultValue "data"
|
||||||
|
let jsonPath =
|
||||||
|
if it.Name.Contains '.' then "#>>'{" + String.concat "," (it.Name.Split '.') + "}'"
|
||||||
|
else $"->>'{it.Name}'"
|
||||||
|
let column = fieldName + jsonPath
|
||||||
|
match it.Op with
|
||||||
|
| EX | NEX -> $"{column} {it.Op}"
|
||||||
| BT ->
|
| BT ->
|
||||||
let names = $"{paramName}min AND {paramName}max"
|
let p = defaultArg it.ParameterName (nameField ())
|
||||||
let values = field.Value :?> obj list
|
let names = $"{p}min AND {p}max"
|
||||||
|
let values = it.Value :?> obj list
|
||||||
match values[0] with
|
match values[0] with
|
||||||
| :? int8 | :? uint8 | :? int16 | :? uint16 | :? int | :? uint32 | :? int64 | :? uint64
|
| :? int8 | :? uint8 | :? int16 | :? uint16 | :? int | :? uint32 | :? int64 | :? uint64
|
||||||
| :? decimal | :? single | :? double -> $"(data->>'{field.Name}')::numeric {field.Op} {names}"
|
| :? decimal | :? single | :? double -> $"({column})::numeric {it.Op} {names}"
|
||||||
| _ -> $"data->>'{field.Name}' {field.Op} {names}"
|
| _ -> $"{column} {it.Op} {names}"
|
||||||
| _ -> $"data->>'{field.Name}' {field.Op} %s{paramName}"
|
| _ ->
|
||||||
|
let p = defaultArg it.ParameterName (nameField ())
|
||||||
|
$"{column} {it.Op} {p}")
|
||||||
|
|> String.concat (match howMatched with Any -> " OR " | All -> " AND ")
|
||||||
|
|
||||||
|
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
|
||||||
|
[<CompiledName "WhereByField">]
|
||||||
|
//[<Obsolete "Use whereByFields / WhereByFields instead">]
|
||||||
|
let whereByField field paramName =
|
||||||
|
whereByFields [ { field with ParameterName = Some paramName } ] Any
|
||||||
|
|
||||||
/// Create a WHERE clause fragment to implement an ID-based query
|
/// Create a WHERE clause fragment to implement an ID-based query
|
||||||
[<CompiledName "WhereById">]
|
[<CompiledName "WhereById">]
|
||||||
let whereById paramName =
|
let whereById paramName =
|
||||||
whereByField (Field.EQ (Configuration.idField ()) 0) paramName
|
whereByFields [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ] Any
|
||||||
|
|
||||||
/// Table and index definition queries
|
/// Table and index definition queries
|
||||||
module Definition =
|
module Definition =
|
||||||
|
|
|
@ -115,9 +115,9 @@ let all =
|
||||||
Expect.equal "@name" field.ParameterName.Value "The parameter name is incorrect"
|
Expect.equal "@name" field.ParameterName.Value "The parameter name is incorrect"
|
||||||
}
|
}
|
||||||
test "WithQualifier succeeds" {
|
test "WithQualifier succeeds" {
|
||||||
let field = (Field.EQ "Bill" "Matt").WithParameterName "@joe"
|
let field = (Field.EQ "Bill" "Matt").WithQualifier "joe"
|
||||||
Expect.isSome field.Qualifier "The table qualifier should have been filled"
|
Expect.isSome field.Qualifier "The table qualifier should have been filled"
|
||||||
Expect.equal "@joe" field.Qualifier.Value "The table qualifier is incorrect"
|
Expect.equal "joe" field.Qualifier.Value "The table qualifier is incorrect"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
testList "Query" [
|
testList "Query" [
|
||||||
|
|
Loading…
Reference in New Issue
Block a user