From 097208139d6f99bd09c32803c2d139ab6857bda6 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 22 Jan 2024 22:58:22 -0500 Subject: [PATCH] Add Field type for criteria - Implement in SQLite --- src/Common/Library.fs | 45 ++++++++++ src/Sqlite/Extensions.fs | 56 ++++++------ src/Sqlite/Library.fs | 86 +++++++++++-------- src/Tests.CSharp/CommonCSharpTests.cs | 57 ++++++++++++ .../SqliteCSharpExtensionTests.cs | 32 +++---- src/Tests.CSharp/SqliteCSharpTests.cs | 32 +++---- src/Tests/SqliteExtensionTests.fs | 32 +++---- src/Tests/SqliteTests.fs | 32 +++---- 8 files changed, 242 insertions(+), 130 deletions(-) diff --git a/src/Common/Library.fs b/src/Common/Library.fs index 2f45c2b..47caade 100644 --- a/src/Common/Library.fs +++ b/src/Common/Library.fs @@ -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 = diff --git a/src/Sqlite/Extensions.fs b/src/Sqlite/Extensions.fs index 89fab23..3416614 100644 --- a/src/Sqlite/Extensions.fs +++ b/src/Sqlite/Extensions.fs @@ -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 [] - 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 [] @@ -169,8 +169,8 @@ type SqliteConnectionCSharpExtensions = /// Determine if a document exists using a comparison on a JSON field [] - 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 [] @@ -184,13 +184,13 @@ type SqliteConnectionCSharpExtensions = /// Retrieve documents via a comparison on a JSON field [] - 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 [] - 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 [] @@ -209,8 +209,8 @@ type SqliteConnectionCSharpExtensions = /// Patch documents using a comparison on a JSON field [] - 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 [] @@ -219,8 +219,8 @@ type SqliteConnectionCSharpExtensions = /// Remove a field from a document via a comparison on a JSON field in the document [] - 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 [] @@ -229,5 +229,5 @@ type SqliteConnectionCSharpExtensions = /// Delete documents by matching a comparison on a JSON field [] - 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 diff --git a/src/Sqlite/Library.fs b/src/Sqlite/Library.fs index 6be811e..86b4ee6 100644 --- a/src/Sqlite/Library.fs +++ b/src/Sqlite/Library.fs @@ -12,7 +12,7 @@ module Configuration = /// Register a connection string to use for query execution (enables foreign keys) [] 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 [] - 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 [] @@ -257,8 +257,8 @@ module WithConn = /// Determine if a document exists using a comparison on a JSON field [] - 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 [] @@ -284,23 +284,31 @@ module WithConn = /// 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 - 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 [] - 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 [] @@ -331,9 +339,11 @@ module WithConn = /// Patch documents using a comparison on a JSON field [] - 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 [] @@ -346,10 +356,10 @@ module WithConn = /// Remove a field from a document via a comparison on a JSON field in the document [] - 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 [] - 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 [] - 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 [] @@ -470,9 +480,9 @@ module Exists = /// Determine if a document exists using a comparison on a JSON field [] - 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 [] @@ -502,25 +512,25 @@ module Find = /// 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 - 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 [] - 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 [] @@ -555,9 +565,9 @@ module Patch = /// Patch documents using a comparison on a JSON field in the WHERE clause [] - 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 [] @@ -571,9 +581,9 @@ module RemoveField = /// Remove a field from a document via a comparison on a JSON field in the document [] - 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 [] @@ -587,6 +597,6 @@ module Delete = /// Delete documents by matching a comparison on a JSON field [] - 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 diff --git a/src/Tests.CSharp/CommonCSharpTests.cs b/src/Tests.CSharp/CommonCSharpTests.cs index c75d2ba..7f989d9 100644 --- a/src/Tests.CSharp/CommonCSharpTests.cs +++ b/src/Tests.CSharp/CommonCSharpTests.cs @@ -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", () => diff --git a/src/Tests.CSharp/SqliteCSharpExtensionTests.cs b/src/Tests.CSharp/SqliteCSharpExtensionTests.cs index 89e2178..cc5061d 100644 --- a/src/Tests.CSharp/SqliteCSharpExtensionTests.cs +++ b/src/Tests.CSharp/SqliteCSharpExtensionTests.cs @@ -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(SqliteDb.TableName, "NumValue", Op.GT, 15); + var docs = await conn.FindByField(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(SqliteDb.TableName, "Value", Op.EQ, "mauve"); + var docs = await conn.FindByField(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(SqliteDb.TableName, "Value", Op.EQ, "another"); + var doc = await conn.FindFirstByField(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(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green"); + var doc = await conn.FindFirstByField(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(SqliteDb.TableName, "Value", Op.EQ, "absent"); + var doc = await conn.FindFirstByField(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(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"); }) diff --git a/src/Tests.CSharp/SqliteCSharpTests.cs b/src/Tests.CSharp/SqliteCSharpTests.cs index cd7440d..c86cc07 100644 --- a/src/Tests.CSharp/SqliteCSharpTests.cs +++ b/src/Tests.CSharp/SqliteCSharpTests.cs @@ -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(SqliteDb.TableName, "NumValue", Op.GT, 15); + var docs = await Find.ByField(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(SqliteDb.TableName, "Value", Op.EQ, "mauve"); + var docs = await Find.ByField(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(SqliteDb.TableName, "Value", Op.EQ, "another"); + var doc = await Find.FirstByField(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(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green"); + var doc = await Find.FirstByField(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(SqliteDb.TableName, "Value", Op.EQ, "absent"); + var doc = await Find.FirstByField(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(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"); }) diff --git a/src/Tests/SqliteExtensionTests.fs b/src/Tests/SqliteExtensionTests.fs index b7586e3..ee89a9b 100644 --- a/src/Tests/SqliteExtensionTests.fs +++ b/src/Tests/SqliteExtensionTests.fs @@ -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 SqliteDb.TableName "Sub.Foo" EQ "green" + let! docs = conn.findByField 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 SqliteDb.TableName "Value" EQ "mauve" + let! docs = conn.findByField 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 SqliteDb.TableName "Value" EQ "another" + let! doc = conn.findFirstByField 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 SqliteDb.TableName "Sub.Foo" EQ "green" + let! doc = conn.findFirstByField 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 SqliteDb.TableName "Value" EQ "absent" + let! doc = conn.findFirstByField 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 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" } diff --git a/src/Tests/SqliteTests.fs b/src/Tests/SqliteTests.fs index 613d0ac..3f09467 100644 --- a/src/Tests/SqliteTests.fs +++ b/src/Tests/SqliteTests.fs @@ -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 SqliteDb.TableName "NumValue" GT 15 + let! docs = Find.byField 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 SqliteDb.TableName "NumValue" GT 100 + let! docs = Find.byField 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 SqliteDb.TableName "Value" EQ "another" + let! doc = Find.firstByField 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 SqliteDb.TableName "Sub.Foo" EQ "green" + let! doc = Find.firstByField 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 SqliteDb.TableName "Value" EQ "absent" + let! doc = Find.firstByField 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 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" }