V3 rc2 #2

Merged
danieljsummers merged 6 commits from v3-rc2 into main 2024-01-24 02:23:24 +00:00
5 changed files with 196 additions and 0 deletions
Showing only changes of commit 7ac174350c - Show all commits

View File

@ -88,6 +88,14 @@ module Extensions =
member conn.patchByField tableName fieldName op (value: obj) (patch: 'TPatch) = member conn.patchByField tableName fieldName op (value: obj) (patch: 'TPatch) =
WithConn.Patch.byField tableName fieldName op value patch conn WithConn.Patch.byField tableName fieldName op value 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
/// Delete a document by its ID /// Delete a document by its ID
member conn.deleteById tableName (docId: 'TKey) = member conn.deleteById tableName (docId: 'TKey) =
WithConn.Delete.byId tableName docId conn WithConn.Delete.byId tableName docId conn
@ -204,6 +212,16 @@ type SqliteConnectionCSharpExtensions =
static member inline PatchByField<'TPatch>(conn, tableName, fieldName, op, value: obj, patch: 'TPatch) = static member inline PatchByField<'TPatch>(conn, tableName, fieldName, op, value: obj, patch: 'TPatch) =
WithConn.Patch.byField tableName fieldName op value patch conn WithConn.Patch.byField tableName fieldName op value patch conn
/// Remove a field from a document by the document's ID
[<Extension>]
static member inline RemoveFieldById<'TKey>(conn, 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
[<Extension>]
static member inline RemoveFieldByField(conn, tableName, whereFieldName, op, value: obj, removeFieldName) =
WithConn.RemoveField.byField tableName whereFieldName op value removeFieldName conn
/// Delete a document by its ID /// Delete a document by its ID
[<Extension>] [<Extension>]
static member inline DeleteById<'TKey>(conn, tableName, docId: 'TKey) = static member inline DeleteById<'TKey>(conn, tableName, docId: 'TKey) =

View File

@ -467,6 +467,68 @@ public static class SqliteCSharpExtensionTests
await conn.PatchByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" }); await conn.PatchByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
}) })
}), }),
TestList("RemoveFieldById", new[]
{
TestCase("succeeds when a field is removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.RemoveFieldById(SqliteDb.TableName, "two", "Sub");
var updated = await Find.ById<string, JsonDocument>(SqliteDb.TableName, "two");
Expect.isNotNull(updated, "The updated document should have been retrieved");
Expect.isNull(updated.Sub, "The sub-document should have been removed");
}),
TestCase("succeeds when a field is not removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
// This not raising an exception is the test
await conn.RemoveFieldById(SqliteDb.TableName, "two", "AFieldThatIsNotThere");
}),
TestCase("succeeds when no document is matched", async () =>
{
await using var db = await SqliteDb.BuildDb();
await using var conn = Sqlite.Configuration.DbConn();
// This not raising an exception is the test
await conn.RemoveFieldById(SqliteDb.TableName, "two", "Value");
})
}),
TestList("RemoveFieldByField", new[]
{
TestCase("succeeds when a field is removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
await conn.RemoveFieldByField(SqliteDb.TableName, "NumValue", Op.EQ, 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");
}),
TestCase("succeeds when a field is not removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs();
// This not raising an exception is the test
await conn.RemoveFieldByField(SqliteDb.TableName, "NumValue", Op.EQ, 17, "Nothing");
}),
TestCase("succeeds when no document is matched", async () =>
{
await using var db = await SqliteDb.BuildDb();
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");
})
}),
TestList("DeleteById", new[] TestList("DeleteById", new[]
{ {
TestCase("succeeds when a document is deleted", async () => TestCase("succeeds when a document is deleted", async () =>

View File

@ -585,6 +585,34 @@ public static class SqliteCSharpTests
// This not raising an exception is the test // This not raising an exception is the test
await RemoveField.ById(SqliteDb.TableName, "two", "Value"); await RemoveField.ById(SqliteDb.TableName, "two", "Value");
}) })
}),
TestList("ByField", new[]
{
TestCase("succeeds when a field is removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
await RemoveField.ByField(SqliteDb.TableName, "NumValue", Op.EQ, 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");
}),
TestCase("succeeds when a field is not removed", async () =>
{
await using var db = await SqliteDb.BuildDb();
await LoadDocs();
// This not raising an exception is the test
await RemoveField.ByField(SqliteDb.TableName, "NumValue", Op.EQ, 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");
})
}) })
}), }),
TestList("Delete", new[] TestList("Delete", new[]

View File

@ -1,5 +1,6 @@
module SqliteExtensionTests module SqliteExtensionTests
open System.Text.Json
open BitBadger.Documents open BitBadger.Documents
open BitBadger.Documents.Sqlite open BitBadger.Documents.Sqlite
open BitBadger.Documents.Tests open BitBadger.Documents.Tests
@ -344,6 +345,66 @@ let integrationTests =
do! conn.patchByField SqliteDb.TableName "Value" EQ "burgundy" {| Foo = "green" |} do! conn.patchByField SqliteDb.TableName "Value" EQ "burgundy" {| Foo = "green" |}
} }
] ]
testList "removeFieldById" [
testTask "succeeds when a field is removed" {
use! db = SqliteDb.BuildDb()
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.removeFieldById SqliteDb.TableName "two" "Sub"
try
let! _ = conn.findById<string, JsonDocument> SqliteDb.TableName "two"
Expect.isTrue false "The updated document should have failed to parse"
with
| :? JsonException -> ()
| exn as ex -> Expect.isTrue false $"Threw {ex.GetType().Name} ({ex.Message})"
}
testTask "succeeds when a field is not removed" {
use! db = SqliteDb.BuildDb()
use conn = Configuration.dbConn ()
do! loadDocs ()
// This not raising an exception is the test
do! conn.removeFieldById SqliteDb.TableName "two" "AFieldThatIsNotThere"
}
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.removeFieldById SqliteDb.TableName "two" "Value"
}
]
testList "removeFieldByField" [
testTask "succeeds when a field is removed" {
use! db = SqliteDb.BuildDb()
use conn = Configuration.dbConn ()
do! loadDocs ()
do! conn.removeFieldByField SqliteDb.TableName "NumValue" EQ 17 "Sub"
try
let! _ = conn.findById<string, JsonDocument> SqliteDb.TableName "four"
Expect.isTrue false "The updated document should have failed to parse"
with
| :? JsonException -> ()
| exn as ex -> Expect.isTrue false $"Threw {ex.GetType().Name} ({ex.Message})"
}
testTask "succeeds when a field is not removed" {
use! db = SqliteDb.BuildDb()
use conn = Configuration.dbConn ()
do! loadDocs ()
// This not raising an exception is the test
do! conn.removeFieldByField SqliteDb.TableName "NumValue" EQ 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"
}
]
testList "deleteById" [ testList "deleteById" [
testTask "succeeds when a document is deleted" { testTask "succeeds when a document is deleted" {
use! db = SqliteDb.BuildDb() use! db = SqliteDb.BuildDb()

View File

@ -532,6 +532,33 @@ let integrationTests =
do! RemoveField.byId SqliteDb.TableName "two" "Value" do! RemoveField.byId SqliteDb.TableName "two" "Value"
} }
] ]
testList "byField" [
testTask "succeeds when a field is removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! RemoveField.byField SqliteDb.TableName "NumValue" EQ 17 "Sub"
try
let! _ = Find.byId<string, JsonDocument> SqliteDb.TableName "four"
Expect.isTrue false "The updated document should have failed to parse"
with
| :? JsonException -> ()
| exn as ex -> Expect.isTrue false $"Threw {ex.GetType().Name} ({ex.Message})"
}
testTask "succeeds when a field is not removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveField.byField SqliteDb.TableName "NumValue" EQ 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"
}
]
] ]
testList "Delete" [ testList "Delete" [
testList "byId" [ testList "byId" [