Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5580284910 | |||
| 147a72b476 | |||
| 740767661c |
@@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Common files for PostgreSQL and SQLite document database libraries</Description>
|
<Description>Common files for PostgreSQL and SQLite document database libraries</Description>
|
||||||
<PackageTags>JSON Document SQL</PackageTags>
|
<PackageTags>JSON Document SQL</PackageTags>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -13,7 +14,9 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FSharp.SystemTextJson" Version="1.3.13" />
|
<PackageReference Include="FSharp.SystemTextJson" Version="1.3.13" />
|
||||||
<PackageReference Update="FSharp.Core" Version="8.0.300" />
|
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||||
|
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.0" />
|
||||||
|
<PackageReference Include="System.Text.Json" Version="9.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,32 +2,44 @@
|
|||||||
|
|
||||||
open System.Security.Cryptography
|
open System.Security.Cryptography
|
||||||
|
|
||||||
/// The types of comparisons available for JSON fields
|
/// <summary>The types of comparisons available for JSON fields</summary>
|
||||||
|
/// <exclude />
|
||||||
type Comparison =
|
type Comparison =
|
||||||
/// Equals (=)
|
|
||||||
|
/// <summary>Equals (<tt>=</tt>)</summary>
|
||||||
| Equal of Value: obj
|
| Equal of Value: obj
|
||||||
/// Greater Than (>)
|
|
||||||
|
/// <summary>Greater Than (<tt>></tt>)</summary>
|
||||||
| Greater of Value: obj
|
| Greater of Value: obj
|
||||||
/// Greater Than or Equal To (>=)
|
|
||||||
|
/// <summary>Greater Than or Equal To (<tt>>=</tt>)</summary>
|
||||||
| GreaterOrEqual of Value: obj
|
| GreaterOrEqual of Value: obj
|
||||||
/// Less Than (<)
|
|
||||||
|
/// <summary>Less Than (<tt><</tt>)</summary>
|
||||||
| Less of Value: obj
|
| Less of Value: obj
|
||||||
/// Less Than or Equal To (<=)
|
|
||||||
|
/// <summary>Less Than or Equal To (<tt><=</tt>)</summary>
|
||||||
| LessOrEqual of Value: obj
|
| LessOrEqual of Value: obj
|
||||||
/// Not Equal to (<>)
|
|
||||||
|
/// <summary>Not Equal to (<tt><></tt>)</summary>
|
||||||
| NotEqual of Value: obj
|
| NotEqual of Value: obj
|
||||||
/// Between (BETWEEN)
|
|
||||||
|
/// <summary>Between (<tt>BETWEEN</tt>)</summary>
|
||||||
| Between of Min: obj * Max: obj
|
| Between of Min: obj * Max: obj
|
||||||
/// In (IN)
|
|
||||||
|
/// <summary>In (<tt>IN</tt>)</summary>
|
||||||
| In of Values: obj seq
|
| In of Values: obj seq
|
||||||
/// In Array (PostgreSQL: |?, SQLite: EXISTS / json_each / IN)
|
|
||||||
|
/// <summary>In Array (PostgreSQL: <tt>|?</tt>, SQLite: <tt>EXISTS / json_each / IN</tt>)</summary>
|
||||||
| InArray of Table: string * Values: obj seq
|
| InArray of Table: string * Values: obj seq
|
||||||
/// Exists (IS NOT NULL)
|
|
||||||
|
/// <summary>Exists (<tt>IS NOT NULL</tt>)</summary>
|
||||||
| Exists
|
| Exists
|
||||||
/// Does Not Exist (IS NULL)
|
|
||||||
|
/// <summary>Does Not Exist (<tt>IS NULL</tt>)</summary>
|
||||||
| NotExists
|
| NotExists
|
||||||
|
|
||||||
/// Get the operator SQL for this comparison
|
/// <summary>The operator SQL for this comparison</summary>
|
||||||
member this.OpSql =
|
member this.OpSql =
|
||||||
match this with
|
match this with
|
||||||
| Equal _ -> "="
|
| Equal _ -> "="
|
||||||
@@ -43,116 +55,190 @@ type Comparison =
|
|||||||
| NotExists -> "IS NULL"
|
| NotExists -> "IS NULL"
|
||||||
|
|
||||||
|
|
||||||
/// The dialect in which a command should be rendered
|
/// <summary>The dialect in which a command should be rendered</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type Dialect =
|
type Dialect =
|
||||||
| PostgreSQL
|
| PostgreSQL
|
||||||
| SQLite
|
| SQLite
|
||||||
|
|
||||||
|
|
||||||
/// The format in which an element of a JSON field should be extracted
|
/// <summary>The format in which an element of a JSON field should be extracted</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type FieldFormat =
|
type FieldFormat =
|
||||||
/// Use ->> or #>>; extracts a text (PostgreSQL) or SQL (SQLite) value
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use <tt>->></tt> or <tt>#>></tt>; extracts a text (PostgreSQL) or SQL (SQLite) value
|
||||||
|
/// </summary>
|
||||||
| AsSql
|
| AsSql
|
||||||
/// Use -> or #>; extracts a JSONB (PostgreSQL) or JSON (SQLite) value
|
|
||||||
|
/// <summary>Use <tt>-></tt> or <tt>#></tt>; extracts a JSONB (PostgreSQL) or JSON (SQLite) value</summary>
|
||||||
| AsJson
|
| AsJson
|
||||||
|
|
||||||
|
|
||||||
/// Criteria for a field WHERE clause
|
/// <summary>Criteria for a field <tt>WHERE</tt> clause</summary>
|
||||||
type Field =
|
type Field = {
|
||||||
{ /// The name of the field
|
|
||||||
Name: string
|
|
||||||
|
|
||||||
/// The comparison for the field
|
/// <summary>The name of the field</summary>
|
||||||
Comparison: Comparison
|
Name: string
|
||||||
|
|
||||||
/// The name of the parameter for this field
|
/// <summary>The comparison for the field</summary>
|
||||||
ParameterName: string option
|
Comparison: Comparison
|
||||||
|
|
||||||
/// The table qualifier for this field
|
/// <summary>The name of the parameter for this field</summary>
|
||||||
Qualifier: string option }
|
ParameterName: string option
|
||||||
with
|
|
||||||
|
|
||||||
/// Create a comparison against a field
|
/// <summary>The table qualifier for this field</summary>
|
||||||
static member Where name comparison =
|
Qualifier: string option
|
||||||
|
} with
|
||||||
|
|
||||||
|
/// <summary>Create a comparison against a field</summary>
|
||||||
|
/// <param name="name">The name of the field against which the comparison should be applied</param>
|
||||||
|
/// <param name="comparison">The comparison for the given field</param>
|
||||||
|
/// <returns>A new <tt>Field</tt> instance implementing the given comparison</returns>
|
||||||
|
static member Where name (comparison: Comparison) =
|
||||||
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
|
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
|
||||||
|
|
||||||
/// Create an equals (=) field criterion
|
/// <summary>Create an equals (<tt>=</tt>) field criterion</summary>
|
||||||
static member Equal name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member Equal<'T> name (value: 'T) =
|
||||||
Field.Where name (Equal value)
|
Field.Where name (Equal value)
|
||||||
|
|
||||||
/// Create an equals (=) field criterion (alias)
|
/// <summary>Create an equals (<tt>=</tt>) field criterion (alias)</summary>
|
||||||
static member EQ name (value: obj) = Field.Equal name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member EQ<'T> name (value: 'T) = Field.Equal name value
|
||||||
|
|
||||||
/// Create a greater than (>) field criterion
|
/// <summary>Create a greater than (<tt>></tt>) field criterion</summary>
|
||||||
static member Greater name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member Greater<'T> name (value: 'T) =
|
||||||
Field.Where name (Greater value)
|
Field.Where name (Greater value)
|
||||||
|
|
||||||
/// Create a greater than (>) field criterion (alias)
|
/// <summary>Create a greater than (<tt>></tt>) field criterion (alias)</summary>
|
||||||
static member GT name (value: obj) = Field.Greater name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member GT<'T> name (value: 'T) = Field.Greater name value
|
||||||
|
|
||||||
/// Create a greater than or equal to (>=) field criterion
|
/// <summary>Create a greater than or equal to (<tt>>=</tt>) field criterion</summary>
|
||||||
static member GreaterOrEqual name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member GreaterOrEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (GreaterOrEqual value)
|
Field.Where name (GreaterOrEqual value)
|
||||||
|
|
||||||
/// Create a greater than or equal to (>=) field criterion (alias)
|
/// <summary>Create a greater than or equal to (<tt>>=</tt>) field criterion (alias)</summary>
|
||||||
static member GE name (value: obj) = Field.GreaterOrEqual name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member GE<'T> name (value: 'T) = Field.GreaterOrEqual name value
|
||||||
|
|
||||||
/// Create a less than (<) field criterion
|
/// <summary>Create a less than (<tt><</tt>) field criterion</summary>
|
||||||
static member Less name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member Less<'T> name (value: 'T) =
|
||||||
Field.Where name (Less value)
|
Field.Where name (Less value)
|
||||||
|
|
||||||
/// Create a less than (<) field criterion (alias)
|
/// <summary>Create a less than (<tt><</tt>) field criterion (alias)</summary>
|
||||||
static member LT name (value: obj) = Field.Less name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member LT<'T> name (value: 'T) = Field.Less name value
|
||||||
|
|
||||||
/// Create a less than or equal to (<=) field criterion
|
/// <summary>Create a less than or equal to (<tt><=</tt>) field criterion</summary>
|
||||||
static member LessOrEqual name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member LessOrEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (LessOrEqual value)
|
Field.Where name (LessOrEqual value)
|
||||||
|
|
||||||
/// Create a less than or equal to (<=) field criterion (alias)
|
/// <summary>Create a less than or equal to (<tt><=</tt>) field criterion (alias)</summary>
|
||||||
static member LE name (value: obj) = Field.LessOrEqual name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member LE<'T> name (value: 'T) = Field.LessOrEqual name value
|
||||||
|
|
||||||
/// Create a not equals (<>) field criterion
|
/// <summary>Create a not equals (<tt><></tt>) field criterion</summary>
|
||||||
static member NotEqual name (value: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member NotEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (NotEqual value)
|
Field.Where name (NotEqual value)
|
||||||
|
|
||||||
/// Create a not equals (<>) field criterion (alias)
|
/// <summary>Create a not equals (<tt><></tt>) field criterion (alias)</summary>
|
||||||
static member NE name (value: obj) = Field.NotEqual name value
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="value">The value for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member NE<'T> name (value: 'T) = Field.NotEqual name value
|
||||||
|
|
||||||
/// Create a Between field criterion
|
/// <summary>Create a Between field criterion</summary>
|
||||||
static member Between name (min: obj) (max: obj) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="min">The minimum value for the comparison range</param>
|
||||||
|
/// <param name="max">The maximum value for the comparison range</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member Between<'T> name (min: 'T) (max: 'T) =
|
||||||
Field.Where name (Between(min, max))
|
Field.Where name (Between(min, max))
|
||||||
|
|
||||||
/// Create a Between field criterion (alias)
|
/// <summary>Create a Between field criterion (alias)</summary>
|
||||||
static member BT name (min: obj) (max: obj) = Field.Between name min max
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="min">The minimum value for the comparison range</param>
|
||||||
|
/// <param name="max">The maximum value for the comparison range</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member BT<'T> name (min: 'T) (max: 'T) = Field.Between name min max
|
||||||
|
|
||||||
/// Create an In field criterion
|
/// <summary>Create an In field criterion</summary>
|
||||||
static member In name (values: obj seq) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
Field.Where name (In values)
|
/// <param name="values">The values for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member In<'T> name (values: 'T seq) =
|
||||||
|
Field.Where name (In (Seq.map box values))
|
||||||
|
|
||||||
/// Create an In field criterion (alias)
|
/// <summary>Create an In field criterion (alias)</summary>
|
||||||
static member IN name (values: obj seq) = Field.In name values
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <param name="values">The values for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member IN<'T> name (values: 'T seq) = Field.In name values
|
||||||
|
|
||||||
/// Create an InArray field criterion
|
/// <summary>Create an InArray field criterion</summary>
|
||||||
static member InArray name tableName (values: obj seq) =
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
Field.Where name (InArray(tableName, values))
|
/// <param name="tableName">The name of the table in which the field's documents are stored</param>
|
||||||
|
/// <param name="values">The values for the comparison</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
|
static member InArray<'T> name tableName (values: 'T seq) =
|
||||||
|
Field.Where name (InArray(tableName, Seq.map box values))
|
||||||
|
|
||||||
/// Create an exists (IS NOT NULL) field criterion
|
/// <summary>Create an exists (<tt>IS NOT NULL</tt>) field criterion</summary>
|
||||||
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Exists name =
|
static member Exists name =
|
||||||
Field.Where name Exists
|
Field.Where name Exists
|
||||||
|
|
||||||
/// Create an exists (IS NOT NULL) field criterion (alias)
|
/// <summary>Create an exists (<tt>IS NOT NULL</tt>) field criterion (alias)</summary>
|
||||||
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member EX name = Field.Exists name
|
static member EX name = Field.Exists name
|
||||||
|
|
||||||
/// Create a not exists (IS NULL) field criterion
|
/// <summary>Create a not exists (<tt>IS NULL</tt>) field criterion</summary>
|
||||||
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NotExists name =
|
static member NotExists name =
|
||||||
Field.Where name NotExists
|
Field.Where name NotExists
|
||||||
|
|
||||||
/// Create a not exists (IS NULL) field criterion (alias)
|
/// <summary>Create a not exists (<tt>IS NULL</tt>) field criterion (alias)</summary>
|
||||||
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NEX name = Field.NotExists name
|
static member NEX name = Field.NotExists name
|
||||||
|
|
||||||
/// Transform a field name (a.b.c) to a path for the given SQL dialect
|
/// <summary>Transform a field name (<tt>a.b.c</tt>) to a path for the given SQL dialect</summary>
|
||||||
|
/// <param name="name">The name of the field in dotted format</param>
|
||||||
|
/// <param name="dialect">The SQL dialect to use when converting the name to nested path format</param>
|
||||||
|
/// <param name="format">Whether to reference this path as a JSON value or a SQL value</param>
|
||||||
|
/// <returns>A <tt>string</tt> with the path required to address the nested document value</returns>
|
||||||
static member NameToPath (name: string) dialect format =
|
static member NameToPath (name: string) dialect format =
|
||||||
let path =
|
let path =
|
||||||
if name.Contains '.' then
|
if name.Contains '.' then
|
||||||
@@ -169,43 +255,59 @@ with
|
|||||||
match format with AsJson -> $"->'{name}'" | AsSql -> $"->>'{name}'"
|
match format with AsJson -> $"->'{name}'" | AsSql -> $"->>'{name}'"
|
||||||
$"data{path}"
|
$"data{path}"
|
||||||
|
|
||||||
/// Create a field with a given name, but no other properties filled (op will be EQ, value will be "")
|
/// <summary>Create a field with a given name, but no other properties filled</summary>
|
||||||
|
/// <param name="name">The field name, along with any other qualifications if used in a sorting context</param>
|
||||||
|
/// <remarks><tt>Comparison</tt> will be <tt>Equal</tt>, value will be an empty string</remarks>
|
||||||
static member Named name =
|
static member Named name =
|
||||||
Field.Where name (Equal "")
|
Field.Where name (Equal "")
|
||||||
|
|
||||||
/// Specify the name of the parameter for this field
|
/// <summary>Specify the name of the parameter for this field</summary>
|
||||||
|
/// <param name="name">The parameter name (including <tt>:</tt> or <tt>@</tt>)</param>
|
||||||
|
/// <returns>A field with the given parameter name specified</returns>
|
||||||
member this.WithParameterName name =
|
member this.WithParameterName name =
|
||||||
{ this with ParameterName = Some name }
|
{ this with ParameterName = Some name }
|
||||||
|
|
||||||
/// Specify a qualifier (alias) for the table from which this field will be referenced
|
/// <summary>Specify a qualifier (alias) for the table from which this field will be referenced</summary>
|
||||||
|
/// <param name="alias">The table alias for this field comparison</param>
|
||||||
|
/// <returns>A field with the given qualifier specified</returns>
|
||||||
member this.WithQualifier alias =
|
member this.WithQualifier alias =
|
||||||
{ this with Qualifier = Some alias }
|
{ this with Qualifier = Some alias }
|
||||||
|
|
||||||
/// Get the qualified path to the field
|
/// <summary>Get the qualified path to the field</summary>
|
||||||
|
/// <param name="dialect">The SQL dialect to use when converting the name to nested path format</param>
|
||||||
|
/// <param name="format">Whether to reference this path as a JSON value or a SQL value</param>
|
||||||
|
/// <returns>A <tt>string</tt> with the qualified path required to address the nested document value</returns>
|
||||||
member this.Path dialect format =
|
member this.Path dialect format =
|
||||||
(this.Qualifier |> Option.map (fun q -> $"{q}.") |> Option.defaultValue "")
|
(this.Qualifier |> Option.map (fun q -> $"{q}.") |> Option.defaultValue "")
|
||||||
+ Field.NameToPath this.Name dialect format
|
+ Field.NameToPath this.Name dialect format
|
||||||
|
|
||||||
|
|
||||||
/// How fields should be matched
|
/// <summary>How fields should be matched</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type FieldMatch =
|
type FieldMatch =
|
||||||
/// Any field matches (OR)
|
|
||||||
|
/// <summary>Any field matches (<tt>OR</tt>)</summary>
|
||||||
| Any
|
| Any
|
||||||
/// All fields match (AND)
|
|
||||||
|
/// <summary>All fields match (<tt>AND</tt>)</summary>
|
||||||
| All
|
| All
|
||||||
|
|
||||||
/// The SQL value implementing each matching strategy
|
/// <summary>The SQL value implementing each matching strategy</summary>
|
||||||
override this.ToString() =
|
override this.ToString() =
|
||||||
match this with Any -> "OR" | All -> "AND"
|
match this with Any -> "OR" | All -> "AND"
|
||||||
|
|
||||||
|
|
||||||
/// Derive parameter names (each instance wraps a counter to uniquely name anonymous fields)
|
/// <summary>Derive parameter names (each instance wraps a counter to uniquely name anonymous fields)</summary>
|
||||||
type ParameterName() =
|
type ParameterName() =
|
||||||
|
|
||||||
/// The counter for the next field value
|
/// The counter for the next field value
|
||||||
let mutable currentIdx = -1
|
let mutable currentIdx = -1
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// Return the specified name for the parameter, or an anonymous parameter name if none is specified
|
/// Return the specified name for the parameter, or an anonymous parameter name if none is specified
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paramName">The optional name of the parameter</param>
|
||||||
|
/// <returns>The name of the parameter, derived if no name was provided</returns>
|
||||||
member this.Derive paramName =
|
member this.Derive paramName =
|
||||||
match paramName with
|
match paramName with
|
||||||
| Some it -> it
|
| Some it -> it
|
||||||
@@ -213,37 +315,42 @@ type ParameterName() =
|
|||||||
currentIdx <- currentIdx + 1
|
currentIdx <- currentIdx + 1
|
||||||
$"@field{currentIdx}"
|
$"@field{currentIdx}"
|
||||||
|
|
||||||
#if NET6_0
|
|
||||||
open System.Text
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Automatically-generated document ID strategies
|
/// <summary>Automatically-generated document ID strategies</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type AutoId =
|
type AutoId =
|
||||||
/// No automatic IDs will be generated
|
|
||||||
|
/// <summary>No automatic IDs will be generated</summary>
|
||||||
| Disabled
|
| Disabled
|
||||||
/// Generate a MAX-plus-1 numeric value for documents
|
|
||||||
|
/// <summary>Generate a MAX-plus-1 numeric value for documents</summary>
|
||||||
| Number
|
| Number
|
||||||
/// Generate a GUID for each document (as a lowercase, no-dashes, 32-character string)
|
|
||||||
|
/// <summary>Generate a <tt>GUID</tt> for each document (as a lowercase, no-dashes, 32-character string)</summary>
|
||||||
| Guid
|
| Guid
|
||||||
/// Generate a random string of hexadecimal characters for each document
|
|
||||||
|
/// <summary>Generate a random string of hexadecimal characters for each document</summary>
|
||||||
| RandomString
|
| RandomString
|
||||||
with
|
with
|
||||||
/// Generate a GUID string
|
/// <summary>Generate a <tt>GUID</tt> string</summary>
|
||||||
static member GenerateGuid () =
|
/// <returns>A <tt>GUID</tt> string</returns>
|
||||||
|
static member GenerateGuid() =
|
||||||
System.Guid.NewGuid().ToString "N"
|
System.Guid.NewGuid().ToString "N"
|
||||||
|
|
||||||
/// Generate a string of random hexadecimal characters
|
/// <summary>Generate a string of random hexadecimal characters</summary>
|
||||||
static member GenerateRandomString (length: int) =
|
/// <param name="length">The number of characters to generate</param>
|
||||||
#if NET8_0_OR_GREATER
|
/// <returns>A string of the given length with random hexadecimal characters</returns>
|
||||||
|
static member GenerateRandomString(length: int) =
|
||||||
RandomNumberGenerator.GetHexString(length, lowercase = true)
|
RandomNumberGenerator.GetHexString(length, lowercase = true)
|
||||||
#else
|
|
||||||
RandomNumberGenerator.GetBytes((length / 2) + 1)
|
|
||||||
|> Array.fold (fun (str: StringBuilder) byt -> str.Append(byt.ToString "x2")) (StringBuilder length)
|
|
||||||
|> function it -> it.Length <- length; it.ToString()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Does the given document need an automatic ID generated?
|
/// <summary>Does the given document need an automatic ID generated?</summary>
|
||||||
|
/// <param name="strategy">The auto-ID strategy currently in use</param>
|
||||||
|
/// <param name="document">The document being inserted</param>
|
||||||
|
/// <param name="idProp">The name of the ID property in the given document</param>
|
||||||
|
/// <returns>True if an auto-ID strategy is implemented and the ID has no value, false otherwise</returns>
|
||||||
|
/// <exception cref="T:System.InvalidOperationException">
|
||||||
|
/// If the ID field type and requested ID value are not compatible
|
||||||
|
/// </exception>
|
||||||
static member NeedsAutoId<'T> strategy (document: 'T) idProp =
|
static member NeedsAutoId<'T> strategy (document: 'T) idProp =
|
||||||
match strategy with
|
match strategy with
|
||||||
| Disabled -> false
|
| Disabled -> false
|
||||||
@@ -278,17 +385,17 @@ with
|
|||||||
| Disabled -> false
|
| Disabled -> false
|
||||||
|
|
||||||
|
|
||||||
/// The required document serialization implementation
|
/// <summary>The required document serialization implementation</summary>
|
||||||
type IDocumentSerializer =
|
type IDocumentSerializer =
|
||||||
|
|
||||||
/// Serialize an object to a JSON string
|
/// <summary>Serialize an object to a JSON string</summary>
|
||||||
abstract Serialize<'T> : 'T -> string
|
abstract Serialize<'T> : 'T -> string
|
||||||
|
|
||||||
/// Deserialize a JSON string into an object
|
/// <summary>Deserialize a JSON string into an object</summary>
|
||||||
abstract Deserialize<'T> : string -> 'T
|
abstract Deserialize<'T> : string -> 'T
|
||||||
|
|
||||||
|
|
||||||
/// Document serializer defaults
|
/// <summary>Document serializer defaults</summary>
|
||||||
module DocumentSerializer =
|
module DocumentSerializer =
|
||||||
|
|
||||||
open System.Text.Json
|
open System.Text.Json
|
||||||
@@ -300,7 +407,7 @@ module DocumentSerializer =
|
|||||||
o.Converters.Add(JsonFSharpConverter())
|
o.Converters.Add(JsonFSharpConverter())
|
||||||
o
|
o
|
||||||
|
|
||||||
/// The default JSON serializer
|
/// <summary>The default JSON serializer</summary>
|
||||||
[<CompiledName "Default">]
|
[<CompiledName "Default">]
|
||||||
let ``default`` =
|
let ``default`` =
|
||||||
{ new IDocumentSerializer with
|
{ new IDocumentSerializer with
|
||||||
@@ -311,19 +418,21 @@ module DocumentSerializer =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Configuration for document handling
|
/// <summary>Configuration for document handling</summary>
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Configuration =
|
module Configuration =
|
||||||
|
|
||||||
/// The serializer to use for document manipulation
|
/// The serializer to use for document manipulation
|
||||||
let mutable private serializerValue = DocumentSerializer.``default``
|
let mutable private serializerValue = DocumentSerializer.``default``
|
||||||
|
|
||||||
/// Register a serializer to use for translating documents to domain types
|
/// <summary>Register a serializer to use for translating documents to domain types</summary>
|
||||||
|
/// <param name="ser">The serializer to use when manipulating documents</param>
|
||||||
[<CompiledName "UseSerializer">]
|
[<CompiledName "UseSerializer">]
|
||||||
let useSerializer ser =
|
let useSerializer ser =
|
||||||
serializerValue <- ser
|
serializerValue <- ser
|
||||||
|
|
||||||
/// Retrieve the currently configured serializer
|
/// <summary>Retrieve the currently configured serializer</summary>
|
||||||
|
/// <returns>The currently configured serializer</returns>
|
||||||
[<CompiledName "Serializer">]
|
[<CompiledName "Serializer">]
|
||||||
let serializer () =
|
let serializer () =
|
||||||
serializerValue
|
serializerValue
|
||||||
@@ -331,12 +440,14 @@ module Configuration =
|
|||||||
/// The serialized name of the ID field for documents
|
/// The serialized name of the ID field for documents
|
||||||
let mutable private idFieldValue = "Id"
|
let mutable private idFieldValue = "Id"
|
||||||
|
|
||||||
/// Specify the name of the ID field for documents
|
/// <summary>Specify the name of the ID field for documents</summary>
|
||||||
|
/// <param name="it">The name of the ID field for documents</param>
|
||||||
[<CompiledName "UseIdField">]
|
[<CompiledName "UseIdField">]
|
||||||
let useIdField it =
|
let useIdField it =
|
||||||
idFieldValue <- it
|
idFieldValue <- it
|
||||||
|
|
||||||
/// Retrieve the currently configured ID field for documents
|
/// <summary>Retrieve the currently configured ID field for documents</summary>
|
||||||
|
/// <returns>The currently configured ID field</returns>
|
||||||
[<CompiledName "IdField">]
|
[<CompiledName "IdField">]
|
||||||
let idField () =
|
let idField () =
|
||||||
idFieldValue
|
idFieldValue
|
||||||
@@ -344,12 +455,14 @@ module Configuration =
|
|||||||
/// The automatic ID strategy used by the library
|
/// The automatic ID strategy used by the library
|
||||||
let mutable private autoIdValue = Disabled
|
let mutable private autoIdValue = Disabled
|
||||||
|
|
||||||
/// Specify the automatic ID generation strategy used by the library
|
/// <summary>Specify the automatic ID generation strategy used by the library</summary>
|
||||||
|
/// <param name="it">The automatic ID generation strategy to use</param>
|
||||||
[<CompiledName "UseAutoIdStrategy">]
|
[<CompiledName "UseAutoIdStrategy">]
|
||||||
let useAutoIdStrategy it =
|
let useAutoIdStrategy it =
|
||||||
autoIdValue <- it
|
autoIdValue <- it
|
||||||
|
|
||||||
/// Retrieve the currently configured automatic ID generation strategy
|
/// <summary>Retrieve the currently configured automatic ID generation strategy</summary>
|
||||||
|
/// <returns>The current automatic ID generation strategy</returns>
|
||||||
[<CompiledName "AutoIdStrategy">]
|
[<CompiledName "AutoIdStrategy">]
|
||||||
let autoIdStrategy () =
|
let autoIdStrategy () =
|
||||||
autoIdValue
|
autoIdValue
|
||||||
@@ -357,30 +470,38 @@ module Configuration =
|
|||||||
/// The length of automatically generated random strings
|
/// The length of automatically generated random strings
|
||||||
let mutable private idStringLengthValue = 16
|
let mutable private idStringLengthValue = 16
|
||||||
|
|
||||||
/// Specify the length of automatically generated random strings
|
/// <summary>Specify the length of automatically generated random strings</summary>
|
||||||
|
/// <param name="length">The length of automatically generated random strings</param>
|
||||||
[<CompiledName "UseIdStringLength">]
|
[<CompiledName "UseIdStringLength">]
|
||||||
let useIdStringLength length =
|
let useIdStringLength length =
|
||||||
idStringLengthValue <- length
|
idStringLengthValue <- length
|
||||||
|
|
||||||
/// Retrieve the currently configured length of automatically generated random strings
|
/// <summary>Retrieve the currently configured length of automatically generated random strings</summary>
|
||||||
|
/// <returns>The current length of automatically generated random strings</returns>
|
||||||
[<CompiledName "IdStringLength">]
|
[<CompiledName "IdStringLength">]
|
||||||
let idStringLength () =
|
let idStringLength () =
|
||||||
idStringLengthValue
|
idStringLengthValue
|
||||||
|
|
||||||
|
|
||||||
/// Query construction functions
|
/// <summary>Query construction functions</summary>
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Query =
|
module Query =
|
||||||
|
|
||||||
/// Combine a query (select, update, etc.) and a WHERE clause
|
/// <summary>Combine a query (<tt>SELECT</tt>, <tt>UPDATE</tt>, etc.) and a <tt>WHERE</tt> clause</summary>
|
||||||
|
/// <param name="statement">The first part of the statement</param>
|
||||||
|
/// <param name="where">The <tt>WHERE</tt> clause for the statement</param>
|
||||||
|
/// <returns>The two parts of the query combined with <tt>WHERE</tt></returns>
|
||||||
[<CompiledName "StatementWhere">]
|
[<CompiledName "StatementWhere">]
|
||||||
let statementWhere statement where =
|
let statementWhere statement where =
|
||||||
$"%s{statement} WHERE %s{where}"
|
$"%s{statement} WHERE %s{where}"
|
||||||
|
|
||||||
/// Queries to define tables and indexes
|
/// <summary>Queries to define tables and indexes</summary>
|
||||||
module Definition =
|
module Definition =
|
||||||
|
|
||||||
/// SQL statement to create a document table
|
/// <summary>SQL statement to create a document table</summary>
|
||||||
|
/// <param name="name">The name of the table to create (may include schema)</param>
|
||||||
|
/// <param name="dataType">The type of data for the column (<tt>JSON</tt>, <tt>JSONB</tt>, etc.)</param>
|
||||||
|
/// <returns>A query to create a document table</returns>
|
||||||
[<CompiledName "EnsureTableFor">]
|
[<CompiledName "EnsureTableFor">]
|
||||||
let ensureTableFor name dataType =
|
let ensureTableFor name dataType =
|
||||||
$"CREATE TABLE IF NOT EXISTS %s{name} (data %s{dataType} NOT NULL)"
|
$"CREATE TABLE IF NOT EXISTS %s{name} (data %s{dataType} NOT NULL)"
|
||||||
@@ -390,7 +511,12 @@ module Query =
|
|||||||
let parts = tableName.Split '.'
|
let parts = tableName.Split '.'
|
||||||
if Array.length parts = 1 then "", tableName else parts[0], parts[1]
|
if Array.length parts = 1 then "", tableName else parts[0], parts[1]
|
||||||
|
|
||||||
/// SQL statement to create an index on one or more fields in a JSON document
|
/// <summary>SQL statement to create an index on one or more fields in a JSON document</summary>
|
||||||
|
/// <param name="tableName">The table on which an index should be created (may include schema)</param>
|
||||||
|
/// <param name="indexName">The name of the index to be created</param>
|
||||||
|
/// <param name="fields">One or more fields to include in the index</param>
|
||||||
|
/// <param name="dialect">The SQL dialect to use when creating this index</param>
|
||||||
|
/// <returns>A query to create the field index</returns>
|
||||||
[<CompiledName "EnsureIndexOn">]
|
[<CompiledName "EnsureIndexOn">]
|
||||||
let ensureIndexOn tableName indexName (fields: string seq) dialect =
|
let ensureIndexOn tableName indexName (fields: string seq) dialect =
|
||||||
let _, tbl = splitSchemaAndTable tableName
|
let _, tbl = splitSchemaAndTable tableName
|
||||||
@@ -404,55 +530,84 @@ module Query =
|
|||||||
|> String.concat ", "
|
|> String.concat ", "
|
||||||
$"CREATE INDEX IF NOT EXISTS idx_{tbl}_%s{indexName} ON {tableName} ({jsonFields})"
|
$"CREATE INDEX IF NOT EXISTS idx_{tbl}_%s{indexName} ON {tableName} ({jsonFields})"
|
||||||
|
|
||||||
/// SQL statement to create a key index for a document table
|
/// <summary>SQL statement to create a key index for a document table</summary>
|
||||||
|
/// <param name="tableName">The table on which a key index should be created (may include schema)</param>
|
||||||
|
/// <param name="dialect">The SQL dialect to use when creating this index</param>
|
||||||
|
/// <returns>A query to create the key index</returns>
|
||||||
[<CompiledName "EnsureKey">]
|
[<CompiledName "EnsureKey">]
|
||||||
let ensureKey tableName dialect =
|
let ensureKey tableName dialect =
|
||||||
(ensureIndexOn tableName "key" [ Configuration.idField () ] dialect).Replace("INDEX", "UNIQUE INDEX")
|
(ensureIndexOn tableName "key" [ Configuration.idField () ] dialect).Replace("INDEX", "UNIQUE INDEX")
|
||||||
|
|
||||||
/// Query to insert a document
|
/// <summary>Query to insert a document</summary>
|
||||||
|
/// <param name="tableName">The table into which to insert (may include schema)</param>
|
||||||
|
/// <returns>A query to insert a document</returns>
|
||||||
[<CompiledName "Insert">]
|
[<CompiledName "Insert">]
|
||||||
let insert tableName =
|
let insert tableName =
|
||||||
$"INSERT INTO %s{tableName} VALUES (@data)"
|
$"INSERT INTO %s{tableName} VALUES (@data)"
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// Query to save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
/// Query to save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table into which to save (may include schema)</param>
|
||||||
|
/// <returns>A query to save a document</returns>
|
||||||
[<CompiledName "Save">]
|
[<CompiledName "Save">]
|
||||||
let save tableName =
|
let save tableName =
|
||||||
sprintf
|
sprintf
|
||||||
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data"
|
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data"
|
||||||
tableName (Configuration.idField ())
|
tableName (Configuration.idField ())
|
||||||
|
|
||||||
/// Query to count documents in a table (no WHERE clause)
|
/// <summary>Query to count documents in a table</summary>
|
||||||
|
/// <param name="tableName">The table in which to count documents (may include schema)</param>
|
||||||
|
/// <returns>A query to count documents</returns>
|
||||||
|
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
||||||
[<CompiledName "Count">]
|
[<CompiledName "Count">]
|
||||||
let count tableName =
|
let count tableName =
|
||||||
$"SELECT COUNT(*) AS it FROM %s{tableName}"
|
$"SELECT COUNT(*) AS it FROM %s{tableName}"
|
||||||
|
|
||||||
/// Query to check for document existence in a table
|
/// <summary>Query to check for document existence in a table</summary>
|
||||||
|
/// <param name="tableName">The table in which existence should be checked (may include schema)</param>
|
||||||
|
/// <param name="where">The <tt>WHERE</tt> clause with the existence criteria</param>
|
||||||
|
/// <returns>A query to check document existence</returns>
|
||||||
[<CompiledName "Exists">]
|
[<CompiledName "Exists">]
|
||||||
let exists tableName where =
|
let exists tableName where =
|
||||||
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it"
|
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it"
|
||||||
|
|
||||||
/// Query to select documents from a table (no WHERE clause)
|
/// <summary>Query to select documents from a table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be found (may include schema)</param>
|
||||||
|
/// <returns>A query to retrieve documents</returns>
|
||||||
|
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
||||||
[<CompiledName "Find">]
|
[<CompiledName "Find">]
|
||||||
let find tableName =
|
let find tableName =
|
||||||
$"SELECT data FROM %s{tableName}"
|
$"SELECT data FROM %s{tableName}"
|
||||||
|
|
||||||
/// Query to update a document (no WHERE clause)
|
/// <summary>Query to update (replace) a document</summary>
|
||||||
|
/// <param name="tableName">The table in which documents should be replaced (may include schema)</param>
|
||||||
|
/// <returns>A query to update documents</returns>
|
||||||
|
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
||||||
[<CompiledName "Update">]
|
[<CompiledName "Update">]
|
||||||
let update tableName =
|
let update tableName =
|
||||||
$"UPDATE %s{tableName} SET data = @data"
|
$"UPDATE %s{tableName} SET data = @data"
|
||||||
|
|
||||||
/// Query to delete documents from a table (no WHERE clause)
|
/// <summary>Query to delete documents from a table</summary>
|
||||||
|
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
|
||||||
|
/// <returns>A query to delete documents</returns>
|
||||||
|
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
||||||
[<CompiledName "Delete">]
|
[<CompiledName "Delete">]
|
||||||
let delete tableName =
|
let delete tableName =
|
||||||
$"DELETE FROM %s{tableName}"
|
$"DELETE FROM %s{tableName}"
|
||||||
|
|
||||||
/// Create a SELECT clause to retrieve the document data from the given table
|
/// <summary>Create a SELECT clause to retrieve the document data from the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be found (may include schema)</param>
|
||||||
|
/// <returns>A query to retrieve documents</returns>
|
||||||
[<CompiledName "SelectFromTable">]
|
[<CompiledName "SelectFromTable">]
|
||||||
[<System.Obsolete "Use Find instead">]
|
[<System.Obsolete "Use Find instead">]
|
||||||
let selectFromTable tableName =
|
let selectFromTable tableName =
|
||||||
find tableName
|
find tableName
|
||||||
|
|
||||||
/// Create an ORDER BY clause for the given fields
|
/// <summary>Create an <tt>ORDER BY</tt> clause for the given fields</summary>
|
||||||
|
/// <param name="fields">One or more fields by which to order</param>
|
||||||
|
/// <param name="dialect">The SQL dialect for the generated clause</param>
|
||||||
|
/// <returns>An <tt>ORDER BY</tt> clause for the given fields</returns>
|
||||||
[<CompiledName "OrderBy">]
|
[<CompiledName "OrderBy">]
|
||||||
let orderBy fields dialect =
|
let orderBy fields dialect =
|
||||||
if Seq.isEmpty fields then ""
|
if Seq.isEmpty fields then ""
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ This package provides common definitions and functionality for `BitBadger.Docume
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
||||||
|
- Automatically generate IDs for documents (numeric IDs, GUIDs, or random strings)
|
||||||
- Addresses documents via ID and via comparison on any field (for PostgreSQL, also via equality on any property by using JSON containment, or via condition on any property using JSON Path queries)
|
- Addresses documents via ID and via comparison on any field (for PostgreSQL, also via equality on any property by using JSON containment, or via condition on any property using JSON Path queries)
|
||||||
- Accesses documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
- Accesses documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
||||||
- Uses `Task`-based async for all data access functions
|
- Uses `Task`-based async for all data access functions
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<AssemblyVersion>4.0.0.0</AssemblyVersion>
|
<AssemblyVersion>4.0.1.0</AssemblyVersion>
|
||||||
<FileVersion>4.0.0.0</FileVersion>
|
<FileVersion>4.0.1.0</FileVersion>
|
||||||
<VersionPrefix>4.0.0</VersionPrefix>
|
<VersionPrefix>4.0.1</VersionPrefix>
|
||||||
<VersionSuffix>rc4</VersionSuffix>
|
<PackageReleaseNotes>From v4.0: Add XML documention (IDE support)
|
||||||
<PackageReleaseNotes>From rc3: Add In/InArray field comparisons, revamp internal comparison handling. From rc2: preserve additional ORDER BY qualifiers. From rc1: add case-insensitive ordering. From v3.1: Change ByField to ByFields; support dot-access to nested document fields; add Find*Ordered functions/methods; see project site for breaking changes and compatibility</PackageReleaseNotes>
|
From v3.1: See 4.0 release for breaking changes and compatibility</PackageReleaseNotes>
|
||||||
<Authors>danieljsummers</Authors>
|
<Authors>danieljsummers</Authors>
|
||||||
<Company>Bit Badger Solutions</Company>
|
<Company>Bit Badger Solutions</Company>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Use PostgreSQL as a document database</Description>
|
<Description>Use PostgreSQL as a document database</Description>
|
||||||
<PackageTags>JSON Document PostgreSQL Npgsql</PackageTags>
|
<PackageTags>JSON Document PostgreSQL Npgsql</PackageTags>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Library.fs" />
|
<Compile Include="Library.fs" />
|
||||||
|
<Compile Include="WithProps.fs" />
|
||||||
|
<Compile Include="Functions.fs" />
|
||||||
<Compile Include="Extensions.fs" />
|
<Compile Include="Extensions.fs" />
|
||||||
<Compile Include="Compat.fs" />
|
<Compile Include="Compat.fs" />
|
||||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||||
@@ -14,8 +17,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Npgsql.FSharp" Version="5.7.0" />
|
<PackageReference Include="Npgsql" Version="9.0.2" />
|
||||||
<PackageReference Update="FSharp.Core" Version="8.0.300" />
|
<PackageReference Include="Npgsql.FSharp" Version="8.0.0" />
|
||||||
|
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ module WithProps =
|
|||||||
|
|
||||||
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
||||||
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
||||||
let FirstByField<'TDoc when 'TDoc: null>(tableName, field, sqlProps) =
|
let FirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, field, sqlProps) =
|
||||||
WithProps.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
|
WithProps.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
@@ -144,7 +144,7 @@ module Find =
|
|||||||
|
|
||||||
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
||||||
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
||||||
let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
|
let FirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, field) =
|
||||||
Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
|
Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
|
||||||
|
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ type NpgsqlConnectionCSharpCompatExtensions =
|
|||||||
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
|
||||||
[<Extension>]
|
[<Extension>]
|
||||||
[<System.Obsolete "Use FindFirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FindFirstByFields instead ~ will be removed in v4.1">]
|
||||||
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
|
static member inline FindFirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(conn, tableName, field) =
|
||||||
WithProps.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], Sql.existingConnection conn)
|
WithProps.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], 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 (->> =)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
617
src/Postgres/Functions.fs
Normal file
617
src/Postgres/Functions.fs
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
namespace BitBadger.Documents.Postgres
|
||||||
|
|
||||||
|
/// <summary>Commands to execute custom SQL queries</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Custom =
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a list of results</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpList">]
|
||||||
|
let list<'TDoc> query parameters (mapFunc: RowReader -> 'TDoc) =
|
||||||
|
WithProps.Custom.list<'TDoc> query parameters mapFunc (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a list of results</summary>
|
||||||
|
/// <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>
|
||||||
|
let List<'TDoc>(query, parameters, mapFunc: System.Func<RowReader, 'TDoc>) =
|
||||||
|
WithProps.Custom.List<'TDoc>(query, parameters, mapFunc, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first matching result, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpSingle">]
|
||||||
|
let single<'TDoc> query parameters (mapFunc: RowReader -> 'TDoc) =
|
||||||
|
WithProps.Custom.single<'TDoc> query parameters mapFunc (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <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>
|
||||||
|
let Single<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
query, parameters, mapFunc: System.Func<RowReader, 'TDoc>) =
|
||||||
|
WithProps.Custom.Single<'TDoc>(query, parameters, mapFunc, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns no results</summary>
|
||||||
|
/// <param name="query">The query to retrieve the results</param>
|
||||||
|
/// <param name="parameters">Parameters to use for the query</param>
|
||||||
|
[<CompiledName "NonQuery">]
|
||||||
|
let nonQuery query parameters =
|
||||||
|
WithProps.Custom.nonQuery query parameters (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpScalar">]
|
||||||
|
let scalar<'T when 'T: struct> query parameters (mapFunc: RowReader -> 'T) =
|
||||||
|
WithProps.Custom.scalar query parameters mapFunc (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <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>
|
||||||
|
let Scalar<'T when 'T: struct>(query, parameters, mapFunc: System.Func<RowReader, 'T>) =
|
||||||
|
WithProps.Custom.Scalar<'T>(query, parameters, mapFunc, fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Table and index definition commands</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Definition =
|
||||||
|
|
||||||
|
/// <summary>Create a document table</summary>
|
||||||
|
/// <param name="name">The table whose existence should be ensured (may include schema)</param>
|
||||||
|
[<CompiledName "EnsureTable">]
|
||||||
|
let ensureTable name =
|
||||||
|
WithProps.Definition.ensureTable name (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Create an index on documents in the specified table</summary>
|
||||||
|
/// <param name="name">The table to be indexed (may include schema)</param>
|
||||||
|
/// <param name="idxType">The type of document index to create</param>
|
||||||
|
[<CompiledName "EnsureDocumentIndex">]
|
||||||
|
let ensureDocumentIndex name idxType =
|
||||||
|
WithProps.Definition.ensureDocumentIndex name idxType (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Create an index on field(s) within documents in the specified table</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "EnsureFieldIndex">]
|
||||||
|
let ensureFieldIndex tableName indexName fields =
|
||||||
|
WithProps.Definition.ensureFieldIndex tableName indexName fields (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Document writing functions</summary>
|
||||||
|
[<AutoOpen>]
|
||||||
|
module Document =
|
||||||
|
|
||||||
|
/// <summary>Insert a new document</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "Insert">]
|
||||||
|
let insert<'TDoc> tableName (document: 'TDoc) =
|
||||||
|
WithProps.Document.insert<'TDoc> tableName document (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "Save">]
|
||||||
|
let save<'TDoc> tableName (document: 'TDoc) =
|
||||||
|
WithProps.Document.save<'TDoc> tableName document (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Queries to count documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Count =
|
||||||
|
|
||||||
|
/// <summary>Count all documents in a table</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "All">]
|
||||||
|
let all tableName =
|
||||||
|
WithProps.Count.all tableName (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields =
|
||||||
|
WithProps.Count.byFields tableName howMatched fields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName criteria =
|
||||||
|
WithProps.Count.byContains tableName criteria (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath =
|
||||||
|
WithProps.Count.byJsonPath tableName jsonPath (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Queries to determine if documents exist</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Exists =
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists for the given ID</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName docId =
|
||||||
|
WithProps.Exists.byId tableName docId (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields =
|
||||||
|
WithProps.Exists.byFields tableName howMatched fields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName criteria =
|
||||||
|
WithProps.Exists.byContains tableName criteria (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath =
|
||||||
|
WithProps.Exists.byJsonPath tableName jsonPath (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Commands to retrieve documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Find =
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
|
||||||
|
/// <returns>All documents from the given table</returns>
|
||||||
|
[<CompiledName "FSharpAll">]
|
||||||
|
let all<'TDoc> tableName =
|
||||||
|
WithProps.Find.all<'TDoc> tableName (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
|
||||||
|
/// <returns>All documents from the given table</returns>
|
||||||
|
let All<'TDoc> tableName =
|
||||||
|
WithProps.Find.All<'TDoc>(tableName, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table ordered by the given fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpAllOrdered">]
|
||||||
|
let allOrdered<'TDoc> tableName orderFields =
|
||||||
|
WithProps.Find.allOrdered<'TDoc> tableName orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table ordered by the given fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
let AllOrdered<'TDoc> tableName orderFields =
|
||||||
|
WithProps.Find.AllOrdered<'TDoc>(tableName, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <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><tt>Some</tt> with the document if found, <tt>None</tt> otherwise</returns>
|
||||||
|
[<CompiledName "FSharpById">]
|
||||||
|
let byId<'TKey, 'TDoc> tableName docId =
|
||||||
|
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
let ById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, docId: 'TKey) =
|
||||||
|
WithProps.Find.ById<'TKey, 'TDoc>(tableName, docId, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByFields">]
|
||||||
|
let byFields<'TDoc> tableName howMatched fields =
|
||||||
|
WithProps.Find.byFields<'TDoc> tableName howMatched fields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
let ByFields<'TDoc>(tableName, howMatched, fields) =
|
||||||
|
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByFieldsOrdered">]
|
||||||
|
let byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
||||||
|
WithProps.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields) =
|
||||||
|
WithProps.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByContains">]
|
||||||
|
let byContains<'TDoc> tableName (criteria: obj) =
|
||||||
|
WithProps.Find.byContains<'TDoc> tableName criteria (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
let ByContains<'TDoc>(tableName, criteria: obj) =
|
||||||
|
WithProps.Find.ByContains<'TDoc>(tableName, criteria, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON containment query (<tt>@></tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByContainsOrdered">]
|
||||||
|
let byContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
|
||||||
|
WithProps.Find.byContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON containment query (<tt>@></tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let ByContainsOrdered<'TDoc>(tableName, criteria: obj, orderFields) =
|
||||||
|
WithProps.Find.ByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByJsonPath">]
|
||||||
|
let byJsonPath<'TDoc> tableName jsonPath =
|
||||||
|
WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
let ByJsonPath<'TDoc>(tableName, jsonPath) =
|
||||||
|
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpByJsonPathOrdered">]
|
||||||
|
let byJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
|
||||||
|
WithProps.Find.byJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields) =
|
||||||
|
WithProps.Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByFields">]
|
||||||
|
let firstByFields<'TDoc> tableName howMatched fields =
|
||||||
|
WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, howMatched, fields) =
|
||||||
|
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given
|
||||||
|
/// fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByFieldsOrdered">]
|
||||||
|
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
||||||
|
WithProps.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given
|
||||||
|
/// fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByFieldsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
tableName, howMatched, queryFields, orderFields) =
|
||||||
|
WithProps.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByContains">]
|
||||||
|
let firstByContains<'TDoc> tableName (criteria: obj) =
|
||||||
|
WithProps.Find.firstByContains<'TDoc> tableName criteria (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByContains<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, criteria: obj) =
|
||||||
|
WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON containment query (<tt>@></tt>) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByContainsOrdered">]
|
||||||
|
let firstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
|
||||||
|
WithProps.Find.firstByContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON containment query (<tt>@></tt>) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByContainsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, criteria: obj, orderFields) =
|
||||||
|
WithProps.Find.FirstByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByJsonPath">]
|
||||||
|
let firstByJsonPath<'TDoc> tableName jsonPath =
|
||||||
|
WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByJsonPath<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, jsonPath) =
|
||||||
|
WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByJsonPathOrdered">]
|
||||||
|
let firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
|
||||||
|
WithProps.Find.firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let FirstByJsonPathOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, jsonPath, orderFields) =
|
||||||
|
WithProps.Find.FirstByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Commands to update documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Update =
|
||||||
|
|
||||||
|
/// <summary>Update (replace) an entire document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) (document: 'TDoc) =
|
||||||
|
WithProps.Update.byId tableName docId document (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "FSharpFullFunc">]
|
||||||
|
let byFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) =
|
||||||
|
WithProps.Update.byFunc tableName idFunc document (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
let ByFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
|
||||||
|
WithProps.Update.ByFunc(tableName, idFunc, document, fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Commands to patch (partially update) documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Patch =
|
||||||
|
|
||||||
|
/// <summary>Patch a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) (patch: 'TPatch) =
|
||||||
|
WithProps.Patch.byId tableName docId patch (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Patch documents using a JSON field comparison query in the <tt>WHERE</tt> clause (<tt>->> =</tt>, etc.)
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields (patch: 'TPatch) =
|
||||||
|
WithProps.Patch.byFields tableName howMatched fields patch (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Patch documents using a JSON containment query in the <tt>WHERE</tt> clause (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
|
||||||
|
WithProps.Patch.byContains tableName criteria patch (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Patch documents using a JSON Path match query in the <tt>WHERE</tt> clause (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath (patch: 'TPatch) =
|
||||||
|
WithProps.Patch.byJsonPath tableName jsonPath patch (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Commands to remove fields from documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module RemoveFields =
|
||||||
|
|
||||||
|
/// <summary>Remove fields from a document by the document's ID</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) fieldNames =
|
||||||
|
WithProps.RemoveFields.byId tableName docId fieldNames (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a comparison on JSON fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields fieldNames =
|
||||||
|
WithProps.RemoveFields.byFields tableName howMatched fields fieldNames (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) fieldNames =
|
||||||
|
WithProps.RemoveFields.byContains tableName criteria fieldNames (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath fieldNames =
|
||||||
|
WithProps.RemoveFields.byJsonPath tableName jsonPath fieldNames (fromDataSource ())
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Commands to delete documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Delete =
|
||||||
|
|
||||||
|
/// <summary>Delete a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) =
|
||||||
|
WithProps.Delete.byId tableName docId (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON field comparison query (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields =
|
||||||
|
WithProps.Delete.byFields tableName howMatched fields (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON contains query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) =
|
||||||
|
WithProps.Delete.byContains tableName criteria (fromDataSource ())
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON Path match query (@?)</summary>
|
||||||
|
/// <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>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath =
|
||||||
|
WithProps.Delete.byJsonPath tableName jsonPath (fromDataSource ())
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -5,11 +5,16 @@ This package provides a lightweight document library backed by [PostgreSQL](http
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
||||||
|
- Automatically generate IDs for documents (numeric IDs, GUIDs, or random strings)
|
||||||
- Address documents via ID, via comparison on any field, via equality on any property (using JSON containment, on a likely indexed field), or via condition on any property (using JSON Path queries)
|
- Address documents via ID, via comparison on any field, via equality on any property (using JSON containment, on a likely indexed field), or via condition on any property (using JSON Path queries)
|
||||||
- Access documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
- Access documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
||||||
- Use `Task`-based async for all data access functions
|
- Use `Task`-based async for all data access functions
|
||||||
- Use building blocks for more complex queries
|
- Use building blocks for more complex queries
|
||||||
|
|
||||||
|
## Upgrading from v3
|
||||||
|
|
||||||
|
There is a breaking API change for `ByField` (C#) / `byField` (F#), along with a compatibility namespace that can mitigate the impact of these changes. See [the migration guide](https://bitbadger.solutions/open-source/relational-documents/upgrade-from-v3-to-v4.html) for full details.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Once the package is installed, the library needs a data source. Construct an `NpgsqlDataSource` instance, and provide it to the library:
|
Once the package is installed, the library needs a data source. Construct an `NpgsqlDataSource` instance, and provide it to the library:
|
||||||
|
|||||||
840
src/Postgres/WithProps.fs
Normal file
840
src/Postgres/WithProps.fs
Normal file
@@ -0,0 +1,840 @@
|
|||||||
|
/// <summary>Versions of queries that accept <tt>SqlProps</tt> as the last parameter</summary>
|
||||||
|
module BitBadger.Documents.Postgres.WithProps
|
||||||
|
|
||||||
|
open BitBadger.Documents
|
||||||
|
open Npgsql.FSharp
|
||||||
|
|
||||||
|
/// <summary>Commands to execute custom SQL queries</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Custom =
|
||||||
|
|
||||||
|
module FSharpList = Microsoft.FSharp.Collections.List
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a list of results</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>A list of results for the given query</returns>
|
||||||
|
[<CompiledName "FSharpList">]
|
||||||
|
let list<'TDoc> query parameters (mapFunc: RowReader -> 'TDoc) sqlProps =
|
||||||
|
Sql.query query sqlProps
|
||||||
|
|> Sql.parameters (FSharpList.ofSeq parameters)
|
||||||
|
|> Sql.executeAsync mapFunc
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a list of results</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>A list of results for the given query</returns>
|
||||||
|
let List<'TDoc>(query, parameters, mapFunc: System.Func<RowReader, 'TDoc>, sqlProps) = backgroundTask {
|
||||||
|
let! results = list<'TDoc> query parameters mapFunc.Invoke sqlProps
|
||||||
|
return ResizeArray results
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns><tt>Some</tt> with the first matching result, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpSingle">]
|
||||||
|
let single<'TDoc> query parameters mapFunc sqlProps = backgroundTask {
|
||||||
|
let! results = list<'TDoc> query parameters mapFunc sqlProps
|
||||||
|
return FSharpList.tryHead results
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first matching result, or <tt>null</tt> if not found</returns>
|
||||||
|
let Single<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
query, parameters, mapFunc: System.Func<RowReader, 'TDoc>, sqlProps) = backgroundTask {
|
||||||
|
let! result = single<'TDoc> query parameters mapFunc.Invoke sqlProps
|
||||||
|
return Option.toObj result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns no results</summary>
|
||||||
|
/// <param name="query">The query to retrieve the results</param>
|
||||||
|
/// <param name="parameters">Parameters to use for the query</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "NonQuery">]
|
||||||
|
let nonQuery query parameters sqlProps =
|
||||||
|
Sql.query query sqlProps
|
||||||
|
|> Sql.parameters (FSharpList.ofSeq parameters)
|
||||||
|
|> Sql.executeNonQueryAsync
|
||||||
|
|> ignoreTask
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The scalar value for the query</returns>
|
||||||
|
[<CompiledName "FSharpScalar">]
|
||||||
|
let scalar<'T when 'T: struct> query parameters (mapFunc: RowReader -> 'T) sqlProps =
|
||||||
|
Sql.query query sqlProps
|
||||||
|
|> Sql.parameters (FSharpList.ofSeq parameters)
|
||||||
|
|> Sql.executeRowAsync mapFunc
|
||||||
|
|
||||||
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The scalar value for the query</returns>
|
||||||
|
let Scalar<'T when 'T: struct>(query, parameters, mapFunc: System.Func<RowReader, 'T>, sqlProps) =
|
||||||
|
scalar<'T> query parameters mapFunc.Invoke sqlProps
|
||||||
|
|
||||||
|
/// <summary>Table and index definition commands</summary>
|
||||||
|
module Definition =
|
||||||
|
|
||||||
|
/// <summary>Create a document table</summary>
|
||||||
|
/// <param name="name">The table whose existence should be ensured (may include schema)</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "EnsureTable">]
|
||||||
|
let ensureTable name sqlProps = backgroundTask {
|
||||||
|
do! Custom.nonQuery (Query.Definition.ensureTable name) [] sqlProps
|
||||||
|
do! Custom.nonQuery (Query.Definition.ensureKey name PostgreSQL) [] sqlProps
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Create an index on documents in the specified table</summary>
|
||||||
|
/// <param name="name">The table to be indexed (may include schema)</param>
|
||||||
|
/// <param name="idxType">The type of document index to create</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "EnsureDocumentIndex">]
|
||||||
|
let ensureDocumentIndex name idxType sqlProps =
|
||||||
|
Custom.nonQuery (Query.Definition.ensureDocumentIndex name idxType) [] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Create an index on field(s) within documents in the specified table</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "EnsureFieldIndex">]
|
||||||
|
let ensureFieldIndex tableName indexName fields sqlProps =
|
||||||
|
Custom.nonQuery (Query.Definition.ensureIndexOn tableName indexName fields PostgreSQL) [] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to add documents</summary>
|
||||||
|
[<AutoOpen>]
|
||||||
|
module Document =
|
||||||
|
|
||||||
|
/// <summary>Insert a new document</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "Insert">]
|
||||||
|
let insert<'TDoc> tableName (document: 'TDoc) sqlProps =
|
||||||
|
let query =
|
||||||
|
match Configuration.autoIdStrategy () with
|
||||||
|
| Disabled -> Query.insert tableName
|
||||||
|
| strategy ->
|
||||||
|
let idField = Configuration.idField ()
|
||||||
|
let dataParam =
|
||||||
|
if AutoId.NeedsAutoId strategy document idField then
|
||||||
|
match strategy with
|
||||||
|
| Number ->
|
||||||
|
$"' || (SELECT COALESCE(MAX((data->>'{idField}')::numeric), 0) + 1 FROM {tableName}) || '"
|
||||||
|
| Guid -> $"\"{AutoId.GenerateGuid()}\""
|
||||||
|
| RandomString -> $"\"{AutoId.GenerateRandomString(Configuration.idStringLength ())}\""
|
||||||
|
| Disabled -> "@data"
|
||||||
|
|> function it -> $"""@data::jsonb || ('{{"{idField}":{it}}}')::jsonb"""
|
||||||
|
else "@data"
|
||||||
|
(Query.insert tableName).Replace("@data", dataParam)
|
||||||
|
Custom.nonQuery query [ jsonParam "@data" document ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "Save">]
|
||||||
|
let save<'TDoc> tableName (document: 'TDoc) sqlProps =
|
||||||
|
Custom.nonQuery (Query.save tableName) [ jsonParam "@data" document ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to count documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Count =
|
||||||
|
|
||||||
|
/// <summary>Count all documents in a table</summary>
|
||||||
|
/// <param name="tableName">The table in which documents should be counted (may include schema)</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The count of the documents in the table</returns>
|
||||||
|
[<CompiledName "All">]
|
||||||
|
let all tableName sqlProps =
|
||||||
|
Custom.scalar (Query.count tableName) [] toCount sqlProps
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The count of matching documents in the table</returns>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.byFields (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount sqlProps
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The count of the documents in the table</returns>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.byContains (Query.count tableName)) [ jsonParam "@criteria" criteria ] toCount sqlProps
|
||||||
|
|
||||||
|
/// <summary>Count matching documents using a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The count of the documents in the table</returns>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.byPathMatch (Query.count tableName)) [ "@path", Sql.string jsonPath ] toCount sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to determine if documents exist</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Exists =
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists for the given ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>True if a document exists, false if not</returns>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) sqlProps =
|
||||||
|
Custom.scalar (Query.exists tableName (Query.whereById docId)) [ idParam docId ] toExists sqlProps
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>True if any matching documents exist, false if not</returns>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.exists tableName (Query.whereByFields howMatched fields))
|
||||||
|
(addFieldParams fields [])
|
||||||
|
toExists
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>True if any matching documents exist, false if not</returns>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.exists tableName (Query.whereDataContains "@criteria"))
|
||||||
|
[ jsonParam "@criteria" criteria ]
|
||||||
|
toExists
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Determine if a document exists using a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>True if any matching documents exist, false if not</returns>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath sqlProps =
|
||||||
|
Custom.scalar
|
||||||
|
(Query.exists tableName (Query.whereJsonPathMatches "@path"))
|
||||||
|
[ "@path", Sql.string jsonPath ]
|
||||||
|
toExists
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to retrieve documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Find =
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents from the given table</returns>
|
||||||
|
[<CompiledName "FSharpAll">]
|
||||||
|
let all<'TDoc> tableName sqlProps =
|
||||||
|
Custom.list<'TDoc> (Query.find tableName) [] fromData<'TDoc> sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents from the given table</returns>
|
||||||
|
let All<'TDoc>(tableName, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(Query.find tableName, [], fromData<'TDoc>, sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table ordered by the given fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents from the given table, ordered by the given fields</returns>
|
||||||
|
[<CompiledName "FSharpAllOrdered">]
|
||||||
|
let allOrdered<'TDoc> tableName orderFields sqlProps =
|
||||||
|
Custom.list<'TDoc> (Query.find tableName + Query.orderBy orderFields PostgreSQL) [] fromData<'TDoc> sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve all documents in the given table ordered by the given fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents from the given table, ordered by the given fields</returns>
|
||||||
|
let AllOrdered<'TDoc>(tableName, orderFields, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.find tableName + Query.orderBy orderFields PostgreSQL, [], fromData<'TDoc>, sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns><tt>Some</tt> with the document if found, <tt>None</tt> otherwise</returns>
|
||||||
|
[<CompiledName "FSharpById">]
|
||||||
|
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) sqlProps =
|
||||||
|
Custom.single (Query.byId (Query.find tableName) docId) [ idParam docId ] fromData<'TDoc> sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The document if found, <tt>null</tt> otherwise</returns>
|
||||||
|
let ById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, docId: 'TKey, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
Query.byId (Query.find tableName) docId, [ idParam docId ], fromData<'TDoc>, sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given fields</returns>
|
||||||
|
[<CompiledName "FSharpByFields">]
|
||||||
|
let byFields<'TDoc> tableName howMatched fields sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byFields (Query.find tableName) howMatched fields)
|
||||||
|
(addFieldParams fields [])
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given fields</returns>
|
||||||
|
let ByFields<'TDoc>(tableName, howMatched, fields, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byFields (Query.find tableName) howMatched fields,
|
||||||
|
addFieldParams fields [],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given fields, ordered by the other given fields</returns>
|
||||||
|
[<CompiledName "FSharpByFieldsOrdered">]
|
||||||
|
let byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields PostgreSQL)
|
||||||
|
(addFieldParams queryFields [])
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given fields, ordered by the other given fields</returns>
|
||||||
|
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields PostgreSQL,
|
||||||
|
addFieldParams queryFields [],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given containment query</returns>
|
||||||
|
[<CompiledName "FSharpByContains">]
|
||||||
|
let byContains<'TDoc> tableName (criteria: obj) sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byContains (Query.find tableName)) [ jsonParam "@criteria" criteria ] fromData<'TDoc> sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given containment query</returns>
|
||||||
|
let ByContains<'TDoc>(tableName, criteria: obj, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byContains (Query.find tableName),
|
||||||
|
[ jsonParam "@criteria" criteria ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON containment query (<tt>@></tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given containment query, ordered by the given fields</returns>
|
||||||
|
[<CompiledName "FSharpByContainsOrdered">]
|
||||||
|
let byContainsOrdered<'TDoc> tableName (criteria: obj) orderFields sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byContains (Query.find tableName) + Query.orderBy orderFields PostgreSQL)
|
||||||
|
[ jsonParam "@criteria" criteria ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON containment query (<tt>@></tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given containment query, ordered by the given fields</returns>
|
||||||
|
let ByContainsOrdered<'TDoc>(tableName, criteria: obj, orderFields, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byContains (Query.find tableName) + Query.orderBy orderFields PostgreSQL,
|
||||||
|
[ jsonParam "@criteria" criteria ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given JSON Path expression</returns>
|
||||||
|
[<CompiledName "FSharpByJsonPath">]
|
||||||
|
let byJsonPath<'TDoc> tableName jsonPath sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byPathMatch (Query.find tableName)) [ "@path", Sql.string jsonPath ] fromData<'TDoc> sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve documents matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given JSON Path expression</returns>
|
||||||
|
let ByJsonPath<'TDoc>(tableName, jsonPath, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byPathMatch (Query.find tableName),
|
||||||
|
[ "@path", Sql.string jsonPath ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given JSON Path expression, ordered by the given fields</returns>
|
||||||
|
[<CompiledName "FSharpByJsonPathOrdered">]
|
||||||
|
let byJsonPathOrdered<'TDoc> tableName jsonPath orderFields sqlProps =
|
||||||
|
Custom.list<'TDoc>
|
||||||
|
(Query.byPathMatch (Query.find tableName) + Query.orderBy orderFields PostgreSQL)
|
||||||
|
[ "@path", Sql.string jsonPath ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve documents matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>All documents matching the given JSON Path expression, ordered by the given fields</returns>
|
||||||
|
let ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, sqlProps) =
|
||||||
|
Custom.List<'TDoc>(
|
||||||
|
Query.byPathMatch (Query.find tableName) + Query.orderBy orderFields PostgreSQL,
|
||||||
|
[ "@path", Sql.string jsonPath ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByFields">]
|
||||||
|
let firstByFields<'TDoc> tableName howMatched fields sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1"
|
||||||
|
(addFieldParams fields [])
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, howMatched, fields, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1",
|
||||||
|
addFieldParams fields [],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given
|
||||||
|
/// fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByFieldsOrdered">]
|
||||||
|
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byFields (Query.find tableName) howMatched queryFields}{Query.orderBy orderFields PostgreSQL} LIMIT 1"
|
||||||
|
(addFieldParams queryFields [])
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given
|
||||||
|
/// fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByFieldsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
tableName, howMatched, queryFields, orderFields, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byFields (Query.find tableName) howMatched queryFields}{Query.orderBy orderFields PostgreSQL} LIMIT 1",
|
||||||
|
addFieldParams queryFields [],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByContains">]
|
||||||
|
let firstByContains<'TDoc> tableName (criteria: obj) sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byContains (Query.find tableName)} LIMIT 1"
|
||||||
|
[ jsonParam "@criteria" criteria ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByContains<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, criteria: obj, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byContains (Query.find tableName)} LIMIT 1",
|
||||||
|
[ jsonParam "@criteria" criteria ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON containment query (<tt>@></tt>) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByContainsOrdered">]
|
||||||
|
let firstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byContains (Query.find tableName)}{Query.orderBy orderFields PostgreSQL} LIMIT 1"
|
||||||
|
[ jsonParam "@criteria" criteria ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON containment query (<tt>@></tt>) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByContainsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
tableName, criteria: obj, orderFields, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byContains (Query.find tableName)}{Query.orderBy orderFields PostgreSQL} LIMIT 1",
|
||||||
|
[ jsonParam "@criteria" criteria ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
|
[<CompiledName "FSharpFirstByJsonPath">]
|
||||||
|
let firstByJsonPath<'TDoc> tableName jsonPath sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byPathMatch (Query.find tableName)} LIMIT 1"
|
||||||
|
[ "@path", Sql.string jsonPath ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Retrieve the first document matching a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByJsonPath<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, jsonPath, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byPathMatch (Query.find tableName)} LIMIT 1",
|
||||||
|
[ "@path", Sql.string jsonPath ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
|
[<CompiledName "FSharpFirstByJsonPathOrdered">]
|
||||||
|
let firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields sqlProps =
|
||||||
|
Custom.single<'TDoc>
|
||||||
|
$"{Query.byPathMatch (Query.find tableName)}{Query.orderBy orderFields PostgreSQL} LIMIT 1"
|
||||||
|
[ "@path", Sql.string jsonPath ]
|
||||||
|
fromData<'TDoc>
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve the first document matching a JSON Path match query (<tt>@?</tt>) ordered by the given fields in the
|
||||||
|
/// document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
/// <returns>The first document ordered by the given fields, or <tt>null</tt> if not found</returns>
|
||||||
|
let FirstByJsonPathOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
tableName, jsonPath, orderFields, sqlProps) =
|
||||||
|
Custom.Single<'TDoc>(
|
||||||
|
$"{Query.byPathMatch (Query.find tableName)}{Query.orderBy orderFields PostgreSQL} LIMIT 1",
|
||||||
|
[ "@path", Sql.string jsonPath ],
|
||||||
|
fromData<'TDoc>,
|
||||||
|
sqlProps)
|
||||||
|
|
||||||
|
/// <summary>Commands to update documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Update =
|
||||||
|
|
||||||
|
/// <summary>Update (replace) an entire document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) (document: 'TDoc) sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byId (Query.update tableName) docId) [ idParam docId; jsonParam "@data" document ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "FSharpByFunc">]
|
||||||
|
let byFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) sqlProps =
|
||||||
|
byId tableName (idFunc document) document sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update (replace) an entire document by its ID, using the provided function to obtain the ID from the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
let ByFunc(tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc, sqlProps) =
|
||||||
|
byFunc tableName idFunc.Invoke document sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to patch (partially update) documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Patch =
|
||||||
|
|
||||||
|
/// <summary>Patch a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) (patch: 'TPatch) sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byId (Query.patch tableName) docId) [ idParam docId; jsonParam "@data" patch ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Patch documents using a JSON field comparison query in the <tt>WHERE</tt> clause (<tt>->> =</tt>, etc.)
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields (patch: 'TPatch) sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byFields (Query.patch tableName) howMatched fields)
|
||||||
|
(addFieldParams fields [ jsonParam "@data" patch ])
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Patch documents using a JSON containment query in the <tt>WHERE</tt> clause (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byContains (Query.patch tableName))
|
||||||
|
[ jsonParam "@data" patch; jsonParam "@criteria" criteria ]
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Patch documents using a JSON Path match query in the <tt>WHERE</tt> clause (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath (patch: 'TPatch) sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byPathMatch (Query.patch tableName))
|
||||||
|
[ jsonParam "@data" patch; "@path", Sql.string jsonPath ]
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to remove fields from documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module RemoveFields =
|
||||||
|
|
||||||
|
/// <summary>Remove fields from a document by the document's ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) fieldNames sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byId (Query.removeFields tableName) docId) [ idParam docId; fieldNameParams fieldNames ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a comparison on JSON fields in the document</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields fieldNames sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byFields (Query.removeFields tableName) howMatched fields)
|
||||||
|
(addFieldParams fields [ fieldNameParams fieldNames ])
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a JSON containment query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TContains) fieldNames sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byContains (Query.removeFields tableName))
|
||||||
|
[ jsonParam "@criteria" criteria; fieldNameParams fieldNames ]
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Remove fields from documents via a JSON Path match query (<tt>@?</tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "FSharpByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath fieldNames sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byPathMatch (Query.removeFields tableName))
|
||||||
|
[ "@path", Sql.string jsonPath; fieldNameParams fieldNames ]
|
||||||
|
sqlProps
|
||||||
|
|
||||||
|
/// <summary>Commands to delete documents</summary>
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Delete =
|
||||||
|
|
||||||
|
/// <summary>Delete a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ById">]
|
||||||
|
let byId tableName (docId: 'TKey) sqlProps =
|
||||||
|
Custom.nonQuery (Query.byId (Query.delete tableName) docId) [ idParam docId ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON field comparison query (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByFields">]
|
||||||
|
let byFields tableName howMatched fields sqlProps =
|
||||||
|
Custom.nonQuery
|
||||||
|
(Query.byFields (Query.delete tableName) howMatched fields) (addFieldParams fields []) sqlProps
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON contains query (<tt>@></tt>)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByContains">]
|
||||||
|
let byContains tableName (criteria: 'TCriteria) sqlProps =
|
||||||
|
Custom.nonQuery (Query.byContains (Query.delete tableName)) [ jsonParam "@criteria" criteria ] sqlProps
|
||||||
|
|
||||||
|
/// <summary>Delete documents by matching a JSON Path match query (@?)</summary>
|
||||||
|
/// <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>
|
||||||
|
/// <param name="sqlProps">The <tt>SqlProps</tt> to use to execute the query</param>
|
||||||
|
[<CompiledName "ByJsonPath">]
|
||||||
|
let byJsonPath tableName jsonPath sqlProps =
|
||||||
|
Custom.nonQuery (Query.byPathMatch (Query.delete tableName)) [ "@path", Sql.string jsonPath ] sqlProps
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Use SQLite as a document database</Description>
|
<Description>Use SQLite as a document database</Description>
|
||||||
<PackageTags>JSON Document SQLite</PackageTags>
|
<PackageTags>JSON Document SQLite</PackageTags>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.6" />
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.0" />
|
||||||
<PackageReference Update="FSharp.Core" Version="8.0.300" />
|
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ module WithConn =
|
|||||||
|
|
||||||
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
||||||
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
||||||
let FirstByField<'TDoc when 'TDoc: null>(tableName, field, conn) =
|
let FirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, field, conn) =
|
||||||
WithConn.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, conn)
|
WithConn.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, conn)
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
@@ -144,7 +144,7 @@ module Find =
|
|||||||
|
|
||||||
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
|
||||||
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FirstByFields instead ~ will be removed in v4.1">]
|
||||||
let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
|
let FirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(tableName, field) =
|
||||||
Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
|
Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
|
||||||
|
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ type SqliteConnectionCSharpCompatExtensions =
|
|||||||
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
|
/// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
|
||||||
[<Extension>]
|
[<Extension>]
|
||||||
[<System.Obsolete "Use FindFirstByFields instead ~ will be removed in v4.1">]
|
[<System.Obsolete "Use FindFirstByFields instead ~ will be removed in v4.1">]
|
||||||
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
|
static member inline FindFirstByField<'TDoc when 'TDoc: null and 'TDoc: not struct>(conn, tableName, field) =
|
||||||
WithConn.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], conn)
|
WithConn.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], 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 (->> =)
|
||||||
|
|||||||
@@ -1,270 +1,488 @@
|
|||||||
namespace BitBadger.Documents.Sqlite
|
namespace BitBadger.Documents.Sqlite
|
||||||
|
|
||||||
open BitBadger.Documents
|
|
||||||
open Microsoft.Data.Sqlite
|
open Microsoft.Data.Sqlite
|
||||||
|
|
||||||
/// F# extensions for the SqliteConnection type
|
/// <summary>F# extensions for the SqliteConnection type</summary>
|
||||||
[<AutoOpen>]
|
[<AutoOpen>]
|
||||||
module Extensions =
|
module Extensions =
|
||||||
|
|
||||||
type SqliteConnection with
|
type SqliteConnection with
|
||||||
|
|
||||||
/// Execute a query that returns a list of results
|
/// <summary>Execute a query that returns a list of results</summary>
|
||||||
|
/// <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>
|
||||||
member conn.customList<'TDoc> query parameters mapFunc =
|
member conn.customList<'TDoc> query parameters mapFunc =
|
||||||
WithConn.Custom.list<'TDoc> query parameters mapFunc conn
|
WithConn.Custom.list<'TDoc> query parameters mapFunc conn
|
||||||
|
|
||||||
/// Execute a query that returns one or no results
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first matching result, or <tt>None</tt> if not found</returns>
|
||||||
member conn.customSingle<'TDoc> query parameters mapFunc =
|
member conn.customSingle<'TDoc> query parameters mapFunc =
|
||||||
WithConn.Custom.single<'TDoc> query parameters mapFunc conn
|
WithConn.Custom.single<'TDoc> query parameters mapFunc conn
|
||||||
|
|
||||||
/// Execute a query that does not return a value
|
/// <summary>Execute a query that returns no results</summary>
|
||||||
|
/// <param name="query">The query to retrieve the results</param>
|
||||||
|
/// <param name="parameters">Parameters to use for the query</param>
|
||||||
member conn.customNonQuery query parameters =
|
member conn.customNonQuery query parameters =
|
||||||
WithConn.Custom.nonQuery query parameters conn
|
WithConn.Custom.nonQuery query parameters conn
|
||||||
|
|
||||||
/// Execute a query that returns a scalar value
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <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>
|
||||||
member conn.customScalar<'T when 'T: struct> query parameters mapFunc =
|
member conn.customScalar<'T when 'T: struct> query parameters mapFunc =
|
||||||
WithConn.Custom.scalar<'T> query parameters mapFunc conn
|
WithConn.Custom.scalar<'T> query parameters mapFunc conn
|
||||||
|
|
||||||
/// Create a document table
|
/// <summary>Create a document table</summary>
|
||||||
|
/// <param name="name">The table whose existence should be ensured (may include schema)</param>
|
||||||
member conn.ensureTable name =
|
member conn.ensureTable name =
|
||||||
WithConn.Definition.ensureTable name conn
|
WithConn.Definition.ensureTable name conn
|
||||||
|
|
||||||
/// Create an index on a document table
|
/// <summary>Create an index on field(s) within documents in the specified table</summary>
|
||||||
|
/// <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>
|
||||||
member conn.ensureFieldIndex tableName indexName fields =
|
member conn.ensureFieldIndex tableName indexName fields =
|
||||||
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
||||||
|
|
||||||
/// Insert a new document
|
/// <summary>Insert a new document</summary>
|
||||||
|
/// <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>
|
||||||
member conn.insert<'TDoc> tableName (document: 'TDoc) =
|
member conn.insert<'TDoc> tableName (document: 'TDoc) =
|
||||||
WithConn.Document.insert<'TDoc> tableName document conn
|
WithConn.Document.insert<'TDoc> tableName document conn
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// 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")
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
member conn.save<'TDoc> tableName (document: 'TDoc) =
|
member conn.save<'TDoc> tableName (document: 'TDoc) =
|
||||||
WithConn.Document.save tableName document conn
|
WithConn.Document.save tableName document conn
|
||||||
|
|
||||||
/// Count all documents in a table
|
/// <summary>Count all documents in a table</summary>
|
||||||
|
/// <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>
|
||||||
member conn.countAll tableName =
|
member conn.countAll tableName =
|
||||||
WithConn.Count.all tableName conn
|
WithConn.Count.all tableName conn
|
||||||
|
|
||||||
/// Count matching documents using a comparison on JSON fields
|
/// <summary>Count matching documents using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
member conn.countByFields tableName howMatched fields =
|
member conn.countByFields tableName howMatched fields =
|
||||||
WithConn.Count.byFields tableName howMatched fields conn
|
WithConn.Count.byFields tableName howMatched fields conn
|
||||||
|
|
||||||
/// Determine if a document exists for the given ID
|
/// <summary>Determine if a document exists for the given ID</summary>
|
||||||
|
/// <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>
|
||||||
member conn.existsById tableName (docId: 'TKey) =
|
member conn.existsById tableName (docId: 'TKey) =
|
||||||
WithConn.Exists.byId tableName docId conn
|
WithConn.Exists.byId tableName docId conn
|
||||||
|
|
||||||
/// Determine if a document exists using a comparison on JSON fields
|
/// <summary>Determine if a document exists using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
member conn.existsByFields tableName howMatched fields =
|
member conn.existsByFields tableName howMatched fields =
|
||||||
WithConn.Exists.byFields tableName howMatched fields conn
|
WithConn.Exists.byFields tableName howMatched fields conn
|
||||||
|
|
||||||
/// Retrieve all documents in the given table
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="tableName">The table from which documents should be retrieved (may include schema)</param>
|
||||||
|
/// <returns>All documents from the given table</returns>
|
||||||
member conn.findAll<'TDoc> tableName =
|
member conn.findAll<'TDoc> tableName =
|
||||||
WithConn.Find.all<'TDoc> tableName conn
|
WithConn.Find.all<'TDoc> tableName 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="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>
|
||||||
member conn.findAllOrdered<'TDoc> tableName orderFields =
|
member conn.findAllOrdered<'TDoc> tableName orderFields =
|
||||||
WithConn.Find.allOrdered<'TDoc> tableName orderFields conn
|
WithConn.Find.allOrdered<'TDoc> tableName orderFields conn
|
||||||
|
|
||||||
/// Retrieve a document by its ID
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <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><tt>Some</tt> with the document if found, <tt>None</tt> otherwise</returns>
|
||||||
member conn.findById<'TKey, 'TDoc> tableName (docId: 'TKey) =
|
member conn.findById<'TKey, 'TDoc> tableName (docId: 'TKey) =
|
||||||
WithConn.Find.byId<'TKey, 'TDoc> tableName docId conn
|
WithConn.Find.byId<'TKey, 'TDoc> tableName docId conn
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
member conn.findByFields<'TDoc> tableName howMatched fields =
|
member conn.findByFields<'TDoc> tableName howMatched fields =
|
||||||
WithConn.Find.byFields<'TDoc> tableName howMatched fields conn
|
WithConn.Find.byFields<'TDoc> tableName howMatched fields conn
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields
|
||||||
|
/// in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
member conn.findByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
member conn.findByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
||||||
WithConn.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
|
WithConn.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields, returning only the first result
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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><tt>Some</tt> with the first document, or <tt>None</tt> if not found</returns>
|
||||||
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
|
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
|
||||||
WithConn.Find.firstByFields<'TDoc> tableName howMatched fields conn
|
WithConn.Find.firstByFields<'TDoc> tableName howMatched fields conn
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document, returning
|
/// <summary>
|
||||||
/// only the first result
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the
|
||||||
|
/// given fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
/// <tt>Some</tt> with the first document ordered by the given fields, or <tt>None</tt> if not found
|
||||||
|
/// </returns>
|
||||||
member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
|
||||||
WithConn.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
|
WithConn.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
|
||||||
|
|
||||||
/// Update an entire document by its ID
|
/// <summary>Update (replace) an entire document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
|
member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
|
||||||
WithConn.Update.byId tableName docId document conn
|
WithConn.Update.byId tableName docId document 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="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>
|
||||||
member conn.updateByFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) =
|
member conn.updateByFunc tableName (idFunc: 'TDoc -> 'TKey) (document: 'TDoc) =
|
||||||
WithConn.Update.byFunc tableName idFunc document conn
|
WithConn.Update.byFunc tableName idFunc document conn
|
||||||
|
|
||||||
/// Patch a document by its ID
|
/// <summary>Patch a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
member conn.patchById tableName (docId: 'TKey) (patch: 'TPatch) =
|
member conn.patchById tableName (docId: 'TKey) (patch: 'TPatch) =
|
||||||
WithConn.Patch.byId tableName docId patch conn
|
WithConn.Patch.byId tableName docId patch conn
|
||||||
|
|
||||||
/// Patch documents using a comparison on JSON fields
|
/// <summary>
|
||||||
|
/// Patch documents using a JSON field comparison query in the <tt>WHERE</tt> clause (<tt>->> =</tt>,
|
||||||
|
/// etc.)
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
member conn.patchByFields tableName howMatched fields (patch: 'TPatch) =
|
member conn.patchByFields tableName howMatched fields (patch: 'TPatch) =
|
||||||
WithConn.Patch.byFields tableName howMatched fields patch conn
|
WithConn.Patch.byFields tableName howMatched fields patch 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="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>
|
||||||
member conn.removeFieldsById tableName (docId: 'TKey) fieldNames =
|
member conn.removeFieldsById tableName (docId: 'TKey) fieldNames =
|
||||||
WithConn.RemoveFields.byId tableName docId fieldNames conn
|
WithConn.RemoveFields.byId tableName docId fieldNames conn
|
||||||
|
|
||||||
/// Remove a field from a document 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="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>
|
||||||
member conn.removeFieldsByFields tableName howMatched fields fieldNames =
|
member conn.removeFieldsByFields tableName howMatched fields fieldNames =
|
||||||
WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
|
WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
|
||||||
|
|
||||||
/// Delete a document by its ID
|
/// <summary>Delete a document by its ID</summary>
|
||||||
|
/// <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>
|
||||||
member conn.deleteById tableName (docId: 'TKey) =
|
member conn.deleteById tableName (docId: 'TKey) =
|
||||||
WithConn.Delete.byId tableName docId conn
|
WithConn.Delete.byId tableName docId conn
|
||||||
|
|
||||||
/// Delete documents by matching a comparison on JSON fields
|
/// <summary>Delete documents by matching a JSON field comparison query (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <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>
|
||||||
member conn.deleteByFields tableName howMatched fields =
|
member conn.deleteByFields tableName howMatched fields =
|
||||||
WithConn.Delete.byFields tableName howMatched fields conn
|
WithConn.Delete.byFields tableName howMatched fields conn
|
||||||
|
|
||||||
|
|
||||||
open System.Runtime.CompilerServices
|
open System.Runtime.CompilerServices
|
||||||
|
|
||||||
/// C# extensions on the SqliteConnection type
|
/// <summary>C# extensions on the SqliteConnection type</summary>
|
||||||
type SqliteConnectionCSharpExtensions =
|
type SqliteConnectionCSharpExtensions =
|
||||||
|
|
||||||
/// 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CustomList<'TDoc>(conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'TDoc>) =
|
static member inline CustomList<'TDoc>(conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'TDoc>) =
|
||||||
WithConn.Custom.List<'TDoc>(query, parameters, mapFunc, conn)
|
WithConn.Custom.List<'TDoc>(query, parameters, mapFunc, conn)
|
||||||
|
|
||||||
/// Execute a query that returns one or no results
|
/// <summary>Execute a query that returns one or no results</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CustomSingle<'TDoc when 'TDoc: null>(
|
static member inline CustomSingle<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'TDoc>) =
|
conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'TDoc>) =
|
||||||
WithConn.Custom.Single<'TDoc>(query, parameters, mapFunc, conn)
|
WithConn.Custom.Single<'TDoc>(query, parameters, mapFunc, conn)
|
||||||
|
|
||||||
/// Execute a query that does not return a value
|
/// <summary>Execute a query that returns no results</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CustomNonQuery(conn, query, parameters) =
|
static member inline CustomNonQuery(conn, query, parameters) =
|
||||||
WithConn.Custom.nonQuery query parameters conn
|
WithConn.Custom.nonQuery query parameters conn
|
||||||
|
|
||||||
/// Execute a query that returns a scalar value
|
/// <summary>Execute a query that returns a scalar value</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CustomScalar<'T when 'T: struct>(
|
static member inline CustomScalar<'T when 'T: struct>(
|
||||||
conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'T>) =
|
conn, query, parameters, mapFunc: System.Func<SqliteDataReader, 'T>) =
|
||||||
WithConn.Custom.Scalar<'T>(query, parameters, mapFunc, conn)
|
WithConn.Custom.Scalar<'T>(query, parameters, mapFunc, conn)
|
||||||
|
|
||||||
/// Create a document table
|
/// <summary>Create a document table</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</tt> on which to run the query</param>
|
||||||
|
/// <param name="name">The table whose existence should be ensured (may include schema)</param>
|
||||||
[<Extension>]
|
[<Extension>]
|
||||||
static member inline EnsureTable(conn, name) =
|
static member inline EnsureTable(conn, name) =
|
||||||
WithConn.Definition.ensureTable name conn
|
WithConn.Definition.ensureTable name conn
|
||||||
|
|
||||||
/// Create an index on one or more fields in a document table
|
/// <summary>Create an index on field(s) within documents in the specified table</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline EnsureFieldIndex(conn, tableName, indexName, fields) =
|
static member inline EnsureFieldIndex(conn, tableName, indexName, fields) =
|
||||||
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
||||||
|
|
||||||
/// Insert a new document
|
/// <summary>Insert a new document</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline Insert<'TDoc>(conn, tableName, document: 'TDoc) =
|
static member inline Insert<'TDoc>(conn, tableName, document: 'TDoc) =
|
||||||
WithConn.Document.insert<'TDoc> tableName document conn
|
WithConn.Document.insert<'TDoc> tableName document 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline Save<'TDoc>(conn, tableName, document: 'TDoc) =
|
static member inline Save<'TDoc>(conn, tableName, document: 'TDoc) =
|
||||||
WithConn.Document.save<'TDoc> tableName document conn
|
WithConn.Document.save<'TDoc> tableName document conn
|
||||||
|
|
||||||
/// Count all documents in a table
|
/// <summary>Count all documents in a table</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CountAll(conn, tableName) =
|
static member inline CountAll(conn, tableName) =
|
||||||
WithConn.Count.all tableName conn
|
WithConn.Count.all tableName conn
|
||||||
|
|
||||||
/// Count matching documents using a comparison on JSON fields
|
/// <summary>Count matching documents using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline CountByFields(conn, tableName, howMatched, fields) =
|
static member inline CountByFields(conn, tableName, howMatched, fields) =
|
||||||
WithConn.Count.byFields tableName howMatched fields conn
|
WithConn.Count.byFields tableName howMatched fields 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline ExistsById<'TKey>(conn, tableName, docId: 'TKey) =
|
static member inline ExistsById<'TKey>(conn, tableName, docId: 'TKey) =
|
||||||
WithConn.Exists.byId tableName docId conn
|
WithConn.Exists.byId tableName docId conn
|
||||||
|
|
||||||
/// Determine if a document exists using a comparison on JSON fields
|
/// <summary>Determine if a document exists using JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline ExistsByFields(conn, tableName, howMatched, fields) =
|
static member inline ExistsByFields(conn, tableName, howMatched, fields) =
|
||||||
WithConn.Exists.byFields tableName howMatched fields conn
|
WithConn.Exists.byFields tableName howMatched fields conn
|
||||||
|
|
||||||
/// Retrieve all documents in the given table
|
/// <summary>Retrieve all documents in the given table</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindAll<'TDoc>(conn, tableName) =
|
static member inline FindAll<'TDoc>(conn, tableName) =
|
||||||
WithConn.Find.All<'TDoc>(tableName, conn)
|
WithConn.Find.All<'TDoc>(tableName, 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
|
static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
|
||||||
WithConn.Find.AllOrdered<'TDoc>(tableName, orderFields, conn)
|
WithConn.Find.AllOrdered<'TDoc>(tableName, orderFields, conn)
|
||||||
|
|
||||||
/// Retrieve a document by its ID
|
/// <summary>Retrieve a document by its ID</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindById<'TKey, 'TDoc when 'TDoc: null>(conn, tableName, docId: 'TKey) =
|
static member inline FindById<'TKey, 'TDoc when 'TDoc: null and 'TDoc: not struct>(conn, tableName, docId: 'TKey) =
|
||||||
WithConn.Find.ById<'TKey, 'TDoc>(tableName, docId, conn)
|
WithConn.Find.ById<'TKey, 'TDoc>(tableName, docId, conn)
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields
|
/// <summary>Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) =
|
static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) =
|
||||||
WithConn.Find.ByFields<'TDoc>(tableName, howMatched, fields, conn)
|
WithConn.Find.ByFields<'TDoc>(tableName, howMatched, fields, conn)
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document
|
/// <summary>
|
||||||
|
/// Retrieve documents matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given fields in
|
||||||
|
/// the document
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
|
static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
|
||||||
WithConn.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
|
WithConn.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields, returning only the first result
|
/// <summary>Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) =
|
static member inline FindFirstByFields<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
|
conn, tableName, howMatched, fields) =
|
||||||
WithConn.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, conn)
|
WithConn.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, conn)
|
||||||
|
|
||||||
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document, returning only
|
/// <summary>
|
||||||
/// the first result
|
/// Retrieve the first document matching JSON field comparisons (<tt>->> =</tt>, etc.) ordered by the given
|
||||||
|
/// fields in the document
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline FindFirstByFieldsOrdered<'TDoc when 'TDoc: null>(
|
static member inline FindFirstByFieldsOrdered<'TDoc when 'TDoc: null and 'TDoc: not struct>(
|
||||||
conn, tableName, howMatched, queryFields, orderFields) =
|
conn, tableName, howMatched, queryFields, orderFields) =
|
||||||
WithConn.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
|
WithConn.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
|
||||||
|
|
||||||
/// Update an entire document by its ID
|
/// <summary>Update (replace) an entire document by its ID</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline UpdateById<'TKey, 'TDoc>(conn, tableName, docId: 'TKey, document: 'TDoc) =
|
static member inline UpdateById<'TKey, 'TDoc>(conn, tableName, docId: 'TKey, document: 'TDoc) =
|
||||||
WithConn.Update.byId tableName docId document conn
|
WithConn.Update.byId tableName docId document 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline UpdateByFunc<'TKey, 'TDoc>(conn, tableName, idFunc: System.Func<'TDoc, 'TKey>, doc: 'TDoc) =
|
static member inline UpdateByFunc<'TKey, 'TDoc>(
|
||||||
WithConn.Update.ByFunc(tableName, idFunc, doc, conn)
|
conn, tableName, idFunc: System.Func<'TDoc, 'TKey>, document: 'TDoc) =
|
||||||
|
WithConn.Update.ByFunc(tableName, idFunc, document, conn)
|
||||||
|
|
||||||
/// Patch a document by its ID
|
/// <summary>Patch a document by its ID</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline PatchById<'TKey, 'TPatch>(conn, tableName, docId: 'TKey, patch: 'TPatch) =
|
static member inline PatchById<'TKey, 'TPatch>(conn, tableName, docId: 'TKey, patch: 'TPatch) =
|
||||||
WithConn.Patch.byId tableName docId patch conn
|
WithConn.Patch.byId tableName docId patch conn
|
||||||
|
|
||||||
/// Patch documents using a comparison on JSON fields
|
/// <summary>
|
||||||
|
/// Patch documents using a JSON field comparison query in the <tt>WHERE</tt> clause (<tt>->> =</tt>, etc.)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline PatchByFields<'TPatch>(conn, tableName, howMatched, fields, patch: 'TPatch) =
|
static member inline PatchByFields<'TPatch>(conn, tableName, howMatched, fields, patch: 'TPatch) =
|
||||||
WithConn.Patch.byFields tableName howMatched fields patch conn
|
WithConn.Patch.byFields tableName howMatched fields patch 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline RemoveFieldsById<'TKey>(conn, tableName, docId: 'TKey, fieldNames) =
|
static member inline RemoveFieldsById<'TKey>(conn, tableName, docId: 'TKey, fieldNames) =
|
||||||
WithConn.RemoveFields.byId tableName docId fieldNames conn
|
WithConn.RemoveFields.byId tableName docId fieldNames 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>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline RemoveFieldsByFields(conn, tableName, howMatched, fields, fieldNames) =
|
static member inline RemoveFieldsByFields(conn, tableName, howMatched, fields, fieldNames) =
|
||||||
WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
|
WithConn.RemoveFields.byFields tableName howMatched fields fieldNames conn
|
||||||
|
|
||||||
/// Delete a document by its ID
|
/// <summary>Delete a document by its ID</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline DeleteById<'TKey>(conn, tableName, docId: 'TKey) =
|
static member inline DeleteById<'TKey>(conn, tableName, docId: 'TKey) =
|
||||||
WithConn.Delete.byId tableName docId conn
|
WithConn.Delete.byId tableName docId conn
|
||||||
|
|
||||||
/// Delete documents by matching a comparison on JSON fields
|
/// <summary>Delete documents by matching a JSON field comparison query (<tt>->> =</tt>, etc.)</summary>
|
||||||
|
/// <param name="conn">The <tt>SqliteConnection</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>]
|
[<Extension>]
|
||||||
static member inline DeleteByFields(conn, tableName, howMatched, fields) =
|
static member inline DeleteByFields(conn, tableName, howMatched, fields) =
|
||||||
WithConn.Delete.byFields tableName howMatched fields conn
|
WithConn.Delete.byFields tableName howMatched fields conn
|
||||||
|
|
||||||
/// Delete documents by matching a comparison on a JSON field
|
|
||||||
[<Extension>]
|
|
||||||
[<System.Obsolete "Use DeleteByFields instead; will be removed in v4">]
|
|
||||||
static member inline DeleteByField(conn, tableName, field) =
|
|
||||||
conn.DeleteByFields(tableName, Any, [ field ])
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,11 +5,16 @@ This package provides a lightweight document library backed by [SQLite](https://
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
- Select, insert, update, save (upsert), delete, count, and check existence of documents, and create tables and indexes for these documents
|
||||||
|
- Automatically generate IDs for documents (numeric IDs, GUIDs, or random strings)
|
||||||
- Address documents via ID or via comparison on any field
|
- Address documents via ID or via comparison on any field
|
||||||
- Access documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
- Access documents as your domain models (<abbr title="Plain Old CLR Objects">POCO</abbr>s)
|
||||||
- Use `Task`-based async for all data access functions
|
- Use `Task`-based async for all data access functions
|
||||||
- Use building blocks for more complex queries
|
- Use building blocks for more complex queries
|
||||||
|
|
||||||
|
## Upgrading from v3
|
||||||
|
|
||||||
|
There is a breaking API change for `ByField` (C#) / `byField` (F#), along with a compatibility namespace that can mitigate the impact of these changes. See [the migration guide](https://bitbadger.solutions/open-source/relational-documents/upgrade-from-v3-to-v4.html) for full details.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Once the package is installed, the library needs a connection string. Once it has been obtained / constructed, provide it to the library:
|
Once the package is installed, the library needs a connection string. Once it has been obtained / constructed, provide it to the library:
|
||||||
@@ -72,28 +77,28 @@ Count customers in Atlanta:
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// C#; parameters are table name, field, operator, and value
|
// C#; parameters are table name, field, operator, and value
|
||||||
// Count.ByField type signature is Func<string, Field, Task<long>>
|
// Count.ByFields type signature is Func<string, FieldMatch, IEnumerable<Field>, Task<long>>
|
||||||
var customerCount = await Count.ByField("customer", Field.Equal("City", "Atlanta"));
|
var customerCount = await Count.ByFields("customer", FieldMatch.Any, [Field.Equal("City", "Atlanta")]);
|
||||||
```
|
```
|
||||||
|
|
||||||
```fsharp
|
```fsharp
|
||||||
// F#
|
// F#
|
||||||
// Count.byField type signature is string -> Field -> Task<int64>
|
// Count.byFields type signature is string -> FieldMatch -> Field seq -> Task<int64>
|
||||||
let! customerCount = Count.byField "customer" (Field.Equal "City" "Atlanta")
|
let! customerCount = Count.byFields "customer" Any [ Field.Equal "City" "Atlanta" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
Delete customers in Chicago: _(no offense, Second City; just an example...)_
|
Delete customers in Chicago: _(no offense, Second City; just an example...)_
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// C#; parameters are same as above, except return is void
|
// C#; parameters are same as above, except return is void
|
||||||
// Delete.ByField type signature is Func<string, Field, Task>
|
// Delete.ByFields type signature is Func<string, FieldMatch, IEnumerable<Field>, Task>
|
||||||
await Delete.ByField("customer", Field.Equal("City", "Chicago"));
|
await Delete.ByFields("customer", FieldMatch.Any, [Field.Equal("City", "Chicago")]);
|
||||||
```
|
```
|
||||||
|
|
||||||
```fsharp
|
```fsharp
|
||||||
// F#
|
// F#
|
||||||
// Delete.byField type signature is string -> string -> Op -> obj -> Task<unit>
|
// Delete.byFields type signature is string -> FieldMatch -> Field seq -> Task<unit>
|
||||||
do! Delete.byField "customer" (Field.Equal "City" "Chicago")
|
do! Delete.byFields "customer" Any [ Field.Equal "City" "Chicago" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public static class SqliteCSharpTests
|
|||||||
]),
|
]),
|
||||||
TestCase("WhereById succeeds", () =>
|
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", () =>
|
TestCase("Patch succeeds", () =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Expecto" Version="10.2.1" />
|
<PackageReference Include="Expecto" Version="10.2.1" />
|
||||||
<PackageReference Update="FSharp.Core" Version="8.0.300" />
|
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -97,14 +97,20 @@ let fieldTests = testList "Field" [
|
|||||||
test "In succeeds" {
|
test "In succeeds" {
|
||||||
let field = Field.In "Here" [| 8; 16; 32 |]
|
let field = Field.In "Here" [| 8; 16; 32 |]
|
||||||
Expect.equal field.Name "Here" "Field name incorrect"
|
Expect.equal field.Name "Here" "Field name incorrect"
|
||||||
Expect.equal field.Comparison (In [| 8; 16; 32 |]) "Comparison incorrect"
|
match field.Comparison with
|
||||||
|
| In values -> Expect.equal (List.ofSeq values) [ box 8; box 16; box 32 ] "Comparison incorrect"
|
||||||
|
| it -> Expect.isTrue false $"Expected In, received %A{it}"
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
test "InArray succeeds" {
|
test "InArray succeeds" {
|
||||||
let field = Field.InArray "ArrayField" "table" [| "z" |]
|
let field = Field.InArray "ArrayField" "table" [| "z" |]
|
||||||
Expect.equal field.Name "ArrayField" "Field name incorrect"
|
Expect.equal field.Name "ArrayField" "Field name incorrect"
|
||||||
Expect.equal field.Comparison (InArray("table", [| "z" |])) "Comparison incorrect"
|
match field.Comparison with
|
||||||
|
| InArray (table, values) ->
|
||||||
|
Expect.equal table "table" "Comparison table incorrect"
|
||||||
|
Expect.equal (List.ofSeq values) [ box "z" ] "Comparison values incorrect"
|
||||||
|
| it -> Expect.isTrue false $"Expected InArray, received %A{it}"
|
||||||
Expect.isNone field.ParameterName "The default parameter name should be None"
|
Expect.isNone field.ParameterName "The default parameter name should be None"
|
||||||
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
Expect.isNone field.Qualifier "The default table qualifier should be None"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ let queryTests = testList "Query" [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
test "whereById succeeds" {
|
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" {
|
test "patch succeeds" {
|
||||||
Expect.equal
|
Expect.equal
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dotnet build BitBadger.Documents.sln --no-restore
|
|||||||
cd ./Tests || exit
|
cd ./Tests || exit
|
||||||
|
|
||||||
export BBDOX_PG_PORT=8301
|
export BBDOX_PG_PORT=8301
|
||||||
PG_VERSIONS=('12' '13' '14' '15' 'latest')
|
PG_VERSIONS=('13' '14' '15' '16' 'latest')
|
||||||
NET_VERSIONS=('6.0' '8.0')
|
NET_VERSIONS=('8.0' '9.0')
|
||||||
|
|
||||||
for PG_VERSION in "${PG_VERSIONS[@]}"
|
for PG_VERSION in "${PG_VERSIONS[@]}"
|
||||||
do
|
do
|
||||||
|
|||||||
Reference in New Issue
Block a user