diff --git a/src/Postgres/WithProps.fs b/src/Postgres/WithProps.fs index 2acf943..f0f7c39 100644 --- a/src/Postgres/WithProps.fs +++ b/src/Postgres/WithProps.fs @@ -771,8 +771,10 @@ module Json = /// The ID of the document to retrieve /// The SqlProps to use to execute the query [] - let writeById<'TKey> tableName (writer: StreamWriter) (docId: 'TKey) sqlProps = - byId tableName docId sqlProps |> writer.Write + let writeById<'TKey> tableName (writer: StreamWriter) (docId: 'TKey) sqlProps = backgroundTask { + let! json = byId tableName docId sqlProps + do! writer.WriteAsync json + } /// Retrieve JSON documents matching JSON field comparisons (->> =, etc.) /// The table from which documents should be retrieved (may include schema) diff --git a/src/Tests.CSharp/PostgresCSharpTests.cs b/src/Tests.CSharp/PostgresCSharpTests.cs index 521676b..efc7b90 100644 --- a/src/Tests.CSharp/PostgresCSharpTests.cs +++ b/src/Tests.CSharp/PostgresCSharpTests.cs @@ -1706,6 +1706,423 @@ public static class PostgresCSharpTests [Field.Named("Sub.Bar DESC")]), "four"); }) + ]), + TestList("WriteAll", + [ + TestCase("succeeds when there is data", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteAll(PostgresDb.TableName, writer); + VerifyAllData(StreamText(stream)); + }), + TestCase("succeeds when there is no data", async () => + { + await using var db = PostgresDb.BuildDb(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteAll(PostgresDb.TableName, writer); + VerifyEmpty(StreamText(stream)); + }) + ]), + TestList("WriteAllOrdered", + [ + TestCase("succeeds when ordering numerically", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteAllOrdered(PostgresDb.TableName, writer, [Field.Named("n:NumValue")]); + VerifyExpectedOrder(StreamText(stream), "one", "three", "two", "four", "five"); + }), + TestCase("succeeds when ordering numerically descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteAllOrdered(PostgresDb.TableName, writer, [Field.Named("n:NumValue DESC")]); + VerifyExpectedOrder(StreamText(stream), "five", "four", "two", "three", "one"); + }), + TestCase("succeeds when ordering alphabetically", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteAllOrdered(PostgresDb.TableName, writer, [Field.Named("Id DESC")]); + VerifyExpectedOrder(StreamText(stream), "two", "three", "one", "four", "five"); + }) + ]), + TestList("WriteById", + [ + TestCase("succeeds when a document is found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteById(PostgresDb.TableName, writer, "two"); + var json = StreamText(stream); + Expect.stringStarts(json, """{"Id": "two",""", "An incorrect document was returned"); + Expect.stringEnds(json, "}", "JSON should have ended with this document"); + }), + TestCase("succeeds when a document is not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteById(PostgresDb.TableName, writer, "three hundred eighty-seven"); + VerifyNoDoc(StreamText(stream)); + }) + ]), + TestList("WriteByFields", + [ + TestCase("succeeds when documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFields(PostgresDb.TableName, writer, FieldMatch.All, + [Field.In("Value", ["purple", "blue"]), Field.Exists("Sub")]); + VerifySingleById(StreamText(stream), "four"); + }), + TestCase("succeeds when documents are found using IN with numeric field", async() => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFields(PostgresDb.TableName, writer, FieldMatch.All, + [Field.In("NumValue", [2, 4, 6, 8])]); + VerifySingleById(StreamText(stream), "three"); + }), + TestCase("succeeds when documents are not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFields(PostgresDb.TableName, writer, FieldMatch.All, + [Field.Equal("Value", "mauve"), Field.NotEqual("NumValue", 40)]); + VerifyEmpty(StreamText(stream)); + }), + TestCase("succeeds for InArray when matching documents exist", async () => + { + await using var db = PostgresDb.BuildDb(); + await Definition.EnsureTable(PostgresDb.TableName); + foreach (var doc in ArrayDocument.TestDocuments) await Document.Insert(PostgresDb.TableName, doc); + + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFields(PostgresDb.TableName, writer, FieldMatch.All, + [Field.InArray("Values", PostgresDb.TableName, ["c"])]); + var json = StreamText(stream); + VerifyBeginEnd(json); + VerifyDocById(json, "first"); + VerifyDocById(json, "second"); + }), + TestCase("succeeds for InArray when no matching documents exist", async () => + { + await using var db = PostgresDb.BuildDb(); + await Definition.EnsureTable(PostgresDb.TableName); + foreach (var doc in ArrayDocument.TestDocuments) await Document.Insert(PostgresDb.TableName, doc); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFields(PostgresDb.TableName, writer, FieldMatch.All, + [Field.InArray("Values", PostgresDb.TableName, ["j"])]); + VerifyEmpty(StreamText(stream)); + }) + ]), + TestList("WriteByFieldsOrdered", + [ + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.All, + [Field.Equal("Value", "purple")], [Field.Named("Id")]); + VerifyExpectedOrder(StreamText(stream), "five", "four"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.All, + [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]); + VerifyExpectedOrder(StreamText(stream), "four", "five"); + }) + ]), + TestList("WriteByContains", + [ + TestCase("succeeds when documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByContains(PostgresDb.TableName, writer, new { Sub = new { Foo = "green" } }); + var json = StreamText(stream); + VerifyBeginEnd(json); + VerifyDocById(json, "two"); + VerifyDocById(json, "four"); + }), + TestCase("succeeds when documents are not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByContains(PostgresDb.TableName, writer, new { Value = "mauve" }); + VerifyEmpty(StreamText(stream)); + }) + ]), + TestList("WriteByContainsOrdered", + [ + // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByContainsOrdered(PostgresDb.TableName, writer, new { Sub = new { Foo = "green" } }, + [Field.Named("Sub.Bar")]); + VerifyExpectedOrder(StreamText(stream), "two", "four"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByContainsOrdered(PostgresDb.TableName, writer, new { Sub = new { Foo = "green" } }, + [Field.Named("Sub.Bar DESC")]); + VerifyExpectedOrder(StreamText(stream), "four", "two"); + }) + ]), + TestList("WriteByJsonPath", + [ + TestCase("succeeds when documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByJsonPath(PostgresDb.TableName, writer, "$.NumValue ? (@ < 15)"); + var json = StreamText(stream); + VerifyBeginEnd(json); + VerifyDocById(json, "one"); + VerifyDocById(json, "two"); + VerifyDocById(json, "three"); + }), + TestCase("succeeds when documents are not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByJsonPath(PostgresDb.TableName, writer, "$.NumValue ? (@ < 0)"); + VerifyEmpty(StreamText(stream)); + }) + ]), + TestList("WriteByJsonPathOrdered", + [ + // Id = one, NumValue = 0; Id = two, NumValue = 10; Id = three, NumValue = 4 + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByJsonPathOrdered(PostgresDb.TableName, writer, "$.NumValue ? (@ < 15)", + [Field.Named("n:NumValue")]); + VerifyExpectedOrder(StreamText(stream), "one", "three", "two"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteByJsonPathOrdered(PostgresDb.TableName, writer, "$.NumValue ? (@ < 15)", + [Field.Named("n:NumValue DESC")]); + VerifyExpectedOrder(StreamText(stream), "two", "three", "one"); + }) + ]), + TestList("WriteFirstByFields", + [ + TestCase("succeeds when a document is found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByFields(PostgresDb.TableName, writer, FieldMatch.Any, + [Field.Equal("Value", "another")]); + VerifyDocById(StreamText(stream), "two"); + }), + TestCase("succeeds when multiple documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByFields(PostgresDb.TableName, writer, FieldMatch.Any, + [Field.Equal("Value", "purple")]); + VerifyAnyById(StreamText(stream), ["five", "four"]); + }), + TestCase("succeeds when a document is not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByFields(PostgresDb.TableName, writer, FieldMatch.Any, + [Field.Equal("Value", "absent")]); + VerifyNoDoc(StreamText(stream)); + }) + ]), + TestList("WriteFirstByFieldsOrdered", + [ + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.Any, + [Field.Equal("Value", "purple")], [Field.Named("Id")]); + VerifyDocById(StreamText(stream), "five"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.Any, + [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]); + VerifyDocById(StreamText(stream), "four"); + }) + ]), + TestList("WriteFirstByContains", + [ + TestCase("succeeds when a document is found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByContains(PostgresDb.TableName, writer, new { Value = "another" }); + VerifyDocById(StreamText(stream), "two"); + }), + TestCase("succeeds when multiple documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByContains(PostgresDb.TableName, writer, new { Sub = new { Foo = "green" } }); + VerifyAnyById(StreamText(stream), ["two", "four"]); + }), + TestCase("succeeds when a document is not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByContains(PostgresDb.TableName, writer, new { Value = "absent" }); + VerifyNoDoc(StreamText(stream)); + }) + ]), + TestList("WriteFirstByContainsOrdered", + [ + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByContainsOrdered(PostgresDb.TableName, writer, + new { Sub = new { Foo = "green" } }, [Field.Named("Value")]); + VerifyDocById(StreamText(stream), "two"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByContainsOrdered(PostgresDb.TableName, writer, + new { Sub = new { Foo = "green" } }, [Field.Named("Value DESC")]); + VerifyDocById(StreamText(stream), "four"); + }) + ]), + TestList("WriteFirstByJsonPath", + [ + TestCase("succeeds when a document is found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByJsonPath(PostgresDb.TableName, writer, """$.Value ? (@ == "FIRST!")"""); + VerifyDocById(StreamText(stream), "one"); + }), + TestCase("succeeds when multiple documents are found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByJsonPath(PostgresDb.TableName, writer, """$.Sub.Foo ? (@ == "green")"""); + VerifyAnyById(StreamText(stream), ["two", "four"]); + }), + TestCase("succeeds when a document is not found", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByJsonPath(PostgresDb.TableName, writer, """$.Id ? (@ == "nope")"""); + VerifyNoDoc(StreamText(stream)); + }) + ]), + TestList("WriteFirstByJsonPathOrdered", + [ + TestCase("succeeds when sorting ascending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByJsonPathOrdered(PostgresDb.TableName, writer, """$.Sub.Foo ? (@ == "green")""", + [Field.Named("Sub.Bar")]); + VerifyDocById(StreamText(stream), "two"); + }), + TestCase("succeeds when sorting descending", async () => + { + await using var db = PostgresDb.BuildDb(); + await LoadDocs(); + await using MemoryStream stream = new(); + await using var writer = WriteStream(stream); + await Json.WriteFirstByJsonPathOrdered(PostgresDb.TableName, writer, """$.Sub.Foo ? (@ == "green")""", + [Field.Named("Sub.Bar DESC")]); + VerifyDocById(StreamText(stream), "four"); + }) ]) ]); diff --git a/src/Tests/PostgresTests.fs b/src/Tests/PostgresTests.fs index 8cd730b..d166cbf 100644 --- a/src/Tests/PostgresTests.fs +++ b/src/Tests/PostgresTests.fs @@ -1451,6 +1451,399 @@ let jsonTests = testList "Json" [ verifyDocById json "four" } ] + testList "writeAll" [ + testTask "succeeds when there is data" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeAll PostgresDb.TableName writer + verifyAllData (streamText stream) + } + testTask "succeeds when there is no data" { + use db = PostgresDb.BuildDb() + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeAll PostgresDb.TableName writer + verifyEmpty (streamText stream) + } + ] + testList "writeAllOrdered" [ + testTask "succeeds when ordering numerically" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeAllOrdered PostgresDb.TableName writer [ Field.Named "n:NumValue" ] + verifyExpectedOrder (streamText stream) "one" "three" (Some "two") (Some "four") (Some "five") + } + testTask "succeeds when ordering numerically descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeAllOrdered PostgresDb.TableName writer [ Field.Named "n:NumValue DESC" ] + verifyExpectedOrder (streamText stream) "five" "four" (Some "two") (Some "three") (Some "one") + } + testTask "succeeds when ordering alphabetically" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeAllOrdered PostgresDb.TableName writer [ Field.Named "Id DESC" ] + verifyExpectedOrder (streamText stream) "two" "three" (Some "one") (Some "four") (Some "five") + } + ] + testList "writeById" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeById PostgresDb.TableName writer "two" + let json = streamText stream + Expect.stringStarts json """{"Id": "two",""" "An incorrect document was returned" + Expect.stringEnds json "}" "JSON should have ended with this document" + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeById PostgresDb.TableName writer "three hundred eighty-seven" + verifyNoDoc (streamText stream) + } + ] + testList "writeByFields" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFields + PostgresDb.TableName writer All [ Field.In "Value" [ "purple"; "blue" ]; Field.Exists "Sub" ] + verifySingleById (streamText stream) "four" + } + testTask "succeeds when documents are found using IN with numeric field" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFields PostgresDb.TableName writer All [ Field.In "NumValue" [ 2; 4; 6; 8 ] ] + verifySingleById (streamText stream) "three" + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFields + PostgresDb.TableName writer All [ Field.Equal "Value" "mauve"; Field.NotEqual "NumValue" 40 ] + verifyEmpty (streamText stream) + } + testTask "succeeds for InArray when matching documents exist" { + use db = PostgresDb.BuildDb() + do! Definition.ensureTable PostgresDb.TableName + for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFields + PostgresDb.TableName writer All [ Field.InArray "Values" PostgresDb.TableName [ "c" ] ] + let json = streamText stream + verifyBeginEnd json + verifyDocById json "first" + verifyDocById json "second" + } + testTask "succeeds for InArray when no matching documents exist" { + use db = PostgresDb.BuildDb() + do! Definition.ensureTable PostgresDb.TableName + for doc in ArrayDocument.TestDocuments do do! insert PostgresDb.TableName doc + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFields + PostgresDb.TableName writer All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ] + verifyEmpty (streamText stream) + } + ] + testList "writeByFieldsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFieldsOrdered + PostgresDb.TableName writer All [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] + verifyExpectedOrder (streamText stream) "five" "four" None None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByFieldsOrdered + PostgresDb.TableName writer All [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] + verifyExpectedOrder (streamText stream) "four" "five" None None None + } + ] + testList "writeByContains" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByContains PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} + let json = streamText stream + verifyBeginEnd json + verifyDocById json "two" + verifyDocById json "four" + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByContains PostgresDb.TableName writer {| Value = "mauve" |} + verifyEmpty (streamText stream) + } + ] + testList "writeByContainsOrdered" [ + // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByContainsOrdered + PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar" ] + verifyExpectedOrder (streamText stream) "two" "four" None None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByContainsOrdered + PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar DESC" ] + verifyExpectedOrder (streamText stream) "four" "two" None None None + } + ] + testList "writeByJsonPath" [ + testTask "succeeds when documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByJsonPath PostgresDb.TableName writer "$.NumValue ? (@ < 15)" + let json = streamText stream + verifyBeginEnd json + verifyDocById json "one" + verifyDocById json "two" + verifyDocById json "three" + } + testTask "succeeds when documents are not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByJsonPath PostgresDb.TableName writer "$.NumValue ? (@ < 0)" + verifyEmpty (streamText stream) + } + ] + testList "writeByJsonPathOrdered" [ + // Id = one, NumValue = 0; Id = two, NumValue = 10; Id = three, NumValue = 4 + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByJsonPathOrdered + PostgresDb.TableName writer "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue" ] + verifyExpectedOrder (streamText stream) "one" "three" (Some "two") None None + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeByJsonPathOrdered + PostgresDb.TableName writer "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue DESC" ] + verifyExpectedOrder (streamText stream) "two" "three" (Some "one") None None + } + ] + testList "writeFirstByFields" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByFields PostgresDb.TableName writer Any [ Field.Equal "Value" "another" ] + verifyDocById (streamText stream) "two" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByFields PostgresDb.TableName writer Any [ Field.Equal "Value" "purple" ] + verifyAnyById (streamText stream) [ "five"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByFields PostgresDb.TableName writer Any [ Field.Equal "Value" "absent" ] + verifyNoDoc (streamText stream) + } + ] + testList "writeFirstByFieldsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByFieldsOrdered + PostgresDb.TableName writer Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ] + verifyDocById (streamText stream) "five" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByFieldsOrdered + PostgresDb.TableName writer Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ] + verifyDocById (streamText stream) "four" + } + ] + testList "writeFirstByContains" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByContains PostgresDb.TableName writer {| Value = "another" |} + verifyDocById (streamText stream) "two" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByContains PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} + verifyAnyById (streamText stream) [ "two"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByContains PostgresDb.TableName writer {| Value = "absent" |} + verifyNoDoc (streamText stream) + } + ] + testList "writeFirstByContainsOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByContainsOrdered + PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Value" ] + verifyDocById (streamText stream) "two" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByContainsOrdered + PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Value DESC" ] + verifyDocById (streamText stream) "four" + } + ] + testList "writeFirstByJsonPath" [ + testTask "succeeds when a document is found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByJsonPath PostgresDb.TableName writer """$.Value ? (@ == "FIRST!")""" + verifyDocById (streamText stream) "one" + } + testTask "succeeds when multiple documents are found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByJsonPath PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")""" + verifyAnyById (streamText stream) [ "two"; "four" ] + } + testTask "succeeds when a document is not found" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByJsonPath PostgresDb.TableName writer """$.Id ? (@ == "nope")""" + verifyNoDoc (streamText stream) + } + ] + testList "writeFirstByJsonPathOrdered" [ + testTask "succeeds when sorting ascending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByJsonPathOrdered + PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar" ] + verifyDocById (streamText stream) "two" + } + testTask "succeeds when sorting descending" { + use db = PostgresDb.BuildDb() + do! loadDocs () + + use stream = new MemoryStream() + use writer = writeStream stream + do! Json.writeFirstByJsonPathOrdered + PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar DESC" ] + verifyDocById (streamText stream) "four" + } + ] ] /// Integration tests for the Update module of the PostgreSQL library