diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 932d9dd..cced572 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,11 +3,10 @@ net8.0;net9.0 embedded true - 4.0.1.0 - 4.0.1.0 - 4.0.1 - From v4.0: Add XML documention (IDE support) -From v3.1: See 4.0 release for breaking changes and compatibility + 4.1.0.0 + 4.1.0.0 + 4.1.0 + Add JSON retrieval and stream-writing functions danieljsummers Bit Badger Solutions README.md diff --git a/src/Sqlite/WithConn.fs b/src/Sqlite/WithConn.fs index 763678b..0a163b0 100644 --- a/src/Sqlite/WithConn.fs +++ b/src/Sqlite/WithConn.fs @@ -1,6 +1,7 @@ /// Versions of queries that accept a SqliteConnection as the last parameter module BitBadger.Documents.Sqlite.WithConn +open System.IO open BitBadger.Documents open Microsoft.Data.Sqlite @@ -12,7 +13,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 SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// A list of results for the given query [] let list<'TDoc> query (parameters: SqliteParameter seq) (mapFunc: SqliteDataReader -> 'TDoc) @@ -26,7 +27,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 SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// A list of results for the given query let List<'TDoc>( query, parameters: SqliteParameter seq, mapFunc: System.Func, @@ -37,12 +38,65 @@ module Custom = cmd.Parameters.AddRange parameters ToCustomList<'TDoc>(cmd, mapFunc) + /// Execute a query that returns a JSON array of results + /// The query to retrieve the results + /// Parameters to use for the query + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + /// A JSON array of results for the given query + [] + let jsonArray + query + (parameters: SqliteParameter seq) + (mapFunc: SqliteDataReader -> string) + (conn: SqliteConnection) = + use cmd = conn.CreateCommand() + cmd.CommandText <- query + cmd.Parameters.AddRange parameters + toJsonArray cmd mapFunc + + /// Execute a query that returns a JSON array of results + /// The query to retrieve the results + /// Parameters to use for the query + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + /// A JSON array of results for the given query + let JsonArray(query, parameters, mapFunc: System.Func, conn) = + jsonArray query parameters mapFunc.Invoke conn + + /// Execute a query, writing its results to the given StreamWriter + /// The query to retrieve the results + /// Parameters to use for the query + /// The StreamWriter to which the results should be written + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + [] + let writeJsonArray + query + (parameters: SqliteParameter seq) + writer + (mapFunc: SqliteDataReader -> string) + (conn: SqliteConnection) = + use cmd = conn.CreateCommand() + cmd.CommandText <- query + cmd.Parameters.AddRange parameters + writeJsonArray cmd writer mapFunc + + /// Execute a query, writing its results to the given StreamWriter + /// The query to retrieve the results + /// Parameters to use for the query + /// The StreamWriter to which the results should be written + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + let WriteJsonArray(query, parameters, writer, mapFunc: System.Func, conn) = + writeJsonArray query parameters writer mapFunc.Invoke conn + /// Execute a query that returns one or no results /// The query to retrieve the results /// Parameters to use for the query /// The mapping function between the document and the domain item - /// The SqliteConnection to use to execute the query - /// Some with the first matching result, or None if not found + /// The SqliteConnection to use to execute the query + /// Some with the first matching result, or None if not found [] let single<'TDoc> query parameters (mapFunc: SqliteDataReader -> 'TDoc) conn = backgroundTask { let! results = list query parameters mapFunc conn @@ -53,8 +107,8 @@ 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 SqliteConnection to use to execute the query - /// The first matching result, or null if not found + /// The SqliteConnection to use to execute the query + /// The first matching result, or null if not found let Single<'TDoc when 'TDoc: null and 'TDoc: not struct>( query, parameters, mapFunc: System.Func, conn ) = backgroundTask { @@ -62,10 +116,31 @@ module Custom = return Option.toObj result } + /// Execute a query that returns one or no JSON documents + /// The query to retrieve the results + /// Parameters to use for the query + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + /// The JSON document with the first matching result, or an empty document if not found + [] + let jsonSingle query parameters mapFunc conn = backgroundTask { + let! results = jsonArray $"%s{query} LIMIT 1" parameters mapFunc conn + return if results = "[]" then "{}" else results[1..results.Length - 2] + } + + /// Execute a query that returns one or no JSON documents + /// The query to retrieve the results + /// Parameters to use for the query + /// The mapping function to extract the document + /// The SqliteConnection to use to execute the query + /// The JSON document with the first matching result, or an empty document if not found + let JsonSingle(query, parameters, mapFunc: System.Func, conn) = + jsonSingle query parameters mapFunc.Invoke conn + /// Execute a query that returns no results /// The query to retrieve the results /// Parameters to use for the query - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let nonQuery query (parameters: SqliteParameter seq) (conn: SqliteConnection) = use cmd = conn.CreateCommand() @@ -77,7 +152,7 @@ module Custom = /// The query to retrieve the value /// Parameters to use for the query /// The mapping function to obtain the value - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// The scalar value for the query [] let scalar<'T when 'T : struct> query (parameters: SqliteParameter seq) (mapFunc: SqliteDataReader -> 'T) @@ -94,18 +169,19 @@ module Custom = /// The query to retrieve the value /// Parameters to use for the query /// The mapping function to obtain the value - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// The scalar value for the query let Scalar<'T when 'T: struct>(query, parameters, mapFunc: System.Func, conn) = scalar<'T> query parameters mapFunc.Invoke conn + /// Functions to create tables and indexes [] module Definition = /// Create a document table /// The table whose existence should be ensured (may include schema) - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let ensureTable name conn = backgroundTask { do! Custom.nonQuery (Query.Definition.ensureTable name) [] conn @@ -116,7 +192,7 @@ module Definition = /// The table to be indexed (may include schema) /// The name of the index to create /// One or more fields to be indexed - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let ensureFieldIndex tableName indexName fields conn = Custom.nonQuery (Query.Definition.ensureIndexOn tableName indexName fields SQLite) [] conn @@ -128,7 +204,7 @@ module Document = /// Insert a new document /// The table into which the document should be inserted (may include schema) /// The document to be inserted - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let insert<'TDoc> tableName (document: 'TDoc) conn = let query = @@ -148,39 +224,39 @@ module Document = (Query.insert tableName).Replace("@data", dataParam) Custom.nonQuery query [ jsonParam "@data" document ] conn - /// - /// Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert") - /// + /// Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert") /// The table into which the document should be saved (may include schema) /// The document to be saved - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let save<'TDoc> tableName (document: 'TDoc) conn = Custom.nonQuery (Query.save tableName) [ jsonParam "@data" document ] conn + /// Commands to count documents [] module Count = /// Count all documents in a table /// The table in which documents should be counted (may include schema) - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// The count of the documents in the table [] let all tableName conn = Custom.scalar (Query.count tableName) [] toCount 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// The count of matching documents in the table [] let byFields tableName howMatched fields conn = Custom.scalar (Query.byFields (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount conn + /// Commands to determine if documents exist [] module Exists = @@ -188,17 +264,17 @@ module Exists = /// Determine if a document exists for the given ID /// The table in which existence should be checked (may include schema) /// The ID of the document whose existence should be checked - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// True if a document exists, false if not [] let byId tableName (docId: 'TKey) conn = Custom.scalar (Query.exists tableName (Query.whereById docId)) [ idParam docId ] toExists 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// True if any matching documents exist, false if not [] let byFields tableName howMatched fields conn = @@ -208,13 +284,14 @@ module Exists = toExists conn -/// Commands to retrieve documents + +/// Commands to retrieve documents as domain items [] module Find = /// Retrieve all documents in the given table /// The table from which documents should be retrieved (may include schema) - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents from the given table [] let all<'TDoc> tableName conn = @@ -222,7 +299,7 @@ module Find = /// Retrieve all documents in the given table /// The table from which documents should be retrieved (may include schema) - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents from the given table let All<'TDoc>(tableName, conn) = Custom.List(Query.find tableName, [], fromData<'TDoc>, conn) @@ -230,7 +307,7 @@ module Find = /// Retrieve all documents in the given table ordered by the given fields in the document /// The table from which documents should be retrieved (may include schema) /// Fields by which the results should be ordered - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents from the given table, ordered by the given fields [] let allOrdered<'TDoc> tableName orderFields conn = @@ -239,7 +316,7 @@ module Find = /// Retrieve all documents in the given table ordered by the given fields in the document /// The table from which documents should be retrieved (may include schema) /// Fields by which the results should be ordered - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents from the given table, ordered by the given fields let AllOrdered<'TDoc>(tableName, orderFields, conn) = Custom.List(Query.find tableName + Query.orderBy orderFields SQLite, [], fromData<'TDoc>, conn) @@ -247,8 +324,8 @@ 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 SqliteConnection to use to execute the query - /// Some with the document if found, None otherwise + /// The SqliteConnection to use to execute the query + /// Some with the document if found, None otherwise [] let byId<'TKey, 'TDoc> tableName (docId: 'TKey) conn = Custom.single<'TDoc> (Query.byId (Query.find tableName) docId) [ idParam docId ] fromData<'TDoc> conn @@ -256,16 +333,16 @@ 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 SqliteConnection to use to execute the query - /// The document if found, null otherwise + /// The SqliteConnection to use to execute the query + /// The document if found, null otherwise let ById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, docId: 'TKey, conn) = Custom.Single<'TDoc>(Query.byId (Query.find tableName) docId, [ idParam docId ], fromData<'TDoc>, 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents matching the given fields [] let byFields<'TDoc> tableName howMatched fields conn = @@ -275,11 +352,11 @@ module Find = fromData<'TDoc> 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents matching the given fields let ByFields<'TDoc>(tableName, howMatched, fields, conn) = Custom.List<'TDoc>( @@ -289,14 +366,14 @@ module Find = 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 /// The field conditions to match /// Fields by which the results should be ordered - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents matching the given fields, ordered by the other given fields [] let byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn = @@ -307,14 +384,14 @@ module Find = 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 /// The field conditions to match /// Fields by which the results should be ordered - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// All documents matching the given fields, ordered by the other given fields let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn) = Custom.List<'TDoc>( @@ -323,12 +400,12 @@ module Find = fromData<'TDoc>, 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 - /// The SqliteConnection to use to execute the query - /// Some with the first document, or None if not found + /// The SqliteConnection to use to execute the query + /// Some with the first document, or None if not found [] let firstByFields<'TDoc> tableName howMatched fields conn = Custom.single @@ -337,12 +414,12 @@ module Find = fromData<'TDoc> 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 - /// The SqliteConnection to use to execute the query - /// The first document, or null if not found + /// The SqliteConnection to use to execute the query + /// The first document, or null if not found let FirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, howMatched, fields, conn) = Custom.Single( $"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1", @@ -351,16 +428,16 @@ module Find = 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query /// - /// 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 conn = @@ -371,15 +448,15 @@ module Find = 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 - /// The SqliteConnection to use to execute the query - /// The first document ordered by the given fields, or null if not found + /// The SqliteConnection to use to execute the query + /// 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, conn) = Custom.Single( @@ -388,6 +465,204 @@ module Find = fromData<'TDoc>, conn) + +/// Commands to retrieve documents as raw JSON +[] +module Json = + + /// Retrieve all JSON documents in the given table + /// The table from which documents should be retrieved (may include schema) + /// The SqliteConnection to use to execute the query + /// All JSON documents from the given table + [] + let all tableName conn = + Custom.jsonArray (Query.find tableName) [] jsonFromData conn + + /// Retrieve all JSON documents in the given table ordered by the given fields in the document + /// The table from which documents should be retrieved (may include schema) + /// Fields by which the results should be ordered + /// The SqliteConnection to use to execute the query + /// All JSON documents from the given table, ordered by the given fields + [] + let allOrdered tableName orderFields conn = + Custom.jsonArray (Query.find tableName + Query.orderBy orderFields SQLite) [] jsonFromData conn + + /// Retrieve a JSON document by its ID + /// The table from which a document should be retrieved (may include schema) + /// The ID of the document to retrieve + /// The SqliteConnection to use to execute the query + /// The JSON document if found, an empty JSON document otherwise + [] + let byId<'TKey> tableName (docId: 'TKey) conn = + Custom.jsonSingle (Query.byId (Query.find tableName) docId) [ idParam docId ] jsonFromData conn + + /// Retrieve JSON 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 + /// The SqliteConnection to use to execute the query + /// All JSON documents matching the given fields + [] + let byFields tableName howMatched fields conn = + Custom.jsonArray + (Query.byFields (Query.find tableName) howMatched fields) (addFieldParams fields []) jsonFromData conn + + /// + /// Retrieve JSON 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 + /// The field conditions to match + /// Fields by which the results should be ordered + /// The SqliteConnection to use to execute the query + /// All JSON documents matching the given fields, ordered by the other given fields + [] + let byFieldsOrdered tableName howMatched queryFields orderFields conn = + Custom.jsonArray + (Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite) + (addFieldParams queryFields []) + jsonFromData + conn + + /// Retrieve the first JSON 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 SqliteConnection to use to execute the query + /// The first JSON document if found, an empty JSON document otherwise + [] + let firstByFields tableName howMatched fields conn = + Custom.jsonSingle + (Query.byFields (Query.find tableName) howMatched fields) (addFieldParams fields []) jsonFromData conn + + /// + /// Retrieve the first JSON 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 SqliteConnection to use to execute the query + /// The first JSON document (in order) if found, an empty JSON document otherwise + [] + let firstByFieldsOrdered tableName howMatched queryFields orderFields conn = + Custom.jsonSingle + (Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite) + (addFieldParams queryFields []) + jsonFromData + conn + + /// Write all JSON documents in the given table to the given StreamWriter + /// The table from which documents should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// The SqliteConnection to use to execute the query + [] + let writeAll tableName writer conn = + Custom.writeJsonArray (Query.find tableName) [] writer jsonFromData conn + + /// + /// Write all JSON all documents in the given table to the given StreamWriter, ordered by the given fields in + /// the document + /// + /// The table from which documents should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// Fields by which the results should be ordered + /// The SqliteConnection to use to execute the query + [] + let writeAllOrdered tableName writer orderFields conn = + Custom.writeJsonArray (Query.find tableName + Query.orderBy orderFields SQLite) [] writer jsonFromData conn + + /// Write a JSON document to the given StreamWriter by its ID + /// The table from which a document should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// The ID of the document to retrieve + /// The SqliteConnection to use to execute the query + [] + let writeById<'TKey> tableName (writer: StreamWriter) (docId: 'TKey) conn = backgroundTask { + let! json = Custom.jsonSingle (Query.byId (Query.find tableName) docId) [ idParam docId ] jsonFromData conn + do! writer.WriteAsync json + } + + /// + /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =, etc.) + /// + /// The table from which documents should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// Whether to match any or all of the field conditions + /// The field conditions to match + /// The SqliteConnection to use to execute the query + [] + let writeByFields tableName writer howMatched fields conn = + Custom.writeJsonArray + (Query.byFields (Query.find tableName) howMatched fields) + (addFieldParams fields []) + writer + jsonFromData + conn + + /// + /// Write JSON documents to the given StreamWriter matching JSON field comparisons (->> =, etc.) + /// ordered by the given fields in the document + /// + /// The table from which documents should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// Whether to match any or all of the field conditions + /// The field conditions to match + /// Fields by which the results should be ordered + /// The SqliteConnection to use to execute the query + [] + let writeByFieldsOrdered tableName writer howMatched queryFields orderFields conn = + Custom.writeJsonArray + (Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite) + (addFieldParams queryFields []) + writer + jsonFromData + conn + + /// + /// Write the first JSON document to the given StreamWriter matching JSON field comparisons + /// (->> =, etc.) + /// + /// The table from which a document should be retrieved (may include schema) + /// The StreamWriter to which the results should be written + /// Whether to match any or all of the field conditions + /// The field conditions to match + /// The SqliteConnection to use to execute the query + /// The first JSON document if found, an empty JSON document otherwise + [] + let writeFirstByFields tableName (writer: StreamWriter) howMatched fields conn = backgroundTask { + let! json = + Custom.jsonSingle + (Query.byFields (Query.find tableName) howMatched fields) (addFieldParams fields []) jsonFromData conn + do! writer.WriteAsync json + } + + /// + /// Write the first JSON document to the given StreamWriter 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) + /// The StreamWriter to which the results should be written + /// Whether to match any or all of the field conditions + /// The field conditions to match + /// Fields by which the results should be ordered + /// The SqliteConnection to use to execute the query + /// The first JSON document (in order) if found, an empty JSON document otherwise + [] + let writeFirstByFieldsOrdered tableName (writer: StreamWriter) howMatched queryFields orderFields conn = + backgroundTask { + let! json = + Custom.jsonSingle + (Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite) + (addFieldParams queryFields []) + jsonFromData + conn + do! writer.WriteAsync json + } + + /// Commands to update documents [] module Update = @@ -396,7 +671,7 @@ module Update = /// The table in which a document should be updated (may include schema) /// The ID of the document to be updated (replaced) /// The new document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byId tableName (docId: 'TKey) (document: 'TDoc) conn = Custom.nonQuery @@ -405,28 +680,27 @@ module Update = conn /// - /// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the - /// document + /// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document /// /// The table in which a document should be updated (may include schema) /// The function to obtain the ID of the document /// The new document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) conn = byId tableName (idFunc document) document conn /// - /// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the - /// document + /// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document /// /// The table in which a document should be updated (may include schema) /// The function to obtain the ID of the document /// The new document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query let ByFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc, conn) = byFunc tableName idFunc.Invoke document conn + /// Commands to patch (partially update) documents [] module Patch = @@ -435,21 +709,20 @@ module Patch = /// The table in which a document should be patched (may include schema) /// The ID of the document to patch /// The partial document to patch the existing document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byId tableName (docId: 'TKey) (patch: 'TPatch) conn = Custom.nonQuery (Query.byId (Query.patch tableName) docId) [ idParam docId; jsonParam "@data" patch ] 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 table in which documents should be patched (may include schema) /// Whether to match any or all of the field conditions /// The field conditions to match /// The partial document to patch the existing document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byFields tableName howMatched fields (patch: 'TPatch) conn = Custom.nonQuery @@ -457,6 +730,7 @@ module Patch = (addFieldParams fields [ jsonParam "@data" patch ]) conn + /// Commands to remove fields from documents [] module RemoveFields = @@ -465,7 +739,7 @@ module RemoveFields = /// The table in which a document should be modified (may include schema) /// The ID of the document to modify /// One or more field names to remove from the document - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byId tableName (docId: 'TKey) fieldNames conn = let nameParams = fieldNameParams "@name" fieldNames @@ -479,7 +753,7 @@ module RemoveFields = /// Whether to match any or all of the field conditions /// The field conditions to match /// One or more field names to remove from the matching documents - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byFields tableName howMatched fields fieldNames conn = let nameParams = fieldNameParams "@name" fieldNames @@ -488,23 +762,24 @@ module RemoveFields = (addFieldParams fields nameParams) conn -/// Commands to delete documents + +/// Commands to delete documents [] module Delete = /// Delete a document by its ID /// The table in which a document should be deleted (may include schema) /// The ID of the document to delete - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byId tableName (docId: 'TKey) conn = Custom.nonQuery (Query.byId (Query.delete tableName) docId) [ idParam docId ] 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 - /// The SqliteConnection to use to execute the query + /// The SqliteConnection to use to execute the query [] let byFields tableName howMatched fields conn = Custom.nonQuery (Query.byFields (Query.delete tableName) howMatched fields) (addFieldParams fields []) conn