V3 rc2 #2
|
@ -53,6 +53,21 @@ module Query =
|
|||
sprintf
|
||||
"UPDATE %s SET data = json_patch(data, json(@data)) WHERE %s"
|
||||
tableName (Query.whereByField fieldName op "@field")
|
||||
|
||||
/// Queries to remove a field from a document
|
||||
module RemoveField =
|
||||
|
||||
/// Query to remove a field from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""UPDATE %s{tableName} SET data = json_remove(data, @name) WHERE {Query.whereById "@id"}"""
|
||||
|
||||
/// Query to remove a field from a document via a comparison on a JSON field within the document
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName fieldName op =
|
||||
sprintf
|
||||
"UPDATE %s SET data = json_remove(data, @name) WHERE %s"
|
||||
tableName (Query.whereByField fieldName op "@field")
|
||||
|
||||
|
||||
/// Parameter handling helpers
|
||||
|
@ -74,6 +89,11 @@ module Parameters =
|
|||
let fieldParam (value: obj) =
|
||||
SqliteParameter("@field", value)
|
||||
|
||||
/// Create a JSON field name parameter (name "@name")
|
||||
[<CompiledName "FieldName">]
|
||||
let fieldNameParam name =
|
||||
SqliteParameter("@name", $"$.%s{name}")
|
||||
|
||||
/// An empty parameter sequence
|
||||
[<CompiledName "None">]
|
||||
let noParams =
|
||||
|
@ -315,6 +335,23 @@ module WithConn =
|
|||
Custom.nonQuery
|
||||
(Query.Patch.byField tableName fieldName op) [ fieldParam value; jsonParam "@data" patch ] conn
|
||||
|
||||
/// Commands to remove fields from documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module RemoveField =
|
||||
|
||||
/// Remove a field from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) fieldName conn =
|
||||
Custom.nonQuery (Query.RemoveField.byId tableName) [ idParam docId; fieldNameParam fieldName ] conn
|
||||
|
||||
/// 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 =
|
||||
Custom.nonQuery
|
||||
(Query.RemoveField.byField tableName whereFieldName op)
|
||||
[ fieldParam value; fieldNameParam removeFieldName ]
|
||||
conn
|
||||
|
||||
/// Commands to delete documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module Delete =
|
||||
|
@ -522,6 +559,22 @@ module Patch =
|
|||
use conn = Configuration.dbConn ()
|
||||
WithConn.Patch.byField tableName fieldName op value patch conn
|
||||
|
||||
/// Commands to remove fields from documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module RemoveField =
|
||||
|
||||
/// Remove a field from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) fieldName =
|
||||
use conn = Configuration.dbConn ()
|
||||
WithConn.RemoveField.byId tableName docId fieldName conn
|
||||
|
||||
/// 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 =
|
||||
use conn = Configuration.dbConn ()
|
||||
WithConn.RemoveField.byField tableName whereFieldName op value removeFieldName conn
|
||||
|
||||
/// Commands to delete documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module Delete =
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Expecto.CSharp;
|
||||
using System.Text.Json;
|
||||
using Expecto.CSharp;
|
||||
using Expecto;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.FSharp.Core;
|
||||
|
@ -40,6 +41,21 @@ public static class SqliteCSharpTests
|
|||
"UPDATE partial by JSON comparison query not correct");
|
||||
})
|
||||
}),
|
||||
TestList("RemoveField", new[]
|
||||
{
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.RemoveField.ById("tbl"),
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data ->> 'Id' = @id",
|
||||
"Remove field by ID query not correct");
|
||||
}),
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.RemoveField.ByField("tbl", "Fly", Op.LT),
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data ->> 'Fly' < @field",
|
||||
"Remove field by field query not correct");
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Parameters", new[]
|
||||
{
|
||||
|
@ -540,6 +556,37 @@ public static class SqliteCSharpTests
|
|||
})
|
||||
})
|
||||
}),
|
||||
TestList("RemoveField", new[]
|
||||
{
|
||||
TestList("ById", new[]
|
||||
{
|
||||
TestCase("succeeds when a field is removed", async () =>
|
||||
{
|
||||
await using var db = await SqliteDb.BuildDb();
|
||||
await LoadDocs();
|
||||
|
||||
await RemoveField.ById(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 LoadDocs();
|
||||
|
||||
// This not raising an exception is the test
|
||||
await RemoveField.ById(SqliteDb.TableName, "two", "AFieldThatIsNotThere");
|
||||
}),
|
||||
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.ById(SqliteDb.TableName, "two", "Value");
|
||||
})
|
||||
})
|
||||
}),
|
||||
TestList("Delete", new[]
|
||||
{
|
||||
TestList("ById", new[]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
module SqliteTests
|
||||
|
||||
open System.Text.Json
|
||||
open BitBadger.Documents
|
||||
open BitBadger.Documents.Sqlite
|
||||
open BitBadger.Documents.Tests
|
||||
|
@ -31,6 +32,20 @@ let unitTests =
|
|||
"UPDATE partial by JSON comparison query not correct"
|
||||
}
|
||||
]
|
||||
testList "RemoveField" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveField.byId "tbl")
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data ->> 'Id' = @id"
|
||||
"Remove field by ID query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveField.byField "tbl" "Fly" GT)
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data ->> 'Fly' > @field"
|
||||
"Remove field by field query not correct"
|
||||
}
|
||||
]
|
||||
]
|
||||
testList "Parameters" [
|
||||
test "idParam succeeds" {
|
||||
|
@ -489,6 +504,35 @@ let integrationTests =
|
|||
}
|
||||
]
|
||||
]
|
||||
testList "RemoveField" [
|
||||
testList "byId" [
|
||||
testTask "succeeds when a field is removed" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
do! loadDocs ()
|
||||
|
||||
do! RemoveField.byId SqliteDb.TableName "two" "Sub"
|
||||
try
|
||||
let! _ = Find.byId<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()
|
||||
do! loadDocs ()
|
||||
|
||||
// This not raising an exception is the test
|
||||
do! RemoveField.byId SqliteDb.TableName "two" "AFieldThatIsNotThere"
|
||||
}
|
||||
testTask "succeeds when no document is matched" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
|
||||
// This not raising an exception is the test
|
||||
do! RemoveField.byId SqliteDb.TableName "two" "Value"
|
||||
}
|
||||
]
|
||||
]
|
||||
testList "Delete" [
|
||||
testList "byId" [
|
||||
testTask "succeeds when a document is deleted" {
|
||||
|
|
Loading…
Reference in New Issue
Block a user