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