Add Field type for criteria

- Implement in SQLite
This commit is contained in:
Daniel J. Summers 2024-01-22 22:58:22 -05:00
parent 7ac174350c
commit 097208139d
8 changed files with 242 additions and 130 deletions

View File

@ -32,6 +32,51 @@ type Op =
| NEX -> "IS NULL"
/// Criteria for a field WHERE clause
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
} with
/// Create an equals (=) field criteria
static member EQ name (value: obj) =
{ Name = name; Op = EQ; Value = value }
/// Create a greater than (>) field criteria
static member GT name (value: obj) =
{ Name = name; Op = GT; Value = value }
/// Create a greater than or equal to (>=) field criteria
static member GE name (value: obj) =
{ Name = name; Op = GE; Value = value }
/// Create a less than (<) field criteria
static member LT name (value: obj) =
{ Name = name; Op = LT; Value = value }
/// Create a less than or equal to (<=) field criteria
static member LE name (value: obj) =
{ Name = name; Op = LE; Value = value }
/// Create a not equals (<>) field criteria
static member NE name (value: obj) =
{ Name = name; Op = NE; Value = value }
/// Create an exists (IS NOT NULL) field criteria
static member EX name =
{ Name = name; Op = EX; Value = obj () }
/// Create an not exists (IS NULL) field criteria
static member NEX name =
{ Name = name; Op = NEX; Value = obj () }
/// The required document serialization implementation
type IDocumentSerializer =

View File

@ -45,16 +45,16 @@ module Extensions =
WithConn.Count.all tableName conn
/// Count matching documents using a comparison on a JSON field
member conn.countByField tableName fieldName op (value: obj) =
WithConn.Count.byField tableName fieldName op value conn
member conn.countByField tableName field =
WithConn.Count.byField tableName field conn
/// Determine if a document exists for the given ID
member conn.existsById tableName (docId: 'TKey) =
WithConn.Exists.byId tableName docId conn
/// Determine if a document exists using a comparison on a JSON field
member conn.existsByField tableName fieldName op (value: obj) =
WithConn.Exists.byField tableName fieldName op value conn
member conn.existsByField tableName field =
WithConn.Exists.byField tableName field conn
/// Retrieve all documents in the given table
member conn.findAll<'TDoc> tableName =
@ -65,12 +65,12 @@ module Extensions =
WithConn.Find.byId<'TKey, 'TDoc> tableName docId conn
/// Retrieve documents via a comparison on a JSON field
member conn.findByField<'TDoc> tableName fieldName op (value: obj) =
WithConn.Find.byField<'TDoc> tableName fieldName op value conn
member conn.findByField<'TDoc> tableName field =
WithConn.Find.byField<'TDoc> tableName field conn
/// Retrieve documents via a comparison on a JSON field, returning only the first result
member conn.findFirstByField<'TDoc> tableName fieldName op (value: obj) =
WithConn.Find.firstByField<'TDoc> tableName fieldName op value conn
member conn.findFirstByField<'TDoc> tableName field =
WithConn.Find.firstByField<'TDoc> tableName field conn
/// Update an entire document by its ID
member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
@ -85,24 +85,24 @@ module Extensions =
WithConn.Patch.byId tableName docId patch conn
/// Patch documents using a comparison on a JSON field
member conn.patchByField tableName fieldName op (value: obj) (patch: 'TPatch) =
WithConn.Patch.byField tableName fieldName op value patch conn
member conn.patchByField tableName field (patch: 'TPatch) =
WithConn.Patch.byField tableName field patch conn
/// Remove a field from a document by the document's ID
member conn.removeFieldById tableName (docId: 'TKey) fieldName =
WithConn.RemoveField.byId tableName docId fieldName conn
/// Remove a field from a document via a comparison on a JSON field in the document
member conn.removeFieldByField tableName whereFieldName op (value: obj) removeFieldName =
WithConn.RemoveField.byField tableName whereFieldName op value removeFieldName conn
member conn.removeFieldByField tableName field fieldName =
WithConn.RemoveField.byField tableName field fieldName conn
/// Delete a document by its ID
member conn.deleteById tableName (docId: 'TKey) =
WithConn.Delete.byId tableName docId conn
/// Delete documents by matching a comparison on a JSON field
member conn.deleteByField tableName fieldName op (value: obj) =
WithConn.Delete.byField tableName fieldName op value conn
member conn.deleteByField tableName field =
WithConn.Delete.byField tableName field conn
open System.Runtime.CompilerServices
@ -159,8 +159,8 @@ type SqliteConnectionCSharpExtensions =
/// Count matching documents using a comparison on a JSON field
[<Extension>]
static member inline CountByField(conn, tableName, fieldName, op, value: obj) =
WithConn.Count.byField tableName fieldName op value conn
static member inline CountByField(conn, tableName, field) =
WithConn.Count.byField tableName field conn
/// Determine if a document exists for the given ID
[<Extension>]
@ -169,8 +169,8 @@ type SqliteConnectionCSharpExtensions =
/// Determine if a document exists using a comparison on a JSON field
[<Extension>]
static member inline ExistsByField(conn, tableName, fieldName, op, value: obj) =
WithConn.Exists.byField tableName fieldName op value conn
static member inline ExistsByField(conn, tableName, field) =
WithConn.Exists.byField tableName field conn
/// Retrieve all documents in the given table
[<Extension>]
@ -184,13 +184,13 @@ type SqliteConnectionCSharpExtensions =
/// Retrieve documents via a comparison on a JSON field
[<Extension>]
static member inline FindByField<'TDoc>(conn, tableName, fieldName, op, value) =
WithConn.Find.ByField<'TDoc>(tableName, fieldName, op, value, conn)
static member inline FindByField<'TDoc>(conn, tableName, field) =
WithConn.Find.ByField<'TDoc>(tableName, field, conn)
/// Retrieve documents via a comparison on a JSON field, returning only the first result
[<Extension>]
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, fieldName, op, value: obj) =
WithConn.Find.FirstByField<'TDoc>(tableName, fieldName, op, value, conn)
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
WithConn.Find.FirstByField<'TDoc>(tableName, field, conn)
/// Update an entire document by its ID
[<Extension>]
@ -209,8 +209,8 @@ type SqliteConnectionCSharpExtensions =
/// Patch documents using a comparison on a JSON field
[<Extension>]
static member inline PatchByField<'TPatch>(conn, tableName, fieldName, op, value: obj, patch: 'TPatch) =
WithConn.Patch.byField tableName fieldName op value patch conn
static member inline PatchByField<'TPatch>(conn, tableName, field, patch: 'TPatch) =
WithConn.Patch.byField tableName field patch conn
/// Remove a field from a document by the document's ID
[<Extension>]
@ -219,8 +219,8 @@ type SqliteConnectionCSharpExtensions =
/// Remove a field from a document via a comparison on a JSON field in the document
[<Extension>]
static member inline RemoveFieldByField(conn, tableName, whereFieldName, op, value: obj, removeFieldName) =
WithConn.RemoveField.byField tableName whereFieldName op value removeFieldName conn
static member inline RemoveFieldByField(conn, tableName, field, fieldName) =
WithConn.RemoveField.byField tableName field fieldName conn
/// Delete a document by its ID
[<Extension>]
@ -229,5 +229,5 @@ type SqliteConnectionCSharpExtensions =
/// Delete documents by matching a comparison on a JSON field
[<Extension>]
static member inline DeleteByField(conn, tableName, fieldName, op, value: obj) =
WithConn.Delete.byField tableName fieldName op value conn
static member inline DeleteByField(conn, tableName, field) =
WithConn.Delete.byField tableName field conn

View File

@ -12,7 +12,7 @@ module Configuration =
/// Register a connection string to use for query execution (enables foreign keys)
[<CompiledName "UseConnectionString">]
let useConnectionString connStr =
let builder = SqliteConnectionStringBuilder(connStr)
let builder = SqliteConnectionStringBuilder connStr
builder.ForeignKeys <- Option.toNullable (Some true)
connectionString <- Some (string builder)
@ -243,8 +243,8 @@ module WithConn =
/// Count matching documents using a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) conn =
Custom.scalar (Query.Count.byField tableName fieldName op) [ fieldParam value ] toCount conn
let byField tableName field conn =
Custom.scalar (Query.Count.byField tableName field.Name field.Op) [ fieldParam field.Value ] toCount conn
/// Commands to determine if documents exist
[<RequireQualifiedAccess>]
@ -257,8 +257,8 @@ module WithConn =
/// Determine if a document exists using a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) conn =
Custom.scalar (Query.Exists.byField tableName fieldName op) [ fieldParam value ] toExists conn
let byField tableName field conn =
Custom.scalar (Query.Exists.byField tableName field.Name field.Op) [ fieldParam field.Value ] toExists conn
/// Commands to retrieve documents
[<RequireQualifiedAccess>]
@ -284,23 +284,31 @@ module WithConn =
/// Retrieve documents via a comparison on a JSON field
[<CompiledName "FSharpByField">]
let byField<'TDoc> tableName fieldName op (value: obj) conn =
Custom.list<'TDoc> (Query.Find.byField tableName fieldName op) [ fieldParam value ] fromData<'TDoc> conn
let byField<'TDoc> tableName field conn =
Custom.list<'TDoc>
(Query.Find.byField tableName field.Name field.Op) [ fieldParam field.Value ] fromData<'TDoc> conn
/// Retrieve documents via a comparison on a JSON field
let ByField<'TDoc>(tableName, fieldName, op, value: obj, conn) =
Custom.List<'TDoc>(Query.Find.byField tableName fieldName op, [ fieldParam value ], fromData<'TDoc>, conn)
let ByField<'TDoc>(tableName, field, conn) =
Custom.List<'TDoc>(
Query.Find.byField tableName field.Name field.Op, [ fieldParam field.Value ], fromData<'TDoc>, conn)
/// Retrieve documents via a comparison on a JSON field, returning only the first result
[<CompiledName "FSharpFirstByField">]
let firstByField<'TDoc> tableName fieldName op (value: obj) conn =
let firstByField<'TDoc> tableName field conn =
Custom.single
$"{Query.Find.byField tableName fieldName op} LIMIT 1" [ fieldParam value ] fromData<'TDoc> conn
$"{Query.Find.byField tableName field.Name field.Op} LIMIT 1"
[ fieldParam field.Value ]
fromData<'TDoc>
conn
/// Retrieve documents via a comparison on a JSON field, returning only the first result
let FirstByField<'TDoc when 'TDoc: null>(tableName, fieldName, op, value: obj, conn) =
let FirstByField<'TDoc when 'TDoc: null>(tableName, field, conn) =
Custom.Single(
$"{Query.Find.byField tableName fieldName op} LIMIT 1", [ fieldParam value ], fromData<'TDoc>, conn)
$"{Query.Find.byField tableName field.Name field.Op} LIMIT 1",
[ fieldParam field.Value ],
fromData<'TDoc>,
conn)
/// Commands to update documents
[<RequireQualifiedAccess>]
@ -331,9 +339,11 @@ module WithConn =
/// Patch documents using a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) (patch: 'TPatch) (conn: SqliteConnection) =
let byField tableName field (patch: 'TPatch) (conn: SqliteConnection) =
Custom.nonQuery
(Query.Patch.byField tableName fieldName op) [ fieldParam value; jsonParam "@data" patch ] conn
(Query.Patch.byField tableName field.Name field.Op)
[ fieldParam field.Value; jsonParam "@data" patch ]
conn
/// Commands to remove fields from documents
[<RequireQualifiedAccess>]
@ -346,10 +356,10 @@ module WithConn =
/// Remove a field from a document via a comparison on a JSON field in the document
[<CompiledName "ByField">]
let byField tableName whereFieldName op (value: obj) removeFieldName conn =
let byField tableName field fieldName conn =
Custom.nonQuery
(Query.RemoveField.byField tableName whereFieldName op)
[ fieldParam value; fieldNameParam removeFieldName ]
(Query.RemoveField.byField tableName field.Name field.Op)
[ fieldParam field.Value; fieldNameParam fieldName ]
conn
/// Commands to delete documents
@ -363,8 +373,8 @@ module WithConn =
/// Delete documents by matching a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) conn =
Custom.nonQuery (Query.Delete.byField tableName fieldName op) [ fieldParam value ] conn
let byField tableName field conn =
Custom.nonQuery (Query.Delete.byField tableName field.Name field.Op) [ fieldParam field.Value ] conn
/// Commands to execute custom SQL queries
@ -454,9 +464,9 @@ module Count =
/// Count matching documents using a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) =
let byField tableName field =
use conn = Configuration.dbConn ()
WithConn.Count.byField tableName fieldName op value conn
WithConn.Count.byField tableName field conn
/// Commands to determine if documents exist
[<RequireQualifiedAccess>]
@ -470,9 +480,9 @@ module Exists =
/// Determine if a document exists using a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) =
let byField tableName field =
use conn = Configuration.dbConn ()
WithConn.Exists.byField tableName fieldName op value conn
WithConn.Exists.byField tableName field conn
/// Commands to determine if documents exist
[<RequireQualifiedAccess>]
@ -502,25 +512,25 @@ module Find =
/// Retrieve documents via a comparison on a JSON field
[<CompiledName "FSharpByField">]
let byField<'TDoc> tableName fieldName op value =
let byField<'TDoc> tableName field =
use conn = Configuration.dbConn ()
WithConn.Find.byField<'TDoc> tableName fieldName op value conn
WithConn.Find.byField<'TDoc> tableName field conn
/// Retrieve documents via a comparison on a JSON field
let ByField<'TDoc>(tableName, fieldName, op, value) =
let ByField<'TDoc>(tableName, field) =
use conn = Configuration.dbConn ()
WithConn.Find.ByField<'TDoc>(tableName, fieldName, op, value, conn)
WithConn.Find.ByField<'TDoc>(tableName, field, conn)
/// Retrieve documents via a comparison on a JSON field, returning only the first result
[<CompiledName "FSharpFirstByField">]
let firstByField<'TDoc> tableName fieldName op value =
let firstByField<'TDoc> tableName field =
use conn = Configuration.dbConn ()
WithConn.Find.firstByField<'TDoc> tableName fieldName op value conn
WithConn.Find.firstByField<'TDoc> tableName field conn
/// Retrieve documents via a comparison on a JSON field, returning only the first result
let FirstByField<'TDoc when 'TDoc: null>(tableName, fieldName, op, value) =
let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
use conn = Configuration.dbConn ()
WithConn.Find.FirstByField<'TDoc>(tableName, fieldName, op, value, conn)
WithConn.Find.FirstByField<'TDoc>(tableName, field, conn)
/// Commands to update documents
[<RequireQualifiedAccess>]
@ -555,9 +565,9 @@ module Patch =
/// Patch documents using a comparison on a JSON field in the WHERE clause
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) (patch: 'TPatch) =
let byField tableName field (patch: 'TPatch) =
use conn = Configuration.dbConn ()
WithConn.Patch.byField tableName fieldName op value patch conn
WithConn.Patch.byField tableName field patch conn
/// Commands to remove fields from documents
[<RequireQualifiedAccess>]
@ -571,9 +581,9 @@ module RemoveField =
/// Remove a field from a document via a comparison on a JSON field in the document
[<CompiledName "ByField">]
let byField tableName whereFieldName op (value: obj) removeFieldName =
let byField tableName field fieldName =
use conn = Configuration.dbConn ()
WithConn.RemoveField.byField tableName whereFieldName op value removeFieldName conn
WithConn.RemoveField.byField tableName field fieldName conn
/// Commands to delete documents
[<RequireQualifiedAccess>]
@ -587,6 +597,6 @@ module Delete =
/// Delete documents by matching a comparison on a JSON field
[<CompiledName "ByField">]
let byField tableName fieldName op (value: obj) =
let byField tableName field =
use conn = Configuration.dbConn ()
WithConn.Delete.byField tableName fieldName op value conn
WithConn.Delete.byField tableName field conn

View File

@ -105,6 +105,63 @@ public static class CommonCSharpTests
Expect.equal(Op.NEX.ToString(), "IS NULL", "The \"not exists\" operator was not correct");
})
}),
TestList("Field", new[]
{
TestCase("EQ succeeds", () =>
{
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");
}),
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");
}),
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");
}),
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");
}),
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");
}),
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");
}),
TestCase("EX succeeds", () =>
{
var field = Field.EX("Groovy");
Expect.equal(field.Name, "Groovy", "Field name incorrect");
Expect.equal(field.Op, Op.EX, "Operator 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");
})
}),
TestList("Query", new[]
{
TestCase("SelectFromTable succeeds", () =>

View File

@ -219,7 +219,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var theCount = await conn.CountByField(SqliteDb.TableName, "Value", Op.EQ, "purple");
var theCount = await conn.CountByField(SqliteDb.TableName, Field.EQ("Value", "purple"));
Expect.equal(theCount, 2L, "There should have been 2 matching documents");
}),
TestList("ExistsById", new[]
@ -251,7 +251,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var exists = await conn.ExistsByField(SqliteDb.TableName, "NumValue", Op.GE, 10);
var exists = await conn.ExistsByField(SqliteDb.TableName, Field.GE("NumValue", 10));
Expect.isTrue(exists, "There should have been existing documents");
}),
TestCase("succeeds when no matching documents exist", async () =>
@ -260,7 +260,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var exists = await conn.ExistsByField(SqliteDb.TableName, "Nothing", Op.EQ, "none");
var exists = await conn.ExistsByField(SqliteDb.TableName, Field.EQ("Nothing", "none"));
Expect.isFalse(exists, "There should not have been any existing documents");
})
}),
@ -316,7 +316,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "NumValue", Op.GT, 15);
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, Field.GT("NumValue", 15));
Expect.equal(docs.Count, 2, "There should have been two documents returned");
}),
TestCase("succeeds when documents are not found", async () =>
@ -325,7 +325,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "mauve");
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "mauve"));
Expect.isEmpty(docs, "There should have been no documents returned");
})
}),
@ -337,7 +337,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "another");
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "another"));
Expect.isNotNull(doc, "There should have been a document returned");
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
}),
@ -347,7 +347,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green");
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Sub.Foo", "green"));
Expect.isNotNull(doc, "There should have been a document returned");
Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
}),
@ -357,7 +357,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "absent");
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "absent"));
Expect.isNull(doc, "There should not have been a document returned");
})
}),
@ -452,8 +452,8 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.PatchByField(SqliteDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
var after = await conn.CountByField(SqliteDb.TableName, "NumValue", Op.EQ, 77);
await conn.PatchByField(SqliteDb.TableName, Field.EQ("Value", "purple"), new { NumValue = 77 });
var after = await conn.CountByField(SqliteDb.TableName, Field.EQ("NumValue", 77));
Expect.equal(after, 2L, "There should have been 2 documents returned");
}),
TestCase("succeeds when no document is updated", async () =>
@ -464,7 +464,7 @@ public static class SqliteCSharpExtensionTests
Expect.isEmpty(before, "There should have been no documents returned");
// This not raising an exception is the test
await conn.PatchByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
await conn.PatchByField(SqliteDb.TableName, Field.EQ("Value", "burgundy"), new { Foo = "green" });
})
}),
TestList("RemoveFieldById", new[]
@ -506,7 +506,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.RemoveFieldByField(SqliteDb.TableName, "NumValue", Op.EQ, 17, "Sub");
await conn.RemoveFieldByField(SqliteDb.TableName, Field.EQ("NumValue", 17), "Sub");
var updated = await Find.ById<string, JsonDocument>(SqliteDb.TableName, "four");
Expect.isNotNull(updated, "The updated document should have been retrieved");
Expect.isNull(updated.Sub, "The sub-document should have been removed");
@ -518,7 +518,7 @@ public static class SqliteCSharpExtensionTests
await LoadDocs();
// This not raising an exception is the test
await conn.RemoveFieldByField(SqliteDb.TableName, "NumValue", Op.EQ, 17, "Nothing");
await conn.RemoveFieldByField(SqliteDb.TableName, Field.EQ("NumValue", 17), "Nothing");
}),
TestCase("succeeds when no document is matched", async () =>
{
@ -526,7 +526,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
// This not raising an exception is the test
await conn.RemoveFieldByField(SqliteDb.TableName, "Abracadabra", Op.NE, "apple", "Value");
await conn.RemoveFieldByField(SqliteDb.TableName, Field.NE("Abracadabra", "apple"), "Value");
})
}),
TestList("DeleteById", new[]
@ -560,7 +560,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.NE, "purple");
await conn.DeleteByField(SqliteDb.TableName, Field.NE("Value", "purple"));
var remaining = await conn.CountAll(SqliteDb.TableName);
Expect.equal(remaining, 2L, "There should have been 2 documents remaining");
}),
@ -570,7 +570,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.EQ, "crimson");
await conn.DeleteByField(SqliteDb.TableName, Field.EQ("Value", "crimson"));
var remaining = await conn.CountAll(SqliteDb.TableName);
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
})

View File

@ -312,7 +312,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var theCount = await Count.ByField(SqliteDb.TableName, "Value", Op.EQ, "purple");
var theCount = await Count.ByField(SqliteDb.TableName, Field.EQ("Value", "purple"));
Expect.equal(theCount, 2L, "There should have been 2 matching documents");
})
}),
@ -344,7 +344,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var exists = await Exists.ByField(SqliteDb.TableName, "NumValue", Op.GE, 10);
var exists = await Exists.ByField(SqliteDb.TableName, Field.GE("NumValue", 10));
Expect.isTrue(exists, "There should have been existing documents");
}),
TestCase("succeeds when no matching documents exist", async () =>
@ -352,7 +352,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var exists = await Exists.ByField(SqliteDb.TableName, "Nothing", Op.EQ, "none");
var exists = await Exists.ByField(SqliteDb.TableName, Field.EQ("Nothing", "none"));
Expect.isFalse(exists, "There should not have been any existing documents");
})
})
@ -406,7 +406,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var docs = await Find.ByField<JsonDocument>(SqliteDb.TableName, "NumValue", Op.GT, 15);
var docs = await Find.ByField<JsonDocument>(SqliteDb.TableName, Field.GT("NumValue", 15));
Expect.equal(docs.Count, 2, "There should have been two documents returned");
}),
TestCase("succeeds when documents are not found", async () =>
@ -414,7 +414,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var docs = await Find.ByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "mauve");
var docs = await Find.ByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "mauve"));
Expect.isEmpty(docs, "There should have been no documents returned");
})
}),
@ -425,7 +425,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "another");
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "another"));
Expect.isNotNull(doc, "There should have been a document returned");
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
}),
@ -434,7 +434,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green");
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Sub.Foo", "green"));
Expect.isNotNull(doc, "There should have been a document returned");
Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
}),
@ -443,7 +443,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "absent");
var doc = await Find.FirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "absent"));
Expect.isNull(doc, "There should not have been a document returned");
})
})
@ -540,8 +540,8 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
await Patch.ByField(SqliteDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
var after = await Count.ByField(SqliteDb.TableName, "NumValue", Op.EQ, 77);
await Patch.ByField(SqliteDb.TableName, Field.EQ("Value", "purple"), new { NumValue = 77 });
var after = await Count.ByField(SqliteDb.TableName, Field.EQ("NumValue", 77));
Expect.equal(after, 2L, "There should have been 2 documents returned");
}),
TestCase("succeeds when no document is updated", async () =>
@ -552,7 +552,7 @@ public static class SqliteCSharpTests
Expect.isEmpty(before, "There should have been no documents returned");
// This not raising an exception is the test
await Patch.ByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
await Patch.ByField(SqliteDb.TableName, Field.EQ("Value", "burgundy"), new { Foo = "green" });
})
})
}),
@ -593,7 +593,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
await RemoveField.ByField(SqliteDb.TableName, "NumValue", Op.EQ, 17, "Sub");
await RemoveField.ByField(SqliteDb.TableName, Field.EQ("NumValue", 17), "Sub");
var updated = await Find.ById<string, JsonDocument>(SqliteDb.TableName, "four");
Expect.isNotNull(updated, "The updated document should have been retrieved");
Expect.isNull(updated.Sub, "The sub-document should have been removed");
@ -604,14 +604,14 @@ public static class SqliteCSharpTests
await LoadDocs();
// This not raising an exception is the test
await RemoveField.ByField(SqliteDb.TableName, "NumValue", Op.EQ, 17, "Nothing");
await RemoveField.ByField(SqliteDb.TableName, Field.EQ("NumValue", 17), "Nothing");
}),
TestCase("succeeds when no document is matched", async () =>
{
await using var db = await SqliteDb.BuildDb();
// This not raising an exception is the test
await RemoveField.ByField(SqliteDb.TableName, "Abracadabra", Op.NE, "apple", "Value");
await RemoveField.ByField(SqliteDb.TableName, Field.NE("Abracadabra", "apple"), "Value");
})
})
}),
@ -645,7 +645,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
await Delete.ByField(SqliteDb.TableName, "Value", Op.NE, "purple");
await Delete.ByField(SqliteDb.TableName, Field.NE("Value", "purple"));
var remaining = await Count.All(SqliteDb.TableName);
Expect.equal(remaining, 2L, "There should have been 2 documents remaining");
}),
@ -654,7 +654,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
await Delete.ByField(SqliteDb.TableName, "Value", Op.EQ, "crimson");
await Delete.ByField(SqliteDb.TableName, Field.EQ("Value", "crimson"));
var remaining = await Count.All(SqliteDb.TableName);
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
})

View File

@ -118,7 +118,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! theCount = conn.countByField SqliteDb.TableName "Value" EQ "purple"
let! theCount = conn.countByField SqliteDb.TableName (Field.EQ "Value" "purple")
Expect.equal theCount 2L "There should have been 2 matching documents"
}
testList "existsById" [
@ -145,7 +145,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! exists = conn.existsByField SqliteDb.TableName "NumValue" EQ 10
let! exists = conn.existsByField SqliteDb.TableName (Field.EQ "NumValue" 10)
Expect.isTrue exists "There should have been existing documents"
}
testTask "succeeds when no matching documents exist" {
@ -153,7 +153,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! exists = conn.existsByField SqliteDb.TableName "Nothing" EQ "none"
let! exists = conn.existsByField SqliteDb.TableName (Field.EQ "Nothing" "none")
Expect.isFalse exists "There should not have been any existing documents"
}
]
@ -206,7 +206,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! docs = conn.findByField<JsonDocument> SqliteDb.TableName "Sub.Foo" EQ "green"
let! docs = conn.findByField<JsonDocument> SqliteDb.TableName (Field.EQ "Sub.Foo" "green")
Expect.equal (List.length docs) 2 "There should have been two documents returned"
}
testTask "succeeds when documents are not found" {
@ -214,7 +214,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! docs = conn.findByField<JsonDocument> SqliteDb.TableName "Value" EQ "mauve"
let! docs = conn.findByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "mauve")
Expect.isTrue (List.isEmpty docs) "There should have been no documents returned"
}
]
@ -224,7 +224,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName "Value" EQ "another"
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "another")
Expect.isTrue (Option.isSome doc) "There should have been a document returned"
Expect.equal doc.Value.Id "two" "The incorrect document was returned"
}
@ -233,7 +233,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName "Sub.Foo" EQ "green"
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Sub.Foo" "green")
Expect.isTrue (Option.isSome doc) "There should have been a document returned"
Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned"
}
@ -242,7 +242,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName "Value" EQ "absent"
let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "absent")
Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
}
]
@ -330,8 +330,8 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.patchByField SqliteDb.TableName "Value" EQ "purple" {| NumValue = 77 |}
let! after = conn.countByField SqliteDb.TableName "NumValue" EQ 77
do! conn.patchByField SqliteDb.TableName (Field.EQ "Value" "purple") {| NumValue = 77 |}
let! after = conn.countByField SqliteDb.TableName (Field.EQ "NumValue" 77)
Expect.equal after 2L "There should have been 2 documents returned"
}
testTask "succeeds when no document is updated" {
@ -342,7 +342,7 @@ let integrationTests =
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! conn.patchByField SqliteDb.TableName "Value" EQ "burgundy" {| Foo = "green" |}
do! conn.patchByField SqliteDb.TableName (Field.EQ "Value" "burgundy") {| Foo = "green" |}
}
]
testList "removeFieldById" [
@ -381,7 +381,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.removeFieldByField SqliteDb.TableName "NumValue" EQ 17 "Sub"
do! conn.removeFieldByField SqliteDb.TableName (Field.EQ "NumValue" 17) "Sub"
try
let! _ = conn.findById<string, JsonDocument> SqliteDb.TableName "four"
Expect.isTrue false "The updated document should have failed to parse"
@ -395,14 +395,14 @@ let integrationTests =
do! loadDocs ()
// This not raising an exception is the test
do! conn.removeFieldByField SqliteDb.TableName "NumValue" EQ 17 "Nothing"
do! conn.removeFieldByField SqliteDb.TableName (Field.EQ "NumValue" 17) "Nothing"
}
testTask "succeeds when no document is matched" {
use! db = SqliteDb.BuildDb()
use conn = Configuration.dbConn ()
// This not raising an exception is the test
do! conn.removeFieldByField SqliteDb.TableName "Abracadabra" NE "apple" "Value"
do! conn.removeFieldByField SqliteDb.TableName (Field.NE "Abracadabra" "apple") "Value"
}
]
testList "deleteById" [
@ -431,7 +431,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.deleteByField SqliteDb.TableName "Value" NE "purple"
do! conn.deleteByField SqliteDb.TableName (Field.NE "Value" "purple")
let! remaining = conn.countAll SqliteDb.TableName
Expect.equal remaining 2L "There should have been 2 documents remaining"
}
@ -440,7 +440,7 @@ let integrationTests =
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.deleteByField SqliteDb.TableName "Value" EQ "crimson"
do! conn.deleteByField SqliteDb.TableName (Field.EQ "Value" "crimson")
let! remaining = conn.countAll SqliteDb.TableName
Expect.equal remaining 5L "There should have been 5 documents remaining"
}

View File

@ -292,7 +292,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! theCount = Count.byField SqliteDb.TableName "Value" EQ "purple"
let! theCount = Count.byField SqliteDb.TableName (Field.EQ "Value" "purple")
Expect.equal theCount 2L "There should have been 2 matching documents"
}
]
@ -318,14 +318,14 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! exists = Exists.byField SqliteDb.TableName "NumValue" EQ 10
let! exists = Exists.byField SqliteDb.TableName (Field.EQ "NumValue" 10)
Expect.isTrue exists "There should have been existing documents"
}
testTask "succeeds when no matching documents exist" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! exists = Exists.byField SqliteDb.TableName "Nothing" LT "none"
let! exists = Exists.byField SqliteDb.TableName (Field.LT "Nothing" "none")
Expect.isFalse exists "There should not have been any existing documents"
}
]
@ -375,14 +375,14 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! docs = Find.byField<JsonDocument> SqliteDb.TableName "NumValue" GT 15
let! docs = Find.byField<JsonDocument> SqliteDb.TableName (Field.GT "NumValue" 15)
Expect.equal (List.length docs) 2 "There should have been two documents returned"
}
testTask "succeeds when documents are not found" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! docs = Find.byField<JsonDocument> SqliteDb.TableName "NumValue" GT 100
let! docs = Find.byField<JsonDocument> SqliteDb.TableName (Field.GT "NumValue" 100)
Expect.isTrue (List.isEmpty docs) "There should have been no documents returned"
}
]
@ -391,7 +391,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName "Value" EQ "another"
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "another")
Expect.isTrue (Option.isSome doc) "There should have been a document returned"
Expect.equal doc.Value.Id "two" "The incorrect document was returned"
}
@ -399,7 +399,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName "Sub.Foo" EQ "green"
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Sub.Foo" "green")
Expect.isTrue (Option.isSome doc) "There should have been a document returned"
Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned"
}
@ -407,7 +407,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName "Value" EQ "absent"
let! doc = Find.firstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "absent")
Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
}
]
@ -489,8 +489,8 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! Patch.byField SqliteDb.TableName "Value" EQ "purple" {| NumValue = 77 |}
let! after = Count.byField SqliteDb.TableName "NumValue" EQ 77
do! Patch.byField SqliteDb.TableName (Field.EQ "Value" "purple") {| NumValue = 77 |}
let! after = Count.byField SqliteDb.TableName (Field.EQ "NumValue" 77)
Expect.equal after 2L "There should have been 2 documents returned"
}
testTask "succeeds when no document is updated" {
@ -500,7 +500,7 @@ let integrationTests =
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byField SqliteDb.TableName "Value" EQ "burgundy" {| Foo = "green" |}
do! Patch.byField SqliteDb.TableName (Field.EQ "Value" "burgundy") {| Foo = "green" |}
}
]
]
@ -537,7 +537,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! RemoveField.byField SqliteDb.TableName "NumValue" EQ 17 "Sub"
do! RemoveField.byField SqliteDb.TableName (Field.EQ "NumValue" 17) "Sub"
try
let! _ = Find.byId<string, JsonDocument> SqliteDb.TableName "four"
Expect.isTrue false "The updated document should have failed to parse"
@ -550,13 +550,13 @@ let integrationTests =
do! loadDocs ()
// This not raising an exception is the test
do! RemoveField.byField SqliteDb.TableName "NumValue" EQ 17 "Nothing"
do! RemoveField.byField SqliteDb.TableName (Field.EQ "NumValue" 17) "Nothing"
}
testTask "succeeds when no document is matched" {
use! db = SqliteDb.BuildDb()
// This not raising an exception is the test
do! RemoveField.byField SqliteDb.TableName "Abracadabra" NE "apple" "Value"
do! RemoveField.byField SqliteDb.TableName (Field.NE "Abracadabra" "apple") "Value"
}
]
]
@ -584,7 +584,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! Delete.byField SqliteDb.TableName "Value" NE "purple"
do! Delete.byField SqliteDb.TableName (Field.NE "Value" "purple")
let! remaining = Count.all SqliteDb.TableName
Expect.equal remaining 2L "There should have been 2 documents remaining"
}
@ -592,7 +592,7 @@ let integrationTests =
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! Delete.byField SqliteDb.TableName "Value" EQ "crimson"
do! Delete.byField SqliteDb.TableName (Field.EQ "Value" "crimson")
let! remaining = Count.all SqliteDb.TableName
Expect.equal remaining 5L "There should have been 5 documents remaining"
}