v4.1 #11
@ -5,40 +5,40 @@ open System.Security.Cryptography
|
|||||||
/// <summary>The types of comparisons available for JSON fields</summary>
|
/// <summary>The types of comparisons available for JSON fields</summary>
|
||||||
/// <exclude />
|
/// <exclude />
|
||||||
type Comparison =
|
type Comparison =
|
||||||
|
|
||||||
/// <summary>Equals (<tt>=</tt>)</summary>
|
/// <summary>Equals (<c>=</c>)</summary>
|
||||||
| Equal of Value: obj
|
| Equal of Value: obj
|
||||||
|
|
||||||
/// <summary>Greater Than (<tt>></tt>)</summary>
|
/// <summary>Greater Than (<c>></c>)</summary>
|
||||||
| Greater of Value: obj
|
| Greater of Value: obj
|
||||||
|
|
||||||
/// <summary>Greater Than or Equal To (<tt>>=</tt>)</summary>
|
/// <summary>Greater Than or Equal To (<c>>=</c>)</summary>
|
||||||
| GreaterOrEqual of Value: obj
|
| GreaterOrEqual of Value: obj
|
||||||
|
|
||||||
/// <summary>Less Than (<tt><</tt>)</summary>
|
/// <summary>Less Than (<c><</c>)</summary>
|
||||||
| Less of Value: obj
|
| Less of Value: obj
|
||||||
|
|
||||||
/// <summary>Less Than or Equal To (<tt><=</tt>)</summary>
|
/// <summary>Less Than or Equal To (<c><=</c>)</summary>
|
||||||
| LessOrEqual of Value: obj
|
| LessOrEqual of Value: obj
|
||||||
|
|
||||||
/// <summary>Not Equal to (<tt><></tt>)</summary>
|
/// <summary>Not Equal to (<c><></c>)</summary>
|
||||||
| NotEqual of Value: obj
|
| NotEqual of Value: obj
|
||||||
|
|
||||||
/// <summary>Between (<tt>BETWEEN</tt>)</summary>
|
/// <summary>Between (<c>BETWEEN</c>)</summary>
|
||||||
| Between of Min: obj * Max: obj
|
| Between of Min: obj * Max: obj
|
||||||
|
|
||||||
/// <summary>In (<tt>IN</tt>)</summary>
|
/// <summary>In (<c>IN</c>)</summary>
|
||||||
| In of Values: obj seq
|
| In of Values: obj seq
|
||||||
|
|
||||||
/// <summary>In Array (PostgreSQL: <tt>|?</tt>, SQLite: <tt>EXISTS / json_each / IN</tt>)</summary>
|
/// <summary>In Array (PostgreSQL: <c>|?</c>, SQLite: <c>EXISTS / json_each / IN</c>)</summary>
|
||||||
| InArray of Table: string * Values: obj seq
|
| InArray of Table: string * Values: obj seq
|
||||||
|
|
||||||
/// <summary>Exists (<tt>IS NOT NULL</tt>)</summary>
|
/// <summary>Exists (<c>IS NOT NULL</c>)</summary>
|
||||||
| Exists
|
| Exists
|
||||||
|
|
||||||
/// <summary>Does Not Exist (<tt>IS NULL</tt>)</summary>
|
/// <summary>Does Not Exist (<c>IS NULL</c>)</summary>
|
||||||
| NotExists
|
| NotExists
|
||||||
|
|
||||||
/// <summary>The operator SQL for this comparison</summary>
|
/// <summary>The operator SQL for this comparison</summary>
|
||||||
member this.OpSql =
|
member this.OpSql =
|
||||||
match this with
|
match this with
|
||||||
@ -50,7 +50,7 @@ type Comparison =
|
|||||||
| NotEqual _ -> "<>"
|
| NotEqual _ -> "<>"
|
||||||
| Between _ -> "BETWEEN"
|
| Between _ -> "BETWEEN"
|
||||||
| In _ -> "IN"
|
| In _ -> "IN"
|
||||||
| InArray _ -> "?|" // PostgreSQL only; SQL needs a subquery for this
|
| InArray _ -> "?|" // PostgreSQL only; SQL needs a subquery for this
|
||||||
| Exists -> "IS NOT NULL"
|
| Exists -> "IS NOT NULL"
|
||||||
| NotExists -> "IS NULL"
|
| NotExists -> "IS NULL"
|
||||||
|
|
||||||
@ -62,120 +62,120 @@ type Dialect =
|
|||||||
| SQLite
|
| SQLite
|
||||||
|
|
||||||
|
|
||||||
/// <summary>The format in which an element of a JSON field should be extracted</summary>
|
/// <summary>The format in which an element of a JSON field should be extracted</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type FieldFormat =
|
type FieldFormat =
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use <tt>->></tt> or <tt>#>></tt>; extracts a text (PostgreSQL) or SQL (SQLite) value
|
/// Use <c>->></c> or <c>#>></c>; extracts a text (PostgreSQL) or SQL (SQLite) value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
| AsSql
|
| AsSql
|
||||||
|
|
||||||
/// <summary>Use <tt>-></tt> or <tt>#></tt>; extracts a JSONB (PostgreSQL) or JSON (SQLite) value</summary>
|
/// <summary>Use <c>-></c> or <c>#></c>; extracts a JSONB (PostgreSQL) or JSON (SQLite) value</summary>
|
||||||
| AsJson
|
| AsJson
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Criteria for a field <tt>WHERE</tt> clause</summary>
|
/// <summary>Criteria for a field <c>WHERE</c> clause</summary>
|
||||||
type Field = {
|
type Field = {
|
||||||
|
|
||||||
/// <summary>The name of the field</summary>
|
/// <summary>The name of the field</summary>
|
||||||
Name: string
|
Name: string
|
||||||
|
|
||||||
/// <summary>The comparison for the field</summary>
|
/// <summary>The comparison for the field</summary>
|
||||||
Comparison: Comparison
|
Comparison: Comparison
|
||||||
|
|
||||||
/// <summary>The name of the parameter for this field</summary>
|
/// <summary>The name of the parameter for this field</summary>
|
||||||
ParameterName: string option
|
ParameterName: string option
|
||||||
|
|
||||||
/// <summary>The table qualifier for this field</summary>
|
/// <summary>The table qualifier for this field</summary>
|
||||||
Qualifier: string option
|
Qualifier: string option
|
||||||
} with
|
} with
|
||||||
|
|
||||||
/// <summary>Create a comparison against a field</summary>
|
/// <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="name">The name of the field against which the comparison should be applied</param>
|
||||||
/// <param name="comparison">The comparison for the given field</param>
|
/// <param name="comparison">The comparison for the given field</param>
|
||||||
/// <returns>A new <tt>Field</tt> instance implementing the given comparison</returns>
|
/// <returns>A new <c>Field</c> instance implementing the given comparison</returns>
|
||||||
static member Where name (comparison: Comparison) =
|
static member Where name (comparison: Comparison) =
|
||||||
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
|
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
|
||||||
|
|
||||||
/// <summary>Create an equals (<tt>=</tt>) field criterion</summary>
|
/// <summary>Create an equals (<c>=</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Equal<'T> name (value: 'T) =
|
static member Equal<'T> name (value: 'T) =
|
||||||
Field.Where name (Equal value)
|
Field.Where name (Equal value)
|
||||||
|
|
||||||
/// <summary>Create an equals (<tt>=</tt>) field criterion (alias)</summary>
|
/// <summary>Create an equals (<c>=</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member EQ<'T> name (value: 'T) = Field.Equal name value
|
static member EQ<'T> name (value: 'T) = Field.Equal name value
|
||||||
|
|
||||||
/// <summary>Create a greater than (<tt>></tt>) field criterion</summary>
|
/// <summary>Create a greater than (<c>></c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Greater<'T> name (value: 'T) =
|
static member Greater<'T> name (value: 'T) =
|
||||||
Field.Where name (Greater value)
|
Field.Where name (Greater value)
|
||||||
|
|
||||||
/// <summary>Create a greater than (<tt>></tt>) field criterion (alias)</summary>
|
/// <summary>Create a greater than (<c>></c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member GT<'T> name (value: 'T) = Field.Greater name value
|
static member GT<'T> name (value: 'T) = Field.Greater name value
|
||||||
|
|
||||||
/// <summary>Create a greater than or equal to (<tt>>=</tt>) field criterion</summary>
|
/// <summary>Create a greater than or equal to (<c>>=</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member GreaterOrEqual<'T> name (value: 'T) =
|
static member GreaterOrEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (GreaterOrEqual value)
|
Field.Where name (GreaterOrEqual value)
|
||||||
|
|
||||||
/// <summary>Create a greater than or equal to (<tt>>=</tt>) field criterion (alias)</summary>
|
/// <summary>Create a greater than or equal to (<c>>=</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member GE<'T> name (value: 'T) = Field.GreaterOrEqual name value
|
static member GE<'T> name (value: 'T) = Field.GreaterOrEqual name value
|
||||||
|
|
||||||
/// <summary>Create a less than (<tt><</tt>) field criterion</summary>
|
/// <summary>Create a less than (<c><</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Less<'T> name (value: 'T) =
|
static member Less<'T> name (value: 'T) =
|
||||||
Field.Where name (Less value)
|
Field.Where name (Less value)
|
||||||
|
|
||||||
/// <summary>Create a less than (<tt><</tt>) field criterion (alias)</summary>
|
/// <summary>Create a less than (<c><</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member LT<'T> name (value: 'T) = Field.Less name value
|
static member LT<'T> name (value: 'T) = Field.Less name value
|
||||||
|
|
||||||
/// <summary>Create a less than or equal to (<tt><=</tt>) field criterion</summary>
|
/// <summary>Create a less than or equal to (<c><=</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member LessOrEqual<'T> name (value: 'T) =
|
static member LessOrEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (LessOrEqual value)
|
Field.Where name (LessOrEqual value)
|
||||||
|
|
||||||
/// <summary>Create a less than or equal to (<tt><=</tt>) field criterion (alias)</summary>
|
/// <summary>Create a less than or equal to (<c><=</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member LE<'T> name (value: 'T) = Field.LessOrEqual name value
|
static member LE<'T> name (value: 'T) = Field.LessOrEqual name value
|
||||||
|
|
||||||
/// <summary>Create a not equals (<tt><></tt>) field criterion</summary>
|
/// <summary>Create a not equals (<c><></c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NotEqual<'T> name (value: 'T) =
|
static member NotEqual<'T> name (value: 'T) =
|
||||||
Field.Where name (NotEqual value)
|
Field.Where name (NotEqual value)
|
||||||
|
|
||||||
/// <summary>Create a not equals (<tt><></tt>) field criterion (alias)</summary>
|
/// <summary>Create a not equals (<c><></c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="value">The value for the comparison</param>
|
/// <param name="value">The value for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NE<'T> name (value: 'T) = Field.NotEqual name value
|
static member NE<'T> name (value: 'T) = Field.NotEqual name value
|
||||||
|
|
||||||
/// <summary>Create a Between field criterion</summary>
|
/// <summary>Create a Between field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <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="min">The minimum value for the comparison range</param>
|
||||||
@ -183,27 +183,27 @@ type Field = {
|
|||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Between<'T> name (min: 'T) (max: 'T) =
|
static member Between<'T> name (min: 'T) (max: 'T) =
|
||||||
Field.Where name (Between(min, max))
|
Field.Where name (Between(min, max))
|
||||||
|
|
||||||
/// <summary>Create a Between field criterion (alias)</summary>
|
/// <summary>Create a Between field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <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="min">The minimum value for the comparison range</param>
|
||||||
/// <param name="max">The maximum 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>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member BT<'T> name (min: 'T) (max: 'T) = Field.Between name min max
|
static member BT<'T> name (min: 'T) (max: 'T) = Field.Between name min max
|
||||||
|
|
||||||
/// <summary>Create an In field criterion</summary>
|
/// <summary>Create an In field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="values">The values for the comparison</param>
|
/// <param name="values">The values for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member In<'T> name (values: 'T seq) =
|
static member In<'T> name (values: 'T seq) =
|
||||||
Field.Where name (In (Seq.map box values))
|
Field.Where name (In (Seq.map box values))
|
||||||
|
|
||||||
/// <summary>Create an In field criterion (alias)</summary>
|
/// <summary>Create an In field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="values">The values for the comparison</param>
|
/// <param name="values">The values for the comparison</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member IN<'T> name (values: 'T seq) = Field.In name values
|
static member IN<'T> name (values: 'T seq) = Field.In name values
|
||||||
|
|
||||||
/// <summary>Create an InArray field criterion</summary>
|
/// <summary>Create an InArray field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <param name="tableName">The name of the table in which the field's documents are stored</param>
|
/// <param name="tableName">The name of the table in which the field's documents are stored</param>
|
||||||
@ -211,34 +211,34 @@ type Field = {
|
|||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member InArray<'T> name tableName (values: 'T seq) =
|
static member InArray<'T> name tableName (values: 'T seq) =
|
||||||
Field.Where name (InArray(tableName, Seq.map box values))
|
Field.Where name (InArray(tableName, Seq.map box values))
|
||||||
|
|
||||||
/// <summary>Create an exists (<tt>IS NOT NULL</tt>) field criterion</summary>
|
/// <summary>Create an exists (<c>IS NOT NULL</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member Exists name =
|
static member Exists name =
|
||||||
Field.Where name Exists
|
Field.Where name Exists
|
||||||
|
|
||||||
/// <summary>Create an exists (<tt>IS NOT NULL</tt>) field criterion (alias)</summary>
|
/// <summary>Create an exists (<c>IS NOT NULL</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member EX name = Field.Exists name
|
static member EX name = Field.Exists name
|
||||||
|
|
||||||
/// <summary>Create a not exists (<tt>IS NULL</tt>) field criterion</summary>
|
/// <summary>Create a not exists (<c>IS NULL</c>) field criterion</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NotExists name =
|
static member NotExists name =
|
||||||
Field.Where name NotExists
|
Field.Where name NotExists
|
||||||
|
|
||||||
/// <summary>Create a not exists (<tt>IS NULL</tt>) field criterion (alias)</summary>
|
/// <summary>Create a not exists (<c>IS NULL</c>) field criterion (alias)</summary>
|
||||||
/// <param name="name">The name of the field to be compared</param>
|
/// <param name="name">The name of the field to be compared</param>
|
||||||
/// <returns>A field with the given comparison</returns>
|
/// <returns>A field with the given comparison</returns>
|
||||||
static member NEX name = Field.NotExists name
|
static member NEX name = Field.NotExists name
|
||||||
|
|
||||||
/// <summary>Transform a field name (<tt>a.b.c</tt>) to a path for the given SQL dialect</summary>
|
/// <summary>Transform a field name (<c>a.b.c</c>) to a path for the given SQL dialect</summary>
|
||||||
/// <param name="name">The name of the field in dotted format</param>
|
/// <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="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>
|
/// <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>
|
/// <returns>A <c>string</c> 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
|
||||||
@ -254,19 +254,19 @@ type Field = {
|
|||||||
else
|
else
|
||||||
match format with AsJson -> $"->'{name}'" | AsSql -> $"->>'{name}'"
|
match format with AsJson -> $"->'{name}'" | AsSql -> $"->>'{name}'"
|
||||||
$"data{path}"
|
$"data{path}"
|
||||||
|
|
||||||
/// <summary>Create a field with a given name, but no other properties filled</summary>
|
/// <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>
|
/// <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>
|
/// <remarks><c>Comparison</c> will be <c>Equal</c>, value will be an empty string</remarks>
|
||||||
static member Named name =
|
static member Named name =
|
||||||
Field.Where name (Equal "")
|
Field.Where name (Equal "")
|
||||||
|
|
||||||
/// <summary>Specify the name of the parameter for this field</summary>
|
/// <summary>Specify the name of the parameter for this field</summary>
|
||||||
/// <param name="name">The parameter name (including <tt>:</tt> or <tt>@</tt>)</param>
|
/// <param name="name">The parameter name (including <c>:</c> or <c>@</c>)</param>
|
||||||
/// <returns>A field with the given parameter name specified</returns>
|
/// <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 }
|
||||||
|
|
||||||
/// <summary>Specify a qualifier (alias) for the table from which this field will be referenced</summary>
|
/// <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>
|
/// <param name="alias">The table alias for this field comparison</param>
|
||||||
/// <returns>A field with the given qualifier specified</returns>
|
/// <returns>A field with the given qualifier specified</returns>
|
||||||
@ -276,7 +276,7 @@ type Field = {
|
|||||||
/// <summary>Get the qualified path to the field</summary>
|
/// <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="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>
|
/// <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>
|
/// <returns>A <c>string</c> 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
|
||||||
@ -285,13 +285,13 @@ type Field = {
|
|||||||
/// <summary>How fields should be matched</summary>
|
/// <summary>How fields should be matched</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type FieldMatch =
|
type FieldMatch =
|
||||||
|
|
||||||
/// <summary>Any field matches (<tt>OR</tt>)</summary>
|
/// <summary>Any field matches (<c>OR</c>)</summary>
|
||||||
| Any
|
| Any
|
||||||
|
|
||||||
/// <summary>All fields match (<tt>AND</tt>)</summary>
|
/// <summary>All fields match (<c>AND</c>)</summary>
|
||||||
| All
|
| All
|
||||||
|
|
||||||
/// <summary>The SQL value implementing each matching strategy</summary>
|
/// <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"
|
||||||
@ -299,10 +299,10 @@ type FieldMatch =
|
|||||||
|
|
||||||
/// <summary>Derive parameter names (each instance wraps a counter to uniquely name anonymous fields)</summary>
|
/// <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>
|
/// <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>
|
/// </summary>
|
||||||
@ -319,30 +319,30 @@ type ParameterName() =
|
|||||||
/// <summary>Automatically-generated document ID strategies</summary>
|
/// <summary>Automatically-generated document ID strategies</summary>
|
||||||
[<Struct>]
|
[<Struct>]
|
||||||
type AutoId =
|
type AutoId =
|
||||||
|
|
||||||
/// <summary>No automatic IDs will be generated</summary>
|
/// <summary>No automatic IDs will be generated</summary>
|
||||||
| Disabled
|
| Disabled
|
||||||
|
|
||||||
/// <summary>Generate a MAX-plus-1 numeric value for documents</summary>
|
/// <summary>Generate a MAX-plus-1 numeric value for documents</summary>
|
||||||
| Number
|
| Number
|
||||||
|
|
||||||
/// <summary>Generate a <tt>GUID</tt> for each document (as a lowercase, no-dashes, 32-character string)</summary>
|
/// <summary>Generate a <c>GUID</c> for each document (as a lowercase, no-dashes, 32-character string)</summary>
|
||||||
| Guid
|
| Guid
|
||||||
|
|
||||||
/// <summary>Generate a random string of hexadecimal characters for each document</summary>
|
/// <summary>Generate a random string of hexadecimal characters for each document</summary>
|
||||||
| RandomString
|
| RandomString
|
||||||
with
|
with
|
||||||
/// <summary>Generate a <tt>GUID</tt> string</summary>
|
/// <summary>Generate a <c>GUID</c> string</summary>
|
||||||
/// <returns>A <tt>GUID</tt> string</returns>
|
/// <returns>A <c>GUID</c> string</returns>
|
||||||
static member GenerateGuid() =
|
static member GenerateGuid() =
|
||||||
System.Guid.NewGuid().ToString "N"
|
System.Guid.NewGuid().ToString "N"
|
||||||
|
|
||||||
/// <summary>Generate a string of random hexadecimal characters</summary>
|
/// <summary>Generate a string of random hexadecimal characters</summary>
|
||||||
/// <param name="length">The number of characters to generate</param>
|
/// <param name="length">The number of characters to generate</param>
|
||||||
/// <returns>A string of the given length with random hexadecimal characters</returns>
|
/// <returns>A string of the given length with random hexadecimal characters</returns>
|
||||||
static member GenerateRandomString(length: int) =
|
static member GenerateRandomString(length: int) =
|
||||||
RandomNumberGenerator.GetHexString(length, lowercase = true)
|
RandomNumberGenerator.GetHexString(length, lowercase = true)
|
||||||
|
|
||||||
/// <summary>Does the given document need an automatic ID generated?</summary>
|
/// <summary>Does the given document need an automatic ID generated?</summary>
|
||||||
/// <param name="strategy">The auto-ID strategy currently in use</param>
|
/// <param name="strategy">The auto-ID strategy currently in use</param>
|
||||||
/// <param name="document">The document being inserted</param>
|
/// <param name="document">The document being inserted</param>
|
||||||
@ -387,26 +387,26 @@ with
|
|||||||
|
|
||||||
/// <summary>The required document serialization implementation</summary>
|
/// <summary>The required document serialization implementation</summary>
|
||||||
type IDocumentSerializer =
|
type IDocumentSerializer =
|
||||||
|
|
||||||
/// <summary>Serialize an object to a JSON string</summary>
|
/// <summary>Serialize an object to a JSON string</summary>
|
||||||
abstract Serialize<'T> : 'T -> string
|
abstract Serialize<'T> : 'T -> string
|
||||||
|
|
||||||
/// <summary>Deserialize a JSON string into an object</summary>
|
/// <summary>Deserialize a JSON string into an object</summary>
|
||||||
abstract Deserialize<'T> : string -> 'T
|
abstract Deserialize<'T> : string -> 'T
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Document serializer defaults</summary>
|
/// <summary>Document serializer defaults</summary>
|
||||||
module DocumentSerializer =
|
module DocumentSerializer =
|
||||||
|
|
||||||
open System.Text.Json
|
open System.Text.Json
|
||||||
open System.Text.Json.Serialization
|
open System.Text.Json.Serialization
|
||||||
|
|
||||||
/// The default JSON serializer options to use with the stock serializer
|
/// The default JSON serializer options to use with the stock serializer
|
||||||
let private jsonDefaultOpts =
|
let private jsonDefaultOpts =
|
||||||
let o = JsonSerializerOptions()
|
let o = JsonSerializerOptions()
|
||||||
o.Converters.Add(JsonFSharpConverter())
|
o.Converters.Add(JsonFSharpConverter())
|
||||||
o
|
o
|
||||||
|
|
||||||
/// <summary>The default JSON serializer</summary>
|
/// <summary>The default JSON serializer</summary>
|
||||||
[<CompiledName "Default">]
|
[<CompiledName "Default">]
|
||||||
let ``default`` =
|
let ``default`` =
|
||||||
@ -424,7 +424,7 @@ 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``
|
||||||
|
|
||||||
/// <summary>Register a serializer to use for translating documents to domain types</summary>
|
/// <summary>Register a serializer to use for translating documents to domain types</summary>
|
||||||
/// <param name="ser">The serializer to use when manipulating documents</param>
|
/// <param name="ser">The serializer to use when manipulating documents</param>
|
||||||
[<CompiledName "UseSerializer">]
|
[<CompiledName "UseSerializer">]
|
||||||
@ -436,46 +436,46 @@ module Configuration =
|
|||||||
[<CompiledName "Serializer">]
|
[<CompiledName "Serializer">]
|
||||||
let serializer () =
|
let serializer () =
|
||||||
serializerValue
|
serializerValue
|
||||||
|
|
||||||
/// 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"
|
||||||
|
|
||||||
/// <summary>Specify the name of the ID field for documents</summary>
|
/// <summary>Specify the name of the ID field for documents</summary>
|
||||||
/// <param name="it">The name of the ID field for documents</param>
|
/// <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
|
||||||
|
|
||||||
/// <summary>Retrieve the currently configured ID field for documents</summary>
|
/// <summary>Retrieve the currently configured ID field for documents</summary>
|
||||||
/// <returns>The currently configured ID field</returns>
|
/// <returns>The currently configured ID field</returns>
|
||||||
[<CompiledName "IdField">]
|
[<CompiledName "IdField">]
|
||||||
let idField () =
|
let idField () =
|
||||||
idFieldValue
|
idFieldValue
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
||||||
/// <summary>Specify the automatic ID generation strategy used by the library</summary>
|
/// <summary>Specify the automatic ID generation strategy used by the library</summary>
|
||||||
/// <param name="it">The automatic ID generation strategy to use</param>
|
/// <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
|
||||||
|
|
||||||
/// <summary>Retrieve the currently configured automatic ID generation strategy</summary>
|
/// <summary>Retrieve the currently configured automatic ID generation strategy</summary>
|
||||||
/// <returns>The current automatic ID generation strategy</returns>
|
/// <returns>The current automatic ID generation strategy</returns>
|
||||||
[<CompiledName "AutoIdStrategy">]
|
[<CompiledName "AutoIdStrategy">]
|
||||||
let autoIdStrategy () =
|
let autoIdStrategy () =
|
||||||
autoIdValue
|
autoIdValue
|
||||||
|
|
||||||
/// The length of automatically generated random strings
|
/// The length of automatically generated random strings
|
||||||
let mutable private idStringLengthValue = 16
|
let mutable private idStringLengthValue = 16
|
||||||
|
|
||||||
/// <summary>Specify the length of automatically generated random strings</summary>
|
/// <summary>Specify the length of automatically generated random strings</summary>
|
||||||
/// <param name="length">The length of automatically generated random strings</param>
|
/// <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
|
||||||
|
|
||||||
/// <summary>Retrieve the currently configured length of automatically generated random strings</summary>
|
/// <summary>Retrieve the currently configured length of automatically generated random strings</summary>
|
||||||
/// <returns>The current length of automatically generated random strings</returns>
|
/// <returns>The current length of automatically generated random strings</returns>
|
||||||
[<CompiledName "IdStringLength">]
|
[<CompiledName "IdStringLength">]
|
||||||
@ -486,31 +486,31 @@ module Configuration =
|
|||||||
/// <summary>Query construction functions</summary>
|
/// <summary>Query construction functions</summary>
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Query =
|
module Query =
|
||||||
|
|
||||||
/// <summary>Combine a query (<tt>SELECT</tt>, <tt>UPDATE</tt>, etc.) and a <tt>WHERE</tt> clause</summary>
|
/// <summary>Combine a query (<c>SELECT</c>, <c>UPDATE</c>, etc.) and a <c>WHERE</c> clause</summary>
|
||||||
/// <param name="statement">The first part of the statement</param>
|
/// <param name="statement">The first part of the statement</param>
|
||||||
/// <param name="where">The <tt>WHERE</tt> clause for the statement</param>
|
/// <param name="where">The <c>WHERE</c> clause for the statement</param>
|
||||||
/// <returns>The two parts of the query combined with <tt>WHERE</tt></returns>
|
/// <returns>The two parts of the query combined with <c>WHERE</c></returns>
|
||||||
[<CompiledName "StatementWhere">]
|
[<CompiledName "StatementWhere">]
|
||||||
let statementWhere statement where =
|
let statementWhere statement where =
|
||||||
$"%s{statement} WHERE %s{where}"
|
$"%s{statement} WHERE %s{where}"
|
||||||
|
|
||||||
/// <summary>Queries to define tables and indexes</summary>
|
/// <summary>Queries to define tables and indexes</summary>
|
||||||
module Definition =
|
module Definition =
|
||||||
|
|
||||||
/// <summary>SQL statement to create a document table</summary>
|
/// <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="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>
|
/// <param name="dataType">The type of data for the column (<c>JSON</c>, <c>JSONB</c>, etc.)</param>
|
||||||
/// <returns>A query to create a document table</returns>
|
/// <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)"
|
||||||
|
|
||||||
/// Split a schema and table name
|
/// Split a schema and table name
|
||||||
let private splitSchemaAndTable (tableName: string) =
|
let private splitSchemaAndTable (tableName: string) =
|
||||||
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]
|
||||||
|
|
||||||
/// <summary>SQL statement to create an index on one or more fields in a JSON document</summary>
|
/// <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="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="indexName">The name of the index to be created</param>
|
||||||
@ -537,7 +537,7 @@ module Query =
|
|||||||
[<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")
|
||||||
|
|
||||||
/// <summary>Query to insert a document</summary>
|
/// <summary>Query to insert a document</summary>
|
||||||
/// <param name="tableName">The table into which to insert (may include schema)</param>
|
/// <param name="tableName">The table into which to insert (may include schema)</param>
|
||||||
/// <returns>A query to insert a document</returns>
|
/// <returns>A query to insert a document</returns>
|
||||||
@ -554,48 +554,48 @@ module Query =
|
|||||||
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 ())
|
||||||
|
|
||||||
/// <summary>Query to count documents in a table</summary>
|
/// <summary>Query to count documents in a table</summary>
|
||||||
/// <param name="tableName">The table in which to count documents (may include schema)</param>
|
/// <param name="tableName">The table in which to count documents (may include schema)</param>
|
||||||
/// <returns>A query to count documents</returns>
|
/// <returns>A query to count documents</returns>
|
||||||
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
/// <remarks>This query has no <c>WHERE</c> 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}"
|
||||||
|
|
||||||
/// <summary>Query to check for document existence in a table</summary>
|
/// <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="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>
|
/// <param name="where">The <c>WHERE</c> clause with the existence criteria</param>
|
||||||
/// <returns>A query to check document existence</returns>
|
/// <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"
|
||||||
|
|
||||||
/// <summary>Query to select documents from a table</summary>
|
/// <summary>Query to select documents from a table</summary>
|
||||||
/// <param name="tableName">The table from which documents should be found (may include schema)</param>
|
/// <param name="tableName">The table from which documents should be found (may include schema)</param>
|
||||||
/// <returns>A query to retrieve documents</returns>
|
/// <returns>A query to retrieve documents</returns>
|
||||||
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
/// <remarks>This query has no <c>WHERE</c> clause</remarks>
|
||||||
[<CompiledName "Find">]
|
[<CompiledName "Find">]
|
||||||
let find tableName =
|
let find tableName =
|
||||||
$"SELECT data FROM %s{tableName}"
|
$"SELECT data FROM %s{tableName}"
|
||||||
|
|
||||||
/// <summary>Query to update (replace) a document</summary>
|
/// <summary>Query to update (replace) a document</summary>
|
||||||
/// <param name="tableName">The table in which documents should be replaced (may include schema)</param>
|
/// <param name="tableName">The table in which documents should be replaced (may include schema)</param>
|
||||||
/// <returns>A query to update documents</returns>
|
/// <returns>A query to update documents</returns>
|
||||||
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
/// <remarks>This query has no <c>WHERE</c> clause</remarks>
|
||||||
[<CompiledName "Update">]
|
[<CompiledName "Update">]
|
||||||
let update tableName =
|
let update tableName =
|
||||||
$"UPDATE %s{tableName} SET data = @data"
|
$"UPDATE %s{tableName} SET data = @data"
|
||||||
|
|
||||||
/// <summary>Query to delete documents from a table</summary>
|
/// <summary>Query to delete documents from a table</summary>
|
||||||
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
|
/// <param name="tableName">The table in which documents should be deleted (may include schema)</param>
|
||||||
/// <returns>A query to delete documents</returns>
|
/// <returns>A query to delete documents</returns>
|
||||||
/// <remarks>This query has no <tt>WHERE</tt> clause</remarks>
|
/// <remarks>This query has no <c>WHERE</c> clause</remarks>
|
||||||
[<CompiledName "Delete">]
|
[<CompiledName "Delete">]
|
||||||
let delete tableName =
|
let delete tableName =
|
||||||
$"DELETE FROM %s{tableName}"
|
$"DELETE FROM %s{tableName}"
|
||||||
|
|
||||||
/// <summary>Create a SELECT clause to retrieve the document data from the given table</summary>
|
/// <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>
|
/// <param name="tableName">The table from which documents should be found (may include schema)</param>
|
||||||
/// <returns>A query to retrieve documents</returns>
|
/// <returns>A query to retrieve documents</returns>
|
||||||
@ -603,11 +603,11 @@ module Query =
|
|||||||
[<System.Obsolete "Use Find instead">]
|
[<System.Obsolete "Use Find instead">]
|
||||||
let selectFromTable tableName =
|
let selectFromTable tableName =
|
||||||
find tableName
|
find tableName
|
||||||
|
|
||||||
/// <summary>Create an <tt>ORDER BY</tt> clause for the given fields</summary>
|
/// <summary>Create an <c>ORDER BY</c> clause for the given fields</summary>
|
||||||
/// <param name="fields">One or more fields by which to order</param>
|
/// <param name="fields">One or more fields by which to order</param>
|
||||||
/// <param name="dialect">The SQL dialect for the generated clause</param>
|
/// <param name="dialect">The SQL dialect for the generated clause</param>
|
||||||
/// <returns>An <tt>ORDER BY</tt> clause for the given fields</returns>
|
/// <returns>An <c>ORDER BY</c> 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 ""
|
||||||
|
@ -16,7 +16,7 @@ internal class TestSerializer : IDocumentSerializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// C# Tests for common functionality in <tt>BitBadger.Documents</tt>
|
/// C# Tests for common functionality in <c>BitBadger.Documents</c>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class CommonCSharpTests
|
public static class CommonCSharpTests
|
||||||
{
|
{
|
||||||
@ -417,7 +417,7 @@ public static class CommonCSharpTests
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unit tests for the Configuration static class
|
/// Unit tests for the Configuration static class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -647,7 +647,7 @@ public static class CommonCSharpTests
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unit tests
|
/// Unit tests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -344,6 +344,55 @@ public static class PostgresCSharpTests
|
|||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify a JSON array begins with "[" and ends with "]"</summary>
|
||||||
|
private static void VerifyBeginEnd(string json)
|
||||||
|
{
|
||||||
|
Expect.stringStarts(json, "[", "The array should have started with `[`");
|
||||||
|
Expect.stringEnds(json, "]", "The array should have ended with `]`");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify the presence of a document by its ID</summary>
|
||||||
|
private static void VerifyDocById(string json, string docId)
|
||||||
|
{
|
||||||
|
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify the presence of a document by its ID</summary>
|
||||||
|
private static void VerifySingleById(string json, string docId)
|
||||||
|
{
|
||||||
|
VerifyBeginEnd(json);
|
||||||
|
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify the presence of any of the given document IDs in the given JSON</summary>
|
||||||
|
private static void VerifyAnyById(string json, IEnumerable<string> docIds)
|
||||||
|
{
|
||||||
|
var theIds = docIds.ToList();
|
||||||
|
if (theIds.Any(it => json.Contains($"{{\"Id\": \"{it}\""))) return;
|
||||||
|
var ids = string.Join(", ", theIds);
|
||||||
|
Expect.isTrue(false, $"Could not find any of IDs {ids} in {json}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify the JSON for `all` returning data</summary>
|
||||||
|
private static void VerifyAllData(string json)
|
||||||
|
{
|
||||||
|
VerifyBeginEnd(json);
|
||||||
|
IEnumerable<string> ids = ["one", "two", "three", "four", "five"];
|
||||||
|
foreach (var docId in ids) VerifyDocById(json, docId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify an empty JSON array</summary>
|
||||||
|
private static void VerifyEmpty(string json)
|
||||||
|
{
|
||||||
|
Expect.equal(json, "[]", "There should be no documents returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verify an empty JSON document</summary>
|
||||||
|
private static void VerifyNoDoc(string json)
|
||||||
|
{
|
||||||
|
Expect.equal(json, "{}", "There should be no document returned");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integration tests for the Configuration module of the PostgreSQL library
|
/// Integration tests for the Configuration module of the PostgreSQL library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1291,55 +1340,6 @@ public static class PostgresCSharpTests
|
|||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// <summary>Verify a JSON array begins with "[" and ends with "]"</summary>
|
|
||||||
private static void VerifyBeginEnd(string json)
|
|
||||||
{
|
|
||||||
Expect.stringStarts(json, "[", "The array should have started with `[`");
|
|
||||||
Expect.stringEnds(json, "]", "The array should have ended with `]`");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify the presence of a document by its ID</summary>
|
|
||||||
private static void VerifyDocById(string json, string docId)
|
|
||||||
{
|
|
||||||
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify the presence of a document by its ID</summary>
|
|
||||||
private static void VerifySingleById(string json, string docId)
|
|
||||||
{
|
|
||||||
VerifyBeginEnd(json);
|
|
||||||
Expect.stringContains(json, $"{{\"Id\": \"{docId}\",", $"Document `{docId}` not present");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify the presence of any of the given document IDs in the given JSON</summary>
|
|
||||||
private static void VerifyAnyById(string json, IEnumerable<string> docIds)
|
|
||||||
{
|
|
||||||
var theIds = docIds.ToList();
|
|
||||||
if (theIds.Any(it => json.Contains($"{{\"Id\": \"{it}\""))) return;
|
|
||||||
var ids = string.Join(", ", theIds);
|
|
||||||
Expect.isTrue(false, $"Could not find any of IDs {ids} in {json}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify the JSON for `all` returning data</summary>
|
|
||||||
private static void VerifyAllData(string json)
|
|
||||||
{
|
|
||||||
VerifyBeginEnd(json);
|
|
||||||
IEnumerable<string> ids = ["one", "two", "three", "four", "five"];
|
|
||||||
foreach (var docId in ids) VerifyDocById(json, docId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify an empty JSON array</summary>
|
|
||||||
private static void VerifyEmpty(string json)
|
|
||||||
{
|
|
||||||
Expect.equal(json, "[]", "There should be no documents returned");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify an empty JSON document</summary>
|
|
||||||
private static void VerifyNoDoc(string json)
|
|
||||||
{
|
|
||||||
Expect.equal(json, "{}", "There should be no document returned");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Verify the JSON for an ordered query</summary>
|
/// <summary>Verify the JSON for an ordered query</summary>
|
||||||
private static void VerifyExpectedOrder(string json, string idFirst, string idSecond, string? idThird = null,
|
private static void VerifyExpectedOrder(string json, string idFirst, string idSecond, string? idThird = null,
|
||||||
string? idFourth = null, string? idFifth = null)
|
string? idFourth = null, string? idFifth = null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user