Add ordered* tests for SQLite
- Ignore "n:" prefix for SQLite fields - Remove byFIeld functions
This commit is contained in:
		
							parent
							
								
									d993f71788
								
							
						
					
					
						commit
						e2948ea6a1
					
				@ -309,10 +309,10 @@ module Query =
 | 
			
		||||
                    { it with Name = parts[0] }, Some $" {parts[1]}"
 | 
			
		||||
                else it, None)
 | 
			
		||||
            |> Seq.map (fun (field, direction) ->
 | 
			
		||||
                let path =
 | 
			
		||||
                    if dialect = PostgreSQL && field.Name.StartsWith "n:" then
 | 
			
		||||
                        $"({ { field with Name = field.Name[2..] }.Path dialect})::numeric"
 | 
			
		||||
                    else field.Path dialect
 | 
			
		||||
                path + defaultArg direction "")
 | 
			
		||||
                match dialect, field.Name.StartsWith "n:" with
 | 
			
		||||
                | PostgreSQL, true -> $"({ { field with Name = field.Name[2..] }.Path PostgreSQL})::numeric"
 | 
			
		||||
                | SQLite, true     -> { field with Name = field.Name[2..] }.Path SQLite
 | 
			
		||||
                | _, _             -> field.Path dialect
 | 
			
		||||
                |> function path -> path + defaultArg direction "")
 | 
			
		||||
            |> String.concat ", "
 | 
			
		||||
            |> function it -> $" ORDER BY {it}"
 | 
			
		||||
 | 
			
		||||
@ -49,11 +49,6 @@ module Extensions =
 | 
			
		||||
        member conn.countByFields tableName howMatched fields =
 | 
			
		||||
            WithConn.Count.byFields tableName howMatched fields conn
 | 
			
		||||
        
 | 
			
		||||
        /// Count matching documents using a comparison on a JSON field
 | 
			
		||||
        [<System.Obsolete "Use countByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.countByField tableName field =
 | 
			
		||||
            conn.countByFields tableName Any [ field ]
 | 
			
		||||
        
 | 
			
		||||
        /// Determine if a document exists for the given ID
 | 
			
		||||
        member conn.existsById tableName (docId: 'TKey) =
 | 
			
		||||
            WithConn.Exists.byId tableName docId conn
 | 
			
		||||
@ -62,11 +57,6 @@ module Extensions =
 | 
			
		||||
        member conn.existsByFields tableName howMatched fields =
 | 
			
		||||
            WithConn.Exists.byFields tableName howMatched fields conn
 | 
			
		||||
        
 | 
			
		||||
        /// Determine if a document exists using a comparison on a JSON field
 | 
			
		||||
        [<System.Obsolete "Use existsByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.existsByField tableName field =
 | 
			
		||||
            conn.existsByFields tableName Any [ field ]
 | 
			
		||||
 | 
			
		||||
        /// Retrieve all documents in the given table
 | 
			
		||||
        member conn.findAll<'TDoc> tableName =
 | 
			
		||||
            WithConn.Find.all<'TDoc> tableName conn
 | 
			
		||||
@ -87,11 +77,6 @@ module Extensions =
 | 
			
		||||
        member conn.findByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
 | 
			
		||||
            WithConn.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
 | 
			
		||||
        
 | 
			
		||||
        /// Retrieve documents via a comparison on a JSON field
 | 
			
		||||
        [<System.Obsolete "Use findByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.findByField<'TDoc> tableName field =
 | 
			
		||||
            conn.findByFields<'TDoc> tableName Any [ field ]
 | 
			
		||||
        
 | 
			
		||||
        /// Retrieve documents via a comparison on JSON fields, returning only the first result
 | 
			
		||||
        member conn.findFirstByFields<'TDoc> tableName howMatched fields =
 | 
			
		||||
            WithConn.Find.firstByFields<'TDoc> tableName howMatched fields conn
 | 
			
		||||
@ -101,11 +86,6 @@ module Extensions =
 | 
			
		||||
        member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
 | 
			
		||||
            WithConn.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
 | 
			
		||||
        
 | 
			
		||||
        /// Retrieve documents via a comparison on a JSON field, returning only the first result
 | 
			
		||||
        [<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.findFirstByField<'TDoc> tableName field =
 | 
			
		||||
            conn.findFirstByFields<'TDoc> tableName Any [ field ]
 | 
			
		||||
 | 
			
		||||
        /// Update an entire document by its ID
 | 
			
		||||
        member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
 | 
			
		||||
            WithConn.Update.byId tableName docId document conn
 | 
			
		||||
@ -122,11 +102,6 @@ module Extensions =
 | 
			
		||||
        member conn.patchByFields tableName howMatched fields (patch: 'TPatch) =
 | 
			
		||||
            WithConn.Patch.byFields tableName howMatched fields patch conn
 | 
			
		||||
        
 | 
			
		||||
        /// Patch documents using a comparison on a JSON field
 | 
			
		||||
        [<System.Obsolete "Use patchByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.patchByField tableName field (patch: 'TPatch) =
 | 
			
		||||
            conn.patchByFields tableName Any [ field ] patch
 | 
			
		||||
 | 
			
		||||
        /// Remove fields from a document by the document's ID
 | 
			
		||||
        member conn.removeFieldsById tableName (docId: 'TKey) fieldNames =
 | 
			
		||||
            WithConn.RemoveFields.byId tableName docId fieldNames conn
 | 
			
		||||
@ -135,11 +110,6 @@ module Extensions =
 | 
			
		||||
        member conn.removeFieldsByFields tableName howMatched fields fieldNames =
 | 
			
		||||
            WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
 | 
			
		||||
        
 | 
			
		||||
        /// Remove a field from a document via a comparison on a JSON field in the document
 | 
			
		||||
        [<System.Obsolete "Use removeFieldsByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.removeFieldsByField tableName field fieldNames =
 | 
			
		||||
            conn.removeFieldsByFields tableName Any [ field ] fieldNames
 | 
			
		||||
        
 | 
			
		||||
        /// Delete a document by its ID
 | 
			
		||||
        member conn.deleteById tableName (docId: 'TKey) =
 | 
			
		||||
            WithConn.Delete.byId tableName docId conn
 | 
			
		||||
@ -147,11 +117,6 @@ module Extensions =
 | 
			
		||||
        /// Delete documents by matching a comparison on JSON fields
 | 
			
		||||
        member conn.deleteByFields tableName howMatched fields =
 | 
			
		||||
            WithConn.Delete.byFields tableName howMatched fields conn
 | 
			
		||||
        
 | 
			
		||||
        /// Delete documents by matching a comparison on a JSON field
 | 
			
		||||
        [<System.Obsolete "Use deleteByFields instead; will be removed in v4">]
 | 
			
		||||
        member conn.deleteByField tableName field =
 | 
			
		||||
            conn.deleteByFields tableName Any [ field ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
open System.Runtime.CompilerServices
 | 
			
		||||
@ -211,12 +176,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    static member inline CountByFields(conn, tableName, howMatched, fields) =
 | 
			
		||||
        WithConn.Count.byFields tableName howMatched fields conn
 | 
			
		||||
    
 | 
			
		||||
    /// Count matching documents using a comparison on a JSON field
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use CountByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline CountByField(conn, tableName, field) =
 | 
			
		||||
        conn.CountByFields(tableName, Any, [ field ])
 | 
			
		||||
 | 
			
		||||
    /// Determine if a document exists for the given ID
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline ExistsById<'TKey>(conn, tableName, docId: 'TKey) =
 | 
			
		||||
@ -227,12 +186,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    static member inline ExistsByFields(conn, tableName, howMatched, fields) =
 | 
			
		||||
        WithConn.Exists.byFields tableName howMatched fields conn
 | 
			
		||||
    
 | 
			
		||||
    /// Determine if a document exists using a comparison on a JSON field
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use ExistsByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline ExistsByField(conn, tableName, field) =
 | 
			
		||||
        conn.ExistsByFields(tableName, Any, [ field ])
 | 
			
		||||
    
 | 
			
		||||
    /// Retrieve all documents in the given table
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline FindAll<'TDoc>(conn, tableName) =
 | 
			
		||||
@ -241,7 +194,7 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    /// Retrieve all documents in the given table ordered by the given fields in the document
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
 | 
			
		||||
        WithConn.Find.AllOrdered<'TDoc>(tableName, conn, orderFields)
 | 
			
		||||
        WithConn.Find.AllOrdered<'TDoc>(tableName, orderFields, conn)
 | 
			
		||||
 | 
			
		||||
    /// Retrieve a document by its ID
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
@ -258,12 +211,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
 | 
			
		||||
        WithConn.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
 | 
			
		||||
    
 | 
			
		||||
    /// Retrieve documents via a comparison on a JSON field
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use FindByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline FindByField<'TDoc>(conn, tableName, field) =
 | 
			
		||||
        conn.FindByFields<'TDoc>(tableName, Any, [ field ])
 | 
			
		||||
 | 
			
		||||
    /// Retrieve documents via a comparison on JSON fields, returning only the first result
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) =
 | 
			
		||||
@ -276,12 +223,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
            conn, tableName, howMatched, queryFields, orderFields) =
 | 
			
		||||
        WithConn.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
 | 
			
		||||
    
 | 
			
		||||
    /// Retrieve documents via a comparison on a JSON field, returning only the first result
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
 | 
			
		||||
        conn.FindFirstByFields<'TDoc>(tableName, Any, [ field ])
 | 
			
		||||
 | 
			
		||||
    /// Update an entire document by its ID
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline UpdateById<'TKey, 'TDoc>(conn, tableName, docId: 'TKey, document: 'TDoc) =
 | 
			
		||||
@ -302,12 +243,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    static member inline PatchByFields<'TPatch>(conn, tableName, howMatched, fields, patch: 'TPatch) =
 | 
			
		||||
        WithConn.Patch.byFields tableName howMatched fields patch conn
 | 
			
		||||
    
 | 
			
		||||
    /// Patch documents using a comparison on a JSON field
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use PatchByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline PatchByField<'TPatch>(conn, tableName, field, patch: 'TPatch) =
 | 
			
		||||
        conn.PatchByFields(tableName, Any, [ field ], patch)
 | 
			
		||||
 | 
			
		||||
    /// Remove fields from a document by the document's ID
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline RemoveFieldsById<'TKey>(conn, tableName, docId: 'TKey, fieldNames) =
 | 
			
		||||
@ -318,12 +253,6 @@ type SqliteConnectionCSharpExtensions =
 | 
			
		||||
    static member inline RemoveFieldsByFields(conn, tableName, howMatched, fields, fieldNames) =
 | 
			
		||||
        WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
 | 
			
		||||
    
 | 
			
		||||
    /// Remove fields from documents via a comparison on a JSON field in the document
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    [<System.Obsolete "Use RemoveFieldsByFields instead; will be removed in v4">]
 | 
			
		||||
    static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) =
 | 
			
		||||
        conn.RemoveFieldsByFields(tableName, Any, [ field ], fieldNames)
 | 
			
		||||
    
 | 
			
		||||
    /// Delete a document by its ID
 | 
			
		||||
    [<Extension>]
 | 
			
		||||
    static member inline DeleteById<'TKey>(conn, tableName, docId: 'TKey) =
 | 
			
		||||
 | 
			
		||||
@ -321,7 +321,7 @@ module WithConn =
 | 
			
		||||
 | 
			
		||||
        /// Retrieve all documents in the given table ordered by the given fields in the document
 | 
			
		||||
        let AllOrdered<'TDoc>(tableName, orderFields, conn) =
 | 
			
		||||
            Custom.List(Query.find tableName + Query.orderBy orderFields PostgreSQL, [], fromData<'TDoc>, conn)
 | 
			
		||||
            Custom.List(Query.find tableName + Query.orderBy orderFields SQLite, [], fromData<'TDoc>, conn)
 | 
			
		||||
 | 
			
		||||
        /// Retrieve a document by its ID (returns None if not found)
 | 
			
		||||
        [<CompiledName "FSharpById">]
 | 
			
		||||
 | 
			
		||||
@ -386,43 +386,53 @@ public static class CommonCSharpTests
 | 
			
		||||
            [
 | 
			
		||||
                TestCase("succeeds for no fields", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal("", Query.OrderBy([], Dialect.PostgreSQL),
 | 
			
		||||
                    Expect.equal(Query.OrderBy([], Dialect.PostgreSQL), "",
 | 
			
		||||
                        "Order By should have been blank (PostgreSQL)");
 | 
			
		||||
                    Expect.equal("", Query.OrderBy([], Dialect.SQLite), "Order By should have been blank (SQLite)");
 | 
			
		||||
                    Expect.equal(Query.OrderBy([], Dialect.SQLite), "", "Order By should have been blank (SQLite)");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for PostgreSQL with one field and no direction", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(" ORDER BY data->>'TestField'",
 | 
			
		||||
                        Query.OrderBy([Field.Named("TestField")], Dialect.PostgreSQL),
 | 
			
		||||
                        "Order By not constructed correctly");
 | 
			
		||||
                    Expect.equal(Query.OrderBy([Field.Named("TestField")], Dialect.PostgreSQL),
 | 
			
		||||
                        " ORDER BY data->>'TestField'", "Order By not constructed correctly");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for SQLite with one field and no direction", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(" ORDER BY data->>'TestField'",
 | 
			
		||||
                        Query.OrderBy([Field.Named("TestField")], Dialect.SQLite),
 | 
			
		||||
                        "Order By not constructed correctly");
 | 
			
		||||
                    Expect.equal(Query.OrderBy([Field.Named("TestField")], Dialect.SQLite),
 | 
			
		||||
                        " ORDER BY data->>'TestField'", "Order By not constructed correctly");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for PostgreSQL with multiple fields and direction", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
 | 
			
		||||
                    Expect.equal(
 | 
			
		||||
                        Query.OrderBy(
 | 
			
		||||
                            [
 | 
			
		||||
                                Field.Named("Nested.Test.Field DESC"), Field.Named("AnotherField"),
 | 
			
		||||
                                Field.Named("It DESC")
 | 
			
		||||
                            ],
 | 
			
		||||
                            Dialect.PostgreSQL), "Order By not constructed correctly");
 | 
			
		||||
                            Dialect.PostgreSQL),
 | 
			
		||||
                        " ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
 | 
			
		||||
                        "Order By not constructed correctly");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for SQLite with multiple fields and direction", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(
 | 
			
		||||
                        " ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
 | 
			
		||||
                        Query.OrderBy(
 | 
			
		||||
                            [
 | 
			
		||||
                                Field.Named("Nested.Test.Field DESC"), Field.Named("AnotherField"),
 | 
			
		||||
                                Field.Named("It DESC")
 | 
			
		||||
                            ],
 | 
			
		||||
                            Dialect.SQLite),
 | 
			
		||||
                        " ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
 | 
			
		||||
                        "Order By not constructed correctly");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for PostgreSQL numeric fields", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(Query.OrderBy([Field.Named("n:Test")], Dialect.PostgreSQL),
 | 
			
		||||
                        " ORDER BY (data->>'Test')::numeric", "Order By not constructed correctly for numeric field");
 | 
			
		||||
                }),
 | 
			
		||||
                TestCase("succeeds for SQLite numeric fields", () =>
 | 
			
		||||
                {
 | 
			
		||||
                    Expect.equal(Query.OrderBy([Field.Named("n:Test")], Dialect.SQLite), " ORDER BY data->>'Test'",
 | 
			
		||||
                        "Order By not constructed correctly for numeric field");
 | 
			
		||||
                })
 | 
			
		||||
            ])
 | 
			
		||||
        ])
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
using Expecto.CSharp;
 | 
			
		||||
using Expecto;
 | 
			
		||||
using Microsoft.Data.Sqlite;
 | 
			
		||||
using BitBadger.Documents.Sqlite;
 | 
			
		||||
 | 
			
		||||
namespace BitBadger.Documents.Tests.CSharp;
 | 
			
		||||
@ -29,7 +28,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
 | 
			
		||||
                    new[] { Parameters.Id("one") }, Results.FromData<JsonDocument>);
 | 
			
		||||
                    [Parameters.Id("one")], Results.FromData<JsonDocument>);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal(doc!.Id, "one", "The incorrect document was returned");
 | 
			
		||||
            }),
 | 
			
		||||
@ -40,7 +39,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
 | 
			
		||||
                    new[] { Parameters.Id("eighty") }, Results.FromData<JsonDocument>);
 | 
			
		||||
                    [Parameters.Id("eighty")], Results.FromData<JsonDocument>);
 | 
			
		||||
                Expect.isNull(doc, "There should not have been a document returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
@ -63,8 +62,8 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await conn.CustomList(
 | 
			
		||||
                    $"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
 | 
			
		||||
                    new[] { new SqliteParameter("@value", 100) }, Results.FromData<JsonDocument>);
 | 
			
		||||
                    $"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value", [new("@value", 100)],
 | 
			
		||||
                    Results.FromData<JsonDocument>);
 | 
			
		||||
                Expect.isEmpty(docs, "There should have been no documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
@ -88,7 +87,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.CustomNonQuery($"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
 | 
			
		||||
                    new[] { new SqliteParameter("@value", 100) });
 | 
			
		||||
                    [new("@value", 100)]);
 | 
			
		||||
 | 
			
		||||
                var remaining = await conn.CountAll(SqliteDb.TableName);
 | 
			
		||||
                Expect.equal(remaining, 5L, "There should be 5 documents remaining in the table");
 | 
			
		||||
@ -107,38 +106,41 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
            await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
            await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
 | 
			
		||||
            Func<string, ValueTask<bool>> itExists = async name =>
 | 
			
		||||
                await conn.CustomScalar(
 | 
			
		||||
                    $"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
 | 
			
		||||
                    new SqliteParameter[] { new("@name", name) }, Results.ToExists);
 | 
			
		||||
 | 
			
		||||
            var exists = await itExists("ensured");
 | 
			
		||||
            var alsoExists = await itExists("idx_ensured_key");
 | 
			
		||||
            var exists = await ItExists("ensured");
 | 
			
		||||
            var alsoExists = await ItExists("idx_ensured_key");
 | 
			
		||||
            Expect.isFalse(exists, "The table should not exist already");
 | 
			
		||||
            Expect.isFalse(alsoExists, "The key index should not exist already");
 | 
			
		||||
 | 
			
		||||
            await conn.EnsureTable("ensured");
 | 
			
		||||
 | 
			
		||||
            exists = await itExists("ensured");
 | 
			
		||||
            alsoExists = await itExists("idx_ensured_key");
 | 
			
		||||
            exists = await ItExists("ensured");
 | 
			
		||||
            alsoExists = await ItExists("idx_ensured_key");
 | 
			
		||||
            Expect.isTrue(exists, "The table should now exist");
 | 
			
		||||
            Expect.isTrue(alsoExists, "The key index should now exist");
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
            Task<bool> ItExists(string name) =>
 | 
			
		||||
                conn.CustomScalar($"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
 | 
			
		||||
                    [new("@name", name)], Results.ToExists);
 | 
			
		||||
        }),
 | 
			
		||||
        TestCase("EnsureFieldIndex succeeds", async () =>
 | 
			
		||||
        {
 | 
			
		||||
            await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
            await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
            var indexExists = () => conn.CustomScalar(
 | 
			
		||||
                $"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it",
 | 
			
		||||
                Parameters.None, Results.ToExists);
 | 
			
		||||
 | 
			
		||||
            var exists = await indexExists();
 | 
			
		||||
            var exists = await IndexExists();
 | 
			
		||||
            Expect.isFalse(exists, "The index should not exist already");
 | 
			
		||||
 | 
			
		||||
            await conn.EnsureTable("ensured");
 | 
			
		||||
            await conn.EnsureFieldIndex("ensured", "test", new[] { "Id", "Category" });
 | 
			
		||||
            exists = await indexExists();
 | 
			
		||||
            await conn.EnsureFieldIndex("ensured", "test", ["Id", "Category"]);
 | 
			
		||||
            exists = await IndexExists();
 | 
			
		||||
            Expect.isTrue(exists, "The index should now exist");
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
            Task<bool> IndexExists() =>
 | 
			
		||||
                conn.CustomScalar(
 | 
			
		||||
                    $"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it",
 | 
			
		||||
                    Parameters.None, Results.ToExists);
 | 
			
		||||
        }),
 | 
			
		||||
        TestList("Insert",
 | 
			
		||||
        [
 | 
			
		||||
@ -213,17 +215,15 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
            var theCount = await conn.CountAll(SqliteDb.TableName);
 | 
			
		||||
            Expect.equal(theCount, 5L, "There should have been 5 matching documents");
 | 
			
		||||
        }),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestCase("CountByField succeeds", async () =>
 | 
			
		||||
        {
 | 
			
		||||
            await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
            await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
            await LoadDocs();
 | 
			
		||||
 | 
			
		||||
            var theCount = await conn.CountByField(SqliteDb.TableName, Field.EQ("Value", "purple"));
 | 
			
		||||
            var theCount = await conn.CountByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "purple")]);
 | 
			
		||||
            Expect.equal(theCount, 2L, "There should have been 2 matching documents");
 | 
			
		||||
        }),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestList("ExistsById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document exists", async () =>
 | 
			
		||||
@ -245,8 +245,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                Expect.isFalse(exists, "There should not have been an existing document");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestList("ExistsByField",
 | 
			
		||||
        TestList("ExistsByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when documents exist", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -254,7 +253,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var exists = await conn.ExistsByField(SqliteDb.TableName, Field.GE("NumValue", 10));
 | 
			
		||||
                var exists = await conn.ExistsByFields(SqliteDb.TableName, FieldMatch.Any, [Field.GE("NumValue", 10)]);
 | 
			
		||||
                Expect.isTrue(exists, "There should have been existing documents");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when no matching documents exist", async () =>
 | 
			
		||||
@ -263,11 +262,11 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var exists = await conn.ExistsByField(SqliteDb.TableName, Field.EQ("Nothing", "none"));
 | 
			
		||||
                var exists =
 | 
			
		||||
                    await conn.ExistsByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Nothing", "none")]);
 | 
			
		||||
                Expect.isFalse(exists, "There should not have been any existing documents");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestList("FindAll",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when there is data", async () =>
 | 
			
		||||
@ -290,6 +289,43 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                Expect.isEmpty(results, "There should have been no documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FindAllOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when ordering numerically", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results = await conn.FindAllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("n:NumValue")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "one|three|two|four|five",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when ordering numerically descending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results =
 | 
			
		||||
                    await conn.FindAllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("n:NumValue DESC")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "five|four|two|three|one",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when ordering alphabetically", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results = await conn.FindAllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("Id DESC")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "two|three|one|four|five",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FindById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is found", async () =>
 | 
			
		||||
@ -312,8 +348,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                Expect.isNull(doc, "There should not have been a document returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestList("FindByField",
 | 
			
		||||
        TestList("FindByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when documents are found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -321,7 +356,8 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, Field.GT("NumValue", 15));
 | 
			
		||||
                var docs = await conn.FindByFields<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.GT("NumValue", 15)]);
 | 
			
		||||
                Expect.equal(docs.Count, 2, "There should have been two documents returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when documents are not found", async () =>
 | 
			
		||||
@ -330,11 +366,37 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "mauve"));
 | 
			
		||||
                var docs = await conn.FindByFields<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Value", "mauve")]);
 | 
			
		||||
                Expect.isEmpty(docs, "There should have been no documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FindFirstByField",
 | 
			
		||||
        TestList("ByFieldsOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when documents are found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await conn.FindByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.GT("NumValue", 15)], [Field.Named("Id")]);
 | 
			
		||||
                Expect.equal(string.Join('|', docs.Select(x => x.Id)), "five|four",
 | 
			
		||||
                    "There should have been two documents returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when documents are not found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await conn.FindByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.GT("NumValue", 15)], [Field.Named("Id DESC")]);
 | 
			
		||||
                Expect.equal(string.Join('|', docs.Select(x => x.Id)), "four|five",
 | 
			
		||||
                    "There should have been two documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FindFirstByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -342,7 +404,8 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "another"));
 | 
			
		||||
                var doc = await conn.FindFirstByFields<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Value", "another")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal(doc!.Id, "two", "The incorrect document was returned");
 | 
			
		||||
            }),
 | 
			
		||||
@ -352,9 +415,10 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Sub.Foo", "green"));
 | 
			
		||||
                var doc = await conn.FindFirstByFields<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Sub.Foo", "green")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
 | 
			
		||||
                Expect.contains(["two", "four"], doc!.Id, "An incorrect document was returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when a document is not found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -362,11 +426,36 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, Field.EQ("Value", "absent"));
 | 
			
		||||
                var doc = await conn.FindFirstByFields<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Value", "absent")]);
 | 
			
		||||
                Expect.isNull(doc, "There should not have been a document returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestList("FindFirstByFieldsOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when sorting ascending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.FindFirstByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Sub.Foo", "green")], [Field.Named("Sub.Bar")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal("two", doc!.Id, "An incorrect document was returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when sorting descending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await conn.FindFirstByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Sub.Foo", "green")], [Field.Named("Sub.Bar DESC")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal("four", doc!.Id, "An incorrect document was returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("UpdateById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is updated", async () =>
 | 
			
		||||
@ -450,8 +539,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await conn.PatchById(SqliteDb.TableName, "test", new { Foo = "green" });
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestList("PatchByField",
 | 
			
		||||
        TestList("PatchByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is updated", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -459,8 +547,9 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.PatchByField(SqliteDb.TableName, Field.EQ("Value", "purple"), new { NumValue = 77 });
 | 
			
		||||
                var after = await conn.CountByField(SqliteDb.TableName, Field.EQ("NumValue", 77));
 | 
			
		||||
                await conn.PatchByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "purple")],
 | 
			
		||||
                    new { NumValue = 77 });
 | 
			
		||||
                var after = await conn.CountByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 77)]);
 | 
			
		||||
                Expect.equal(after, 2L, "There should have been 2 documents returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when no document is updated", async () =>
 | 
			
		||||
@ -471,10 +560,10 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                Expect.isEmpty(before, "There should have been no documents returned");
 | 
			
		||||
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                await conn.PatchByField(SqliteDb.TableName, Field.EQ("Value", "burgundy"), new { Foo = "green" });
 | 
			
		||||
                await conn.PatchByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "burgundy")],
 | 
			
		||||
                    new { Foo = "green" });
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestList("RemoveFieldsById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when fields are removed", async () =>
 | 
			
		||||
@ -483,7 +572,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", new[] { "Sub", "Value" });
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", ["Sub", "Value"]);
 | 
			
		||||
                var updated = await Find.ById<string, JsonDocument>(SqliteDb.TableName, "two");
 | 
			
		||||
                Expect.isNotNull(updated, "The updated document should have been retrieved");
 | 
			
		||||
                Expect.equal(updated.Value, "", "The string value should have been removed");
 | 
			
		||||
@ -496,7 +585,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
                    
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", new[] { "AFieldThatIsNotThere" });
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", ["AFieldThatIsNotThere"]);
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when no document is matched", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -504,11 +593,10 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", new[] { "Value" });
 | 
			
		||||
                await conn.RemoveFieldsById(SqliteDb.TableName, "two", ["Value"]);
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestList("RemoveFieldsByField",
 | 
			
		||||
        TestList("RemoveFieldsByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a field is removed", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -516,7 +604,8 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.RemoveFieldsByField(SqliteDb.TableName, Field.EQ("NumValue", 17), new[] { "Sub" });
 | 
			
		||||
                await conn.RemoveFieldsByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 17)],
 | 
			
		||||
                    ["Sub"]);
 | 
			
		||||
                var updated = await Find.ById<string, JsonDocument>(SqliteDb.TableName, "four");
 | 
			
		||||
                Expect.isNotNull(updated, "The updated document should have been retrieved");
 | 
			
		||||
                Expect.isNull(updated.Sub, "The sub-document should have been removed");
 | 
			
		||||
@ -528,7 +617,8 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
                    
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                await conn.RemoveFieldsByField(SqliteDb.TableName, Field.EQ("NumValue", 17), new[] { "Nothing" });
 | 
			
		||||
                await conn.RemoveFieldsByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("NumValue", 17)],
 | 
			
		||||
                    ["Nothing"]);
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when no document is matched", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -536,10 +626,10 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                await conn.RemoveFieldsByField(SqliteDb.TableName, Field.NE("Abracadabra", "apple"), new[] { "Value" });
 | 
			
		||||
                await conn.RemoveFieldsByFields(SqliteDb.TableName, FieldMatch.Any, [Field.NE("Abracadabra", "apple")],
 | 
			
		||||
                    ["Value"]);
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestList("DeleteById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is deleted", async () =>
 | 
			
		||||
@ -563,8 +653,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning disable CS0618
 | 
			
		||||
        TestList("DeleteByField",
 | 
			
		||||
        TestList("DeleteByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when documents are deleted", async () =>
 | 
			
		||||
            {
 | 
			
		||||
@ -572,7 +661,7 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.DeleteByField(SqliteDb.TableName, Field.NE("Value", "purple"));
 | 
			
		||||
                await conn.DeleteByFields(SqliteDb.TableName, FieldMatch.Any, [Field.NE("Value", "purple")]);
 | 
			
		||||
                var remaining = await conn.CountAll(SqliteDb.TableName);
 | 
			
		||||
                Expect.equal(remaining, 2L, "There should have been 2 documents remaining");
 | 
			
		||||
            }),
 | 
			
		||||
@ -582,12 +671,11 @@ public static class SqliteCSharpExtensionTests
 | 
			
		||||
                await using var conn = Sqlite.Configuration.DbConn();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                await conn.DeleteByField(SqliteDb.TableName, Field.EQ("Value", "crimson"));
 | 
			
		||||
                await conn.DeleteByFields(SqliteDb.TableName, FieldMatch.Any, [Field.EQ("Value", "crimson")]);
 | 
			
		||||
                var remaining = await conn.CountAll(SqliteDb.TableName);
 | 
			
		||||
                Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
#pragma warning restore CS0618
 | 
			
		||||
        TestCase("Clean up database", () => Sqlite.Configuration.UseConnectionString("data source=:memory:"))
 | 
			
		||||
    ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -467,6 +467,39 @@ public static class SqliteCSharpTests
 | 
			
		||||
                Expect.isEmpty(results, "There should have been no documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("AllOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when ordering numerically", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results = await Find.AllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("n:NumValue")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "one|three|two|four|five",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when ordering numerically descending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results = await Find.AllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("n:NumValue DESC")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "five|four|two|three|one",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when ordering alphabetically", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var results = await Find.AllOrdered<JsonDocument>(SqliteDb.TableName, [Field.Named("Id DESC")]);
 | 
			
		||||
                Expect.hasLength(results, 5, "There should have been 5 documents returned");
 | 
			
		||||
                Expect.equal(string.Join('|', results.Select(x => x.Id)), "two|three|one|four|five",
 | 
			
		||||
                    "The documents were not ordered correctly");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("ById",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is found", async () =>
 | 
			
		||||
@ -508,6 +541,29 @@ public static class SqliteCSharpTests
 | 
			
		||||
                Expect.isEmpty(docs, "There should have been no documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("ByFieldsOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when documents are found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await Find.ByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.GT("NumValue", 15)], [Field.Named("Id")]);
 | 
			
		||||
                Expect.equal(string.Join('|', docs.Select(x => x.Id)), "five|four",
 | 
			
		||||
                    "There should have been two documents returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when documents are not found", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var docs = await Find.ByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.GT("NumValue", 15)], [Field.Named("Id DESC")]);
 | 
			
		||||
                Expect.equal(string.Join('|', docs.Select(x => x.Id)), "four|five",
 | 
			
		||||
                    "There should have been two documents returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FirstByFields",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when a document is found", async () =>
 | 
			
		||||
@ -539,6 +595,29 @@ public static class SqliteCSharpTests
 | 
			
		||||
                    [Field.EQ("Value", "absent")]);
 | 
			
		||||
                Expect.isNull(doc, "There should not have been a document returned");
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
        TestList("FirstByFieldsOrdered",
 | 
			
		||||
        [
 | 
			
		||||
            TestCase("succeeds when sorting ascending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await Find.FirstByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Sub.Foo", "green")], [Field.Named("Sub.Bar")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal("two", doc!.Id, "An incorrect document was returned");
 | 
			
		||||
            }),
 | 
			
		||||
            TestCase("succeeds when sorting descending", async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await using var db = await SqliteDb.BuildDb();
 | 
			
		||||
                await LoadDocs();
 | 
			
		||||
 | 
			
		||||
                var doc = await Find.FirstByFieldsOrdered<JsonDocument>(SqliteDb.TableName, FieldMatch.Any,
 | 
			
		||||
                    [Field.EQ("Sub.Foo", "green")], [Field.Named("Sub.Bar DESC")]);
 | 
			
		||||
                Expect.isNotNull(doc, "There should have been a document returned");
 | 
			
		||||
                Expect.equal("four", doc!.Id, "An incorrect document was returned");
 | 
			
		||||
            })
 | 
			
		||||
        ])
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -277,37 +277,49 @@ let all =
 | 
			
		||||
            }
 | 
			
		||||
            testList "orderBy" [
 | 
			
		||||
                test "succeeds for no fields" {
 | 
			
		||||
                    Expect.equal "" (Query.orderBy [] PostgreSQL) "Order By should have been blank (PostgreSQL)"
 | 
			
		||||
                    Expect.equal "" (Query.orderBy [] SQLite) "Order By should have been blank (SQLite)"
 | 
			
		||||
                    Expect.equal (Query.orderBy [] PostgreSQL) "" "Order By should have been blank (PostgreSQL)"
 | 
			
		||||
                    Expect.equal (Query.orderBy [] SQLite) "" "Order By should have been blank (SQLite)"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for PostgreSQL with one field and no direction" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        " ORDER BY data->>'TestField'"
 | 
			
		||||
                        (Query.orderBy [ Field.Named "TestField" ] PostgreSQL)
 | 
			
		||||
                        " ORDER BY data->>'TestField'"
 | 
			
		||||
                        "Order By not constructed correctly"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for SQLite with one field and no direction" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        " ORDER BY data->>'TestField'"
 | 
			
		||||
                        (Query.orderBy [ Field.Named "TestField" ] SQLite)
 | 
			
		||||
                        " ORDER BY data->>'TestField'"
 | 
			
		||||
                        "Order By not constructed correctly"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for PostgreSQL with multiple fields and direction" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        " ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC"
 | 
			
		||||
                        (Query.orderBy
 | 
			
		||||
                             [ Field.Named "Nested.Test.Field DESC"; Field.Named "AnotherField"; Field.Named "It DESC" ]
 | 
			
		||||
                             PostgreSQL)
 | 
			
		||||
                        " ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC"
 | 
			
		||||
                        "Order By not constructed correctly"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for SQLite with multiple fields and direction" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        " ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC"
 | 
			
		||||
                        (Query.orderBy
 | 
			
		||||
                             [ Field.Named "Nested.Test.Field DESC"; Field.Named "AnotherField"; Field.Named "It DESC" ]
 | 
			
		||||
                             SQLite)
 | 
			
		||||
                        " ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC"
 | 
			
		||||
                        "Order By not constructed correctly"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for PostgreSQL numeric fields" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        (Query.orderBy [ Field.Named "n:Test" ] PostgreSQL)
 | 
			
		||||
                        " ORDER BY (data->>'Test')::numeric"
 | 
			
		||||
                        "Order By not constructed correctly for numeric field"
 | 
			
		||||
                }
 | 
			
		||||
                test "succeeds for SQLite numeric fields" {
 | 
			
		||||
                    Expect.equal
 | 
			
		||||
                        (Query.orderBy [ Field.Named "n:Test" ] SQLite)
 | 
			
		||||
                        " ORDER BY data->>'Test'"
 | 
			
		||||
                        "Order By not constructed correctly for numeric field"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -8,8 +8,6 @@ open Expecto
 | 
			
		||||
open Microsoft.Data.Sqlite
 | 
			
		||||
open Types
 | 
			
		||||
 | 
			
		||||
#nowarn "0044"
 | 
			
		||||
 | 
			
		||||
/// Integration tests for the F# extensions on the SqliteConnection data type
 | 
			
		||||
let integrationTests =
 | 
			
		||||
    let loadDocs () = backgroundTask {
 | 
			
		||||
@ -115,12 +113,12 @@ let integrationTests =
 | 
			
		||||
            let! theCount = conn.countAll SqliteDb.TableName
 | 
			
		||||
            Expect.equal theCount 5L "There should have been 5 matching documents"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "countByField succeeds" {
 | 
			
		||||
        testTask "countByFields succeeds" {
 | 
			
		||||
            use! db   = SqliteDb.BuildDb()
 | 
			
		||||
            use  conn = Configuration.dbConn ()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
            let! theCount = conn.countByField SqliteDb.TableName (Field.EQ "Value" "purple")
 | 
			
		||||
            let! theCount = conn.countByFields SqliteDb.TableName Any [ Field.EQ "Value" "purple" ]
 | 
			
		||||
            Expect.equal theCount 2L "There should have been 2 matching documents"
 | 
			
		||||
        }
 | 
			
		||||
        testList "existsById" [
 | 
			
		||||
@ -141,13 +139,13 @@ let integrationTests =
 | 
			
		||||
                Expect.isFalse exists "There should not have been an existing document"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "existsByField" [
 | 
			
		||||
        testList "existsByFields" [
 | 
			
		||||
            testTask "succeeds when documents exist" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! exists = conn.existsByField SqliteDb.TableName (Field.EQ "NumValue" 10)
 | 
			
		||||
                let! exists = conn.existsByFields SqliteDb.TableName Any [ Field.EQ "NumValue" 10 ]
 | 
			
		||||
                Expect.isTrue exists "There should have been existing documents"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when no matching documents exist" {
 | 
			
		||||
@ -155,7 +153,7 @@ let integrationTests =
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! exists = conn.existsByField SqliteDb.TableName (Field.EQ "Nothing" "none")
 | 
			
		||||
                let! exists = conn.existsByFields SqliteDb.TableName Any [ Field.EQ "Nothing" "none" ]
 | 
			
		||||
                Expect.isFalse exists "There should not have been any existing documents"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
@ -183,6 +181,44 @@ let integrationTests =
 | 
			
		||||
                Expect.equal results [] "There should have been no documents returned"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findAllOrdered" [
 | 
			
		||||
            testTask "succeeds when ordering numerically" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                let! results = conn.findAllOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue" ]
 | 
			
		||||
                Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
                Expect.equal
 | 
			
		||||
                    (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                    "one|three|two|four|five"
 | 
			
		||||
                    "The documents were not ordered correctly"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when ordering numerically descending" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                let! results = conn.findAllOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue DESC" ]
 | 
			
		||||
                Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
                Expect.equal
 | 
			
		||||
                    (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                    "five|four|two|three|one"
 | 
			
		||||
                    "The documents were not ordered correctly"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when ordering alphabetically" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                let! results = conn.findAllOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "Id DESC" ]
 | 
			
		||||
                Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
                Expect.equal
 | 
			
		||||
                    (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                    "two|three|one|four|five"
 | 
			
		||||
                    "The documents were not ordered correctly"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findById" [
 | 
			
		||||
            testTask "succeeds when a document is found" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
@ -190,7 +226,7 @@ let integrationTests =
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! doc = conn.findById<string, JsonDocument> SqliteDb.TableName "two"
 | 
			
		||||
                Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
                Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
                Expect.equal doc.Value.Id "two" "The incorrect document was returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when a document is not found" {
 | 
			
		||||
@ -199,35 +235,59 @@ let integrationTests =
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! doc = conn.findById<string, JsonDocument> SqliteDb.TableName "three hundred eighty-seven"
 | 
			
		||||
                Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
 | 
			
		||||
                Expect.isNone doc "There should not have been a document returned"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findByField" [
 | 
			
		||||
        testList "findByFields" [
 | 
			
		||||
            testTask "succeeds when documents are found" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! docs = conn.findByField<JsonDocument> SqliteDb.TableName (Field.EQ "Sub.Foo" "green")
 | 
			
		||||
                Expect.equal (List.length docs) 2 "There should have been two documents returned"
 | 
			
		||||
                let! docs = conn.findByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ]
 | 
			
		||||
                Expect.hasLength docs 2 "There should have been two documents returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when documents are not found" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! docs = conn.findByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "mauve")
 | 
			
		||||
                Expect.isTrue (List.isEmpty docs) "There should have been no documents returned"
 | 
			
		||||
                let! docs = conn.findByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Value" "mauve" ]
 | 
			
		||||
                Expect.isEmpty docs "There should have been no documents returned"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findFirstByField" [
 | 
			
		||||
        testList "findByFieldsOrdered" [
 | 
			
		||||
            testTask "succeeds when sorting ascending" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
                let! docs =
 | 
			
		||||
                    conn.findByFieldsOrdered<JsonDocument>
 | 
			
		||||
                        SqliteDb.TableName Any [ Field.GT "NumValue" 15 ] [ Field.Named "Id" ]
 | 
			
		||||
                Expect.equal
 | 
			
		||||
                    (docs |> List.map _.Id |> String.concat "|") "five|four" "The documents were not ordered correctly"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when sorting descending" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
                let! docs =
 | 
			
		||||
                    conn.findByFieldsOrdered<JsonDocument>
 | 
			
		||||
                        SqliteDb.TableName Any [ Field.GT "NumValue" 15 ] [ Field.Named "Id DESC" ]
 | 
			
		||||
                Expect.equal
 | 
			
		||||
                    (docs |> List.map _.Id |> String.concat "|") "four|five" "The documents were not ordered correctly"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findFirstByFields" [
 | 
			
		||||
            testTask "succeeds when a document is found" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "another")
 | 
			
		||||
                Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
                let! doc = conn.findFirstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Value" "another" ]
 | 
			
		||||
                Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
                Expect.equal doc.Value.Id "two" "The incorrect document was returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when multiple documents are found" {
 | 
			
		||||
@ -235,8 +295,8 @@ let integrationTests =
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Sub.Foo" "green")
 | 
			
		||||
                Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
                let! doc = conn.findFirstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ]
 | 
			
		||||
                Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
                Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when a document is not found" {
 | 
			
		||||
@ -244,8 +304,32 @@ let integrationTests =
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! doc = conn.findFirstByField<JsonDocument> SqliteDb.TableName (Field.EQ "Value" "absent")
 | 
			
		||||
                Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
 | 
			
		||||
                let! doc = conn.findFirstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Value" "absent" ]
 | 
			
		||||
                Expect.isNone doc "There should not have been a document returned"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "findFirstByFieldsOrdered" [
 | 
			
		||||
            testTask "succeeds when sorting ascending" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
                let! doc =
 | 
			
		||||
                    conn.findFirstByFieldsOrdered<JsonDocument>
 | 
			
		||||
                        SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ] [ Field.Named "Sub.Bar" ]
 | 
			
		||||
                Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
                Expect.equal "two" doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when sorting descending" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
                let! doc =
 | 
			
		||||
                    conn.findFirstByFieldsOrdered<JsonDocument>
 | 
			
		||||
                        SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ] [ Field.Named "Sub.Bar DESC" ]
 | 
			
		||||
                Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
                Expect.equal "four" doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "updateById" [
 | 
			
		||||
@ -326,14 +410,14 @@ let integrationTests =
 | 
			
		||||
                do! conn.patchById SqliteDb.TableName "test" {| Foo = "green" |}
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "patchByField" [
 | 
			
		||||
        testList "patchByFields" [
 | 
			
		||||
            testTask "succeeds when a document is updated" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                do! conn.patchByField SqliteDb.TableName (Field.EQ "Value" "purple") {| NumValue = 77 |}
 | 
			
		||||
                let! after = conn.countByField SqliteDb.TableName (Field.EQ "NumValue" 77)
 | 
			
		||||
                do! conn.patchByFields SqliteDb.TableName Any [ Field.EQ "Value" "purple" ] {| NumValue = 77 |}
 | 
			
		||||
                let! after = conn.countByFields SqliteDb.TableName Any [ Field.EQ "NumValue" 77 ]
 | 
			
		||||
                Expect.equal after 2L "There should have been 2 documents returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when no document is updated" {
 | 
			
		||||
@ -344,7 +428,7 @@ let integrationTests =
 | 
			
		||||
                Expect.isEmpty before "There should have been no documents returned"
 | 
			
		||||
                
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                do! conn.patchByField SqliteDb.TableName (Field.EQ "Value" "burgundy") {| Foo = "green" |}
 | 
			
		||||
                do! conn.patchByFields SqliteDb.TableName Any [ Field.EQ "Value" "burgundy" ] {| Foo = "green" |}
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "removeFieldsById" [
 | 
			
		||||
@ -377,13 +461,13 @@ let integrationTests =
 | 
			
		||||
                do! conn.removeFieldsById SqliteDb.TableName "two" [ "Value" ]
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "removeFieldByField" [
 | 
			
		||||
        testList "removeFieldByFields" [
 | 
			
		||||
            testTask "succeeds when a field is removed" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                do! conn.removeFieldsByField SqliteDb.TableName (Field.EQ "NumValue" 17) [ "Sub" ]
 | 
			
		||||
                do! conn.removeFieldsByFields SqliteDb.TableName Any [ Field.EQ "NumValue" 17 ] [ "Sub" ]
 | 
			
		||||
                try
 | 
			
		||||
                    let! _ = conn.findById<string, JsonDocument> SqliteDb.TableName "four"
 | 
			
		||||
                    Expect.isTrue false "The updated document should have failed to parse"
 | 
			
		||||
@ -397,14 +481,14 @@ let integrationTests =
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
                
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                do! conn.removeFieldsByField SqliteDb.TableName (Field.EQ "NumValue" 17) [ "Nothing" ]
 | 
			
		||||
                do! conn.removeFieldsByFields SqliteDb.TableName Any [ Field.EQ "NumValue" 17 ] [ "Nothing" ]
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when no document is matched" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                
 | 
			
		||||
                // This not raising an exception is the test
 | 
			
		||||
                do! conn.removeFieldsByField SqliteDb.TableName (Field.NE "Abracadabra" "apple") [ "Value" ]
 | 
			
		||||
                do! conn.removeFieldsByFields SqliteDb.TableName Any [ Field.NE "Abracadabra" "apple" ] [ "Value" ]
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "deleteById" [
 | 
			
		||||
@ -427,13 +511,13 @@ let integrationTests =
 | 
			
		||||
                Expect.equal remaining 5L "There should have been 5 documents remaining"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
        testList "deleteByField" [
 | 
			
		||||
        testList "deleteByFields" [
 | 
			
		||||
            testTask "succeeds when documents are deleted" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                do! conn.deleteByField SqliteDb.TableName (Field.NE "Value" "purple")
 | 
			
		||||
                do! conn.deleteByFields SqliteDb.TableName Any [ Field.NE "Value" "purple" ]
 | 
			
		||||
                let! remaining = conn.countAll SqliteDb.TableName
 | 
			
		||||
                Expect.equal remaining 2L "There should have been 2 documents remaining"
 | 
			
		||||
            }
 | 
			
		||||
@ -442,7 +526,7 @@ let integrationTests =
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                do! conn.deleteByField SqliteDb.TableName (Field.EQ "Value" "crimson")
 | 
			
		||||
                do! conn.deleteByFields SqliteDb.TableName Any [ Field.EQ "Value" "crimson" ]
 | 
			
		||||
                let! remaining = conn.countAll SqliteDb.TableName
 | 
			
		||||
                Expect.equal remaining 5L "There should have been 5 documents remaining"
 | 
			
		||||
            }
 | 
			
		||||
@ -480,8 +564,8 @@ let integrationTests =
 | 
			
		||||
                use  conn = Configuration.dbConn ()
 | 
			
		||||
                do! loadDocs ()
 | 
			
		||||
    
 | 
			
		||||
                let! docs = conn.customList (Query.selectFromTable SqliteDb.TableName) [] fromData<JsonDocument>
 | 
			
		||||
                Expect.hasCountOf docs 5u (fun _ -> true) "There should have been 5 documents returned"
 | 
			
		||||
                let! docs = conn.customList (Query.find SqliteDb.TableName) [] fromData<JsonDocument>
 | 
			
		||||
                Expect.hasLength docs 5 "There should have been 5 documents returned"
 | 
			
		||||
            }
 | 
			
		||||
            testTask "succeeds when data is not found" {
 | 
			
		||||
                use! db   = SqliteDb.BuildDb()
 | 
			
		||||
 | 
			
		||||
@ -424,13 +424,48 @@ let findTests = testList "Find" [
 | 
			
		||||
            Expect.equal results [] "There should have been no documents returned"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "allOrdered" [
 | 
			
		||||
        testTask "succeeds when ordering numerically" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
            
 | 
			
		||||
            let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue" ]
 | 
			
		||||
            Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
            Expect.equal
 | 
			
		||||
                (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                "one|three|two|four|five"
 | 
			
		||||
                "The documents were not ordered correctly"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when ordering numerically descending" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
            
 | 
			
		||||
            let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue DESC" ]
 | 
			
		||||
            Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
            Expect.equal
 | 
			
		||||
                (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                "five|four|two|three|one"
 | 
			
		||||
                "The documents were not ordered correctly"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when ordering alphabetically" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
            
 | 
			
		||||
            let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "Id DESC" ]
 | 
			
		||||
            Expect.hasLength results 5 "There should have been 5 documents returned"
 | 
			
		||||
            Expect.equal
 | 
			
		||||
                (results |> List.map _.Id |> String.concat "|")
 | 
			
		||||
                "two|three|one|four|five"
 | 
			
		||||
                "The documents were not ordered correctly"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "byId" [
 | 
			
		||||
        testTask "succeeds when a document is found" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc = Find.byId<string, JsonDocument> SqliteDb.TableName "two"
 | 
			
		||||
            Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
            Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
            Expect.equal doc.Value.Id "two" "The incorrect document was returned"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when a document is not found" {
 | 
			
		||||
@ -438,7 +473,7 @@ let findTests = testList "Find" [
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc = Find.byId<string, JsonDocument> SqliteDb.TableName "three hundred eighty-seven"
 | 
			
		||||
            Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
 | 
			
		||||
            Expect.isNone doc "There should not have been a document returned"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "byFields" [
 | 
			
		||||
@ -457,13 +492,35 @@ let findTests = testList "Find" [
 | 
			
		||||
            Expect.isTrue (List.isEmpty docs) "There should have been no documents returned"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "byFieldsOrdered" [
 | 
			
		||||
        testTask "succeeds when sorting ascending" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! docs =
 | 
			
		||||
                Find.byFieldsOrdered<JsonDocument>
 | 
			
		||||
                    SqliteDb.TableName Any [ Field.GT "NumValue" 15 ] [ Field.Named "Id" ]
 | 
			
		||||
            Expect.equal
 | 
			
		||||
                (docs |> List.map _.Id |> String.concat "|") "five|four" "The documents were not ordered correctly"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when sorting descending" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! docs =
 | 
			
		||||
                Find.byFieldsOrdered<JsonDocument>
 | 
			
		||||
                    SqliteDb.TableName Any [ Field.GT "NumValue" 15 ] [ Field.Named "Id DESC" ]
 | 
			
		||||
            Expect.equal
 | 
			
		||||
                (docs |> List.map _.Id |> String.concat "|") "four|five" "The documents were not ordered correctly"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "firstByFields" [
 | 
			
		||||
        testTask "succeeds when a document is found" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc = Find.firstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Value" "another" ]
 | 
			
		||||
            Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
            Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
            Expect.equal doc.Value.Id "two" "The incorrect document was returned"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when multiple documents are found" {
 | 
			
		||||
@ -471,7 +528,7 @@ let findTests = testList "Find" [
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc = Find.firstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ]
 | 
			
		||||
            Expect.isTrue (Option.isSome doc) "There should have been a document returned"
 | 
			
		||||
            Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
            Expect.contains [ "two"; "four" ] doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when a document is not found" {
 | 
			
		||||
@ -479,7 +536,29 @@ let findTests = testList "Find" [
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc = Find.firstByFields<JsonDocument> SqliteDb.TableName Any [ Field.EQ "Value" "absent" ]
 | 
			
		||||
            Expect.isFalse (Option.isSome doc) "There should not have been a document returned"
 | 
			
		||||
            Expect.isNone doc "There should not have been a document returned"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
    testList "firstByFieldsOrdered" [
 | 
			
		||||
        testTask "succeeds when sorting ascending" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc =
 | 
			
		||||
                Find.firstByFieldsOrdered<JsonDocument>
 | 
			
		||||
                    SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ] [ Field.Named "Sub.Bar" ]
 | 
			
		||||
            Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
            Expect.equal "two" doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
        }
 | 
			
		||||
        testTask "succeeds when sorting descending" {
 | 
			
		||||
            use! db = SqliteDb.BuildDb()
 | 
			
		||||
            do! loadDocs ()
 | 
			
		||||
 | 
			
		||||
            let! doc =
 | 
			
		||||
                Find.firstByFieldsOrdered<JsonDocument>
 | 
			
		||||
                    SqliteDb.TableName Any [ Field.EQ "Sub.Foo" "green" ] [ Field.Named "Sub.Bar DESC" ]
 | 
			
		||||
            Expect.isSome doc "There should have been a document returned"
 | 
			
		||||
            Expect.equal "four" doc.Value.Id "An incorrect document was returned"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user