Add XML documentation #10

Merged
danieljsummers merged 8 commits from v4.0point1 into main 2024-12-30 22:03:19 +00:00
5 changed files with 752 additions and 259 deletions
Showing only changes of commit f40c93ee66 - Show all commits

View File

@ -4,7 +4,7 @@ open Npgsql
open Npgsql.FSharp
open WithProps
/// F# Extensions for the NpgsqlConnection type
/// <summary>F# Extensions for the NpgsqlConnection type</summary>
[<AutoOpen>]
module Extensions =
@ -377,247 +377,455 @@ module Extensions =
open System.Runtime.CompilerServices
/// C# extensions on the NpgsqlConnection type
/// <summary>C# extensions on the NpgsqlConnection type</summary>
type NpgsqlConnectionCSharpExtensions =
/// Execute a query that returns a list of results
/// <summary>Execute a query that returns a list of results</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="query">The query to retrieve the results</param>
/// <param name="parameters">Parameters to use for the query</param>
/// <param name="mapFunc">The mapping function between the document and the domain item</param>
/// <returns>A list of results for the given query</returns>
[<Extension>]
static member inline CustomList<'TDoc>(conn, query, parameters, mapFunc: System.Func<RowReader, 'TDoc>) =
Custom.List<'TDoc>(query, parameters, mapFunc, Sql.existingConnection conn)
/// Execute a query that returns one or no results; returns None if not found
/// <summary>Execute a query that returns one or no results</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="query">The query to retrieve the results</param>
/// <param name="parameters">Parameters to use for the query</param>
/// <param name="mapFunc">The mapping function between the document and the domain item</param>
/// <returns>The first matching result, or <tt>null</tt> if not found</returns>
[<Extension>]
static member inline CustomSingle<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, query, parameters, mapFunc: System.Func<RowReader, 'TDoc>) =
Custom.Single<'TDoc>(query, parameters, mapFunc, Sql.existingConnection conn)
/// Execute a query that returns no results
/// <summary>Execute a query that returns no results</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="query">The query to retrieve the results</param>
/// <param name="parameters">Parameters to use for the query</param>
[<Extension>]
static member inline CustomNonQuery(conn, query, parameters) =
Custom.nonQuery query parameters (Sql.existingConnection conn)
/// Execute a query that returns a scalar value
/// <summary>Execute a query that returns a scalar value</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="query">The query to retrieve the value</param>
/// <param name="parameters">Parameters to use for the query</param>
/// <param name="mapFunc">The mapping function to obtain the value</param>
/// <returns>The scalar value for the query</returns>
[<Extension>]
static member inline CustomScalar<'T when 'T: struct>(
conn, query, parameters, mapFunc: System.Func<RowReader, 'T>) =
Custom.Scalar(query, parameters, mapFunc, Sql.existingConnection conn)
/// Create a document table
/// <summary>Create a document table</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="name">The table whose existence should be ensured (may include schema)</param>
[<Extension>]
static member inline EnsureTable(conn, name) =
Definition.ensureTable name (Sql.existingConnection conn)
/// Create an index on documents in the specified table
/// <summary>Create an index on documents in the specified table</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="name">The table to be indexed (may include schema)</param>
/// <param name="idxType">The type of document index to create</param>
[<Extension>]
static member inline EnsureDocumentIndex(conn, name, idxType) =
Definition.ensureDocumentIndex name idxType (Sql.existingConnection conn)
/// Create an index on field(s) within documents in the specified table
/// <summary>Create an index on field(s) within documents in the specified table</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table to be indexed (may include schema)</param>
/// <param name="indexName">The name of the index to create</param>
/// <param name="fields">One or more fields to be indexed</param>
[<Extension>]
static member inline EnsureFieldIndex(conn, tableName, indexName, fields) =
Definition.ensureFieldIndex tableName indexName fields (Sql.existingConnection conn)
/// Insert a new document
/// <summary>Insert a new document</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table into which the document should be inserted (may include schema)</param>
/// <param name="document">The document to be inserted</param>
[<Extension>]
static member inline Insert<'TDoc>(conn, tableName, document: 'TDoc) =
insert<'TDoc> tableName document (Sql.existingConnection conn)
/// Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
/// <summary>Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table into which the document should be saved (may include schema)</param>
/// <param name="document">The document to be saved</param>
[<Extension>]
static member inline Save<'TDoc>(conn, tableName, document: 'TDoc) =
save<'TDoc> tableName document (Sql.existingConnection conn)
/// Count all documents in a table
/// <summary>Count all documents in a table</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be counted (may include schema)</param>
/// <returns>The count of the documents in the table</returns>
[<Extension>]
static member inline CountAll(conn, tableName) =
Count.all tableName (Sql.existingConnection conn)
/// Count matching documents using a JSON field comparison query (->> =)
/// <summary>Count matching documents using JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be counted (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <returns>The count of matching documents in the table</returns>
[<Extension>]
static member inline CountByFields(conn, tableName, howMatched, fields) =
Count.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Count matching documents using a JSON containment query (@>)
/// <summary>Count matching documents using a JSON containment query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be counted (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <returns>The count of the documents in the table</returns>
[<Extension>]
static member inline CountByContains(conn, tableName, criteria: 'TCriteria) =
Count.byContains tableName criteria (Sql.existingConnection conn)
/// Count matching documents using a JSON Path match query (@?)
/// <summary>Count matching documents using a JSON Path match query (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be counted (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to be matched</param>
/// <returns>The count of the documents in the table</returns>
[<Extension>]
static member inline CountByJsonPath(conn, tableName, jsonPath) =
Count.byJsonPath tableName jsonPath (Sql.existingConnection conn)
/// Determine if a document exists for the given ID
/// <summary>Determine if a document exists for the given ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which existence should be checked (may include schema)</param>
/// <param name="docId">The ID of the document whose existence should be checked</param>
/// <returns>True if a document exists, false if not</returns>
[<Extension>]
static member inline ExistsById(conn, tableName, docId) =
Exists.byId tableName docId (Sql.existingConnection conn)
/// Determine if documents exist using a JSON field comparison query (->> =)
/// <summary>Determine if a document exists using JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which existence should be checked (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <returns>True if any matching documents exist, false if not</returns>
[<Extension>]
static member inline ExistsByFields(conn, tableName, howMatched, fields) =
Exists.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Determine if documents exist using a JSON containment query (@>)
/// <summary>Determine if a document exists using a JSON containment query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which existence should be checked (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <returns>True if any matching documents exist, false if not</returns>
[<Extension>]
static member inline ExistsByContains(conn, tableName, criteria: 'TCriteria) =
Exists.byContains tableName criteria (Sql.existingConnection conn)
/// Determine if documents exist using a JSON Path match query (@?)
/// <summary>Determine if a document exists using a JSON Path match query (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which existence should be checked (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to be matched</param>
/// <returns>True if any matching documents exist, false if not</returns>
[<Extension>]
static member inline ExistsByJsonPath(conn, tableName, jsonPath) =
Exists.byJsonPath tableName jsonPath (Sql.existingConnection conn)
/// Retrieve all documents in the given table
/// <summary>Retrieve all documents in the given table</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <returns>All documents from the given table</returns>
[<Extension>]
static member inline FindAll<'TDoc>(conn, tableName) =
Find.All<'TDoc>(tableName, Sql.existingConnection conn)
/// Retrieve all documents in the given table ordered by the given fields in the document
/// <summary>Retrieve all documents in the given table ordered by the given fields in the document</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>All documents from the given table, ordered by the given fields</returns>
[<Extension>]
static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
Find.AllOrdered<'TDoc>(tableName, orderFields, Sql.existingConnection conn)
/// Retrieve a document by its ID; returns None if not found
/// <summary>Retrieve a document by its ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="docId">The ID of the document to retrieve</param>
/// <returns>The document if found, <tt>null</tt> otherwise</returns>
[<Extension>]
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 a JSON field comparison query (->> =)
/// <summary>Retrieve documents matching JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <returns>All documents matching the given fields</returns>
[<Extension>]
static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) =
Find.ByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) ordered by the given fields in the document
/// <summary>
/// Retrieve documents matching JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.) ordered by the given fields in
/// the document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="queryFields">The field conditions to match</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>All documents matching the given fields, ordered by the other given fields</returns>
[<Extension>]
static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
Find.ByFieldsOrdered<'TDoc>(
tableName, howMatched, queryFields, orderFields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON containment query (@>)
/// <summary>Retrieve documents matching a JSON containment query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <returns>All documents matching the given containment query</returns>
[<Extension>]
static member inline FindByContains<'TDoc>(conn, tableName, criteria: obj) =
Find.ByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn)
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
/// <summary>
/// Retrieve documents matching a JSON containment query (<tt>@&gt;</tt>) ordered by the given fields in the
/// document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>All documents matching the given containment query, ordered by the given fields</returns>
[<Extension>]
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 (@?)
/// <summary>Retrieve documents matching a JSON Path match query (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <returns>All documents matching the given JSON Path expression</returns>
[<Extension>]
static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) =
Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
/// <summary>
/// Retrieve documents matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>All documents matching the given JSON Path expression, ordered by the given fields</returns>
[<Extension>]
static member inline FindByJsonPathOrdered<'TDoc>(conn, tableName, jsonPath, orderFields) =
Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <returns>The first document, or <tt>null</tt> if not found</returns>
[<Extension>]
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 a JSON field comparison query (->> =) ordered by the given fields in the
/// document; returns null if not found
/// <summary>
/// Retrieve the first document matching JSON field comparisons (<tt>-&gt;&gt; =</tt>, etc.) ordered by the given
/// fields in the document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="queryFields">The field conditions to match</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
[<Extension>]
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 (@>); returns None if not found
/// <summary>Retrieve the first document matching a JSON containment query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <returns>The first document, or <tt>null</tt> if not found</returns>
[<Extension>]
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;
/// returns None if not found
/// <summary>
/// Retrieve the first document matching a JSON containment query (<tt>@&gt;</tt>) ordered by the given fields in
/// the document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="criteria">The document to match with the containment query</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
[<Extension>]
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 (@?); returns None if not found
/// <summary>Retrieve the first document matching a JSON Path match query (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <returns>The first document, or <tt>null</tt> if not found</returns>
[<Extension>]
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 document;
/// returns None if not found
/// <summary>
/// Retrieve the first document matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the
/// document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table from which a document should be retrieved (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <param name="orderFields">Fields by which the results should be ordered</param>
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
[<Extension>]
static member inline FindFirstByJsonPathOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
conn, tableName, jsonPath, orderFields) =
Find.FirstByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, Sql.existingConnection conn)
/// Update an entire document by its ID
/// <summary>Update (replace) an entire document by its ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which a document should be updated (may include schema)</param>
/// <param name="docId">The ID of the document to be updated (replaced)</param>
/// <param name="document">The new document</param>
[<Extension>]
static member inline UpdateById(conn, tableName, docId: 'TKey, document: 'TDoc) =
Update.byId tableName docId document (Sql.existingConnection conn)
/// Update an entire document by its ID, using the provided function to obtain the ID from the document
/// <summary>
/// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which a document should be updated (may include schema)</param>
/// <param name="idFunc">The function to obtain the ID of the document</param>
/// <param name="document">The new document</param>
[<Extension>]
static member inline UpdateByFunc(conn, tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
Update.ByFunc(tableName, idFunc, document, Sql.existingConnection conn)
/// Patch a document by its ID
/// <summary>Patch a document by its ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which a document should be patched (may include schema)</param>
/// <param name="docId">The ID of the document to patch</param>
/// <param name="patch">The partial document to patch the existing document</param>
[<Extension>]
static member inline PatchById(conn, tableName, docId: 'TKey, patch: 'TPatch) =
Patch.byId tableName docId patch (Sql.existingConnection conn)
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
/// <summary>
/// Patch documents using a JSON field comparison query in the <tt>WHERE</tt> clause (<tt>-&gt;&gt; =</tt>, etc.)
/// </summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be patched (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <param name="patch">The partial document to patch the existing document</param>
[<Extension>]
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 (@>)
/// <summary>Patch documents using a JSON containment query in the <tt>WHERE</tt> clause (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be patched (may include schema)</param>
/// <param name="criteria">The document to match the containment query</param>
/// <param name="patch">The partial document to patch the existing document</param>
[<Extension>]
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 (@?)
/// <summary>Patch documents using a JSON Path match query in the <tt>WHERE</tt> clause (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be patched (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <param name="patch">The partial document to patch the existing document</param>
[<Extension>]
static member inline PatchByJsonPath(conn, tableName, jsonPath, patch: 'TPatch) =
Patch.byJsonPath tableName jsonPath patch (Sql.existingConnection conn)
/// Remove fields from a document by the document's ID
/// <summary>Remove fields from a document by the document's ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which a document should be modified (may include schema)</param>
/// <param name="docId">The ID of the document to modify</param>
/// <param name="fieldNames">One or more field names to remove from the document</param>
[<Extension>]
static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) =
RemoveFields.byId tableName docId fieldNames (Sql.existingConnection conn)
/// Remove fields from documents via a comparison on JSON fields in the document
/// <summary>Remove fields from documents via a comparison on JSON fields in the document</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be modified (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
/// <param name="fieldNames">One or more field names to remove from the matching documents</param>
[<Extension>]
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 (@>)
/// <summary>Remove fields from documents via a JSON containment query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be modified (may include schema)</param>
/// <param name="criteria">The document to match the containment query</param>
/// <param name="fieldNames">One or more field names to remove from the matching documents</param>
[<Extension>]
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 (@?)
/// <summary>Remove fields from documents via a JSON Path match query (<tt>@?</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be modified (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
/// <param name="fieldNames">One or more field names to remove from the matching documents</param>
[<Extension>]
static member inline RemoveFieldsByJsonPath(conn, tableName, jsonPath, fieldNames) =
RemoveFields.byJsonPath tableName jsonPath fieldNames (Sql.existingConnection conn)
/// Delete a document by its ID
/// <summary>Delete a document by its ID</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which a document should be deleted (may include schema)</param>
/// <param name="docId">The ID of the document to delete</param>
[<Extension>]
static member inline DeleteById(conn, tableName, docId: 'TKey) =
Delete.byId tableName docId (Sql.existingConnection conn)
/// Delete documents by matching a JSON field comparison query (->> =)
/// <summary>Delete documents by matching a JSON field comparison query (<tt>-&gt;&gt; =</tt>, etc.)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
/// <param name="howMatched">Whether to match any or all of the field conditions</param>
/// <param name="fields">The field conditions to match</param>
[<Extension>]
static member inline DeleteByFields(conn, tableName, howMatched, fields) =
Delete.byFields tableName howMatched fields (Sql.existingConnection conn)
/// Delete documents by matching a JSON containment query (@>)
/// <summary>Delete documents by matching a JSON contains query (<tt>@&gt;</tt>)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
/// <param name="criteria">The document to match the containment query</param>
[<Extension>]
static member inline DeleteByContains(conn, tableName, criteria: 'TContains) =
Delete.byContains tableName criteria (Sql.existingConnection conn)
/// Delete documents by matching a JSON Path match query (@?)
/// <summary>Delete documents by matching a JSON Path match query (@?)</summary>
/// <param name="conn">The <tt>NpgsqlConnection</tt> on which to run the query</param>
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
/// <param name="jsonPath">The JSON Path expression to match</param>
[<Extension>]
static member inline DeleteByJsonPath(conn, tableName, path) =
Delete.byJsonPath tableName path (Sql.existingConnection conn)
static member inline DeleteByJsonPath(conn, tableName, jsonPath) =
Delete.byJsonPath tableName jsonPath (Sql.existingConnection conn)

View File

@ -250,7 +250,7 @@ module Exists =
toExists
sqlProps
/// <summary>Commands to determine if documents exist</summary>
/// <summary>Commands to retrieve documents</summary>
[<RequireQualifiedAccess>]
module Find =

File diff suppressed because it is too large Load Diff

View File

@ -75,7 +75,7 @@ public static class SqliteCSharpTests
]),
TestCase("WhereById succeeds", () =>
{
Expect.equal(Sqlite.Query.WhereById("@id"), "data->>'Id' = @id", "WHERE clause not correct");
Expect.equal(Sqlite.Query.WhereById("abc"), "data->>'Id' = @id", "WHERE clause not correct");
}),
TestCase("Patch succeeds", () =>
{
@ -141,9 +141,9 @@ public static class SqliteCSharpTests
Expect.isEmpty(Parameters.None, "The parameter list should have been empty");
})
]);
// Results are exhaustively executed in the context of other tests
/// <summary>
/// Add the test documents to the database
/// </summary>
@ -989,7 +989,7 @@ public static class SqliteCSharpTests
})
])
]);
/// <summary>
/// All tests for SQLite C# functions and methods
/// </summary>

View File

@ -65,7 +65,7 @@ let queryTests = testList "Query" [
}
]
test "whereById succeeds" {
Expect.equal (Query.whereById "@id") "data->>'Id' = @id" "WHERE clause not correct"
Expect.equal (Query.whereById "abc") "data->>'Id' = @id" "WHERE clause not correct"
}
test "patch succeeds" {
Expect.equal
@ -235,7 +235,7 @@ let definitionTests = testList "Definition" [
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it"
[ SqliteParameter("@name", name) ]
toExists
let! exists = itExists "ensured"
let! alsoExists = itExists "idx_ensured_key"
Expect.isFalse exists "The table should not exist already"
@ -254,7 +254,7 @@ let definitionTests = testList "Definition" [
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it"
[]
toExists
let! exists = indexExists ()
Expect.isFalse exists "The index should not exist already"
@ -272,7 +272,7 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let! before = Find.all<SubDocument> SqliteDb.TableName
Expect.equal before [] "There should be no documents in the table"
let testDoc = { emptyDoc with Id = "turkey"; Sub = Some { Foo = "gobble"; Bar = "gobble" } }
do! insert SqliteDb.TableName testDoc
let! after = Find.all<JsonDocument> SqliteDb.TableName
@ -293,12 +293,12 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let! before = Count.all SqliteDb.TableName
Expect.equal before 0L "There should be no documents in the table"
do! insert SqliteDb.TableName { Key = 0; Text = "one" }
do! insert SqliteDb.TableName { Key = 0; Text = "two" }
do! insert SqliteDb.TableName { Key = 77; Text = "three" }
do! insert SqliteDb.TableName { Key = 0; Text = "four" }
let! after = Find.allOrdered<NumIdDocument> SqliteDb.TableName [ Field.Named "Key" ]
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.equal (after |> List.map _.Key) [ 1; 2; 77; 78 ] "The IDs were not generated correctly"
@ -312,12 +312,12 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let! before = Count.all SqliteDb.TableName
Expect.equal before 0L "There should be no documents in the table"
do! insert SqliteDb.TableName { emptyDoc with Value = "one" }
do! insert SqliteDb.TableName { emptyDoc with Value = "two" }
do! insert SqliteDb.TableName { emptyDoc with Id = "abc123"; Value = "three" }
do! insert SqliteDb.TableName { emptyDoc with Value = "four" }
let! after = Find.all<JsonDocument> SqliteDb.TableName
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.hasCountOf after 3u (fun doc -> doc.Id.Length = 32) "Three of the IDs should have been GUIDs"
@ -332,12 +332,12 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let! before = Count.all SqliteDb.TableName
Expect.equal before 0L "There should be no documents in the table"
do! insert SqliteDb.TableName { emptyDoc with Value = "one" }
do! insert SqliteDb.TableName { emptyDoc with Value = "two" }
do! insert SqliteDb.TableName { emptyDoc with Id = "abc123"; Value = "three" }
do! insert SqliteDb.TableName { emptyDoc with Value = "four" }
let! after = Find.all<JsonDocument> SqliteDb.TableName
Expect.hasLength after 4 "There should have been 4 documents returned"
Expect.hasCountOf
@ -354,7 +354,7 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let! before = Find.all<JsonDocument> SqliteDb.TableName
Expect.equal before [] "There should be no documents in the table"
let testDoc = { emptyDoc with Id = "test"; Sub = Some { Foo = "a"; Bar = "b" } }
do! save SqliteDb.TableName testDoc
let! after = Find.all<JsonDocument> SqliteDb.TableName
@ -364,11 +364,11 @@ let documentTests = testList "Document" [
use! db = SqliteDb.BuildDb()
let testDoc = { emptyDoc with Id = "test"; Sub = Some { Foo = "a"; Bar = "b" } }
do! insert SqliteDb.TableName testDoc
let! before = Find.byId<string, JsonDocument> SqliteDb.TableName "test"
Expect.isSome before "There should have been a document returned"
Expect.equal before.Value testDoc "The document is not correct"
let upd8Doc = { testDoc with Sub = Some { Foo = "c"; Bar = "d" } }
do! save SqliteDb.TableName upd8Doc
let! after = Find.byId<string, JsonDocument> SqliteDb.TableName "test"
@ -391,14 +391,14 @@ let countTests = testList "Count" [
testTask "succeeds for a numeric range" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! theCount = Count.byFields SqliteDb.TableName Any [ Field.Between "NumValue" 10 20 ]
Expect.equal theCount 3L "There should have been 3 matching documents"
}
testTask "succeeds for a non-numeric range" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! theCount = Count.byFields SqliteDb.TableName Any [ Field.Between "Value" "aardvark" "apple" ]
Expect.equal theCount 1L "There should have been 1 matching document"
}
@ -467,7 +467,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering numerically" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@ -478,7 +478,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering numerically descending" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "n:NumValue DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@ -489,7 +489,7 @@ let findTests = testList "Find" [
testTask "succeeds when ordering alphabetically" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> SqliteDb.TableName [ Field.Named "Id DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
@ -541,7 +541,7 @@ let findTests = testList "Find" [
use! db = SqliteDb.BuildDb()
do! Definition.ensureTable SqliteDb.TableName
for doc in ArrayDocument.TestDocuments do do! insert SqliteDb.TableName doc
let! docs =
Find.byFields<ArrayDocument>
SqliteDb.TableName All [ Field.InArray "Values" SqliteDb.TableName [ "c" ] ]
@ -551,7 +551,7 @@ let findTests = testList "Find" [
use! db = SqliteDb.BuildDb()
do! Definition.ensureTable SqliteDb.TableName
for doc in ArrayDocument.TestDocuments do do! insert SqliteDb.TableName doc
let! docs =
Find.byFields<ArrayDocument>
SqliteDb.TableName All [ Field.InArray "Values" SqliteDb.TableName [ "j" ] ]
@ -671,7 +671,7 @@ let updateTests = testList "Update" [
let! before = Find.all<JsonDocument> SqliteDb.TableName
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! Update.byId
SqliteDb.TableName "test" { emptyDoc with Id = "x"; Sub = Some { Foo = "blue"; Bar = "red" } }
@ -695,7 +695,7 @@ let updateTests = testList "Update" [
let! before = Find.all<JsonDocument> SqliteDb.TableName
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! Update.byFunc SqliteDb.TableName (_.Id) { Id = "one"; Value = "le un"; NumValue = 1; Sub = None }
}
@ -708,7 +708,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! Patch.byId SqliteDb.TableName "one" {| NumValue = 44 |}
let! after = Find.byId<string, JsonDocument> SqliteDb.TableName "one"
Expect.isSome after "There should have been a document returned post-update"
@ -719,7 +719,7 @@ let patchTests = testList "Patch" [
let! before = Find.all<SubDocument> SqliteDb.TableName
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byId SqliteDb.TableName "test" {| Foo = "green" |}
}
@ -728,7 +728,7 @@ let patchTests = testList "Patch" [
testTask "succeeds when a document is updated" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! Patch.byFields SqliteDb.TableName Any [ Field.Equal "Value" "purple" ] {| NumValue = 77 |}
let! after = Count.byFields SqliteDb.TableName Any [ Field.Equal "NumValue" 77 ]
Expect.equal after 2L "There should have been 2 documents returned"
@ -738,7 +738,7 @@ let patchTests = testList "Patch" [
let! before = Find.all<SubDocument> SqliteDb.TableName
Expect.isEmpty before "There should have been no documents returned"
// This not raising an exception is the test
do! Patch.byFields SqliteDb.TableName Any [ Field.Equal "Value" "burgundy" ] {| Foo = "green" |}
}
@ -751,7 +751,7 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when fields is removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! RemoveFields.byId SqliteDb.TableName "two" [ "Sub"; "Value" ]
try
let! _ = Find.byId<string, JsonDocument> SqliteDb.TableName "two"
@ -763,13 +763,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byId SqliteDb.TableName "two" [ "AFieldThatIsNotThere" ]
}
testTask "succeeds when no document is matched" {
use! db = SqliteDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byId SqliteDb.TableName "two" [ "Value" ]
}
@ -778,7 +778,7 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
do! RemoveFields.byFields SqliteDb.TableName Any [ Field.Equal "NumValue" 17 ] [ "Sub" ]
try
let! _ = Find.byId<string, JsonDocument> SqliteDb.TableName "four"
@ -790,13 +790,13 @@ let removeFieldsTests = testList "RemoveFields" [
testTask "succeeds when a field is not removed" {
use! db = SqliteDb.BuildDb()
do! loadDocs ()
// This not raising an exception is the test
do! RemoveFields.byFields SqliteDb.TableName Any [ Field.Equal "NumValue" 17 ] [ "Nothing" ]
}
testTask "succeeds when no document is matched" {
use! db = SqliteDb.BuildDb()
// This not raising an exception is the test
do! RemoveFields.byFields SqliteDb.TableName Any [ Field.NotEqual "Abracadabra" "apple" ] [ "Value" ]
}