v3 RC1 #1

Merged
danieljsummers merged 25 commits from merge-projects into main 2024-01-06 20:51:49 +00:00
10 changed files with 225 additions and 230 deletions
Showing only changes of commit d9e37445a8 - Show all commits

View File

@ -163,6 +163,11 @@ module Query =
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data ->> '%s')) DO UPDATE SET data = EXCLUDED.data" "INSERT INTO %s VALUES (@data) ON CONFLICT ((data ->> '%s')) DO UPDATE SET data = EXCLUDED.data"
tableName (Configuration.idField ()) tableName (Configuration.idField ())
/// Query to update a document
[<CompiledName "Update">]
let update tableName =
$"""UPDATE %s{tableName} SET data = @data WHERE {whereById "@id"}"""
/// Queries for counting documents /// Queries for counting documents
module Count = module Count =
@ -202,14 +207,6 @@ module Query =
let byField tableName fieldName op = let byField tableName fieldName op =
$"""{selectFromTable tableName} WHERE {whereByField fieldName op "@field"}""" $"""{selectFromTable tableName} WHERE {whereByField fieldName op "@field"}"""
/// Queries to update documents
module Update =
/// Query to update a document
[<CompiledName "Full">]
let full tableName =
$"""UPDATE %s{tableName} SET data = @data WHERE {whereById "@id"}"""
/// Queries to delete documents /// Queries to delete documents
module Delete = module Delete =

View File

@ -109,29 +109,29 @@ module Extensions =
member conn.findFirstByJsonPath<'TDoc> tableName jsonPath = member conn.findFirstByJsonPath<'TDoc> tableName jsonPath =
WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn) WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
/// Update a full document /// Update an entire document by its ID
member conn.updateFull tableName (docId: 'TKey) (document: 'TDoc) = member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
WithProps.Update.full tableName docId document (Sql.existingConnection conn) WithProps.Update.byId tableName docId document (Sql.existingConnection conn)
/// Update a full document /// Update an entire document by its ID, using the provided function to obtain the ID from the document
member conn.updateFullFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) = member conn.updateByFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) =
WithProps.Update.fullFunc tableName idFunc document (Sql.existingConnection conn) WithProps.Update.byFunc tableName idFunc document (Sql.existingConnection conn)
/// Update a partial document /// Patch a document by its ID
member conn.updatePartialById tableName (docId: 'TKey) (partial: 'TPartial) = member conn.patchById tableName (docId: 'TKey) (patch: 'TPatch) =
WithProps.Update.partialById tableName docId partial (Sql.existingConnection conn) WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn)
/// Update partial documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
member conn.updatePartialByField tableName fieldName op (value: obj) (partial: 'TPartial) = member conn.patchByField tableName fieldName op (value: obj) (patch: 'TPatch) =
WithProps.Update.partialByField tableName fieldName op value partial (Sql.existingConnection conn) WithProps.Patch.byField tableName fieldName op value patch (Sql.existingConnection conn)
/// Update partial documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON containment query in the WHERE clause (@>)
member conn.updatePartialByContains tableName (criteria: 'TCriteria) (partial: 'TPartial) = member conn.patchByContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
WithProps.Update.partialByContains tableName criteria partial (Sql.existingConnection conn) WithProps.Patch.byContains tableName criteria patch (Sql.existingConnection conn)
/// Update partial documents using a JSON Path match query in the WHERE clause (@?) /// Patch documents using a JSON Path match query in the WHERE clause (@?)
member conn.updatePartialByJsonPath tableName jsonPath (partial: 'TPartial) = member conn.patchByJsonPath tableName jsonPath (patch: 'TPatch) =
WithProps.Update.partialByJsonPath tableName jsonPath partial (Sql.existingConnection conn) WithProps.Patch.byJsonPath tableName jsonPath patch (Sql.existingConnection 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) =
@ -282,35 +282,35 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null>(conn, tableName, jsonPath) = static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null>(conn, tableName, jsonPath) =
WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn) WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
/// Update a full document /// Update an entire document by its ID
[<Extension>] [<Extension>]
static member inline UpdateFull(conn, tableName, docId: 'TKey, document: 'TDoc) = static member inline UpdateById(conn, tableName, docId: 'TKey, document: 'TDoc) =
WithProps.Update.full tableName docId document (Sql.existingConnection conn) WithProps.Update.byId tableName docId document (Sql.existingConnection conn)
/// Update a full document /// Update an entire document by its ID, using the provided function to obtain the ID from the document
[<Extension>] [<Extension>]
static member inline UpdateFullFunc(conn, tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) = static member inline UpdateByFunc(conn, tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
WithProps.Update.FullFunc(tableName, idFunc, document, Sql.existingConnection conn) WithProps.Update.ByFunc(tableName, idFunc, document, Sql.existingConnection conn)
/// Update a partial document /// Patch a document by its ID
[<Extension>] [<Extension>]
static member inline UpdatePartialById(conn, tableName, docId: 'TKey, partial: 'TPartial) = static member inline PatchById(conn, tableName, docId: 'TKey, patch: 'TPatch) =
WithProps.Update.partialById tableName docId partial (Sql.existingConnection conn) WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn)
/// Update partial documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<Extension>] [<Extension>]
static member inline UpdatePartialByField(conn, tableName, fieldName, op, value: obj, partial: 'TPartial) = static member inline PatchByField(conn, tableName, fieldName, op, value: obj, patch: 'TPatch) =
WithProps.Update.partialByField tableName fieldName op value partial (Sql.existingConnection conn) WithProps.Patch.byField tableName fieldName op value patch (Sql.existingConnection conn)
/// Update partial documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON containment query in the WHERE clause (@>)
[<Extension>] [<Extension>]
static member inline UpdatePartialByContains(conn, tableName, criteria: 'TCriteria, partial: 'TPartial) = static member inline PatchByContains(conn, tableName, criteria: 'TCriteria, patch: 'TPatch) =
WithProps.Update.partialByContains tableName criteria partial (Sql.existingConnection conn) WithProps.Patch.byContains tableName criteria patch (Sql.existingConnection conn)
/// Update partial documents using a JSON Path match query in the WHERE clause (@?) /// Patch documents using a JSON Path match query in the WHERE clause (@?)
[<Extension>] [<Extension>]
static member inline UpdatePartialByJsonPath(conn, tableName, jsonPath, partial: 'TPartial) = static member inline PatchByJsonPath(conn, tableName, jsonPath, patch: 'TPatch) =
WithProps.Update.partialByJsonPath tableName jsonPath partial (Sql.existingConnection conn) WithProps.Patch.byJsonPath tableName jsonPath patch (Sql.existingConnection conn)
/// Delete a document by its ID /// Delete a document by its ID
[<Extension>] [<Extension>]

View File

@ -142,27 +142,27 @@ module Query =
let byJsonPath tableName = let byJsonPath tableName =
$"""{Query.selectFromTable tableName} WHERE {whereJsonPathMatches "@path"}""" $"""{Query.selectFromTable tableName} WHERE {whereJsonPathMatches "@path"}"""
/// Queries to update documents /// Queries to patch (partially update) documents
module Update = module Patch =
/// Query to update a document /// Query to patch a document by its ID
[<CompiledName "PartialById">] [<CompiledName "ById">]
let partialById tableName = let byId tableName =
$"""UPDATE %s{tableName} SET data = data || @data WHERE {Query.whereById "@id"}""" $"""UPDATE %s{tableName} SET data = data || @data WHERE {Query.whereById "@id"}"""
/// Query to update a document /// Query to patch documents match a JSON field comparison (->> =)
[<CompiledName "PartialByField">] [<CompiledName "ByField">]
let partialByField tableName fieldName op = let byField tableName fieldName op =
$"""UPDATE %s{tableName} SET data = data || @data WHERE {Query.whereByField fieldName op "@field"}""" $"""UPDATE %s{tableName} SET data = data || @data WHERE {Query.whereByField fieldName op "@field"}"""
/// Query to update partial documents matching a JSON containment query (@>) /// Query to patch documents matching a JSON containment query (@>)
[<CompiledName "PartialByContains">] [<CompiledName "ByContains">]
let partialByContains tableName = let byContains tableName =
$"""UPDATE %s{tableName} SET data = data || @data WHERE {whereDataContains "@criteria"}""" $"""UPDATE %s{tableName} SET data = data || @data WHERE {whereDataContains "@criteria"}"""
/// Query to update partial documents matching a JSON containment query (@>) /// Query to patch documents matching a JSON containment query (@>)
[<CompiledName "PartialByJsonPath">] [<CompiledName "ByJsonPath">]
let partialByJsonPath tableName = let byJsonPath tableName =
$"""UPDATE %s{tableName} SET data = data || @data WHERE {whereJsonPathMatches "@path"}""" $"""UPDATE %s{tableName} SET data = data || @data WHERE {whereJsonPathMatches "@path"}"""
/// Queries to delete documents /// Queries to delete documents
@ -436,48 +436,46 @@ module WithProps =
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module Update = module Update =
/// Update an entire document /// Update an entire document by its ID
[<CompiledName "Full">] [<CompiledName "ById">]
let full tableName (docId: 'TKey) (document: 'TDoc) sqlProps = let byId tableName (docId: 'TKey) (document: 'TDoc) sqlProps =
Custom.nonQuery (Query.Update.full tableName) [ idParam docId; jsonParam "@data" document ] sqlProps Custom.nonQuery (Query.update tableName) [ idParam docId; jsonParam "@data" document ] sqlProps
/// Update an entire document /// Update an entire document by its ID, using the provided function to obtain the ID from the document
[<CompiledName "FSharpFullFunc">] [<CompiledName "FSharpByFunc">]
let fullFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) sqlProps = let byFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) sqlProps =
full tableName (idFunc document) document sqlProps byId tableName (idFunc document) document sqlProps
/// Update an entire document /// Update an entire document by its ID, using the provided function to obtain the ID from the document
let FullFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc, sqlProps) = let ByFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc, sqlProps) =
fullFunc tableName idFunc.Invoke document sqlProps byFunc tableName idFunc.Invoke document sqlProps
/// Commands to patch (partially update) documents
[<RequireQualifiedAccess>]
module Patch =
/// Update a partial document /// Patch a document by its ID
[<CompiledName "PartialById">] [<CompiledName "ById">]
let partialById tableName (docId: 'TKey) (partial: 'TPartial) sqlProps = let byId tableName (docId: 'TKey) (patch: 'TPatch) sqlProps =
Custom.nonQuery (Query.Update.partialById tableName) [ idParam docId; jsonParam "@data" partial ] sqlProps Custom.nonQuery (Query.Patch.byId tableName) [ idParam docId; jsonParam "@data" patch ] sqlProps
/// Update partial documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "PartialByField">] [<CompiledName "ByField">]
let partialByField tableName fieldName op (value: obj) (partial: 'TPartial) sqlProps = let byField tableName fieldName op (value: obj) (patch: 'TPatch) sqlProps =
Custom.nonQuery Custom.nonQuery
(Query.Update.partialByField tableName fieldName op) (Query.Patch.byField tableName fieldName op) [ jsonParam "@data" patch; fieldParam value ] sqlProps
[ jsonParam "@data" partial; fieldParam value ]
sqlProps
/// Update partial documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON containment query in the WHERE clause (@>)
[<CompiledName "PartialByContains">] [<CompiledName "ByContains">]
let partialByContains tableName (criteria: 'TContains) (partial: 'TPartial) sqlProps = let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps =
Custom.nonQuery Custom.nonQuery
(Query.Update.partialByContains tableName) (Query.Patch.byContains tableName) [ jsonParam "@data" patch; jsonParam "@criteria" criteria ] sqlProps
[ jsonParam "@data" partial; jsonParam "@criteria" criteria ]
sqlProps
/// Update partial documents using a JSON Path match query in the WHERE clause (@?) /// Patch documents using a JSON Path match query in the WHERE clause (@?)
[<CompiledName "PartialByJsonPath">] [<CompiledName "ByJsonPath">]
let partialByJsonPath tableName jsonPath (partial: 'TPartial) sqlProps = let byJsonPath tableName jsonPath (patch: 'TPatch) sqlProps =
Custom.nonQuery Custom.nonQuery
(Query.Update.partialByJsonPath tableName) (Query.Patch.byJsonPath tableName) [ jsonParam "@data" patch; "@path", Sql.string jsonPath ] sqlProps
[ jsonParam "@data" partial; "@path", Sql.string jsonPath ]
sqlProps
/// Commands to delete documents /// Commands to delete documents
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
@ -707,39 +705,44 @@ module Find =
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module Update = module Update =
/// Update a full document /// Update an entire document by its ID
[<CompiledName "Full">] [<CompiledName "ById">]
let full tableName (docId: 'TKey) (document: 'TDoc) = let byId tableName (docId: 'TKey) (document: 'TDoc) =
WithProps.Update.full tableName docId document (fromDataSource ()) WithProps.Update.byId tableName docId document (fromDataSource ())
/// Update a full document /// Update an entire document by its ID, using the provided function to obtain the ID from the document
[<CompiledName "FSharpFullFunc">] [<CompiledName "FSharpFullFunc">]
let fullFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) = let byFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) =
WithProps.Update.fullFunc tableName idFunc document (fromDataSource ()) WithProps.Update.byFunc tableName idFunc document (fromDataSource ())
/// Update an entire document by its ID, using the provided function to obtain the ID from the document
let ByFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
WithProps.Update.ByFunc(tableName, idFunc, document, fromDataSource ())
/// Update a full document
let FullFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
WithProps.Update.FullFunc(tableName, idFunc, document, fromDataSource ())
/// Update a partial document /// Commands to patch (partially update) documents
[<CompiledName "PartialById">] [<RequireQualifiedAccess>]
let partialById tableName (docId: 'TKey) (partial: 'TPartial) = module Patch =
WithProps.Update.partialById tableName docId partial (fromDataSource ())
/// Update partial documents using a JSON field comparison query in the WHERE clause (->> =) /// Patch a document by its ID
[<CompiledName "PartialByField">] [<CompiledName "ById">]
let partialByField tableName fieldName op (value: obj) (partial: 'TPartial) = let byId tableName (docId: 'TKey) (patch: 'TPatch) =
WithProps.Update.partialByField tableName fieldName op value partial (fromDataSource ()) WithProps.Patch.byId tableName docId patch (fromDataSource ())
/// Update partial documents using a JSON containment query in the WHERE clause (@>) /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
[<CompiledName "PartialByContains">] [<CompiledName "ByField">]
let partialByContains tableName (criteria: 'TCriteria) (partial: 'TPartial) = let byField tableName fieldName op (value: obj) (patch: 'TPatch) =
WithProps.Update.partialByContains tableName criteria partial (fromDataSource ()) WithProps.Patch.byField tableName fieldName op value patch (fromDataSource ())
/// Update partial documents using a JSON Path match query in the WHERE clause (@?) /// Patch documents using a JSON containment query in the WHERE clause (@>)
[<CompiledName "PartialByJsonPath">] [<CompiledName "ByContains">]
let partialByJsonPath tableName jsonPath (partial: 'TPartial) = let byContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
WithProps.Update.partialByJsonPath tableName jsonPath partial (fromDataSource ()) WithProps.Patch.byContains tableName criteria patch (fromDataSource ())
/// Patch documents using a JSON Path match query in the WHERE clause (@?)
[<CompiledName "ByJsonPath">]
let byJsonPath tableName jsonPath (patch: 'TPatch) =
WithProps.Patch.byJsonPath tableName jsonPath patch (fromDataSource ())
/// Commands to delete documents /// Commands to delete documents

View File

@ -298,7 +298,7 @@ module WithConn =
/// Update an entire document /// Update an entire document
[<CompiledName "Full">] [<CompiledName "Full">]
let full tableName (docId: 'TKey) (document: 'TDoc) conn = let full tableName (docId: 'TKey) (document: 'TDoc) conn =
Custom.nonQuery (Query.Update.full tableName) [ idParam docId; jsonParam "@data" document ] conn Custom.nonQuery (Query.update tableName) [ idParam docId; jsonParam "@data" document ] conn
/// Update an entire document /// Update an entire document
[<CompiledName "FSharpFullFunc">] [<CompiledName "FSharpFullFunc">]

View File

@ -172,6 +172,11 @@ public static class CommonCSharpTests
$"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data", $"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data",
"INSERT ON CONFLICT UPDATE statement not correct"); "INSERT ON CONFLICT UPDATE statement not correct");
}), }),
TestCase("Update succeeds", () =>
{
Expect.equal(Query.Update("tbl"), "UPDATE tbl SET data = @data WHERE data ->> 'Id' = @id",
"UPDATE full statement not correct");
}),
TestList("Count", new[] TestList("Count", new[]
{ {
TestCase("All succeeds", () => TestCase("All succeeds", () =>
@ -214,11 +219,6 @@ public static class CommonCSharpTests
"SELECT by JSON comparison query not correct"); "SELECT by JSON comparison query not correct");
}) })
}), }),
TestCase("Update.Full succeeds", () =>
{
Expect.equal(Query.Update.Full("tbl"), "UPDATE tbl SET data = @data WHERE data ->> 'Id' = @id",
"UPDATE full statement not correct");
}),
TestList("Delete", new[] TestList("Delete", new[]
{ {
TestCase("ById succeeds", () => TestCase("ById succeeds", () =>

View File

@ -558,7 +558,7 @@ public class PostgresCSharpExtensionTests
Expect.isNull(doc, "There should not have been a document returned"); Expect.isNull(doc, "There should not have been a document returned");
}) })
}), }),
TestList("UpdateFull", new[] TestList("UpdateById", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -566,7 +566,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdateFull(PostgresDb.TableName, "one", await conn.UpdateById(PostgresDb.TableName, "one",
new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } }); new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } });
var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
@ -585,11 +585,11 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdateFull(PostgresDb.TableName, "test", await conn.UpdateById(PostgresDb.TableName, "test",
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } }); new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
}) })
}), }),
TestList("UpdateFullFunc", new[] TestList("UpdateByFunc", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -597,7 +597,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdateFullFunc(PostgresDb.TableName, doc => doc.Id, await conn.UpdateByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
@ -614,11 +614,11 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdateFullFunc(PostgresDb.TableName, doc => doc.Id, await conn.UpdateByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
}) })
}), }),
TestList("UpdatePartialById", new[] TestList("PatchById", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -626,7 +626,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdatePartialById(PostgresDb.TableName, "one", new { NumValue = 44 }); await conn.PatchById(PostgresDb.TableName, "one", new { NumValue = 44 });
var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await conn.FindById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
Expect.equal(after.NumValue, 44, "The updated document is not correct"); Expect.equal(after.NumValue, 44, "The updated document is not correct");
@ -639,10 +639,10 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdatePartialById(PostgresDb.TableName, "test", new { Foo = "green" }); await conn.PatchById(PostgresDb.TableName, "test", new { Foo = "green" });
}) })
}), }),
TestList("UpdatePartialByField", new[] TestList("PatchByField", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -650,7 +650,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdatePartialByField(PostgresDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 }); await conn.PatchByField(PostgresDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
var after = await conn.CountByField(PostgresDb.TableName, "NumValue", Op.EQ, "77"); var after = await conn.CountByField(PostgresDb.TableName, "NumValue", Op.EQ, "77");
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -662,11 +662,10 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdatePartialByField(PostgresDb.TableName, "Value", Op.EQ, "burgundy", await conn.PatchByField(PostgresDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
new { Foo = "green" });
}) })
}), }),
TestList("UpdatePartialByContains", new[] TestList("PatchByContains", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -674,8 +673,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdatePartialByContains(PostgresDb.TableName, new { Value = "purple" }, await conn.PatchByContains(PostgresDb.TableName, new { Value = "purple" }, new { NumValue = 77 });
new { NumValue = 77 });
var after = await conn.CountByContains(PostgresDb.TableName, new { NumValue = 77 }); var after = await conn.CountByContains(PostgresDb.TableName, new { NumValue = 77 });
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -687,11 +685,10 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdatePartialByContains(PostgresDb.TableName, new { Value = "burgundy" }, await conn.PatchByContains(PostgresDb.TableName, new { Value = "burgundy" }, new { Foo = "green" });
new { Foo = "green" });
}) })
}), }),
TestList("UpdatePartialByJsonPath", new[] TestList("PatchByJsonPath", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
@ -699,8 +696,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
await conn.UpdatePartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)", await conn.PatchByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)", new { NumValue = 1000 });
new { NumValue = 1000 });
var after = await conn.CountByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)"); var after = await conn.CountByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)");
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -712,7 +708,7 @@ public class PostgresCSharpExtensionTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await conn.UpdatePartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" }); await conn.PatchByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" });
}) })
}), }),
TestList("DeleteById", new[] TestList("DeleteById", new[]

View File

@ -124,29 +124,29 @@ public class PostgresCSharpTests
"SELECT by JSON Path match query not correct"); "SELECT by JSON Path match query not correct");
}) })
}), }),
TestList("Update", new[] TestList("Patch", new[]
{ {
TestCase("partialById succeeds", () => TestCase("ById succeeds", () =>
{ {
Expect.equal(Postgres.Query.Update.PartialById(PostgresDb.TableName), Expect.equal(Postgres.Query.Patch.ById(PostgresDb.TableName),
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Id' = @id", $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Id' = @id",
"UPDATE partial by ID statement not correct"); "UPDATE partial by ID statement not correct");
}), }),
TestCase("partialByField succeeds", () => TestCase("ByField succeeds", () =>
{ {
Expect.equal(Postgres.Query.Update.PartialByField(PostgresDb.TableName, "Snail", Op.LT), Expect.equal(Postgres.Query.Patch.ByField(PostgresDb.TableName, "Snail", Op.LT),
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Snail' < @field", $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Snail' < @field",
"UPDATE partial by ID statement not correct"); "UPDATE partial by ID statement not correct");
}), }),
TestCase("partialByContains succeeds", () => TestCase("ByContains succeeds", () =>
{ {
Expect.equal(Postgres.Query.Update.PartialByContains(PostgresDb.TableName), Expect.equal(Postgres.Query.Patch.ByContains(PostgresDb.TableName),
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria", $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria",
"UPDATE partial by JSON containment statement not correct"); "UPDATE partial by JSON containment statement not correct");
}), }),
TestCase("partialByJsonPath succeeds", () => TestCase("ByJsonPath succeeds", () =>
{ {
Expect.equal(Postgres.Query.Update.PartialByJsonPath(PostgresDb.TableName), Expect.equal(Postgres.Query.Patch.ByJsonPath(PostgresDb.TableName),
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath", $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath",
"UPDATE partial by JSON Path statement not correct"); "UPDATE partial by JSON Path statement not correct");
}) })
@ -722,14 +722,14 @@ public class PostgresCSharpTests
}), }),
TestList("Update", new[] TestList("Update", new[]
{ {
TestList("Full", new[] TestList("ById", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.Full(PostgresDb.TableName, "one", await Update.ById(PostgresDb.TableName, "one",
new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } }); new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } });
var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
@ -748,18 +748,18 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.Full(PostgresDb.TableName, "test", await Update.ById(PostgresDb.TableName, "test",
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } }); new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
}) })
}), }),
TestList("FullFunc", new[] TestList("ByFunc", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.FullFunc(PostgresDb.TableName, doc => doc.Id, await Update.ByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
@ -776,18 +776,21 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.FullFunc(PostgresDb.TableName, doc => doc.Id, await Update.ByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 }); new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
}) })
}), })
TestList("PartialById", new[] }),
TestList("Patch", new[]
{
TestList("ById", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.PartialById(PostgresDb.TableName, "one", new { NumValue = 44 }); await Patch.ById(PostgresDb.TableName, "one", new { NumValue = 44 });
var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one"); var after = await Find.ById<string, JsonDocument>(PostgresDb.TableName, "one");
Expect.isNotNull(after, "There should have been a document returned post-update"); Expect.isNotNull(after, "There should have been a document returned post-update");
Expect.equal(after.NumValue, 44, "The updated document is not correct"); Expect.equal(after.NumValue, 44, "The updated document is not correct");
@ -800,17 +803,17 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.PartialById(PostgresDb.TableName, "test", new { Foo = "green" }); await Patch.ById(PostgresDb.TableName, "test", new { Foo = "green" });
}) })
}), }),
TestList("PartialByField", new[] TestList("ByField", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.PartialByField(PostgresDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 }); await Patch.ByField(PostgresDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
var after = await Count.ByField(PostgresDb.TableName, "NumValue", Op.EQ, "77"); var after = await Count.ByField(PostgresDb.TableName, "NumValue", Op.EQ, "77");
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -822,19 +825,17 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.PartialByField(PostgresDb.TableName, "Value", Op.EQ, "burgundy", await Patch.ByField(PostgresDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
new { Foo = "green" });
}) })
}), }),
TestList("PartialByContains", new[] TestList("ByContains", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.PartialByContains(PostgresDb.TableName, new { Value = "purple" }, await Patch.ByContains(PostgresDb.TableName, new { Value = "purple" }, new { NumValue = 77 });
new { NumValue = 77 });
var after = await Count.ByContains(PostgresDb.TableName, new { NumValue = 77 }); var after = await Count.ByContains(PostgresDb.TableName, new { NumValue = 77 });
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -846,19 +847,17 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.PartialByContains(PostgresDb.TableName, new { Value = "burgundy" }, await Patch.ByContains(PostgresDb.TableName, new { Value = "burgundy" }, new { Foo = "green" });
new { Foo = "green" });
}) })
}), }),
TestList("PartialByJsonPath", new[] TestList("ByJsonPath", new[]
{ {
TestCase("succeeds when a document is updated", async () => TestCase("succeeds when a document is updated", async () =>
{ {
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
await Update.PartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)", await Patch.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)", new { NumValue = 1000 });
new { NumValue = 1000 });
var after = await Count.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)"); var after = await Count.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)");
Expect.equal(after, 2, "There should have been 2 documents returned"); Expect.equal(after, 2, "There should have been 2 documents returned");
}), }),
@ -870,7 +869,7 @@ public class PostgresCSharpTests
Expect.equal(before, 0, "There should have been no documents returned"); Expect.equal(before, 0, "There should have been no documents returned");
// This not raising an exception is the test // This not raising an exception is the test
await Update.PartialByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" }); await Patch.ByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" });
}) })
}) })
}), }),

View File

@ -95,6 +95,12 @@ let all =
$"INSERT INTO {tbl} VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data" $"INSERT INTO {tbl} VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data"
"INSERT ON CONFLICT UPDATE statement not correct" "INSERT ON CONFLICT UPDATE statement not correct"
} }
test "update succeeds" {
Expect.equal
(Query.update tbl)
$"UPDATE {tbl} SET data = @data WHERE data ->> 'Id' = @id"
"UPDATE full statement not correct"
}
testList "Count" [ testList "Count" [
test "all succeeds" { test "all succeeds" {
Expect.equal (Query.Count.all tbl) $"SELECT COUNT(*) AS it FROM {tbl}" "Count query not correct" Expect.equal (Query.Count.all tbl) $"SELECT COUNT(*) AS it FROM {tbl}" "Count query not correct"
@ -134,14 +140,6 @@ let all =
"SELECT by JSON comparison query not correct" "SELECT by JSON comparison query not correct"
} }
] ]
testList "Update" [
test "full succeeds" {
Expect.equal
(Query.Update.full tbl)
$"UPDATE {tbl} SET data = @data WHERE data ->> 'Id' = @id"
"UPDATE full statement not correct"
}
]
testList "Delete" [ testList "Delete" [
test "byId succeeds" { test "byId succeeds" {
Expect.equal Expect.equal

View File

@ -486,14 +486,14 @@ let integrationTests =
Expect.isNone doc "There should not have been a document returned" Expect.isNone doc "There should not have been a document returned"
} }
] ]
testList "updateFull" [ testList "updateById" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
let testDoc = { emptyDoc with Id = "one"; Sub = Some { Foo = "blue"; Bar = "red" } } let testDoc = { emptyDoc with Id = "one"; Sub = Some { Foo = "blue"; Bar = "red" } }
do! conn.updateFull PostgresDb.TableName "one" testDoc do! conn.updateById PostgresDb.TableName "one" testDoc
let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one" let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
Expect.equal after.Value testDoc "The updated document is not correct" Expect.equal after.Value testDoc "The updated document is not correct"
@ -505,17 +505,17 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updateFull do! conn.updateById
PostgresDb.TableName "test" { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } } PostgresDb.TableName "test" { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } }
} }
] ]
testList "updateFullFunc" [ testList "updateByFunc" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
do! conn.updateFullFunc do! conn.updateByFunc
PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None } PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one" let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
@ -531,17 +531,17 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updateFullFunc do! conn.updateByFunc
PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None } PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
} }
] ]
testList "updatePartialById" [ testList "patchById" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
do! conn.updatePartialById PostgresDb.TableName "one" {| NumValue = 44 |} do! conn.patchById PostgresDb.TableName "one" {| NumValue = 44 |}
let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one" let! after = conn.findById<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
Expect.equal after.Value.NumValue 44 "The updated document is not correct" Expect.equal after.Value.NumValue 44 "The updated document is not correct"
@ -553,16 +553,16 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updatePartialById PostgresDb.TableName "test" {| Foo = "green" |} do! conn.patchById PostgresDb.TableName "test" {| Foo = "green" |}
} }
] ]
testList "updatePartialByField" [ testList "patchByField" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
do! conn.updatePartialByField PostgresDb.TableName "Value" EQ "purple" {| NumValue = 77 |} do! conn.patchByField PostgresDb.TableName "Value" EQ "purple" {| NumValue = 77 |}
let! after = conn.countByField PostgresDb.TableName "NumValue" EQ "77" let! after = conn.countByField PostgresDb.TableName "NumValue" EQ "77"
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -573,16 +573,16 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updatePartialByField PostgresDb.TableName "Value" EQ "burgundy" {| Foo = "green" |} do! conn.patchByField PostgresDb.TableName "Value" EQ "burgundy" {| Foo = "green" |}
} }
] ]
testList "updatePartialByContains" [ testList "patchByContains" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
do! conn.updatePartialByContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |} do! conn.patchByContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |}
let! after = conn.countByContains PostgresDb.TableName {| NumValue = 77 |} let! after = conn.countByContains PostgresDb.TableName {| NumValue = 77 |}
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -593,16 +593,16 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updatePartialByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |} do! conn.patchByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
} }
] ]
testList "updatePartialByJsonPath" [ testList "patchByJsonPath" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
use conn = mkConn db use conn = mkConn db
do! loadDocs conn do! loadDocs conn
do! conn.updatePartialByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |} do! conn.patchByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |}
let! after = conn.countByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)" let! after = conn.countByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)"
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -613,7 +613,7 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! conn.updatePartialByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |} do! conn.patchByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
} }
] ]
testList "deleteById" [ testList "deleteById" [

View File

@ -101,28 +101,28 @@ let unitTests =
"SELECT by JSON Path match query not correct" "SELECT by JSON Path match query not correct"
} }
] ]
testList "Update" [ testList "Patch" [
test "partialById succeeds" { test "byId succeeds" {
Expect.equal Expect.equal
(Query.Update.partialById PostgresDb.TableName) (Query.Patch.byId PostgresDb.TableName)
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Id' = @id" $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Id' = @id"
"UPDATE partial by ID statement not correct" "UPDATE partial by ID statement not correct"
} }
test "partialByField succeeds" { test "byField succeeds" {
Expect.equal Expect.equal
(Query.Update.partialByField PostgresDb.TableName "Snail" LT) (Query.Patch.byField PostgresDb.TableName "Snail" LT)
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Snail' < @field" $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data ->> 'Snail' < @field"
"UPDATE partial by ID statement not correct" "UPDATE partial by ID statement not correct"
} }
test "partialByContains succeeds" { test "byContains succeeds" {
Expect.equal Expect.equal
(Query.Update.partialByContains PostgresDb.TableName) (Query.Patch.byContains PostgresDb.TableName)
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria" $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria"
"UPDATE partial by JSON containment statement not correct" "UPDATE partial by JSON containment statement not correct"
} }
test "partialByJsonPath succeeds" { test "byJsonPath succeeds" {
Expect.equal Expect.equal
(Query.Update.partialByJsonPath PostgresDb.TableName) (Query.Patch.byJsonPath PostgresDb.TableName)
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath" $"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath"
"UPDATE partial by JSON Path statement not correct" "UPDATE partial by JSON Path statement not correct"
} }
@ -606,13 +606,13 @@ let integrationTests =
] ]
] ]
testList "Update" [ testList "Update" [
testList "full" [ testList "byId" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
let testDoc = { emptyDoc with Id = "one"; Sub = Some { Foo = "blue"; Bar = "red" } } let testDoc = { emptyDoc with Id = "one"; Sub = Some { Foo = "blue"; Bar = "red" } }
do! Update.full PostgresDb.TableName "one" testDoc do! Update.byId PostgresDb.TableName "one" testDoc
let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one" let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
Expect.equal after.Value testDoc "The updated document is not correct" Expect.equal after.Value testDoc "The updated document is not correct"
@ -624,18 +624,18 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.full do! Update.byId
PostgresDb.TableName PostgresDb.TableName
"test" "test"
{ emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } } { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } }
} }
] ]
testList "fullFunc" [ testList "byFunc" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
do! Update.fullFunc PostgresDb.TableName (_.Id) do! Update.byFunc PostgresDb.TableName (_.Id)
{ Id = "one"; Value = "le un"; NumValue = 1; Sub = None } { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one" let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
@ -651,16 +651,18 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.fullFunc do! Update.byFunc
PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None } PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
} }
] ]
testList "partialById" [ ]
testList "Patch" [
testList "byId" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
do! Update.partialById PostgresDb.TableName "one" {| NumValue = 44 |} do! Patch.byId PostgresDb.TableName "one" {| NumValue = 44 |}
let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one" let! after = Find.byId<string, JsonDocument> PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update" Expect.isSome after "There should have been a document returned post-update"
Expect.equal after.Value.NumValue 44 "The updated document is not correct" Expect.equal after.Value.NumValue 44 "The updated document is not correct"
@ -672,15 +674,15 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.partialById PostgresDb.TableName "test" {| Foo = "green" |} do! Patch.byId PostgresDb.TableName "test" {| Foo = "green" |}
} }
] ]
testList "partialByField" [ testList "byField" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
do! Update.partialByField PostgresDb.TableName "Value" EQ "purple" {| NumValue = 77 |} do! Patch.byField PostgresDb.TableName "Value" EQ "purple" {| NumValue = 77 |}
let! after = Count.byField PostgresDb.TableName "NumValue" EQ "77" let! after = Count.byField PostgresDb.TableName "NumValue" EQ "77"
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -691,15 +693,15 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.partialByField PostgresDb.TableName "Value" EQ "burgundy" {| Foo = "green" |} do! Patch.byField PostgresDb.TableName "Value" EQ "burgundy" {| Foo = "green" |}
} }
] ]
testList "partialByContains" [ testList "byContains" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
do! Update.partialByContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |} do! Patch.byContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |}
let! after = Count.byContains PostgresDb.TableName {| NumValue = 77 |} let! after = Count.byContains PostgresDb.TableName {| NumValue = 77 |}
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -710,15 +712,15 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.partialByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |} do! Patch.byContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
} }
] ]
testList "partialByJsonPath" [ testList "byJsonPath" [
testTask "succeeds when a document is updated" { testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()
do! loadDocs () do! loadDocs ()
do! Update.partialByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |} do! Patch.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |}
let! after = Count.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)" let! after = Count.byJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)"
Expect.equal after 2 "There should have been 2 documents returned" Expect.equal after 2 "There should have been 2 documents returned"
} }
@ -729,7 +731,7 @@ let integrationTests =
Expect.equal before 0 "There should have been no documents returned" Expect.equal before 0 "There should have been no documents returned"
// This not raising an exception is the test // This not raising an exception is the test
do! Update.partialByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |} do! Patch.byJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
} }
] ]
] ]