diff --git a/src/Postgres/Extensions.fs b/src/Postgres/Extensions.fs
index e53536c..da0d24d 100644
--- a/src/Postgres/Extensions.fs
+++ b/src/Postgres/Extensions.fs
@@ -38,7 +38,7 @@ module Extensions =
/// The query to retrieve the results
/// Parameters to use for the query
/// The mapping function between the document and the domain item
- /// Some with the first matching result, or None if not found
+ /// Some with the first matching result, or None if not found
member conn.customSingle<'TDoc> query parameters (mapFunc: RowReader -> 'TDoc) =
Custom.single<'TDoc> query parameters mapFunc (Sql.existingConnection conn)
@@ -102,7 +102,7 @@ module Extensions =
member conn.countAll tableName =
Count.all tableName (Sql.existingConnection conn)
- /// Count matching documents using JSON field comparisons (->> =, etc.)
+ /// Count matching documents using JSON field comparisons (->> =, etc.)
/// The table in which documents should be counted (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -110,14 +110,14 @@ module Extensions =
member conn.countByFields tableName howMatched fields =
Count.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Count matching documents using a JSON containment query (@>)
+ /// Count matching documents using a JSON containment query (@>)
/// The table in which documents should be counted (may include schema)
/// The document to match with the containment query
/// The count of the documents in the table
member conn.countByContains tableName criteria =
Count.byContains tableName criteria (Sql.existingConnection conn)
- /// Count matching documents using a JSON Path match query (@?)
+ /// Count matching documents using a JSON Path match query (@?)
/// The table in which documents should be counted (may include schema)
/// The JSON Path expression to be matched
/// The count of the documents in the table
@@ -131,7 +131,7 @@ module Extensions =
member conn.existsById tableName docId =
Exists.byId tableName docId (Sql.existingConnection conn)
- /// Determine if a document exists using JSON field comparisons (->> =, etc.)
+ /// Determine if a document exists using JSON field comparisons (->> =, etc.)
/// The table in which existence should be checked (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -139,14 +139,14 @@ module Extensions =
member conn.existsByFields tableName howMatched fields =
Exists.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Determine if a document exists using a JSON containment query (@>)
+ /// Determine if a document exists using a JSON containment query (@>)
/// The table in which existence should be checked (may include schema)
/// The document to match with the containment query
/// True if any matching documents exist, false if not
member conn.existsByContains tableName criteria =
Exists.byContains tableName criteria (Sql.existingConnection conn)
- /// Determine if a document exists using a JSON Path match query (@?)
+ /// Determine if a document exists using a JSON Path match query (@?)
/// The table in which existence should be checked (may include schema)
/// The JSON Path expression to be matched
/// True if any matching documents exist, false if not
@@ -169,11 +169,11 @@ module Extensions =
/// Retrieve a document by its ID
/// The table from which a document should be retrieved (may include schema)
/// The ID of the document to retrieve
- /// Some with the document if found, None otherwise
+ /// Some with the document if found, None otherwise
member conn.findById<'TKey, 'TDoc> tableName docId =
Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn)
- /// Retrieve documents matching JSON field comparisons (->> =, etc.)
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.)
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -182,8 +182,8 @@ module Extensions =
Find.byFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
///
- /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields
- /// in the document
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in
+ /// the document
///
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
@@ -194,7 +194,7 @@ module Extensions =
Find.byFieldsOrdered<'TDoc>
tableName howMatched queryFields orderFields (Sql.existingConnection conn)
- /// Retrieve documents matching a JSON containment query (@>)
+ /// Retrieve documents matching a JSON containment query (@>)
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
/// All documents matching the given containment query
@@ -202,7 +202,7 @@ module Extensions =
Find.byContains<'TDoc> tableName criteria (Sql.existingConnection conn)
///
- /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the
+ /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the
/// document
///
/// The table from which documents should be retrieved (may include schema)
@@ -212,7 +212,7 @@ module Extensions =
member conn.findByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
Find.byContainsOrdered<'TDoc> tableName criteria orderFields (Sql.existingConnection conn)
- /// Retrieve documents matching a JSON Path match query (@?)
+ /// Retrieve documents matching a JSON Path match query (@?)
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
/// All documents matching the given JSON Path expression
@@ -220,8 +220,7 @@ module Extensions =
Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
///
- /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the
- /// document
+ /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
///
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
@@ -230,65 +229,65 @@ module Extensions =
member conn.findByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
Find.byJsonPathOrdered<'TDoc> tableName jsonPath orderFields (Sql.existingConnection conn)
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
Find.firstByFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
///
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the
- /// given fields in the document
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
+ /// fields in the document
///
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
/// Fields by which the results should be ordered
///
- /// Some with the first document ordered by the given fields, or None if not found
+ /// Some with the first document ordered by the given fields, or None if not found
///
member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
Find.firstByFieldsOrdered<'TDoc>
tableName howMatched queryFields orderFields (Sql.existingConnection conn)
- /// Retrieve the first document matching a JSON containment query (@>)
+ /// Retrieve the first document matching a JSON containment query (@>)
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
member conn.findFirstByContains<'TDoc> tableName (criteria: obj) =
Find.firstByContains<'TDoc> tableName criteria (Sql.existingConnection conn)
///
- /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields
- /// in the document
+ /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in
+ /// the document
///
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
/// Fields by which the results should be ordered
///
- /// Some with the first document ordered by the given fields, or None if not found
+ /// Some with the first document ordered by the given fields, or None if not found
///
member conn.findFirstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
Find.firstByContainsOrdered<'TDoc> tableName criteria orderFields (Sql.existingConnection conn)
- /// Retrieve the first document matching a JSON Path match query (@?)
+ /// Retrieve the first document matching a JSON Path match query (@?)
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
member conn.findFirstByJsonPath<'TDoc> tableName jsonPath =
Find.firstByJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
///
- /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in
- /// the document
+ /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
+ /// document
///
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
/// Fields by which the results should be ordered
///
- /// Some with the first document ordered by the given fields, or None if not found
+ /// Some with the first document ordered by the given fields, or None if not found
///
member conn.findFirstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
Find.firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields (Sql.existingConnection conn)
@@ -605,7 +604,7 @@ module Extensions =
Patch.byId tableName docId patch (Sql.existingConnection conn)
///
- /// Patch documents using a JSON field comparison query in the WHERE clause (->> =,
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =,
/// etc.)
///
/// The table in which documents should be patched (may include schema)
@@ -616,7 +615,7 @@ module Extensions =
Patch.byFields tableName howMatched fields patch (Sql.existingConnection conn)
///
- /// Patch documents using a JSON containment query in the WHERE clause (@>)
+ /// Patch documents using a JSON containment query in the WHERE clause (@>)
///
/// The table in which documents should be patched (may include schema)
/// The document to match the containment query
@@ -624,7 +623,7 @@ module Extensions =
member conn.patchByContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
Patch.byContains tableName criteria patch (Sql.existingConnection conn)
- /// Patch documents using a JSON Path match query in the WHERE clause (@?)
+ /// Patch documents using a JSON Path match query in the WHERE clause (@?)
/// The table in which documents should be patched (may include schema)
/// The JSON Path expression to match
/// The partial document to patch the existing document
@@ -646,14 +645,14 @@ module Extensions =
member conn.removeFieldsByFields tableName howMatched fields fieldNames =
RemoveFields.byFields tableName howMatched fields fieldNames (Sql.existingConnection conn)
- /// Remove fields from documents via a JSON containment query (@>)
+ /// Remove fields from documents via a JSON containment query (@>)
/// The table in which documents should be modified (may include schema)
/// The document to match the containment query
/// One or more field names to remove from the matching documents
member conn.removeFieldsByContains tableName (criteria: 'TContains) fieldNames =
RemoveFields.byContains tableName criteria fieldNames (Sql.existingConnection conn)
- /// Remove fields from documents via a JSON Path match query (@?)
+ /// Remove fields from documents via a JSON Path match query (@?)
/// The table in which documents should be modified (may include schema)
/// The JSON Path expression to match
/// One or more field names to remove from the matching documents
@@ -666,14 +665,14 @@ module Extensions =
member conn.deleteById tableName (docId: 'TKey) =
Delete.byId tableName docId (Sql.existingConnection conn)
- /// Delete documents by matching a JSON field comparison query (->> =, etc.)
+ /// Delete documents by matching a JSON field comparison query (->> =, etc.)
/// The table in which documents should be deleted (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
member conn.deleteByFields tableName howMatched fields =
Delete.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Delete documents by matching a JSON contains query (@>)
+ /// Delete documents by matching a JSON contains query (@>)
/// The table in which documents should be deleted (may include schema)
/// The document to match the containment query
member conn.deleteByContains tableName (criteria: 'TContains) =
@@ -707,6 +706,7 @@ type NpgsqlConnectionCSharpExtensions =
/// Parameters to use for the query
/// The mapping function to extract the document
/// A JSON array of results for the given query
+ []
static member inline CustomJsonArray(conn, query, parameters, mapFunc) =
Custom.JsonArray(query, parameters, mapFunc, Sql.existingConnection conn)
@@ -716,6 +716,7 @@ type NpgsqlConnectionCSharpExtensions =
/// Parameters to use for the query
/// The StreamWriter to which the results should be written
/// The mapping function to extract the document
+ []
static member inline WriteCustomJsonArray(conn, query, parameters, writer, mapFunc) =
Custom.WriteJsonArray(query, parameters, writer, mapFunc, Sql.existingConnection conn)
@@ -724,7 +725,7 @@ type NpgsqlConnectionCSharpExtensions =
/// The query to retrieve the results
/// Parameters to use for the query
/// The mapping function between the document and the domain item
- /// The first matching result, or null if not found
+ /// The first matching result, or null if not found
[]
static member inline CustomSingle<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, query, parameters, mapFunc: System.Func) =
@@ -736,6 +737,7 @@ type NpgsqlConnectionCSharpExtensions =
/// Parameters to use for the query
/// The mapping function to extract the document
/// The JSON document with the first matching result, or an empty document if not found
+ []
static member inline CustomJsonSingle(conn, query, parameters, mapFunc) =
Custom.JsonSingle(query, parameters, mapFunc, Sql.existingConnection conn)
@@ -806,7 +808,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline CountAll(conn, tableName) =
Count.all tableName (Sql.existingConnection conn)
- /// Count matching documents using JSON field comparisons (->> =, etc.)
+ /// Count matching documents using JSON field comparisons (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be counted (may include schema)
/// Whether to match any or all of the field conditions
@@ -816,7 +818,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline CountByFields(conn, tableName, howMatched, fields) =
Count.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Count matching documents using a JSON containment query (@>)
+ /// Count matching documents using a JSON containment query (@>)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be counted (may include schema)
/// The document to match with the containment query
@@ -825,7 +827,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline CountByContains(conn, tableName, criteria: 'TCriteria) =
Count.byContains tableName criteria (Sql.existingConnection conn)
- /// Count matching documents using a JSON Path match query (@?)
+ /// Count matching documents using a JSON Path match query (@?)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be counted (may include schema)
/// The JSON Path expression to be matched
@@ -843,7 +845,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline ExistsById(conn, tableName, docId) =
Exists.byId tableName docId (Sql.existingConnection conn)
- /// Determine if a document exists using JSON field comparisons (->> =, etc.)
+ /// Determine if a document exists using JSON field comparisons (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table in which existence should be checked (may include schema)
/// Whether to match any or all of the field conditions
@@ -853,7 +855,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline ExistsByFields(conn, tableName, howMatched, fields) =
Exists.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Determine if a document exists using a JSON containment query (@>)
+ /// Determine if a document exists using a JSON containment query (@>)
/// The NpgsqlConnection on which to run the query
/// The table in which existence should be checked (may include schema)
/// The document to match with the containment query
@@ -862,7 +864,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline ExistsByContains(conn, tableName, criteria: 'TCriteria) =
Exists.byContains tableName criteria (Sql.existingConnection conn)
- /// Determine if a document exists using a JSON Path match query (@?)
+ /// Determine if a document exists using a JSON Path match query (@?)
/// The NpgsqlConnection on which to run the query
/// The table in which existence should be checked (may include schema)
/// The JSON Path expression to be matched
@@ -892,12 +894,12 @@ type NpgsqlConnectionCSharpExtensions =
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// The ID of the document to retrieve
- /// The document if found, null otherwise
+ /// The document if found, null otherwise
[]
static member inline FindById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(conn, tableName, docId: 'TKey) =
Find.ById<'TKey, 'TDoc>(tableName, docId, Sql.existingConnection conn)
- /// Retrieve documents matching JSON field comparisons (->> =, etc.)
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
@@ -908,8 +910,8 @@ type NpgsqlConnectionCSharpExtensions =
Find.ByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
///
- /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in
- /// the document
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in the
+ /// document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -922,7 +924,7 @@ type NpgsqlConnectionCSharpExtensions =
Find.ByFieldsOrdered<'TDoc>(
tableName, howMatched, queryFields, orderFields, Sql.existingConnection conn)
- /// Retrieve documents matching a JSON containment query (@>)
+ /// Retrieve documents matching a JSON containment query (@>)
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
@@ -932,8 +934,7 @@ type NpgsqlConnectionCSharpExtensions =
Find.ByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn)
///
- /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the
- /// document
+ /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -944,7 +945,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindByContainsOrdered<'TDoc>(conn, tableName, criteria: obj, orderFields) =
Find.ByContainsOrdered<'TDoc>(tableName, criteria, orderFields, Sql.existingConnection conn)
- /// Retrieve documents matching a JSON Path match query (@?)
+ /// Retrieve documents matching a JSON Path match query (@?)
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
@@ -954,7 +955,7 @@ type NpgsqlConnectionCSharpExtensions =
Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
///
- /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
+ /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -965,19 +966,19 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindByJsonPathOrdered<'TDoc>(conn, tableName, jsonPath, orderFields) =
Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, Sql.existingConnection conn)
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
- /// The first document, or null if not found
+ /// The first document, or null if not found
[]
static member inline FindFirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, howMatched, fields) =
Find.FirstByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
///
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
/// fields in the document
///
/// The NpgsqlConnection on which to run the query
@@ -985,55 +986,55 @@ type NpgsqlConnectionCSharpExtensions =
/// Whether to match any or all of the field conditions
/// The field conditions to match
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
[]
static member inline FindFirstByFieldsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, howMatched, queryFields, orderFields) =
Find.FirstByFieldsOrdered<'TDoc>(
tableName, howMatched, queryFields, orderFields, Sql.existingConnection conn)
- /// Retrieve the first document matching a JSON containment query (@>)
+ /// Retrieve the first document matching a JSON containment query (@>)
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
- /// The first document, or null if not found
+ /// The first document, or null if not found
[]
static member inline FindFirstByContains<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, criteria: obj) =
Find.FirstByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn)
///
- /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in
- /// the document
+ /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
+ /// document
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
[]
static member inline FindFirstByContainsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, criteria: obj, orderFields) =
Find.FirstByContainsOrdered<'TDoc>(tableName, criteria, orderFields, Sql.existingConnection conn)
- /// Retrieve the first document matching a JSON Path match query (@?)
+ /// Retrieve the first document matching a JSON Path match query (@?)
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
- /// The first document, or null if not found
+ /// The first document, or null if not found
[]
static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null and 'TDoc: not struct>(conn, tableName, jsonPath) =
Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
///
- /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
+ /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
[]
static member inline FindFirstByJsonPathOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, jsonPath, orderFields) =
@@ -1107,8 +1108,7 @@ type NpgsqlConnectionCSharpExtensions =
Json.byFields tableName howMatched fields (Sql.existingConnection conn)
///
- /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =,
- /// etc.)
+ /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =, etc.)
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1120,8 +1120,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.writeByFields tableName writer howMatched fields (Sql.existingConnection conn)
///
- /// Retrieve JSON documents matching JSON field comparisons (->> =, etc.) ordered by the given
- /// fields in the document
+ /// Retrieve JSON documents matching JSON field comparisons (->> =, etc.) ordered by the given fields
+ /// in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1134,8 +1134,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.byFieldsOrdered tableName howMatched queryFields orderFields (Sql.existingConnection conn)
///
- /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =,
- /// etc.) ordered by the given fields in the document
+ /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =, etc.)
+ /// ordered by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1181,8 +1181,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.byContainsOrdered tableName criteria orderFields (Sql.existingConnection conn)
///
- /// Write JSON documents to the given StreamWriter matching a JSON containment query (@>)
- /// ordered by the given fields in the document
+ /// Write JSON documents to the given StreamWriter matching a JSON containment query (@>) ordered
+ /// by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1214,8 +1214,7 @@ type NpgsqlConnectionCSharpExtensions =
Json.writeByJsonPath tableName writer jsonPath (Sql.existingConnection conn)
///
- /// Retrieve JSON documents matching a JSON Path match query (@?) ordered by the given fields in the
- /// document
+ /// Retrieve JSON documents matching a JSON Path match query (@?) ordered by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1227,8 +1226,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.byJsonPathOrdered tableName jsonPath orderFields (Sql.existingConnection conn)
///
- /// Write JSON documents to the given StreamWriter matching a JSON Path match query (@?) ordered
- /// by the given fields in the document
+ /// Write JSON documents to the given StreamWriter matching a JSON Path match query (@?) ordered by
+ /// the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which documents should be retrieved (may include schema)
@@ -1239,9 +1238,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline WriteJsonByJsonPathOrdered(conn, tableName, writer, jsonPath, orderFields) =
Json.writeByJsonPathOrdered tableName writer jsonPath orderFields (Sql.existingConnection conn)
- ///
- /// Retrieve the first JSON document matching JSON field comparisons (->> =, etc.)
- ///
+ /// Retrieve the first JSON document matching JSON field comparisons (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
@@ -1303,8 +1300,7 @@ type NpgsqlConnectionCSharpExtensions =
Json.firstByContains tableName criteria (Sql.existingConnection conn)
///
- /// Write the first JSON document to the given StreamWriter matching a JSON containment query
- /// (@>)
+ /// Write the first JSON document to the given StreamWriter matching a JSON containment query (@>)
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
@@ -1315,8 +1311,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.writeFirstByContains tableName writer criteria (Sql.existingConnection conn)
///
- /// Retrieve the first JSON document matching a JSON containment query (@>) ordered by the given
- /// fields in the document
+ /// Retrieve the first JSON document matching a JSON containment query (@>) ordered by the given fields in
+ /// the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
@@ -1328,8 +1324,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.firstByContainsOrdered tableName criteria orderFields (Sql.existingConnection conn)
///
- /// Write the first JSON document to the given StreamWriter matching a JSON containment query
- /// (@>) ordered by the given fields in the document
+ /// Write the first JSON document to the given StreamWriter matching a JSON containment query (@>)
+ /// ordered by the given fields in the document
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
@@ -1361,8 +1357,8 @@ type NpgsqlConnectionCSharpExtensions =
Json.writeFirstByJsonPath tableName writer jsonPath (Sql.existingConnection conn)
///
- /// Retrieve the first JSON document matching a JSON Path match query (@?) ordered by the given fields
- /// in the document
+ /// Retrieve the first JSON document matching a JSON Path match query (@?) ordered by the given fields in the
+ /// document
///
/// The NpgsqlConnection on which to run the query
/// The table from which a document should be retrieved (may include schema)
@@ -1416,7 +1412,7 @@ type NpgsqlConnectionCSharpExtensions =
Patch.byId tableName docId patch (Sql.existingConnection conn)
///
- /// Patch documents using a JSON field comparison query in the WHERE clause (->> =, etc.)
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =, etc.)
///
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be patched (may include schema)
@@ -1427,7 +1423,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline PatchByFields(conn, tableName, howMatched, fields, patch: 'TPatch) =
Patch.byFields tableName howMatched fields patch (Sql.existingConnection conn)
- /// Patch documents using a JSON containment query in the WHERE clause (@>)
+ /// Patch documents using a JSON containment query in the WHERE clause (@>)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be patched (may include schema)
/// The document to match the containment query
@@ -1436,7 +1432,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline PatchByContains(conn, tableName, criteria: 'TCriteria, patch: 'TPatch) =
Patch.byContains tableName criteria patch (Sql.existingConnection conn)
- /// Patch documents using a JSON Path match query in the WHERE clause (@?)
+ /// Patch documents using a JSON Path match query in the WHERE clause (@?)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be patched (may include schema)
/// The JSON Path expression to match
@@ -1464,7 +1460,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline RemoveFieldsByFields(conn, tableName, howMatched, fields, fieldNames) =
RemoveFields.byFields tableName howMatched fields fieldNames (Sql.existingConnection conn)
- /// Remove fields from documents via a JSON containment query (@>)
+ /// Remove fields from documents via a JSON containment query (@>)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be modified (may include schema)
/// The document to match the containment query
@@ -1473,7 +1469,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline RemoveFieldsByContains(conn, tableName, criteria: 'TContains, fieldNames) =
RemoveFields.byContains tableName criteria fieldNames (Sql.existingConnection conn)
- /// Remove fields from documents via a JSON Path match query (@?)
+ /// Remove fields from documents via a JSON Path match query (@?)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be modified (may include schema)
/// The JSON Path expression to match
@@ -1490,7 +1486,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline DeleteById(conn, tableName, docId: 'TKey) =
Delete.byId tableName docId (Sql.existingConnection conn)
- /// Delete documents by matching a JSON field comparison query (->> =, etc.)
+ /// Delete documents by matching a JSON field comparison query (->> =, etc.)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be deleted (may include schema)
/// Whether to match any or all of the field conditions
@@ -1499,7 +1495,7 @@ type NpgsqlConnectionCSharpExtensions =
static member inline DeleteByFields(conn, tableName, howMatched, fields) =
Delete.byFields tableName howMatched fields (Sql.existingConnection conn)
- /// Delete documents by matching a JSON contains query (@>)
+ /// Delete documents by matching a JSON contains query (@>)
/// The NpgsqlConnection on which to run the query
/// The table in which documents should be deleted (may include schema)
/// The document to match the containment query
diff --git a/src/Postgres/Functions.fs b/src/Postgres/Functions.fs
index 7ffca97..f9f0eae 100644
--- a/src/Postgres/Functions.fs
+++ b/src/Postgres/Functions.fs
@@ -59,7 +59,7 @@ module Custom =
/// The query to retrieve the results
/// Parameters to use for the query
/// The mapping function between the document and the domain item
- /// Some with the first matching result, or None if not found
+ /// Some with the first matching result, or None if not found
[]
let single<'TDoc> query parameters (mapFunc: RowReader -> 'TDoc) =
WithProps.Custom.single<'TDoc> query parameters mapFunc (fromDataSource ())
@@ -68,7 +68,7 @@ module Custom =
/// The query to retrieve the results
/// Parameters to use for the query
/// The mapping function between the document and the domain item
- /// The first matching result, or null if not found
+ /// The first matching result, or null if not found
let Single<'TDoc when 'TDoc: null and 'TDoc: not struct>(
query, parameters, mapFunc: System.Func) =
WithProps.Custom.Single<'TDoc>(query, parameters, mapFunc, fromDataSource ())
@@ -171,7 +171,7 @@ module Count =
let all tableName =
WithProps.Count.all tableName (fromDataSource ())
- /// Count matching documents using JSON field comparisons (->> =, etc.)
+ /// Count matching documents using JSON field comparisons (->> =, etc.)
/// The table in which documents should be counted (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -180,7 +180,7 @@ module Count =
let byFields tableName howMatched fields =
WithProps.Count.byFields tableName howMatched fields (fromDataSource ())
- /// Count matching documents using a JSON containment query (@>)
+ /// Count matching documents using a JSON containment query (@>)
/// The table in which documents should be counted (may include schema)
/// The document to match with the containment query
/// The count of the documents in the table
@@ -188,7 +188,7 @@ module Count =
let byContains tableName criteria =
WithProps.Count.byContains tableName criteria (fromDataSource ())
- /// Count matching documents using a JSON Path match query (@?)
+ /// Count matching documents using a JSON Path match query (@?)
/// The table in which documents should be counted (may include schema)
/// The JSON Path expression to be matched
/// The count of the documents in the table
@@ -209,7 +209,7 @@ module Exists =
let byId tableName docId =
WithProps.Exists.byId tableName docId (fromDataSource ())
- /// Determine if a document exists using JSON field comparisons (->> =, etc.)
+ /// Determine if a document exists using JSON field comparisons (->> =, etc.)
/// The table in which existence should be checked (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -218,7 +218,7 @@ module Exists =
let byFields tableName howMatched fields =
WithProps.Exists.byFields tableName howMatched fields (fromDataSource ())
- /// Determine if a document exists using a JSON containment query (@>)
+ /// Determine if a document exists using a JSON containment query (@>)
/// The table in which existence should be checked (may include schema)
/// The document to match with the containment query
/// True if any matching documents exist, false if not
@@ -226,7 +226,7 @@ module Exists =
let byContains tableName criteria =
WithProps.Exists.byContains tableName criteria (fromDataSource ())
- /// Determine if a document exists using a JSON Path match query (@?)
+ /// Determine if a document exists using a JSON Path match query (@?)
/// The table in which existence should be checked (may include schema)
/// The JSON Path expression to be matched
/// True if any matching documents exist, false if not
@@ -270,7 +270,7 @@ module Find =
/// Retrieve a document by its ID
/// The table from which a document should be retrieved (may include schema)
/// The ID of the document to retrieve
- /// Some with the document if found, None otherwise
+ /// Some with the document if found, None otherwise
[]
let byId<'TKey, 'TDoc> tableName docId =
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (fromDataSource ())
@@ -278,11 +278,11 @@ module Find =
/// Retrieve a document by its ID
/// The table from which a document should be retrieved (may include schema)
/// The ID of the document to retrieve
- /// The document if found, null otherwise
+ /// The document if found, null otherwise
let ById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, docId: 'TKey) =
WithProps.Find.ById<'TKey, 'TDoc>(tableName, docId, fromDataSource ())
- /// Retrieve documents matching JSON field comparisons (->> =, etc.)
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.)
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -291,7 +291,7 @@ module Find =
let byFields<'TDoc> tableName howMatched fields =
WithProps.Find.byFields<'TDoc> tableName howMatched fields (fromDataSource ())
- /// Retrieve documents matching JSON field comparisons (->> =, etc.)
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.)
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -300,8 +300,8 @@ module Find =
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
///
- /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in
- /// the document
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in the
+ /// document
///
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
@@ -313,8 +313,8 @@ module Find =
WithProps.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields (fromDataSource ())
///
- /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in
- /// the document
+ /// Retrieve documents matching JSON field comparisons (->> =, etc.) ordered by the given fields in the
+ /// document
///
/// The table from which documents should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
@@ -324,7 +324,7 @@ module Find =
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields) =
WithProps.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
- /// Retrieve documents matching a JSON containment query (@>)
+ /// Retrieve documents matching a JSON containment query (@>)
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
/// All documents matching the given containment query
@@ -332,7 +332,7 @@ module Find =
let byContains<'TDoc> tableName (criteria: obj) =
WithProps.Find.byContains<'TDoc> tableName criteria (fromDataSource ())
- /// Retrieve documents matching a JSON containment query (@>)
+ /// Retrieve documents matching a JSON containment query (@>)
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
/// All documents matching the given containment query
@@ -340,8 +340,7 @@ module Find =
WithProps.Find.ByContains<'TDoc>(tableName, criteria, fromDataSource ())
///
- /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the
- /// document
+ /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
///
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
@@ -352,8 +351,7 @@ module Find =
WithProps.Find.byContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
///
- /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the
- /// document
+ /// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
///
/// The table from which documents should be retrieved (may include schema)
/// The document to match with the containment query
@@ -362,7 +360,7 @@ module Find =
let ByContainsOrdered<'TDoc>(tableName, criteria: obj, orderFields) =
WithProps.Find.ByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
- /// Retrieve documents matching a JSON Path match query (@?)
+ /// Retrieve documents matching a JSON Path match query (@?)
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
/// All documents matching the given JSON Path expression
@@ -370,7 +368,7 @@ module Find =
let byJsonPath<'TDoc> tableName jsonPath =
WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (fromDataSource ())
- /// Retrieve documents matching a JSON Path match query (@?)
+ /// Retrieve documents matching a JSON Path match query (@?)
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
/// All documents matching the given JSON Path expression
@@ -378,7 +376,7 @@ module Find =
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
///
- /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
+ /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
///
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
@@ -389,7 +387,7 @@ module Find =
WithProps.Find.byJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
///
- /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
+ /// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
///
/// The table from which documents should be retrieved (may include schema)
/// The JSON Path expression to match
@@ -398,128 +396,122 @@ module Find =
let ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields) =
WithProps.Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
[]
let firstByFields<'TDoc> tableName howMatched fields =
WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (fromDataSource ())
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.)
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
- /// The first document, or null if not found
+ /// The first document, or null if not found
let FirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, howMatched, fields) =
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
///
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
/// fields in the document
///
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
/// Fields by which the results should be ordered
- ///
- /// Some with the first document ordered by the given fields, or None if not found
- ///
+ /// Some with the first document ordered by the given fields, or None if not found
[]
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithProps.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields (fromDataSource ())
///
- /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
+ /// Retrieve the first document matching JSON field comparisons (->> =, etc.) ordered by the given
/// fields in the document
///
/// The table from which a document should be retrieved (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
let FirstByFieldsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
tableName, howMatched, queryFields, orderFields) =
WithProps.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
- /// Retrieve the first document matching a JSON containment query (@>)
+ /// Retrieve the first document matching a JSON containment query (@>)
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
[]
let firstByContains<'TDoc> tableName (criteria: obj) =
WithProps.Find.firstByContains<'TDoc> tableName criteria (fromDataSource ())
- /// Retrieve the first document matching a JSON containment query (@>)
+ /// Retrieve the first document matching a JSON containment query (@>)
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
- /// The first document, or null if not found
+ /// The first document, or null if not found
let FirstByContains<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, criteria: obj) =
WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, fromDataSource ())
///
- /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in
- /// the document
+ /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
+ /// document
///
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
/// Fields by which the results should be ordered
- ///
- /// Some with the first document ordered by the given fields, or None if not found
- ///
+ /// Some with the first document ordered by the given fields, or None if not found
[]
let firstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
WithProps.Find.firstByContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
///
- /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in
- /// the document
+ /// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
+ /// document
///
/// The table from which a document should be retrieved (may include schema)
/// The document to match with the containment query
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
let FirstByContainsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, criteria: obj, orderFields) =
WithProps.Find.FirstByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
- /// Retrieve the first document matching a JSON Path match query (@?)
+ /// Retrieve the first document matching a JSON Path match query (@?)
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
- /// Some with the first document, or None if not found
+ /// Some with the first document, or None if not found
[]
let firstByJsonPath<'TDoc> tableName jsonPath =
WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (fromDataSource ())
- /// Retrieve the first document matching a JSON Path match query (@?)
+ /// Retrieve the first document matching a JSON Path match query (@?)
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
- /// The first document, or null if not found
+ /// The first document, or null if not found
let FirstByJsonPath<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, jsonPath) =
WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
///
- /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
+ /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document
///
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
/// Fields by which the results should be ordered
- ///
- /// Some with the first document ordered by the given fields, or None if not found
- ///
+ /// Some with the first document ordered by the given fields, or None if not found
[]
let firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
WithProps.Find.firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
///
- /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
+ /// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document
///
/// The table from which a document should be retrieved (may include schema)
/// The JSON Path expression to match
/// Fields by which the results should be ordered
- /// The first document ordered by the given fields, or null if not found
+ /// The first document ordered by the given fields, or null if not found
let FirstByJsonPathOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, jsonPath, orderFields) =
WithProps.Find.FirstByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
@@ -885,7 +877,7 @@ module Patch =
WithProps.Patch.byId tableName docId patch (fromDataSource ())
///
- /// Patch documents using a JSON field comparison query in the WHERE clause (->> =, etc.)
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =, etc.)
///
/// The table in which documents should be patched (may include schema)
/// Whether to match any or all of the field conditions
@@ -895,7 +887,7 @@ module Patch =
let byFields tableName howMatched fields (patch: 'TPatch) =
WithProps.Patch.byFields tableName howMatched fields patch (fromDataSource ())
- /// Patch documents using a JSON containment query in the WHERE clause (@>)
+ /// Patch documents using a JSON containment query in the WHERE clause (@>)
/// The table in which documents should be patched (may include schema)
/// The document to match the containment query
/// The partial document to patch the existing document
@@ -903,7 +895,7 @@ module Patch =
let byContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
WithProps.Patch.byContains tableName criteria patch (fromDataSource ())
- /// Patch documents using a JSON Path match query in the WHERE clause (@?)
+ /// Patch documents using a JSON Path match query in the WHERE clause (@?)
/// The table in which documents should be patched (may include schema)
/// The JSON Path expression to match
/// The partial document to patch the existing document
@@ -933,7 +925,7 @@ module RemoveFields =
let byFields tableName howMatched fields fieldNames =
WithProps.RemoveFields.byFields tableName howMatched fields fieldNames (fromDataSource ())
- /// Remove fields from documents via a JSON containment query (@>)
+ /// Remove fields from documents via a JSON containment query (@>)
/// The table in which documents should be modified (may include schema)
/// The document to match the containment query
/// One or more field names to remove from the matching documents
@@ -941,7 +933,7 @@ module RemoveFields =
let byContains tableName (criteria: 'TContains) fieldNames =
WithProps.RemoveFields.byContains tableName criteria fieldNames (fromDataSource ())
- /// Remove fields from documents via a JSON Path match query (@?)
+ /// Remove fields from documents via a JSON Path match query (@?)
/// The table in which documents should be modified (may include schema)
/// The JSON Path expression to match
/// One or more field names to remove from the matching documents
@@ -961,7 +953,7 @@ module Delete =
let byId tableName (docId: 'TKey) =
WithProps.Delete.byId tableName docId (fromDataSource ())
- /// Delete documents by matching a JSON field comparison query (->> =, etc.)
+ /// Delete documents by matching a JSON field comparison query (->> =, etc.)
/// The table in which documents should be deleted (may include schema)
/// Whether to match any or all of the field conditions
/// The field conditions to match
@@ -969,7 +961,7 @@ module Delete =
let byFields tableName howMatched fields =
WithProps.Delete.byFields tableName howMatched fields (fromDataSource ())
- /// Delete documents by matching a JSON contains query (@>)
+ /// Delete documents by matching a JSON contains query (@>)
/// The table in which documents should be deleted (may include schema)
/// The document to match the containment query
[]
diff --git a/src/Postgres/Library.fs b/src/Postgres/Library.fs
index 62e38ae..beb9542 100644
--- a/src/Postgres/Library.fs
+++ b/src/Postgres/Library.fs
@@ -7,11 +7,11 @@ open System.Text
[]
type DocumentIndex =
- /// A GIN index with standard operations (all operators supported)
+ /// A GIN index with standard operations (all operators supported)
| Full
///
- /// A GIN index with JSONPath operations (optimized for @>, @?, @@ operators)
+ /// A GIN index with JSON Path operations (optimized for @>, @?, @@ operators)
///
| Optimized
@@ -97,7 +97,7 @@ module Parameters =
name, Sql.jsonb (Configuration.serializer().Serialize it)
/// Create JSON field parameters
- /// The Fields to convert to parameters
+ /// The Fields to convert to parameters
/// The current parameters for the query
/// A unified sequence of parameter names and values
[]
@@ -132,7 +132,7 @@ module Parameters =
/// Append JSON field name parameters for the given field names to the given parameters
/// The names of fields to be addressed
- /// The name (@name) and parameter value for the field names
+ /// The name (@name) and parameter value for the field names
[]
let fieldNameParams (fieldNames: string seq) =
if Seq.length fieldNames = 1 then "@name", Sql.string (Seq.head fieldNames)
@@ -148,12 +148,10 @@ module Parameters =
[]
module Query =
- ///
- /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
- ///
+ /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document
/// How the fields should be matched
/// The fields for the comparisons
- /// A WHERE clause implementing the comparisons for the given fields
+ /// A WHERE clause implementing the comparisons for the given fields
[]
let whereByFields (howMatched: FieldMatch) fields =
let name = ParameterName()
@@ -182,9 +180,9 @@ module Query =
else $"{it.Path PostgreSQL AsSql} {it.Comparison.OpSql} {param}")
|> String.concat $" {howMatched} "
- /// Create a WHERE clause fragment to implement an ID-based query
+ /// Create a WHERE clause fragment to implement an ID-based query
/// The ID of the document
- /// A WHERE clause fragment identifying a document by its ID
+ /// A WHERE clause fragment identifying a document by its ID
[]
let whereById<'TKey> (docId: 'TKey) =
whereByFields Any [ { Field.Equal (Configuration.idField ()) docId with ParameterName = Some "@id" } ]
@@ -209,32 +207,28 @@ module Query =
let tableName = name.Split '.' |> Array.last
$"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})"
- ///
- /// Create a WHERE clause fragment to implement a @> (JSON contains) condition
- ///
+ /// Create a WHERE clause fragment to implement a @> (JSON contains) condition
/// The parameter name for the query
- /// A WHERE clause fragment for the contains condition
+ /// A WHERE clause fragment for the contains condition
[]
let whereDataContains paramName =
$"data @> %s{paramName}"
- ///
- /// Create a WHERE clause fragment to implement a @? (JSON Path match) condition
- ///
+ /// Create a WHERE clause fragment to implement a @? (JSON Path match) condition
/// The parameter name for the query
- /// A WHERE clause fragment for the JSON Path match condition
+ /// A WHERE clause fragment for the JSON Path match condition
[]
let whereJsonPathMatches paramName =
$"data @? %s{paramName}::jsonpath"
- /// Create an UPDATE statement to patch documents
+ /// Create an UPDATE statement to patch documents
/// The table to be updated
/// A query to patch documents
[]
let patch tableName =
$"UPDATE %s{tableName} SET data = data || @data"
- /// Create an UPDATE statement to remove fields from documents
+ /// Create an UPDATE statement to remove fields from documents
/// The table to be updated
/// A query to remove fields from documents
[]
@@ -292,14 +286,14 @@ module Results =
let fromData<'T> row : 'T =
fromDocument "data" row
- /// Extract a count from the column it
+ /// Extract a count from the column it
/// A row reader set to the row with the count to retrieve
/// The count from the row
[]
let toCount (row: RowReader) =
row.int "it"
- /// Extract a true/false value from the column it
+ /// Extract a true/false value from the column it
/// A row reader set to the row with the true/false value to retrieve
/// The true/false value from the row
[]
diff --git a/src/Postgres/WithProps.fs b/src/Postgres/WithProps.fs
index f0f7c39..2a06c96 100644
--- a/src/Postgres/WithProps.fs
+++ b/src/Postgres/WithProps.fs
@@ -1,4 +1,4 @@
-/// Versions of queries that accept SqlProps as the last parameter
+/// Versions of queries that accept SqlProps as the last parameter
module BitBadger.Documents.Postgres.WithProps
open System.IO
diff --git a/src/Tests.CSharp/PostgresCSharpExtensionTests.cs b/src/Tests.CSharp/PostgresCSharpExtensionTests.cs
index 65b0743..c0398ed 100644
--- a/src/Tests.CSharp/PostgresCSharpExtensionTests.cs
+++ b/src/Tests.CSharp/PostgresCSharpExtensionTests.cs
@@ -9,11 +9,14 @@ using static CommonExtensionsAndTypesForNpgsqlFSharp;
using static Runner;
///
-/// C# tests for the extensions on the NpgsqlConnection type
+/// C# tests for the extensions on the NpgsqlConnection type
///
public class PostgresCSharpExtensionTests
{
- private static Task LoadDocs() => PostgresCSharpTests.LoadDocs();
+ private static async Task LoadDocs(NpgsqlConnection conn)
+ {
+ foreach (var doc in JsonDocument.TestDocuments) await conn.Insert(SqliteDb.TableName, doc);
+ }
///
/// Create a connection to the throwaway database
@@ -27,6 +30,93 @@ public class PostgresCSharpExtensionTests
return conn;
}
+ /// Set up a stream writer for a test
+ private static StreamWriter WriteStream(Stream stream)
+ {
+ StreamWriter writer = new(stream);
+ writer.AutoFlush = true;
+ return writer;
+ }
+
+ /// Get the text of the given stream
+ private static string StreamText(Stream stream)
+ {
+ stream.Position = 0L;
+ using StreamReader reader = new(stream);
+ return reader.ReadToEnd();
+ }
+
+ /// Verify a JSON array begins with "[" and ends with "]"
+ private static void VerifyBeginEnd(string json)
+ {
+ Expect.stringStarts(json, "[", "The array should have started with `[`");
+ Expect.stringEnds(json, "]", "The array should have ended with `]`");
+ }
+
+ /// Verify the presence of a document by its ID
+ private static void VerifyDocById(string json, string docId)
+ {
+ Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
+ }
+
+ /// Verify the presence of a document by its ID
+ private static void VerifySingleById(string json, string docId)
+ {
+ VerifyBeginEnd(json);
+ Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
+ }
+
+ /// Verify the presence of any of the given document IDs in the given JSON
+ private static void VerifyAnyById(string json, IEnumerable docIds)
+ {
+ var theIds = docIds.ToList();
+ if (theIds.Any(it => json.Contains($"{{\"Id\": \"{it}\""))) return;
+ var ids = string.Join(", ", theIds);
+ Expect.isTrue(false, $"Could not find any of IDs {ids} in {json}");
+ }
+
+ /// Verify the JSON for `all` returning data
+ private static void VerifyAllData(string json)
+ {
+ VerifyBeginEnd(json);
+ IEnumerable ids = ["one", "two", "three", "four", "five"];
+ foreach (var docId in ids) VerifyDocById(json, docId);
+ }
+
+ /// Verify an empty JSON array
+ private static void VerifyEmpty(string json)
+ {
+ Expect.equal(json, "[]", "There should be no documents returned");
+ }
+
+ /// Verify an empty JSON document
+ private static void VerifyNoDoc(string json)
+ {
+ Expect.equal(json, "{}", "There should be no document returned");
+ }
+
+ /// Verify the JSON for an ordered query
+ private static void VerifyExpectedOrder(string json, string idFirst, string idSecond, string? idThird = null,
+ string? idFourth = null, string? idFifth = null)
+ {
+ var firstIdx = json.IndexOf($"{{\"Id\": \"{idFirst}\",", StringComparison.Ordinal);
+ var secondIdx = json.IndexOf($"{{\"Id\": \"{idSecond}\",", StringComparison.Ordinal);
+ VerifyBeginEnd(json);
+ Expect.isGreaterThan(secondIdx, firstIdx, $"`{idSecond}` should have been after `{idFirst}`");
+ if (idThird is null) return;
+
+ var thirdIdx = json.IndexOf($"{{\"Id\": \"{idThird}\",", StringComparison.Ordinal);
+ Expect.isGreaterThan(thirdIdx, secondIdx, $"`{idThird}` should have been after `{idSecond}`");
+ if (idFourth is null) return;
+
+ var fourthIdx = json.IndexOf($"{{\"Id\": \"{idFourth}\",", StringComparison.Ordinal);
+ Expect.isGreaterThan(fourthIdx, thirdIdx, $"`{idFourth}` should have been after `{idThird}`");
+ if (idFifth is null) return;
+
+ var fifthIdx = json.IndexOf($"{{\"Id\": \"{idFifth}\",", StringComparison.Ordinal);
+ Expect.isGreaterThan(fifthIdx, fourthIdx, $"`{idFifth}` should have been after `{idFourth}`");
+ }
+
///
/// Integration tests for the SQLite extension methods
///
@@ -39,7 +129,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.CustomList(Query.Find(PostgresDb.TableName), Parameters.None,
Results.FromData);
@@ -49,7 +139,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.CustomList(
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
@@ -58,13 +148,72 @@ public class PostgresCSharpExtensionTests
Expect.isEmpty(docs, "There should have been no documents returned");
})
]),
+ TestList("CustomJsonArray",
+ [
+ TestCase("succeeds when data is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var docs = await conn.CustomJsonArray(Query.Find(PostgresDb.TableName), Parameters.None,
+ Results.JsonFromData);
+ Expect.stringStarts(docs, "[", "The JSON array should have started with `[`");
+ Expect.hasLength(docs.Split("{\"Id\":"), 6, "There should have been 5 documents returned");
+ Expect.stringEnds(docs, "]", "The JSON array should have ended with `[`");
+ }),
+ TestCase("succeeds when data is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var docs = await conn.CustomJsonArray(
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
+ [Tuple.Create("@path", Sql.@string("$.NumValue ? (@ > 100)"))], Results.JsonFromData);
+ Expect.equal(docs, "[]", "There should have been no documents returned");
+ })
+ ]),
+ TestList("WriteJsonArray",
+ [
+ TestCase("succeeds when data is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteCustomJsonArray(Query.Find(PostgresDb.TableName), Parameters.None, writer,
+ Results.JsonFromData);
+
+ var docs = StreamText(stream);
+ Expect.stringStarts(docs, "[", "The JSON array should have started with `[`");
+ Expect.hasLength(docs.Split("{\"Id\":"), 6, "There should have been 5 documents returned");
+ Expect.stringEnds(docs, "]", "The JSON array should have ended with `[`");
+ }),
+ TestCase("succeeds when data is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteCustomJsonArray(
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
+ [Tuple.Create("@path", Sql.@string("$.NumValue ? (@ > 100)"))], writer, Results.JsonFromData);
+
+ Expect.equal(StreamText(stream), "[]", "There should have been no documents returned");
+ })
+ ]),
TestList("CustomSingle",
[
TestCase("succeeds when a row is found", async () =>
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.CustomSingle($"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
[Tuple.Create("@id", Sql.@string("one"))], Results.FromData);
@@ -75,23 +224,50 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.CustomSingle($"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
[Tuple.Create("@id", Sql.@string("eighty"))], Results.FromData);
Expect.isNull(doc, "There should not have been a document returned");
})
]),
+ TestList("CustomJsonSingle",
+ [
+ TestCase("succeeds when a row is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var doc = await conn.CustomJsonSingle(
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
+ [Tuple.Create("@id", Sql.@string("one"))], Results.JsonFromData);
+ Expect.stringStarts(doc, "{", "The document should have started with an open brace");
+ Expect.stringContains(doc, "\"Id\": \"one\"", "An incorrect document was returned");
+ Expect.stringEnds(doc, "}", "The document should have ended with a closing brace");
+ }),
+ TestCase("succeeds when a row is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var doc = await conn.CustomJsonSingle(
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id",
+ [Tuple.Create("@id", Sql.@string("eighty"))], Results.JsonFromData);
+ Expect.equal(doc, "{}", "There should not have been a document returned");
+ })
+ ]),
TestList("CustomNonQuery",
[
TestCase("succeeds when operating on data", async () =>
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.CustomNonQuery($"DELETE FROM {PostgresDb.TableName}", Parameters.None);
-
+
var remaining = await conn.CountAll(PostgresDb.TableName);
Expect.equal(remaining, 0, "There should be no documents remaining in the table");
}),
@@ -99,11 +275,11 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.CustomNonQuery($"DELETE FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
[Tuple.Create("@path", Sql.@string("$.NumValue ? (@ > 100)"))]);
-
+
var remaining = await conn.CountAll(PostgresDb.TableName);
Expect.equal(remaining, 5, "There should be 5 documents remaining in the table");
})
@@ -183,7 +359,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should be no documents in the table");
-
+
await conn.Insert(PostgresDb.TableName,
new JsonDocument { Id = "turkey", Sub = new() { Foo = "gobble", Bar = "gobble" } });
var after = await conn.FindAll(PostgresDb.TableName);
@@ -213,7 +389,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should be no documents in the table");
-
+
await conn.Save(PostgresDb.TableName,
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
var after = await conn.FindAll(PostgresDb.TableName);
@@ -229,7 +405,7 @@ public class PostgresCSharpExtensionTests
var before = await conn.FindById(PostgresDb.TableName, "test");
Expect.isNotNull(before, "There should have been a document returned");
Expect.equal(before.Id, "test", "The document is not correct");
-
+
await conn.Save(PostgresDb.TableName,
new JsonDocument { Id = "test", Sub = new() { Foo = "c", Bar = "d" } });
var after = await conn.FindById(PostgresDb.TableName, "test");
@@ -241,8 +417,8 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
-
+ await LoadDocs(conn);
+
var theCount = await conn.CountAll(PostgresDb.TableName);
Expect.equal(theCount, 5, "There should have been 5 matching documents");
}),
@@ -250,7 +426,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var theCount = await conn.CountByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")]);
@@ -260,7 +436,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var theCount = await conn.CountByContains(PostgresDb.TableName, new { Value = "purple" });
Expect.equal(theCount, 2, "There should have been 2 matching documents");
@@ -269,7 +445,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var theCount = await conn.CountByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 5)");
Expect.equal(theCount, 3, "There should have been 3 matching documents");
@@ -280,7 +456,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsById(PostgresDb.TableName, "three");
Expect.isTrue(exists, "There should have been an existing document");
@@ -289,7 +465,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsById(PostgresDb.TableName, "seven");
Expect.isFalse(exists, "There should not have been an existing document");
@@ -301,7 +477,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Exists("Sub")]);
Expect.isTrue(exists, "There should have been existing documents");
@@ -310,7 +486,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists =
await conn.ExistsByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("NumValue", "six")]);
@@ -323,7 +499,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsByContains(PostgresDb.TableName, new { NumValue = 10 });
Expect.isTrue(exists, "There should have been existing documents");
@@ -332,7 +508,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsByContains(PostgresDb.TableName, new { Nothing = "none" });
Expect.isFalse(exists, "There should not have been any existing documents");
@@ -344,7 +520,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsByJsonPath(PostgresDb.TableName, "$.Sub.Foo ? (@ == \"green\")");
Expect.isTrue(exists, "There should have been existing documents");
@@ -353,7 +529,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var exists = await conn.ExistsByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 1000)");
Expect.isFalse(exists, "There should not have been any existing documents");
@@ -387,7 +563,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var results =
await conn.FindAllOrdered(PostgresDb.TableName, [Field.Named("n:NumValue")]);
@@ -399,7 +575,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var results =
await conn.FindAllOrdered(PostgresDb.TableName, [Field.Named("n:NumValue DESC")]);
@@ -411,7 +587,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var results = await conn.FindAllOrdered(PostgresDb.TableName, [Field.Named("Id DESC")]);
Expect.hasLength(results, 5, "There should have been 5 documents returned");
@@ -425,7 +601,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindById(PostgresDb.TableName, "two");
Expect.isNotNull(doc, "There should have been a document returned");
@@ -435,7 +611,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindById(PostgresDb.TableName, "three hundred eighty-seven");
Expect.isNull(doc, "There should not have been a document returned");
@@ -447,7 +623,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "another")]);
@@ -457,7 +633,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "mauve")]);
@@ -470,7 +646,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")], [Field.Named("Id")]);
@@ -482,7 +658,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")], [Field.Named("Id DESC")]);
@@ -497,7 +673,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByContains(PostgresDb.TableName,
new { Sub = new { Foo = "green" } });
@@ -507,7 +683,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByContains(PostgresDb.TableName, new { Value = "mauve" });
Expect.isEmpty(docs, "There should have been no documents returned");
@@ -520,7 +696,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByContainsOrdered(PostgresDb.TableName,
new { Sub = new { Foo = "green" } }, [Field.Named("Sub.Bar")]);
@@ -532,7 +708,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByContainsOrdered(PostgresDb.TableName,
new { Sub = new { Foo = "green" } }, [Field.Named("Sub.Bar DESC")]);
@@ -547,7 +723,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 15)");
Expect.equal(docs.Count, 3, "There should have been 3 documents returned");
@@ -556,7 +732,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)");
Expect.isEmpty(docs, "There should have been no documents returned");
@@ -569,7 +745,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByJsonPathOrdered(PostgresDb.TableName, "$.NumValue ? (@ < 15)",
[Field.Named("n:NumValue")]);
@@ -581,7 +757,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var docs = await conn.FindByJsonPathOrdered(PostgresDb.TableName, "$.NumValue ? (@ < 15)",
[Field.Named("n:NumValue DESC")]);
@@ -596,7 +772,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "another")]);
@@ -607,7 +783,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")]);
@@ -618,7 +794,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "absent")]);
@@ -631,7 +807,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")], [Field.Named("Id")]);
@@ -642,7 +818,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
[Field.Equal("Value", "purple")], [Field.Named("Id DESC")]);
@@ -656,7 +832,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByContains(PostgresDb.TableName, new { Value = "another" });
Expect.isNotNull(doc, "There should have been a document returned");
@@ -666,7 +842,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByContains(PostgresDb.TableName,
new { Sub = new { Foo = "green" } });
@@ -677,7 +853,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByContains(PostgresDb.TableName, new { Value = "absent" });
Expect.isNull(doc, "There should not have been a document returned");
@@ -689,7 +865,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByContainsOrdered(PostgresDb.TableName,
new { Sub = new { Foo = "green" } }, [Field.Named("Value")]);
@@ -700,7 +876,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByContainsOrdered(PostgresDb.TableName,
new { Sub = new { Foo = "green" } }, [Field.Named("Value DESC")]);
@@ -714,7 +890,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByJsonPath(PostgresDb.TableName,
"$.Value ? (@ == \"FIRST!\")");
@@ -725,7 +901,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByJsonPath(PostgresDb.TableName,
"$.Sub.Foo ? (@ == \"green\")");
@@ -736,7 +912,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByJsonPath(PostgresDb.TableName, "$.Id ? (@ == \"nope\")");
Expect.isNull(doc, "There should not have been a document returned");
@@ -748,7 +924,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByJsonPathOrdered(PostgresDb.TableName,
"$.Sub.Foo ? (@ == \"green\")", [Field.Named("Sub.Bar")]);
@@ -759,7 +935,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
var doc = await conn.FindFirstByJsonPathOrdered(PostgresDb.TableName,
"$.Sub.Foo ? (@ == \"green\")", [Field.Named("Sub.Bar DESC")]);
@@ -767,13 +943,848 @@ public class PostgresCSharpExtensionTests
Expect.equal("four", doc.Id, "An incorrect document was returned");
})
]),
+ TestList("JsonAll",
+ [
+ TestCase("succeeds when there is data", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyAllData(await conn.JsonAll(PostgresDb.TableName));
+ }),
+ TestCase("succeeds when there is no data", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ VerifyEmpty(await conn.JsonAll(PostgresDb.TableName));
+ })
+ ]),
+ TestList("JsonAllOrdered",
+ [
+ TestCase("succeeds when ordering numerically", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(await conn.JsonAllOrdered(PostgresDb.TableName, [Field.Named("n:NumValue")]),
+ "one", "three", "two", "four", "five");
+ }),
+ TestCase("succeeds when ordering numerically descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(await conn.JsonAllOrdered(PostgresDb.TableName, [Field.Named("n:NumValue DESC")]),
+ "five", "four", "two", "three", "one");
+ }),
+ TestCase("succeeds when ordering alphabetically", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(await conn.JsonAllOrdered(PostgresDb.TableName, [Field.Named("Id DESC")]),
+ "two", "three", "one", "four", "five");
+ })
+ ]),
+ TestList("JsonById",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var json = await conn.JsonById(PostgresDb.TableName, "two");
+ 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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyNoDoc(await conn.JsonById(PostgresDb.TableName, "three hundred eighty-seven"));
+ })
+ ]),
+ TestList("JsonByFields",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifySingleById(
+ await conn.JsonByFields(PostgresDb.TableName, FieldMatch.All,
+ [Field.In("Value", ["purple", "blue"]), Field.Exists("Sub")]),
+ "four");
+ }),
+ TestCase("succeeds when documents are found using IN with numeric field", async() =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifySingleById(
+ await conn.JsonByFields(PostgresDb.TableName, FieldMatch.All, [Field.In("NumValue", [2, 4, 6, 8])]),
+ "three");
+ }),
+ TestCase("succeeds when documents are not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyEmpty(await conn.JsonByFields(PostgresDb.TableName, FieldMatch.All,
+ [Field.Equal("Value", "mauve"), Field.NotEqual("NumValue", 40)]));
+ }),
+ TestCase("succeeds for InArray when matching documents exist", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await conn.EnsureTable(PostgresDb.TableName);
+ foreach (var doc in ArrayDocument.TestDocuments) await conn.Insert(PostgresDb.TableName, doc);
+
+ var json = await conn.JsonByFields(PostgresDb.TableName, FieldMatch.All,
+ [Field.InArray("Values", PostgresDb.TableName, ["c"])]);
+ 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 using var conn = MkConn(db);
+ await conn.EnsureTable(PostgresDb.TableName);
+ foreach (var doc in ArrayDocument.TestDocuments) await conn.Insert(PostgresDb.TableName, doc);
+ VerifyEmpty(await conn.JsonByFields(PostgresDb.TableName, FieldMatch.All,
+ [Field.InArray("Values", PostgresDb.TableName, ["j"])]));
+ })
+ ]),
+ TestList("JsonByFieldsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByFieldsOrdered(PostgresDb.TableName, FieldMatch.All,
+ [Field.Equal("Value", "purple")], [Field.Named("Id")]),
+ "five", "four");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByFieldsOrdered(PostgresDb.TableName, FieldMatch.All,
+ [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]),
+ "four", "five");
+ })
+ ]),
+ TestList("JsonByContains",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var json = await conn.JsonByContains(PostgresDb.TableName, new { Sub = new { Foo = "green" } });
+ VerifyBeginEnd(json);
+ VerifyDocById(json, "two");
+ VerifyDocById(json, "four");
+ }),
+ TestCase("succeeds when documents are not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyEmpty(await conn.JsonByContains(PostgresDb.TableName, new { Value = "mauve" }));
+ })
+ ]),
+ TestList("JsonByContainsOrdered",
+ [
+ // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByContainsOrdered(PostgresDb.TableName, new { Sub = new { Foo = "green" } },
+ [Field.Named("Sub.Bar")]),
+ "two", "four");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByContainsOrdered(PostgresDb.TableName, new { Sub = new { Foo = "green" } },
+ [Field.Named("Sub.Bar DESC")]),
+ "four", "two");
+ })
+ ]),
+ TestList("JsonByJsonPath",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ var json = await conn.JsonByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 15)");
+ 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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyEmpty(await conn.JsonByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)"));
+ })
+ ]),
+ TestList("JsonByJsonPathOrdered",
+ [
+ // 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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByJsonPathOrdered(PostgresDb.TableName, "$.NumValue ? (@ < 15)",
+ [Field.Named("n:NumValue")]),
+ "one", "three", "two");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyExpectedOrder(
+ await conn.JsonByJsonPathOrdered(PostgresDb.TableName, "$.NumValue ? (@ < 15)",
+ [Field.Named("n:NumValue DESC")]),
+ "two", "three", "one");
+ })
+ ]),
+ TestList("JsonFirstByFields",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByFields(PostgresDb.TableName, FieldMatch.Any,
+ [Field.Equal("Value", "another")]),
+ "two");
+ }),
+ TestCase("succeeds when multiple documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyAnyById(
+ await conn.JsonFirstByFields(PostgresDb.TableName, FieldMatch.Any,
+ [Field.Equal("Value", "purple")]),
+ ["five", "four"]);
+ }),
+ TestCase("succeeds when a document is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyNoDoc(await conn.JsonFirstByFields(PostgresDb.TableName, FieldMatch.Any,
+ [Field.Equal("Value", "absent")]));
+ })
+ ]),
+ TestList("JsonFirstByFieldsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
+ [Field.Equal("Value", "purple")], [Field.Named("Id")]),
+ "five");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByFieldsOrdered(PostgresDb.TableName, FieldMatch.Any,
+ [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]),
+ "four");
+ })
+ ]),
+ TestList("JsonFirstByContains",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(await conn.JsonFirstByContains(PostgresDb.TableName, new { Value = "another" }), "two");
+ }),
+ TestCase("succeeds when multiple documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyAnyById(await conn.JsonFirstByContains(PostgresDb.TableName, new { Sub = new { Foo = "green" } }),
+ ["two", "four"]);
+ }),
+ TestCase("succeeds when a document is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyNoDoc(await conn.JsonFirstByContains(PostgresDb.TableName, new { Value = "absent" }));
+ })
+ ]),
+ TestList("JsonFirstByContainsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByContainsOrdered(PostgresDb.TableName, new { Sub = new { Foo = "green" } },
+ [Field.Named("Value")]),
+ "two");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByContainsOrdered(PostgresDb.TableName, new { Sub = new { Foo = "green" } },
+ [Field.Named("Value DESC")]),
+ "four");
+ })
+ ]),
+ TestList("JsonFirstByJsonPath",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(await conn.JsonFirstByJsonPath(PostgresDb.TableName, """$.Value ? (@ == "FIRST!")"""),
+ "one");
+ }),
+ TestCase("succeeds when multiple documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyAnyById(await conn.JsonFirstByJsonPath(PostgresDb.TableName, """$.Sub.Foo ? (@ == "green")"""),
+ ["two", "four"]);
+ }),
+ TestCase("succeeds when a document is not found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyNoDoc(await conn.JsonFirstByJsonPath(PostgresDb.TableName, """$.Id ? (@ == "nope")"""));
+ })
+ ]),
+ TestList("JsonFirstByJsonPathOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByJsonPathOrdered(PostgresDb.TableName, """$.Sub.Foo ? (@ == "green")""",
+ [Field.Named("Sub.Bar")]),
+ "two");
+ }),
+ TestCase("succeeds when sorting descending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ VerifyDocById(
+ await conn.JsonFirstByJsonPathOrdered(PostgresDb.TableName, """$.Sub.Foo ? (@ == "green")""",
+ [Field.Named("Sub.Bar DESC")]),
+ "four");
+ })
+ ]),
+ TestList("WriteJsonAll",
+ [
+ TestCase("succeeds when there is data", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonAll(PostgresDb.TableName, writer);
+ VerifyAllData(StreamText(stream));
+ }),
+ TestCase("succeeds when there is no data", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonAll(PostgresDb.TableName, writer);
+ VerifyEmpty(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonAllOrdered",
+ [
+ TestCase("succeeds when ordering numerically", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonAllOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonAllOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonAllOrdered(PostgresDb.TableName, writer, [Field.Named("Id DESC")]);
+ VerifyExpectedOrder(StreamText(stream), "two", "three", "one", "four", "five");
+ })
+ ]),
+ TestList("WriteJsonById",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonById(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonById(PostgresDb.TableName, writer, "three hundred eighty-seven");
+ VerifyNoDoc(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonByFields",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFields(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFields(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFields(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 using var conn = MkConn(db);
+ await conn.EnsureTable(PostgresDb.TableName);
+ foreach (var doc in ArrayDocument.TestDocuments) await conn.Insert(PostgresDb.TableName, doc);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFields(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 using var conn = MkConn(db);
+ await conn.EnsureTable(PostgresDb.TableName);
+ foreach (var doc in ArrayDocument.TestDocuments) await conn.Insert(PostgresDb.TableName, doc);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFields(PostgresDb.TableName, writer, FieldMatch.All,
+ [Field.InArray("Values", PostgresDb.TableName, ["j"])]);
+ VerifyEmpty(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonByFieldsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFieldsOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.All,
+ [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]);
+ VerifyExpectedOrder(StreamText(stream), "four", "five");
+ })
+ ]),
+ TestList("WriteJsonByContains",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByContains(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByContains(PostgresDb.TableName, writer, new { Value = "mauve" });
+ VerifyEmpty(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonByContainsOrdered",
+ [
+ // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByContainsOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByContainsOrdered(PostgresDb.TableName, writer, new { Sub = new { Foo = "green" } },
+ [Field.Named("Sub.Bar DESC")]);
+ VerifyExpectedOrder(StreamText(stream), "four", "two");
+ })
+ ]),
+ TestList("WriteJsonByJsonPath",
+ [
+ TestCase("succeeds when documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByJsonPath(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByJsonPath(PostgresDb.TableName, writer, "$.NumValue ? (@ < 0)");
+ VerifyEmpty(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonByJsonPathOrdered",
+ [
+ // 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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByJsonPathOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonByJsonPathOrdered(PostgresDb.TableName, writer, "$.NumValue ? (@ < 15)",
+ [Field.Named("n:NumValue DESC")]);
+ VerifyExpectedOrder(StreamText(stream), "two", "three", "one");
+ })
+ ]),
+ TestList("WriteJsonFirstByFields",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByFields(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByFields(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByFields(PostgresDb.TableName, writer, FieldMatch.Any,
+ [Field.Equal("Value", "absent")]);
+ VerifyNoDoc(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonFirstByFieldsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByFieldsOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByFieldsOrdered(PostgresDb.TableName, writer, FieldMatch.Any,
+ [Field.Equal("Value", "purple")], [Field.Named("Id DESC")]);
+ VerifyDocById(StreamText(stream), "four");
+ })
+ ]),
+ TestList("WriteJsonFirstByContains",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByContains(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByContains(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByContains(PostgresDb.TableName, writer, new { Value = "absent" });
+ VerifyNoDoc(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonFirstByContainsOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByContainsOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByContainsOrdered(PostgresDb.TableName, writer,
+ new { Sub = new { Foo = "green" } }, [Field.Named("Value DESC")]);
+ VerifyDocById(StreamText(stream), "four");
+ })
+ ]),
+ TestList("WriteJsonFirstByJsonPath",
+ [
+ TestCase("succeeds when a document is found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByJsonPath(PostgresDb.TableName, writer, """$.Value ? (@ == "FIRST!")""");
+ VerifyDocById(StreamText(stream), "one");
+ }),
+ TestCase("succeeds when multiple documents are found", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByJsonPath(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByJsonPath(PostgresDb.TableName, writer, """$.Id ? (@ == "nope")""");
+ VerifyNoDoc(StreamText(stream));
+ })
+ ]),
+ TestList("WriteJsonFirstByJsonPathOrdered",
+ [
+ TestCase("succeeds when sorting ascending", async () =>
+ {
+ await using var db = PostgresDb.BuildDb();
+ await using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByJsonPathOrdered(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 using var conn = MkConn(db);
+ await LoadDocs(conn);
+ await using MemoryStream stream = new();
+ await using var writer = WriteStream(stream);
+ await conn.WriteJsonFirstByJsonPathOrdered(PostgresDb.TableName, writer,
+ """$.Sub.Foo ? (@ == "green")""", [Field.Named("Sub.Bar DESC")]);
+ VerifyDocById(StreamText(stream), "four");
+ })
+ ]),
TestList("UpdateById",
[
TestCase("succeeds when a document is updated", async () =>
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.UpdateById(PostgresDb.TableName, "one",
new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } });
@@ -792,7 +1803,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.UpdateById(PostgresDb.TableName, "test",
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
@@ -804,7 +1815,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.UpdateByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
@@ -821,7 +1832,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.UpdateByFunc(PostgresDb.TableName, doc => doc.Id,
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
@@ -833,7 +1844,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.PatchById(PostgresDb.TableName, "one", new { NumValue = 44 });
var after = await conn.FindById(PostgresDb.TableName, "one");
@@ -846,7 +1857,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.PatchById(PostgresDb.TableName, "test", new { Foo = "green" });
})
@@ -857,7 +1868,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.PatchByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("Value", "purple")],
new { NumValue = 77 });
@@ -871,7 +1882,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.PatchByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("Value", "burgundy")],
new { Foo = "green" });
@@ -883,7 +1894,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.PatchByContains(PostgresDb.TableName, new { Value = "purple" }, new { NumValue = 77 });
var after = await conn.CountByContains(PostgresDb.TableName, new { NumValue = 77 });
@@ -895,7 +1906,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.PatchByContains(PostgresDb.TableName, new { Value = "burgundy" }, new { Foo = "green" });
})
@@ -906,7 +1917,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.PatchByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 10)", new { NumValue = 1000 });
var after = await conn.CountByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 999)");
@@ -918,7 +1929,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db);
var before = await conn.CountAll(PostgresDb.TableName);
Expect.equal(before, 0, "There should have been no documents returned");
-
+
// This not raising an exception is the test
await conn.PatchByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ < 0)", new { Foo = "green" });
})
@@ -929,7 +1940,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsById(PostgresDb.TableName, "two", ["Sub", "Value"]);
var updated = await Find.ById(PostgresDb.TableName, "two");
@@ -941,7 +1952,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsById(PostgresDb.TableName, "two", ["Sub"]);
var updated = await Find.ById(PostgresDb.TableName, "two");
@@ -953,8 +1964,8 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
-
+ await LoadDocs(conn);
+
// This not raising an exception is the test
await conn.RemoveFieldsById(PostgresDb.TableName, "two", ["AFieldThatIsNotThere"]);
}),
@@ -962,7 +1973,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
-
+
// This not raising an exception is the test
await conn.RemoveFieldsById(PostgresDb.TableName, "two", ["Value"]);
})
@@ -973,7 +1984,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("NumValue", "17")],
["Sub", "Value"]);
@@ -986,7 +1997,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("NumValue", "17")],
["Sub"]);
@@ -999,8 +2010,8 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
-
+ await LoadDocs(conn);
+
// This not raising an exception is the test
await conn.RemoveFieldsByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("NumValue", "17")],
["Nothing"]);
@@ -1009,7 +2020,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
-
+
// This not raising an exception is the test
await conn.RemoveFieldsByFields(PostgresDb.TableName, FieldMatch.Any,
[Field.NotEqual("Abracadabra", "apple")], ["Value"]);
@@ -1021,7 +2032,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByContains(PostgresDb.TableName, new { NumValue = 17 }, ["Sub", "Value"]);
var updated = await Find.ById(PostgresDb.TableName, "four");
@@ -1033,7 +2044,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByContains(PostgresDb.TableName, new { NumValue = 17 }, ["Sub"]);
var updated = await Find.ById(PostgresDb.TableName, "four");
@@ -1045,8 +2056,8 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
-
+ await LoadDocs(conn);
+
// This not raising an exception is the test
await conn.RemoveFieldsByContains(PostgresDb.TableName, new { NumValue = 17 }, ["Nothing"]);
}),
@@ -1054,7 +2065,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
-
+
// This not raising an exception is the test
await conn.RemoveFieldsByContains(PostgresDb.TableName, new { Abracadabra = "apple" }, ["Value"]);
})
@@ -1065,7 +2076,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ == 17)", ["Sub", "Value"]);
var updated = await Find.ById(PostgresDb.TableName, "four");
@@ -1077,7 +2088,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.RemoveFieldsByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ == 17)", ["Sub"]);
var updated = await Find.ById(PostgresDb.TableName, "four");
@@ -1089,8 +2100,8 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
-
+ await LoadDocs(conn);
+
// This not raising an exception is the test
await conn.RemoveFieldsByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ == 17)", ["Nothing"]);
}),
@@ -1098,7 +2109,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
-
+
// This not raising an exception is the test
await conn.RemoveFieldsByJsonPath(PostgresDb.TableName, "$.Abracadabra ? (@ == \"apple\")", ["Value"]);
})
@@ -1109,7 +2120,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteById(PostgresDb.TableName, "four");
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1119,7 +2130,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteById(PostgresDb.TableName, "thirty");
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1132,7 +2143,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByFields(PostgresDb.TableName, FieldMatch.Any, [Field.NotEqual("Value", "purple")]);
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1142,7 +2153,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByFields(PostgresDb.TableName, FieldMatch.Any, [Field.Equal("Value", "crimson")]);
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1155,7 +2166,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByContains(PostgresDb.TableName, new { Value = "purple" });
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1165,7 +2176,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByContains(PostgresDb.TableName, new { Value = "crimson" });
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1178,7 +2189,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByJsonPath(PostgresDb.TableName, "$.Sub.Foo ? (@ == \"green\")");
var remaining = await conn.CountAll(PostgresDb.TableName);
@@ -1188,7 +2199,7 @@ public class PostgresCSharpExtensionTests
{
await using var db = PostgresDb.BuildDb();
await using var conn = MkConn(db);
- await LoadDocs();
+ await LoadDocs(conn);
await conn.DeleteByJsonPath(PostgresDb.TableName, "$.NumValue ? (@ > 100)");
var remaining = await conn.CountAll(PostgresDb.TableName);
diff --git a/src/Tests.CSharp/PostgresCSharpTests.cs b/src/Tests.CSharp/PostgresCSharpTests.cs
index efc7b90..df8ab6d 100644
--- a/src/Tests.CSharp/PostgresCSharpTests.cs
+++ b/src/Tests.CSharp/PostgresCSharpTests.cs
@@ -9,7 +9,7 @@ using static CommonExtensionsAndTypesForNpgsqlFSharp;
using static Runner;
///
-/// C# tests for the PostgreSQL implementation of BitBadger.Documents
+/// C# tests for the PostgreSQL implementation of BitBadger.Documents
///
public static class PostgresCSharpTests
{
@@ -323,21 +323,21 @@ public static class PostgresCSharpTests
///
/// Add the test documents to the database
///
- internal static async Task LoadDocs()
+ private static async Task LoadDocs()
{
foreach (var doc in JsonDocument.TestDocuments) await Document.Insert(SqliteDb.TableName, doc);
}
/// Set up a stream writer for a test
- internal static StreamWriter WriteStream(Stream stream)
+ private static StreamWriter WriteStream(Stream stream)
{
StreamWriter writer = new(stream);
writer.AutoFlush = true;
return writer;
}
- /// Get the text of the given stream
- internal static string StreamText(Stream stream)
+ /// Get the text of the given stream
+ private static string StreamText(Stream stream)
{
stream.Position = 0L;
using StreamReader reader = new(stream);
@@ -1298,20 +1298,20 @@ public static class PostgresCSharpTests
Expect.stringEnds(json, "]", "The array should have ended with `]`");
}
- /// Verify the presence of a document by its ID
+ /// Verify the presence of a document by its ID
private static void VerifyDocById(string json, string docId)
{
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
}
- /// Verify the presence of a document by its ID
+ /// Verify the presence of a document by its ID
private static void VerifySingleById(string json, string docId)
{
VerifyBeginEnd(json);
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
}
- /// Verify the presence of any of the given document IDs in the given JSON
+ /// Verify the presence of any of the given document IDs in the given JSON
private static void VerifyAnyById(string json, IEnumerable docIds)
{
var theIds = docIds.ToList();
@@ -1320,7 +1320,7 @@ public static class PostgresCSharpTests
Expect.isTrue(false, $"Could not find any of IDs {ids} in {json}");
}
- /// Verify the JSON for `all` returning data
+ /// Verify the JSON for `all` returning data
private static void VerifyAllData(string json)
{
VerifyBeginEnd(json);
@@ -1328,19 +1328,19 @@ public static class PostgresCSharpTests
foreach (var docId in ids) VerifyDocById(json, docId);
}
- /// Verify an empty JSON array
+ /// Verify an empty JSON array
private static void VerifyEmpty(string json)
{
Expect.equal(json, "[]", "There should be no documents returned");
}
- /// Verify an empty JSON document
+ /// Verify an empty JSON document
private static void VerifyNoDoc(string json)
{
Expect.equal(json, "{}", "There should be no document returned");
}
- /// Verify the JSON for an ordered query
+ /// Verify the JSON for an ordered query
private static void VerifyExpectedOrder(string json, string idFirst, string idSecond, string? idThird = null,
string? idFourth = null, string? idFifth = null)
{
diff --git a/src/Tests/PostgresExtensionTests.fs b/src/Tests/PostgresExtensionTests.fs
index 60fcf31..df675c1 100644
--- a/src/Tests/PostgresExtensionTests.fs
+++ b/src/Tests/PostgresExtensionTests.fs
@@ -1,5 +1,6 @@
module PostgresExtensionTests
+open System.IO
open BitBadger.Documents
open BitBadger.Documents.Postgres
open BitBadger.Documents.Tests
@@ -13,6 +14,75 @@ let private mkConn (db: ThrowawayPostgresDb) =
conn.Open()
conn
+/// Set up a stream writer for a test
+let private writeStream (stream: Stream) =
+ let writer = new StreamWriter(stream)
+ writer.AutoFlush <- true
+ writer
+
+/// Get the text of the given stream
+let private streamText (stream: Stream) =
+ stream.Position <- 0L
+ use reader = new StreamReader(stream)
+ reader.ReadToEnd()
+
+/// Verify a JSON array begins with "[" and ends with "]"
+let private verifyBeginEnd json =
+ Expect.stringStarts json "[" "The array should have started with `[`"
+ Expect.stringEnds json "]" "The array should have ended with `]`"
+
+/// Verify the presence of a document by its ID
+let private verifyDocById json docId =
+ Expect.stringContains json $"{{\"Id\": \"%s{docId}\"," $"Document `{docId}` not present"
+
+/// Verify the presence of a document by its ID
+let private verifySingleById json docId =
+ verifyBeginEnd json
+ Expect.stringContains json $"{{\"Id\": \"%s{docId}\"," $"Document `{docId}` not present"
+
+/// Verify the presence of any of the given document IDs in the given JSON
+let private verifyAnyById (json: string) (docIds: string list) =
+ match docIds |> List.tryFind (fun it -> json.Contains $"{{\"Id\": \"{it}\"") with
+ | Some _ -> ()
+ | None ->
+ let ids = docIds |> String.concat ", "
+ Expect.isTrue false $"Could not find any of IDs {ids} in {json}"
+
+/// Verify the JSON for `all` returning data
+let private verifyAllData json =
+ verifyBeginEnd json
+ [ "one"; "two"; "three"; "four"; "five" ] |> List.iter (verifyDocById json)
+
+/// Verify an empty JSON array
+let private verifyEmpty json =
+ Expect.equal json "[]" "There should be no documents returned"
+
+/// Verify an empty JSON document
+let private verifyNoDoc json =
+ Expect.equal json "{}" "There should be no document returned"
+
+/// Verify the JSON for an ordered query
+let private verifyExpectedOrder (json: string) idFirst idSecond idThird idFourth idFifth =
+ let firstIdx = json.IndexOf $"{{\"Id\": \"%s{idFirst}\","
+ let secondIdx = json.IndexOf $"{{\"Id\": \"%s{idSecond}\","
+ verifyBeginEnd json
+ Expect.isGreaterThan secondIdx firstIdx $"`{idSecond}` should have been after `{idFirst}`"
+ match idThird with
+ | Some id3 ->
+ let thirdIdx = json.IndexOf $"{{\"Id\": \"%s{id3}\","
+ Expect.isGreaterThan thirdIdx secondIdx $"`{id3}` should have been after `{idSecond}`"
+ match idFourth with
+ | Some id4 ->
+ let fourthIdx = json.IndexOf $"{{\"Id\": \"%s{id4}\","
+ Expect.isGreaterThan fourthIdx thirdIdx $"`{id4}` should have been after `{id3}`"
+ match idFifth with
+ | Some id5 ->
+ let fifthIdx = json.IndexOf $"{{\"Id\": \"%s{id5}\","
+ Expect.isGreaterThan fifthIdx fourthIdx $"`{id5}` should have been after `{id4}`"
+ | None -> ()
+ | None -> ()
+ | None -> ()
+
/// Integration tests for the F# extensions on the NpgsqlConnection data type
let integrationTests =
let loadDocs (conn: NpgsqlConnection) = backgroundTask {
@@ -41,6 +111,61 @@ let integrationTests =
Expect.isEmpty docs "There should have been no documents returned"
}
]
+ testList "customJsonArray" [
+ testTask "succeeds when data is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! docs = conn.customJsonArray (Query.find PostgresDb.TableName) [] jsonFromData
+ Expect.stringStarts docs "[" "The JSON array should have started with `[`"
+ Expect.hasLength ((string docs).Split "{\"Id\":") 6 "There should have been 5 documents returned"
+ Expect.stringEnds docs "]" "The JSON array should have ended with `[`"
+ }
+ testTask "succeeds when data is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! docs =
+ conn.customJsonArray
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
+ [ "@path", Sql.string "$.NumValue ? (@ > 100)" ]
+ jsonFromData
+ Expect.equal docs "[]" "There should have been no documents returned"
+ }
+ ]
+ testList "writeCustomJsonArray" [
+ testTask "succeeds when data is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeCustomJsonArray (Query.find PostgresDb.TableName) [] writer jsonFromData
+
+ let docs = streamText stream
+ Expect.stringStarts docs "[" "The JSON array should have started with `[`"
+ Expect.hasLength (docs.Split "{\"Id\":") 6 "There should have been 5 documents returned"
+ Expect.stringEnds docs "]" "The JSON array should have ended with `[`"
+ }
+ testTask "succeeds when data is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeCustomJsonArray
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
+ [ "@path", Sql.string "$.NumValue ? (@ > 100)" ]
+ writer
+ jsonFromData
+
+ Expect.equal (streamText stream) "[]" "There should have been no documents returned"
+ }
+ ]
testList "customSingle" [
testTask "succeeds when a row is found" {
use db = PostgresDb.BuildDb()
@@ -68,6 +193,34 @@ let integrationTests =
Expect.isNone doc "There should not have been a document returned"
}
]
+ testList "customJsonSingle" [
+ testTask "succeeds when a row is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! doc =
+ conn.customJsonSingle
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id"
+ [ "@id", Sql.string "one"]
+ jsonFromData
+ Expect.stringStarts doc "{" "The document should have started with an open brace"
+ Expect.stringContains doc "\"Id\": \"one\"" "An incorrect document was returned"
+ Expect.stringEnds doc "}" "The document should have ended with a closing brace"
+ }
+ testTask "succeeds when a row is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! doc =
+ conn.customJsonSingle
+ $"SELECT data FROM {PostgresDb.TableName} WHERE data ->> 'Id' = @id"
+ [ "@id", Sql.string "eighty" ]
+ jsonFromData
+ Expect.equal doc "{}" "There should not have been a document returned"
+ }
+ ]
testList "customNonQuery" [
testTask "succeeds when operating on data" {
use db = PostgresDb.BuildDb()
@@ -106,7 +259,7 @@ let integrationTests =
let keyExists () =
conn.customScalar
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_key') AS it" [] toExists
-
+
let! exists = tableExists ()
let! alsoExists = keyExists ()
Expect.isFalse exists "The table should not exist already"
@@ -124,7 +277,7 @@ let integrationTests =
let indexExists () =
conn.customScalar
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_document') AS it" [] toExists
-
+
let! exists = indexExists ()
Expect.isFalse exists "The index should not exist already"
@@ -139,7 +292,7 @@ let integrationTests =
let indexExists () =
conn.customScalar
"SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'idx_ensured_test') AS it" [] toExists
-
+
let! exists = indexExists ()
Expect.isFalse exists "The index should not exist already"
@@ -213,7 +366,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
let! theCount = conn.countByFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ]
Expect.equal theCount 2 "There should have been 2 matching documents"
}
@@ -332,7 +485,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
let! results = conn.findAllOrdered PostgresDb.TableName [ Field.Named "n:NumValue" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -344,7 +497,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
let! results = conn.findAllOrdered PostgresDb.TableName [ Field.Named "n:NumValue DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -356,7 +509,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
let! results = conn.findAllOrdered PostgresDb.TableName [ Field.Named "Id DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@@ -677,6 +830,769 @@ let integrationTests =
Expect.equal "four" doc.Value.Id "An incorrect document was returned"
}
]
+ testList "jsonAll" [
+ testTask "succeeds when there is data" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonAll PostgresDb.TableName
+ verifyAllData json
+ }
+ testTask "succeeds when there is no data" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ let! json = conn.jsonAll PostgresDb.TableName
+ verifyEmpty json
+ }
+ ]
+ testList "jsonAllOrdered" [
+ testTask "succeeds when ordering numerically" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonAllOrdered PostgresDb.TableName [ Field.Named "n:NumValue" ]
+ verifyExpectedOrder json "one" "three" (Some "two") (Some "four") (Some "five")
+ }
+ testTask "succeeds when ordering numerically descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonAllOrdered PostgresDb.TableName [ Field.Named "n:NumValue DESC" ]
+ verifyExpectedOrder json "five" "four" (Some "two") (Some "three") (Some "one")
+ }
+ testTask "succeeds when ordering alphabetically" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonAllOrdered PostgresDb.TableName [ Field.Named "Id DESC" ]
+ verifyExpectedOrder json "two" "three" (Some "one") (Some "four") (Some "five")
+ }
+ ]
+ testList "jsonById" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! json = conn.jsonById PostgresDb.TableName "two"
+ 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()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonById PostgresDb.TableName "three hundred eighty-seven"
+ verifyNoDoc json
+ }
+ ]
+ testList "jsonByFields" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByFields
+ PostgresDb.TableName All [ Field.In "Value" [ "purple"; "blue" ]; Field.Exists "Sub" ]
+ verifySingleById json "four"
+ }
+ testTask "succeeds when documents are found using IN with numeric field" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonByFields PostgresDb.TableName All [ Field.In "NumValue" [ 2; 4; 6; 8 ] ]
+ verifySingleById json "three"
+ }
+ testTask "succeeds when documents are not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByFields
+ PostgresDb.TableName All [ Field.Equal "Value" "mauve"; Field.NotEqual "NumValue" 40 ]
+ verifyEmpty json
+ }
+ testTask "succeeds for InArray when matching documents exist" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! conn.ensureTable PostgresDb.TableName
+ for doc in ArrayDocument.TestDocuments do do! conn.insert PostgresDb.TableName doc
+
+ let! json =
+ conn.jsonByFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "c" ] ]
+ verifyBeginEnd json
+ verifyDocById json "first"
+ verifyDocById json "second"
+ }
+ testTask "succeeds for InArray when no matching documents exist" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! conn.ensureTable PostgresDb.TableName
+ for doc in ArrayDocument.TestDocuments do do! conn.insert PostgresDb.TableName doc
+ let! json =
+ conn.jsonByFields PostgresDb.TableName All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ]
+ verifyEmpty json
+ }
+ ]
+ testList "jsoByFieldsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByFieldsOrdered
+ PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ]
+ verifyExpectedOrder json "five" "four" None None None
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByFieldsOrdered
+ PostgresDb.TableName All [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ]
+ verifyExpectedOrder json "four" "five" None None None
+ }
+ ]
+ testList "jsonByContains" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! json = conn.jsonByContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |}
+ verifyBeginEnd json
+ verifyDocById json "two"
+ verifyDocById json "four"
+ }
+ testTask "succeeds when documents are not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonByContains PostgresDb.TableName {| Value = "mauve" |}
+ verifyEmpty json
+ }
+ ]
+ testList "jsonByContainsOrdered" [
+ // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByContainsOrdered
+ PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar" ]
+ verifyExpectedOrder json "two" "four" None None None
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByContainsOrdered
+ PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar DESC" ]
+ verifyExpectedOrder json "four" "two" None None None
+ }
+ ]
+ testList "jsonByJsonPath" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ let! json = conn.jsonByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 15)"
+ verifyBeginEnd json
+ verifyDocById json "one"
+ verifyDocById json "two"
+ verifyDocById json "three"
+ }
+ testTask "succeeds when documents are not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)"
+ verifyEmpty json
+ }
+ ]
+ testList "jsonByJsonPathOrdered" [
+ // Id = one, NumValue = 0; Id = two, NumValue = 10; Id = three, NumValue = 4
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByJsonPathOrdered PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue" ]
+ verifyExpectedOrder json "one" "three" (Some "two") None None
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonByJsonPathOrdered
+ PostgresDb.TableName "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue DESC" ]
+ verifyExpectedOrder json "two" "three" (Some "one") None None
+ }
+ ]
+ testList "jsonFirstByFields" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByFields PostgresDb.TableName Any [ Field.Equal "Value" "another" ]
+ verifyDocById json "two"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ]
+ verifyAnyById json [ "five"; "four" ]
+ }
+ testTask "succeeds when a document is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByFields PostgresDb.TableName Any [ Field.Equal "Value" "absent" ]
+ verifyNoDoc json
+ }
+ ]
+ testList "jsonFirstByFieldsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByFieldsOrdered
+ PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ]
+ verifyDocById json "five"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByFieldsOrdered
+ PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ]
+ verifyDocById json "four"
+ }
+ ]
+ testList "jsonFirstByContains" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByContains PostgresDb.TableName {| Value = "another" |}
+ verifyDocById json "two"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByContains PostgresDb.TableName {| Sub = {| Foo = "green" |} |}
+ verifyAnyById json [ "two"; "four" ]
+ }
+ testTask "succeeds when a document is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByContains PostgresDb.TableName {| Value = "absent" |}
+ verifyNoDoc json
+ }
+ ]
+ testList "jsonFirstByContainsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByContainsOrdered
+ PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value" ]
+ verifyDocById json "two"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByContainsOrdered
+ PostgresDb.TableName {| Sub = {| Foo = "green" |} |} [ Field.Named "Value DESC" ]
+ verifyDocById json "four"
+ }
+ ]
+ testList "jsonFirstByJsonPath" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByJsonPath PostgresDb.TableName """$.Value ? (@ == "FIRST!")"""
+ verifyDocById json "one"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByJsonPath PostgresDb.TableName """$.Sub.Foo ? (@ == "green")"""
+ verifyAnyById json [ "two"; "four" ]
+ }
+ testTask "succeeds when a document is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json = conn.jsonFirstByJsonPath PostgresDb.TableName """$.Id ? (@ == "nope")"""
+ verifyNoDoc json
+ }
+ ]
+ testList "jsonFirstByJsonPathOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByJsonPathOrdered
+ PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar" ]
+ verifyDocById json "two"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+ let! json =
+ conn.jsonFirstByJsonPathOrdered
+ PostgresDb.TableName """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar DESC" ]
+ verifyDocById json "four"
+ }
+ ]
+ testList "writeJsonAll" [
+ testTask "succeeds when there is data" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonAll PostgresDb.TableName writer
+ verifyAllData (streamText stream)
+ }
+ testTask "succeeds when there is no data" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonAll PostgresDb.TableName writer
+ verifyEmpty (streamText stream)
+ }
+ ]
+ testList "writeJsonAllOrdered" [
+ testTask "succeeds when ordering numerically" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonAllOrdered 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonAllOrdered 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonAllOrdered PostgresDb.TableName writer [ Field.Named "Id DESC" ]
+ verifyExpectedOrder (streamText stream) "two" "three" (Some "one") (Some "four") (Some "five")
+ }
+ ]
+ testList "writeJsonById" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonById 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonById PostgresDb.TableName writer "three hundred eighty-seven"
+ verifyNoDoc (streamText stream)
+ }
+ ]
+ testList "writeJsonByFields" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFields
+ 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFields 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFields
+ 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()
+ use conn = mkConn db
+ do! conn.ensureTable PostgresDb.TableName
+ for doc in ArrayDocument.TestDocuments do do! conn.insert PostgresDb.TableName doc
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFields
+ 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()
+ use conn = mkConn db
+ do! conn.ensureTable PostgresDb.TableName
+ for doc in ArrayDocument.TestDocuments do do! conn.insert PostgresDb.TableName doc
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFields
+ PostgresDb.TableName writer All [ Field.InArray "Values" PostgresDb.TableName [ "j" ] ]
+ verifyEmpty (streamText stream)
+ }
+ ]
+ testList "writeJsonByFieldsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFieldsOrdered
+ 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByFieldsOrdered
+ PostgresDb.TableName writer All [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ]
+ verifyExpectedOrder (streamText stream) "four" "five" None None None
+ }
+ ]
+ testList "writeJsonByContains" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByContains 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByContains PostgresDb.TableName writer {| Value = "mauve" |}
+ verifyEmpty (streamText stream)
+ }
+ ]
+ testList "writeJsonByContainsOrdered" [
+ // Id = two, Sub.Bar = blue; Id = four, Sub.Bar = red
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByContainsOrdered
+ 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByContainsOrdered
+ PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Sub.Bar DESC" ]
+ verifyExpectedOrder (streamText stream) "four" "two" None None None
+ }
+ ]
+ testList "writeJsonByJsonPath" [
+ testTask "succeeds when documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByJsonPath 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByJsonPath PostgresDb.TableName writer "$.NumValue ? (@ < 0)"
+ verifyEmpty (streamText stream)
+ }
+ ]
+ testList "writeJsonByJsonPathOrdered" [
+ // Id = one, NumValue = 0; Id = two, NumValue = 10; Id = three, NumValue = 4
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByJsonPathOrdered
+ 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonByJsonPathOrdered
+ PostgresDb.TableName writer "$.NumValue ? (@ < 15)" [ Field.Named "n:NumValue DESC" ]
+ verifyExpectedOrder (streamText stream) "two" "three" (Some "one") None None
+ }
+ ]
+ testList "writeJsonFirstByFields" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByFields PostgresDb.TableName writer Any [ Field.Equal "Value" "another" ]
+ verifyDocById (streamText stream) "two"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByFields 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()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByFields PostgresDb.TableName writer Any [ Field.Equal "Value" "absent" ]
+ verifyNoDoc (streamText stream)
+ }
+ ]
+ testList "writeJsonFirstByFieldsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByFieldsOrdered
+ PostgresDb.TableName writer Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id" ]
+ verifyDocById (streamText stream) "five"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByFieldsOrdered
+ PostgresDb.TableName writer Any [ Field.Equal "Value" "purple" ] [ Field.Named "Id DESC" ]
+ verifyDocById (streamText stream) "four"
+ }
+ ]
+ testList "writeJsonFirstByContains" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByContains PostgresDb.TableName writer {| Value = "another" |}
+ verifyDocById (streamText stream) "two"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByContains PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |}
+ verifyAnyById (streamText stream) [ "two"; "four" ]
+ }
+ testTask "succeeds when a document is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByContains PostgresDb.TableName writer {| Value = "absent" |}
+ verifyNoDoc (streamText stream)
+ }
+ ]
+ testList "writeJsonFirstByContainsOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByContainsOrdered
+ PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Value" ]
+ verifyDocById (streamText stream) "two"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByContainsOrdered
+ PostgresDb.TableName writer {| Sub = {| Foo = "green" |} |} [ Field.Named "Value DESC" ]
+ verifyDocById (streamText stream) "four"
+ }
+ ]
+ testList "writeJsonFirstByJsonPath" [
+ testTask "succeeds when a document is found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByJsonPath PostgresDb.TableName writer """$.Value ? (@ == "FIRST!")"""
+ verifyDocById (streamText stream) "one"
+ }
+ testTask "succeeds when multiple documents are found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByJsonPath PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")"""
+ verifyAnyById (streamText stream) [ "two"; "four" ]
+ }
+ testTask "succeeds when a document is not found" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByJsonPath PostgresDb.TableName writer """$.Id ? (@ == "nope")"""
+ verifyNoDoc (streamText stream)
+ }
+ ]
+ testList "writeJsonFirstByJsonPathOrdered" [
+ testTask "succeeds when sorting ascending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByJsonPathOrdered
+ PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar" ]
+ verifyDocById (streamText stream) "two"
+ }
+ testTask "succeeds when sorting descending" {
+ use db = PostgresDb.BuildDb()
+ use conn = mkConn db
+ do! loadDocs conn
+
+ use stream = new MemoryStream()
+ use writer = writeStream stream
+ do! conn.writeJsonFirstByJsonPathOrdered
+ PostgresDb.TableName writer """$.Sub.Foo ? (@ == "green")""" [ Field.Named "Sub.Bar DESC" ]
+ verifyDocById (streamText stream) "four"
+ }
+ ]
testList "updateById" [
testTask "succeeds when a document is updated" {
use db = PostgresDb.BuildDb()
@@ -694,7 +1610,7 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.updateById
PostgresDb.TableName "test" { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } }
@@ -707,7 +1623,7 @@ let integrationTests =
do! loadDocs conn
do! conn.updateByFunc
- PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
+ PostgresDb.TableName _.Id { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
let! after = conn.findById PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update"
Expect.equal
@@ -720,10 +1636,10 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.updateByFunc
- PostgresDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
+ PostgresDb.TableName _.Id { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
}
]
testList "patchById" [
@@ -731,7 +1647,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
do! conn.patchById PostgresDb.TableName "one" {| NumValue = 44 |}
let! after = conn.findById PostgresDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update"
@@ -742,7 +1658,7 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.patchById PostgresDb.TableName "test" {| Foo = "green" |}
}
@@ -752,7 +1668,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
do! conn.patchByFields PostgresDb.TableName Any [ Field.Equal "Value" "purple" ] {| NumValue = 77 |}
let! after = conn.countByFields PostgresDb.TableName Any [ Field.Equal "NumValue" "77" ]
Expect.equal after 2 "There should have been 2 documents returned"
@@ -762,7 +1678,7 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.patchByFields PostgresDb.TableName Any [ Field.Equal "Value" "burgundy" ] {| Foo = "green" |}
}
@@ -772,7 +1688,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
do! conn.patchByContains PostgresDb.TableName {| Value = "purple" |} {| NumValue = 77 |}
let! after = conn.countByContains PostgresDb.TableName {| NumValue = 77 |}
Expect.equal after 2 "There should have been 2 documents returned"
@@ -782,7 +1698,7 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.patchByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
}
@@ -792,7 +1708,7 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
do! conn.patchByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 10)" {| NumValue = 1000 |}
let! after = conn.countByJsonPath PostgresDb.TableName "$.NumValue ? (@ > 999)"
Expect.equal after 2 "There should have been 2 documents returned"
@@ -802,7 +1718,7 @@ let integrationTests =
use conn = mkConn db
let! before = conn.countAll PostgresDb.TableName
Expect.equal before 0 "There should have been no documents returned"
-
+
// This not raising an exception is the test
do! conn.patchByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
}
@@ -834,14 +1750,14 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
// This not raising an exception is the test
do! conn.removeFieldsById PostgresDb.TableName "two" [ "AFieldThatIsNotThere" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
use conn = mkConn db
-
+
// This not raising an exception is the test
do! conn.removeFieldsById PostgresDb.TableName "two" [ "Value" ]
}
@@ -874,14 +1790,14 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
// This not raising an exception is the test
do! conn.removeFieldsByFields PostgresDb.TableName Any [ Field.Equal "NumValue" "17" ] [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
use conn = mkConn db
-
+
// This not raising an exception is the test
do! conn.removeFieldsByFields
PostgresDb.TableName Any [ Field.NotEqual "Abracadabra" "apple" ] [ "Value" ]
@@ -914,14 +1830,14 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
// This not raising an exception is the test
do! conn.removeFieldsByContains PostgresDb.TableName {| NumValue = 17 |} [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
use conn = mkConn db
-
+
// This not raising an exception is the test
do! conn.removeFieldsByContains PostgresDb.TableName {| Abracadabra = "apple" |} [ "Value" ]
}
@@ -953,14 +1869,14 @@ let integrationTests =
use db = PostgresDb.BuildDb()
use conn = mkConn db
do! loadDocs conn
-
+
// This not raising an exception is the test
do! conn.removeFieldsByJsonPath PostgresDb.TableName "$.NumValue ? (@ == 17)" [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use db = PostgresDb.BuildDb()
use conn = mkConn db
-
+
// This not raising an exception is the test
do! conn.removeFieldsByJsonPath PostgresDb.TableName "$.Abracadabra ? (@ == \"apple\")" [ "Value" ]
}