Change Op to Comparison DU
This commit is contained in:
parent
14c80f32fe
commit
b07ae3f097
|
@ -2,44 +2,45 @@
|
||||||
|
|
||||||
open System.Security.Cryptography
|
open System.Security.Cryptography
|
||||||
|
|
||||||
/// The types of logical operations available for JSON fields
|
/// The types of comparisons available for JSON fields
|
||||||
[<Struct>]
|
type Comparison =
|
||||||
type Op =
|
|
||||||
/// Equals (=)
|
/// Equals (=)
|
||||||
| EQ
|
| Equals of obj
|
||||||
/// Greater Than (>)
|
/// Greater Than (>)
|
||||||
| GT
|
| Greater of obj
|
||||||
/// Greater Than or Equal To (>=)
|
/// Greater Than or Equal To (>=)
|
||||||
| GE
|
| GreaterOrEqual of obj
|
||||||
/// Less Than (<)
|
/// Less Than (<)
|
||||||
| LT
|
| Less of obj
|
||||||
/// Less Than or Equal To (<=)
|
/// Less Than or Equal To (<=)
|
||||||
| LE
|
| LessOrEqual of obj
|
||||||
/// Not Equal to (<>)
|
/// Not Equal to (<>)
|
||||||
| NE
|
| NotEqual of obj
|
||||||
/// Between (BETWEEN)
|
/// Between (BETWEEN)
|
||||||
| BT
|
| Between of obj * obj
|
||||||
/// In (IN)
|
/// In (IN)
|
||||||
| IN
|
| In of obj seq
|
||||||
// Array Contains/Exists (PostgreSQL: |? SQLite: EXISTS / json_each / IN)
|
// Array Contains/Exists (PostgreSQL: |? SQLite: EXISTS / json_each / IN)
|
||||||
//| AEX
|
| Contains of obj
|
||||||
/// Exists (IS NOT NULL)
|
/// Exists (IS NOT NULL)
|
||||||
| EX
|
| Exists
|
||||||
/// Does Not Exist (IS NULL)
|
/// Does Not Exist (IS NULL)
|
||||||
| NEX
|
| NotExists
|
||||||
|
|
||||||
override this.ToString() =
|
/// Get the operator SQL for this comparison
|
||||||
|
member this.OpSql =
|
||||||
match this with
|
match this with
|
||||||
| EQ -> "="
|
| Equals _ -> "="
|
||||||
| GT -> ">"
|
| Greater _ -> ">"
|
||||||
| GE -> ">="
|
| GreaterOrEqual _ -> ">="
|
||||||
| LT -> "<"
|
| Less _ -> "<"
|
||||||
| LE -> "<="
|
| LessOrEqual _ -> "<="
|
||||||
| NE -> "<>"
|
| NotEqual _ -> "<>"
|
||||||
| BT -> "BETWEEN"
|
| Between _ -> "BETWEEN"
|
||||||
| IN -> "IN"
|
| In _ -> "IN"
|
||||||
| EX -> "IS NOT NULL"
|
| Contains _ -> "|?" // PostgreSQL only; SQL needs a subquery for this
|
||||||
| NEX -> "IS NULL"
|
| Exists -> "IS NOT NULL"
|
||||||
|
| NotExists -> "IS NULL"
|
||||||
|
|
||||||
|
|
||||||
/// The dialect in which a command should be rendered
|
/// The dialect in which a command should be rendered
|
||||||
|
@ -53,11 +54,12 @@ type Field = {
|
||||||
/// The name of the field
|
/// The name of the field
|
||||||
Name: string
|
Name: string
|
||||||
|
|
||||||
/// The operation by which the field will be compared
|
Comparison: Comparison
|
||||||
Op: Op
|
// /// The operation by which the field will be compared
|
||||||
|
// Op: Op
|
||||||
/// The value of the field
|
//
|
||||||
Value: obj
|
// /// The value of the field
|
||||||
|
// Value: obj
|
||||||
|
|
||||||
/// The name of the parameter for this field
|
/// The name of the parameter for this field
|
||||||
ParameterName: string option
|
ParameterName: string option
|
||||||
|
@ -66,45 +68,49 @@ type Field = {
|
||||||
Qualifier: string option
|
Qualifier: string option
|
||||||
} with
|
} with
|
||||||
|
|
||||||
|
/// Create a comparison against a field
|
||||||
|
static member Where name comparison =
|
||||||
|
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
|
||||||
|
|
||||||
/// Create an equals (=) field criterion
|
/// Create an equals (=) field criterion
|
||||||
static member EQ name (value: obj) =
|
static member EQ name (value: obj) =
|
||||||
{ Name = name; Op = EQ; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (Equals value)
|
||||||
|
|
||||||
/// Create a greater than (>) field criterion
|
/// Create a greater than (>) field criterion
|
||||||
static member GT name (value: obj) =
|
static member GT name (value: obj) =
|
||||||
{ Name = name; Op = GT; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (Greater value)
|
||||||
|
|
||||||
/// Create a greater than or equal to (>=) field criterion
|
/// Create a greater than or equal to (>=) field criterion
|
||||||
static member GE name (value: obj) =
|
static member GE name (value: obj) =
|
||||||
{ Name = name; Op = GE; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (GreaterOrEqual value)
|
||||||
|
|
||||||
/// Create a less than (<) field criterion
|
/// Create a less than (<) field criterion
|
||||||
static member LT name (value: obj) =
|
static member LT name (value: obj) =
|
||||||
{ Name = name; Op = LT; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (Less value)
|
||||||
|
|
||||||
/// Create a less than or equal to (<=) field criterion
|
/// Create a less than or equal to (<=) field criterion
|
||||||
static member LE name (value: obj) =
|
static member LE name (value: obj) =
|
||||||
{ Name = name; Op = LE; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (LessOrEqual value)
|
||||||
|
|
||||||
/// Create a not equals (<>) field criterion
|
/// Create a not equals (<>) field criterion
|
||||||
static member NE name (value: obj) =
|
static member NE name (value: obj) =
|
||||||
{ Name = name; Op = NE; Value = value; ParameterName = None; Qualifier = None }
|
Field.Where name (NotEqual value)
|
||||||
|
|
||||||
/// Create a BETWEEN field criterion
|
/// Create a BETWEEN field criterion
|
||||||
static member BT name (min: obj) (max: obj) =
|
static member BT name (min: obj) (max: obj) =
|
||||||
{ Name = name; Op = BT; Value = [ min; max ]; ParameterName = None; Qualifier = None }
|
Field.Where name (Between(min, max))
|
||||||
|
|
||||||
/// Create an IN field criterion
|
/// Create an IN field criterion
|
||||||
static member IN name (values: obj seq) =
|
static member IN name (values: obj seq) =
|
||||||
{ Name = name; Op = IN; Value = values; ParameterName = None; Qualifier = None }
|
Field.Where name (In values)
|
||||||
|
|
||||||
/// Create an exists (IS NOT NULL) field criterion
|
/// Create an exists (IS NOT NULL) field criterion
|
||||||
static member EX name =
|
static member EX name =
|
||||||
{ Name = name; Op = EX; Value = obj (); ParameterName = None; Qualifier = None }
|
Field.Where name Exists
|
||||||
|
|
||||||
/// Create a not exists (IS NULL) field criterion
|
/// Create a not exists (IS NULL) field criterion
|
||||||
static member NEX name =
|
static member NEX name =
|
||||||
{ Name = name; Op = NEX; Value = obj (); ParameterName = None; Qualifier = None }
|
Field.Where name NotExists
|
||||||
|
|
||||||
/// Transform a field name (a.b.c) to a path for the given SQL dialect
|
/// Transform a field name (a.b.c) to a path for the given SQL dialect
|
||||||
static member NameToPath (name: string) dialect =
|
static member NameToPath (name: string) dialect =
|
||||||
|
@ -118,7 +124,7 @@ type Field = {
|
||||||
|
|
||||||
/// Create a field with a given name, but no other properties filled (op will be EQ, value will be "")
|
/// Create a field with a given name, but no other properties filled (op will be EQ, value will be "")
|
||||||
static member Named name =
|
static member Named name =
|
||||||
{ Name = name; Op = EQ; Value = ""; ParameterName = None; Qualifier = None }
|
Field.Where name (Equals "")
|
||||||
|
|
||||||
/// Specify the name of the parameter for this field
|
/// Specify the name of the parameter for this field
|
||||||
member this.WithParameterName name =
|
member this.WithParameterName name =
|
||||||
|
|
|
@ -87,25 +87,23 @@ module Parameters =
|
||||||
fields
|
fields
|
||||||
|> Seq.map (fun it ->
|
|> Seq.map (fun it ->
|
||||||
seq {
|
seq {
|
||||||
match it.Op with
|
match it.Comparison with
|
||||||
| EX | NEX -> ()
|
| Exists | NotExists -> ()
|
||||||
| BT ->
|
| Between (min, max) ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
let values = it.Value :?> obj list
|
yield ($"{p}min", parameterFor min (fun v -> Sql.parameter (NpgsqlParameter($"{p}min", v))))
|
||||||
yield ($"{p}min",
|
yield ($"{p}max", parameterFor max (fun v -> Sql.parameter (NpgsqlParameter($"{p}max", v))))
|
||||||
parameterFor (List.head values) (fun v -> Sql.parameter (NpgsqlParameter($"{p}min", v))))
|
| In values ->
|
||||||
yield ($"{p}max",
|
|
||||||
parameterFor (List.last values) (fun v -> Sql.parameter (NpgsqlParameter($"{p}max", v))))
|
|
||||||
| IN ->
|
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
yield!
|
yield!
|
||||||
it.Value :?> obj seq
|
values
|
||||||
|> Seq.mapi (fun idx v ->
|
|> Seq.mapi (fun idx v ->
|
||||||
let paramName = $"{p}_{idx}"
|
let paramName = $"{p}_{idx}"
|
||||||
paramName, Sql.parameter (NpgsqlParameter(paramName, v)))
|
paramName, Sql.parameter (NpgsqlParameter(paramName, v)))
|
||||||
| _ ->
|
| Contains _ -> () // TODO
|
||||||
|
| Equals v | Greater v | GreaterOrEqual v | Less v | LessOrEqual v | NotEqual v ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
yield (p, parameterFor it.Value (fun v -> Sql.parameter (NpgsqlParameter(p, v)))) })
|
yield (p, parameterFor v (fun l -> Sql.parameter (NpgsqlParameter(p, l)))) })
|
||||||
|> Seq.collect id
|
|> Seq.collect id
|
||||||
|> Seq.append parameters
|
|> Seq.append parameters
|
||||||
|> Seq.toList
|
|> Seq.toList
|
||||||
|
@ -138,21 +136,22 @@ module Query =
|
||||||
| _ -> false
|
| _ -> false
|
||||||
fields
|
fields
|
||||||
|> Seq.map (fun it ->
|
|> Seq.map (fun it ->
|
||||||
match it.Op with
|
match it.Comparison with
|
||||||
| EX | NEX -> $"{it.Path PostgreSQL} {it.Op}"
|
| Exists | NotExists -> $"{it.Path PostgreSQL} {it.Comparison.OpSql}"
|
||||||
| _ ->
|
| _ ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
let param, value =
|
let param, value =
|
||||||
match it.Op with
|
match it.Comparison with
|
||||||
| BT -> $"{p}min AND {p}max", (it.Value :?> obj list)[0]
|
| Between (min, _) -> $"{p}min AND {p}max", min
|
||||||
| IN ->
|
| In values ->
|
||||||
let values = it.Value :?> obj seq
|
|
||||||
let paramNames = values |> Seq.mapi (fun idx _ -> $"{p}_{idx}") |> String.concat ", "
|
let paramNames = values |> Seq.mapi (fun idx _ -> $"{p}_{idx}") |> String.concat ", "
|
||||||
$"({paramNames})", defaultArg (Seq.tryHead values) (obj ())
|
$"({paramNames})", defaultArg (Seq.tryHead values) (obj ())
|
||||||
| _ -> p, it.Value
|
| Contains _ -> p, "" // TODO: may need to use -> vs ->> in field SQL
|
||||||
|
| Equals v | Greater v | GreaterOrEqual v | Less v | LessOrEqual v | NotEqual v -> p, v
|
||||||
|
| _ -> p, ""
|
||||||
if isNumeric value then
|
if isNumeric value then
|
||||||
$"({it.Path PostgreSQL})::numeric {it.Op} {param}"
|
$"({it.Path PostgreSQL})::numeric {it.Comparison.OpSql} {param}"
|
||||||
else $"{it.Path PostgreSQL} {it.Op} {param}")
|
else $"{it.Path PostgreSQL} {it.Comparison.OpSql} {param}")
|
||||||
|> String.concat $" {howMatched} "
|
|> String.concat $" {howMatched} "
|
||||||
|
|
||||||
/// Create a WHERE clause fragment to implement an ID-based query
|
/// Create a WHERE clause fragment to implement an ID-based query
|
||||||
|
|
|
@ -37,16 +37,17 @@ module Query =
|
||||||
let name = ParameterName()
|
let name = ParameterName()
|
||||||
fields
|
fields
|
||||||
|> Seq.map (fun it ->
|
|> Seq.map (fun it ->
|
||||||
match it.Op with
|
match it.Comparison with
|
||||||
| EX | NEX -> $"{it.Path SQLite} {it.Op}"
|
| Exists | NotExists -> $"{it.Path SQLite} {it.Comparison.OpSql}"
|
||||||
| BT ->
|
| Between _ ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
$"{it.Path SQLite} {it.Op} {p}min AND {p}max"
|
$"{it.Path SQLite} {it.Comparison.OpSql} {p}min AND {p}max"
|
||||||
| IN ->
|
| In values ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
let paramNames = it.Value :?> obj seq |> Seq.mapi (fun idx _ -> $"{p}_{idx}") |> String.concat ", "
|
let paramNames = values |> Seq.mapi (fun idx _ -> $"{p}_{idx}") |> String.concat ", "
|
||||||
$"{it.Path SQLite} {it.Op} ({paramNames})"
|
$"{it.Path SQLite} {it.Comparison.OpSql} ({paramNames})"
|
||||||
| _ -> $"{it.Path SQLite} {it.Op} {name.Derive it.ParameterName}")
|
| Contains _ -> "" // TODO
|
||||||
|
| _ -> $"{it.Path SQLite} {it.Comparison.OpSql} {name.Derive it.ParameterName}")
|
||||||
|> String.concat $" {howMatched} "
|
|> String.concat $" {howMatched} "
|
||||||
|
|
||||||
/// Create a WHERE clause fragment to implement an ID-based query
|
/// Create a WHERE clause fragment to implement an ID-based query
|
||||||
|
@ -107,17 +108,17 @@ module Parameters =
|
||||||
fields
|
fields
|
||||||
|> Seq.map (fun it ->
|
|> Seq.map (fun it ->
|
||||||
seq {
|
seq {
|
||||||
match it.Op with
|
match it.Comparison with
|
||||||
| EX | NEX -> ()
|
| Exists | NotExists -> ()
|
||||||
| BT ->
|
| Between (min, max) ->
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
let values = it.Value :?> obj list
|
yield! [ SqliteParameter($"{p}min", min); SqliteParameter($"{p}max", max) ]
|
||||||
yield SqliteParameter($"{p}min", List.head values)
|
| In values ->
|
||||||
yield SqliteParameter($"{p}max", List.last values)
|
|
||||||
| IN ->
|
|
||||||
let p = name.Derive it.ParameterName
|
let p = name.Derive it.ParameterName
|
||||||
yield! it.Value :?> obj seq |> Seq.mapi (fun idx v -> SqliteParameter($"{p}_{idx}", v))
|
yield! values |> Seq.mapi (fun idx v -> SqliteParameter($"{p}_{idx}", v))
|
||||||
| _ -> yield SqliteParameter(name.Derive it.ParameterName, it.Value) })
|
| Contains _ -> () // TODO
|
||||||
|
| Equals v | Greater v | GreaterOrEqual v | Less v | LessOrEqual v | NotEqual v ->
|
||||||
|
yield SqliteParameter(name.Derive it.ParameterName, v) })
|
||||||
|> Seq.collect id
|
|> Seq.collect id
|
||||||
|> Seq.append parameters
|
|> Seq.append parameters
|
||||||
|> Seq.toList
|
|> Seq.toList
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Expecto.CSharp;
|
using Expecto.CSharp;
|
||||||
using Expecto;
|
using Expecto;
|
||||||
using Microsoft.FSharp.Collections;
|
|
||||||
using Microsoft.FSharp.Core;
|
using Microsoft.FSharp.Core;
|
||||||
|
|
||||||
namespace BitBadger.Documents.Tests.CSharp;
|
namespace BitBadger.Documents.Tests.CSharp;
|
||||||
|
@ -22,45 +21,53 @@ internal class TestSerializer : IDocumentSerializer
|
||||||
public static class CommonCSharpTests
|
public static class CommonCSharpTests
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unit tests for the Op enum
|
/// Unit tests for the OpSql property of the Comparison discriminated union
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly Test OpTests = TestList("Op",
|
private static readonly Test OpTests = TestList("Comparison.OpSql",
|
||||||
[
|
[
|
||||||
TestCase("EQ succeeds", () =>
|
TestCase("Equals succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.EQ.ToString(), "=", "The equals operator was not correct");
|
Expect.equal(Comparison.NewEquals("").OpSql, "=", "The Equals SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("GT succeeds", () =>
|
TestCase("Greater succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.GT.ToString(), ">", "The greater than operator was not correct");
|
Expect.equal(Comparison.NewGreater("").OpSql, ">", "The Greater SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("GE succeeds", () =>
|
TestCase("GreaterOrEqual succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.GE.ToString(), ">=", "The greater than or equal to operator was not correct");
|
Expect.equal(Comparison.NewGreaterOrEqual("").OpSql, ">=", "The GreaterOrEqual SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("LT succeeds", () =>
|
TestCase("Less succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.LT.ToString(), "<", "The less than operator was not correct");
|
Expect.equal(Comparison.NewLess("").OpSql, "<", "The Less SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("LE succeeds", () =>
|
TestCase("LessOrEqual succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.LE.ToString(), "<=", "The less than or equal to operator was not correct");
|
Expect.equal(Comparison.NewLessOrEqual("").OpSql, "<=", "The LessOrEqual SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("NE succeeds", () =>
|
TestCase("NotEqual succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.NE.ToString(), "<>", "The not equal to operator was not correct");
|
Expect.equal(Comparison.NewNotEqual("").OpSql, "<>", "The NotEqual SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("BT succeeds", () =>
|
TestCase("Between succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.BT.ToString(), "BETWEEN", "The \"between\" operator was not correct");
|
Expect.equal(Comparison.NewBetween("", "").OpSql, "BETWEEN", "The Between SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("EX succeeds", () =>
|
TestCase("In succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.EX.ToString(), "IS NOT NULL", "The \"exists\" operator was not correct");
|
Expect.equal(Comparison.NewIn([]).OpSql, "IN", "The In SQL was not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("NEX succeeds", () =>
|
TestCase("Contains succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.NEX.ToString(), "IS NULL", "The \"not exists\" operator was not correct");
|
Expect.equal(Comparison.NewContains("").OpSql, "|?", "The Contains SQL was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("Exists succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Comparison.Exists.OpSql, "IS NOT NULL", "The Exists SQL was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("NotExists succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Comparison.NotExists.OpSql, "IS NULL", "The NotExists SQL was not correct");
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -73,62 +80,62 @@ public static class CommonCSharpTests
|
||||||
{
|
{
|
||||||
var field = Field.EQ("Test", 14);
|
var field = Field.EQ("Test", 14);
|
||||||
Expect.equal(field.Name, "Test", "Field name incorrect");
|
Expect.equal(field.Name, "Test", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.EQ, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewEquals(14), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, 14, "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("GT succeeds", () =>
|
TestCase("GT succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.GT("Great", "night");
|
var field = Field.GT("Great", "night");
|
||||||
Expect.equal(field.Name, "Great", "Field name incorrect");
|
Expect.equal(field.Name, "Great", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.GT, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewGreater("night"), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, "night", "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("GE succeeds", () =>
|
TestCase("GE succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.GE("Nice", 88L);
|
var field = Field.GE("Nice", 88L);
|
||||||
Expect.equal(field.Name, "Nice", "Field name incorrect");
|
Expect.equal(field.Name, "Nice", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.GE, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewGreaterOrEqual(88L), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, 88L, "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("LT succeeds", () =>
|
TestCase("LT succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.LT("Lesser", "seven");
|
var field = Field.LT("Lesser", "seven");
|
||||||
Expect.equal(field.Name, "Lesser", "Field name incorrect");
|
Expect.equal(field.Name, "Lesser", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.LT, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewLess("seven"), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, "seven", "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("LE succeeds", () =>
|
TestCase("LE succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.LE("Nobody", "KNOWS");
|
var field = Field.LE("Nobody", "KNOWS");
|
||||||
Expect.equal(field.Name, "Nobody", "Field name incorrect");
|
Expect.equal(field.Name, "Nobody", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.LE, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewLessOrEqual("KNOWS"), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, "KNOWS", "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("NE succeeds", () =>
|
TestCase("NE succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.NE("Park", "here");
|
var field = Field.NE("Park", "here");
|
||||||
Expect.equal(field.Name, "Park", "Field name incorrect");
|
Expect.equal(field.Name, "Park", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.NE, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewNotEqual("here"), "Comparison incorrect");
|
||||||
Expect.equal(field.Value, "here", "Value incorrect");
|
|
||||||
}),
|
}),
|
||||||
TestCase("BT succeeds", () =>
|
TestCase("BT succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.BT("Age", 18, 49);
|
var field = Field.BT("Age", 18, 49);
|
||||||
Expect.equal(field.Name, "Age", "Field name incorrect");
|
Expect.equal(field.Name, "Age", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.BT, "Operator incorrect");
|
Expect.equal(field.Comparison, Comparison.NewBetween(18, 49), "Comparison incorrect");
|
||||||
Expect.equal(((FSharpList<object>)field.Value).ToArray(), [18, 49], "Value incorrect");
|
}),
|
||||||
|
TestCase("IN succeeds", () =>
|
||||||
|
{
|
||||||
|
var field = Field.IN("Here", [8, 16, 32]);
|
||||||
|
Expect.equal(field.Name, "Here", "Field name incorrect");
|
||||||
|
Expect.isTrue(field.Comparison.IsIn, "Comparison incorrect");
|
||||||
|
Expect.sequenceEqual(((Comparison.In)field.Comparison).Item, [8, 16, 32], "Value incorrect");
|
||||||
}),
|
}),
|
||||||
TestCase("EX succeeds", () =>
|
TestCase("EX succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.EX("Groovy");
|
var field = Field.EX("Groovy");
|
||||||
Expect.equal(field.Name, "Groovy", "Field name incorrect");
|
Expect.equal(field.Name, "Groovy", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.EX, "Operator incorrect");
|
Expect.isTrue(field.Comparison.IsExists, "Comparison incorrect");
|
||||||
}),
|
}),
|
||||||
TestCase("NEX succeeds", () =>
|
TestCase("NEX succeeds", () =>
|
||||||
{
|
{
|
||||||
var field = Field.NEX("Rad");
|
var field = Field.NEX("Rad");
|
||||||
Expect.equal(field.Name, "Rad", "Field name incorrect");
|
Expect.equal(field.Name, "Rad", "Field name incorrect");
|
||||||
Expect.equal(field.Op, Op.NEX, "Operator incorrect");
|
Expect.isTrue(field.Comparison.IsNotExists, "Comparison incorrect");
|
||||||
}),
|
}),
|
||||||
TestList("NameToPath",
|
TestList("NameToPath",
|
||||||
[
|
[
|
||||||
|
|
|
@ -7,33 +7,39 @@ open Expecto
|
||||||
let tbl = "test_table"
|
let tbl = "test_table"
|
||||||
|
|
||||||
/// Unit tests for the Op DU
|
/// Unit tests for the Op DU
|
||||||
let opTests = testList "Op" [
|
let comparisonTests = testList "Comparison.OpSql" [
|
||||||
test "EQ succeeds" {
|
test "Equals succeeds" {
|
||||||
Expect.equal (string EQ) "=" "The equals operator was not correct"
|
Expect.equal (Equals "").OpSql "=" "The Equals SQL was not correct"
|
||||||
}
|
}
|
||||||
test "GT succeeds" {
|
test "Greater succeeds" {
|
||||||
Expect.equal (string GT) ">" "The greater than operator was not correct"
|
Expect.equal (Greater "").OpSql ">" "The Greater SQL was not correct"
|
||||||
}
|
}
|
||||||
test "GE succeeds" {
|
test "GreaterOrEqual succeeds" {
|
||||||
Expect.equal (string GE) ">=" "The greater than or equal to operator was not correct"
|
Expect.equal (GreaterOrEqual "").OpSql ">=" "The GreaterOrEqual SQL was not correct"
|
||||||
}
|
}
|
||||||
test "LT succeeds" {
|
test "Less succeeds" {
|
||||||
Expect.equal (string LT) "<" "The less than operator was not correct"
|
Expect.equal (Less "").OpSql "<" "The Less SQL was not correct"
|
||||||
}
|
}
|
||||||
test "LE succeeds" {
|
test "LessOrEqual succeeds" {
|
||||||
Expect.equal (string LE) "<=" "The less than or equal to operator was not correct"
|
Expect.equal (LessOrEqual "").OpSql "<=" "The LessOrEqual SQL was not correct"
|
||||||
}
|
}
|
||||||
test "NE succeeds" {
|
test "NotEqual succeeds" {
|
||||||
Expect.equal (string NE) "<>" "The not equal to operator was not correct"
|
Expect.equal (NotEqual "").OpSql "<>" "The NotEqual SQL was not correct"
|
||||||
}
|
}
|
||||||
test "BT succeeds" {
|
test "Between succeeds" {
|
||||||
Expect.equal (string BT) "BETWEEN" """The "between" operator was not correct"""
|
Expect.equal (Between("", "")).OpSql "BETWEEN" "The Between SQL was not correct"
|
||||||
}
|
}
|
||||||
test "EX succeeds" {
|
test "In succeeds" {
|
||||||
Expect.equal (string EX) "IS NOT NULL" """The "exists" operator was not correct"""
|
Expect.equal (In []).OpSql "IN" "The In SQL was not correct"
|
||||||
}
|
}
|
||||||
test "NEX succeeds" {
|
test "Contains succeeds" {
|
||||||
Expect.equal (string NEX) "IS NULL" """The "not exists" operator was not correct"""
|
Expect.equal (Contains "").OpSql "|?" "The Contains SQL was not correct"
|
||||||
|
}
|
||||||
|
test "Exists succeeds" {
|
||||||
|
Expect.equal Exists.OpSql "IS NOT NULL" "The Exists SQL was not correct"
|
||||||
|
}
|
||||||
|
test "NotExists succeeds" {
|
||||||
|
Expect.equal NotExists.OpSql "IS NULL" "The NotExists SQL was not correct"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -42,70 +48,70 @@ let fieldTests = testList "Field" [
|
||||||
test "EQ succeeds" {
|
test "EQ succeeds" {
|
||||||
let field = Field.EQ "Test" 14
|
let field = Field.EQ "Test" 14
|
||||||
Expect.equal field.Name "Test" "Field name incorrect"
|
Expect.equal field.Name "Test" "Field name incorrect"
|
||||||
Expect.equal field.Op EQ "Operator incorrect"
|
Expect.equal field.Comparison (Equals 14) "Comparison incorrect"
|
||||||
Expect.equal field.Value 14 "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "GT succeeds" {
|
test "GT succeeds" {
|
||||||
let field = Field.GT "Great" "night"
|
let field = Field.GT "Great" "night"
|
||||||
Expect.equal field.Name "Great" "Field name incorrect"
|
Expect.equal field.Name "Great" "Field name incorrect"
|
||||||
Expect.equal field.Op GT "Operator incorrect"
|
Expect.equal field.Comparison (Greater "night") "Comparison incorrect"
|
||||||
Expect.equal field.Value "night" "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "GE succeeds" {
|
test "GE succeeds" {
|
||||||
let field = Field.GE "Nice" 88L
|
let field = Field.GE "Nice" 88L
|
||||||
Expect.equal field.Name "Nice" "Field name incorrect"
|
Expect.equal field.Name "Nice" "Field name incorrect"
|
||||||
Expect.equal field.Op GE "Operator incorrect"
|
Expect.equal field.Comparison (GreaterOrEqual 88L) "Comparison incorrect"
|
||||||
Expect.equal field.Value 88L "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "LT succeeds" {
|
test "LT succeeds" {
|
||||||
let field = Field.LT "Lesser" "seven"
|
let field = Field.LT "Lesser" "seven"
|
||||||
Expect.equal field.Name "Lesser" "Field name incorrect"
|
Expect.equal field.Name "Lesser" "Field name incorrect"
|
||||||
Expect.equal field.Op LT "Operator incorrect"
|
Expect.equal field.Comparison (Less "seven") "Comparison incorrect"
|
||||||
Expect.equal field.Value "seven" "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "LE succeeds" {
|
test "LE succeeds" {
|
||||||
let field = Field.LE "Nobody" "KNOWS";
|
let field = Field.LE "Nobody" "KNOWS";
|
||||||
Expect.equal field.Name "Nobody" "Field name incorrect"
|
Expect.equal field.Name "Nobody" "Field name incorrect"
|
||||||
Expect.equal field.Op LE "Operator incorrect"
|
Expect.equal field.Comparison (LessOrEqual "KNOWS") "Comparison incorrect"
|
||||||
Expect.equal field.Value "KNOWS" "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "NE succeeds" {
|
test "NE succeeds" {
|
||||||
let field = Field.NE "Park" "here"
|
let field = Field.NE "Park" "here"
|
||||||
Expect.equal field.Name "Park" "Field name incorrect"
|
Expect.equal field.Name "Park" "Field name incorrect"
|
||||||
Expect.equal field.Op NE "Operator incorrect"
|
Expect.equal field.Comparison (NotEqual "here") "Comparison incorrect"
|
||||||
Expect.equal field.Value "here" "Value incorrect"
|
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "BT succeeds" {
|
test "BT succeeds" {
|
||||||
let field = Field.BT "Age" 18 49
|
let field = Field.BT "Age" 18 49
|
||||||
Expect.equal field.Name "Age" "Field name incorrect"
|
Expect.equal field.Name "Age" "Field name incorrect"
|
||||||
Expect.equal field.Op BT "Operator incorrect"
|
Expect.equal field.Comparison (Between(18, 49)) "Comparison incorrect"
|
||||||
Expect.sequenceEqual (field.Value :?> obj list) [ 18; 49 ] "Value incorrect"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
|
}
|
||||||
|
test "IN succeeds" {
|
||||||
|
let field = Field.IN "Here" [| 8; 16; 32 |]
|
||||||
|
Expect.equal field.Name "Here" "Field name incorrect"
|
||||||
|
Expect.equal field.Comparison (In [| 8; 16; 32 |]) "Comparison incorrect"
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "EX succeeds" {
|
test "EX succeeds" {
|
||||||
let field = Field.EX "Groovy"
|
let field = Field.EX "Groovy"
|
||||||
Expect.equal field.Name "Groovy" "Field name incorrect"
|
Expect.equal field.Name "Groovy" "Field name incorrect"
|
||||||
Expect.equal field.Op EX "Operator incorrect"
|
Expect.equal field.Comparison Exists "Comparison incorrect"
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "NEX succeeds" {
|
test "NEX succeeds" {
|
||||||
let field = Field.NEX "Rad"
|
let field = Field.NEX "Rad"
|
||||||
Expect.equal field.Name "Rad" "Field name incorrect"
|
Expect.equal field.Name "Rad" "Field name incorrect"
|
||||||
Expect.equal field.Op NEX "Operator incorrect"
|
Expect.equal field.Comparison NotExists "Comparison incorrect"
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
|
@ -467,7 +473,7 @@ let queryTests = testList "Query" [
|
||||||
|
|
||||||
/// Tests which do not hit the database
|
/// Tests which do not hit the database
|
||||||
let all = testList "Common" [
|
let all = testList "Common" [
|
||||||
opTests
|
comparisonTests
|
||||||
fieldTests
|
fieldTests
|
||||||
fieldMatchTests
|
fieldMatchTests
|
||||||
parameterNameTests
|
parameterNameTests
|
||||||
|
|
Loading…
Reference in New Issue
Block a user