Add *Ordered functions

- WIP on PostgreSQL numeric ordering
This commit is contained in:
Daniel J. Summers 2024-08-14 22:13:46 -04:00
parent edd4d006da
commit bac3bd2ef0
13 changed files with 536 additions and 7 deletions

View File

@ -105,6 +105,10 @@ type Field = {
else $"->>'{name}'" else $"->>'{name}'"
$"data{path}" $"data{path}"
/// Create a field with a given name, but no other properties filled (op will be EQ, value will be "")
static member Named name =
{ Name = name; Op = EQ; Value = ""; ParameterName = None; Qualifier = None }
/// Specify the name of the parameter for this field /// Specify the name of the parameter for this field
member this.WithParameterName name = member this.WithParameterName name =
{ this with ParameterName = Some name } { this with ParameterName = Some name }
@ -300,7 +304,10 @@ module Query =
else else
fields fields
|> Seq.map (fun it -> |> Seq.map (fun it ->
let direction = if it.Name.Contains ' ' then $" {(it.Name.Split ' ')[1]}" else "" if it.Name.Contains ' ' then
it.Path dialect + direction) let parts = it.Name.Split ' '
{ it with Name = parts[0] }, Some $" {parts[1]}"
else it, None)
|> Seq.map (fun (field, direction) -> field.Path dialect + defaultArg direction "")
|> String.concat ", " |> String.concat ", "
|> function it -> $" ORDER BY {it}" |> function it -> $" ORDER BY {it}"

View File

@ -92,6 +92,10 @@ module Extensions =
member conn.findAll<'TDoc> tableName = member conn.findAll<'TDoc> tableName =
WithProps.Find.all<'TDoc> tableName (Sql.existingConnection conn) WithProps.Find.all<'TDoc> tableName (Sql.existingConnection conn)
/// Retrieve all documents in the given table ordered by the given fields in the document
member conn.findAllOrdered<'TDoc> tableName orderFields =
WithProps.Find.allOrdered<'TDoc> tableName orderFields (Sql.existingConnection conn)
/// Retrieve a document by its ID; returns None if not found /// Retrieve a document by its ID; returns None if not found
member conn.findById<'TKey, 'TDoc> tableName docId = member conn.findById<'TKey, 'TDoc> tableName docId =
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn) WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn)
@ -100,6 +104,12 @@ module Extensions =
member conn.findByFields<'TDoc> tableName howMatched fields = member conn.findByFields<'TDoc> tableName howMatched fields =
WithProps.Find.byFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn) WithProps.Find.byFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) ordered by the given fields in the
/// document
member conn.findByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithProps.Find.byFieldsOrdered<'TDoc>
tableName howMatched queryFields orderFields (Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
[<System.Obsolete "Use findByFields instead; will be removed in v4">] [<System.Obsolete "Use findByFields instead; will be removed in v4">]
member conn.findByField<'TDoc> tableName field = member conn.findByField<'TDoc> tableName field =
@ -109,14 +119,28 @@ module Extensions =
member conn.findByContains<'TDoc> tableName (criteria: obj) = member conn.findByContains<'TDoc> tableName (criteria: obj) =
WithProps.Find.byContains<'TDoc> tableName criteria (Sql.existingConnection conn) WithProps.Find.byContains<'TDoc> tableName criteria (Sql.existingConnection conn)
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
member conn.findByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
WithProps.Find.byContainsOrdered<'TDoc> tableName criteria orderFields (Sql.existingConnection conn)
/// Retrieve documents matching a JSON Path match query (@?) /// Retrieve documents matching a JSON Path match query (@?)
member conn.findByJsonPath<'TDoc> tableName jsonPath = member conn.findByJsonPath<'TDoc> tableName jsonPath =
WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn) WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
member conn.findByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
WithProps.Find.byJsonPathOrdered<'TDoc> tableName jsonPath orderFields (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
member conn.findFirstByFields<'TDoc> tableName howMatched fields = member conn.findFirstByFields<'TDoc> tableName howMatched fields =
WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn) WithProps.Find.firstByFields<'TDoc> tableName howMatched fields (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =) ordered by the given fields in
/// the document; returns None if not found
member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithProps.Find.firstByFieldsOrdered<'TDoc>
tableName howMatched queryFields orderFields (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
[<System.Obsolete "Use findFirstByFields instead; will be removed in v4">] [<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
member conn.findFirstByField<'TDoc> tableName field = member conn.findFirstByField<'TDoc> tableName field =
@ -126,10 +150,20 @@ module Extensions =
member conn.findFirstByContains<'TDoc> tableName (criteria: obj) = member conn.findFirstByContains<'TDoc> tableName (criteria: obj) =
WithProps.Find.firstByContains<'TDoc> tableName criteria (Sql.existingConnection conn) WithProps.Find.firstByContains<'TDoc> tableName criteria (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
/// document; returns None if not found
member conn.findFirstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
WithProps.Find.firstByContainsOrdered<'TDoc> tableName criteria orderFields (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON Path match query (@?); returns None if not found /// Retrieve the first document matching a JSON Path match query (@?); returns None if not found
member conn.findFirstByJsonPath<'TDoc> tableName jsonPath = member conn.findFirstByJsonPath<'TDoc> tableName jsonPath =
WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn) WithProps.Find.firstByJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document; returns None if not found
member conn.findFirstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
WithProps.Find.firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields (Sql.existingConnection conn)
/// Update an entire document by its ID /// Update an entire document by its ID
member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) = member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
WithProps.Update.byId tableName docId document (Sql.existingConnection conn) WithProps.Update.byId tableName docId document (Sql.existingConnection conn)
@ -310,6 +344,11 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindAll<'TDoc>(conn, tableName) = static member inline FindAll<'TDoc>(conn, tableName) =
WithProps.Find.All<'TDoc>(tableName, Sql.existingConnection conn) WithProps.Find.All<'TDoc>(tableName, Sql.existingConnection conn)
/// Retrieve all documents in the given table ordered by the given fields in the document
[<Extension>]
static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
WithProps.Find.AllOrdered<'TDoc>(tableName, orderFields, Sql.existingConnection conn)
/// Retrieve a document by its ID; returns None if not found /// Retrieve a document by its ID; returns None if not found
[<Extension>] [<Extension>]
static member inline FindById<'TKey, 'TDoc when 'TDoc: null>(conn, tableName, docId: 'TKey) = static member inline FindById<'TKey, 'TDoc when 'TDoc: null>(conn, tableName, docId: 'TKey) =
@ -320,6 +359,12 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) = static member inline FindByFields<'TDoc>(conn, tableName, howMatched, fields) =
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn) WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) ordered by the given fields in the document
[<Extension>]
static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
WithProps.Find.ByFieldsOrdered<'TDoc>(
tableName, howMatched, queryFields, orderFields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON field comparison query (->> =) /// Retrieve documents matching a JSON field comparison query (->> =)
[<Extension>] [<Extension>]
[<System.Obsolete "Use FindByFields instead; will be removed in v4">] [<System.Obsolete "Use FindByFields instead; will be removed in v4">]
@ -331,16 +376,34 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindByContains<'TDoc>(conn, tableName, criteria: obj) = static member inline FindByContains<'TDoc>(conn, tableName, criteria: obj) =
WithProps.Find.ByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn) WithProps.Find.ByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn)
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
[<Extension>]
static member inline FindByContainsOrdered<'TDoc>(conn, tableName, criteria: obj, orderFields) =
WithProps.Find.ByContainsOrdered<'TDoc>(tableName, criteria, orderFields, Sql.existingConnection conn)
/// Retrieve documents matching a JSON Path match query (@?) /// Retrieve documents matching a JSON Path match query (@?)
[<Extension>] [<Extension>]
static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) = static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) =
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn) WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
[<Extension>]
static member inline FindByJsonPathOrdered<'TDoc>(conn, tableName, jsonPath, orderFields) =
WithProps.Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, Sql.existingConnection conn)
/// 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>]
static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) = static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) =
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn) WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON field comparison query (->> =) ordered by the given fields in the
/// document; returns null if not found
[<Extension>]
static member inline FindFirstByFieldsOrdered<'TDoc when 'TDoc: null>(
conn, tableName, howMatched, queryFields, orderFields) =
WithProps.Find.FirstByFieldsOrdered<'TDoc>(
tableName, howMatched, queryFields, orderFields, Sql.existingConnection conn)
/// 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">] [<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">]
@ -352,11 +415,24 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindFirstByContains<'TDoc when 'TDoc: null>(conn, tableName, criteria: obj) = static member inline FindFirstByContains<'TDoc when 'TDoc: null>(conn, tableName, criteria: obj) =
WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn) WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the document;
/// returns None if not found
[<Extension>]
static member inline FindFirstByContainsOrdered<'TDoc when 'TDoc: null>(
conn, tableName, criteria: obj, orderFields) =
WithProps.Find.FirstByContainsOrdered<'TDoc>(tableName, criteria, orderFields, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON Path match query (@?); returns None if not found /// Retrieve the first document matching a JSON Path match query (@?); returns None if not found
[<Extension>] [<Extension>]
static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null>(conn, tableName, jsonPath) = static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null>(conn, tableName, jsonPath) =
WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn) WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, Sql.existingConnection conn)
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the document;
/// returns None if not found
[<Extension>]
static member inline FindFirstByJsonPathOrdered<'TDoc when 'TDoc: null>(conn, tableName, jsonPath, orderFields) =
WithProps.Find.FirstByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, Sql.existingConnection conn)
/// Update an entire document by its ID /// Update an entire document by its ID
[<Extension>] [<Extension>]
static member inline UpdateById(conn, tableName, docId: 'TKey, document: 'TDoc) = static member inline UpdateById(conn, tableName, docId: 'TKey, document: 'TDoc) =

View File

@ -407,6 +407,16 @@ module WithProps =
let All<'TDoc>(tableName, sqlProps) = let All<'TDoc>(tableName, sqlProps) =
Custom.List<'TDoc>(Query.find tableName, [], fromData<'TDoc>, sqlProps) Custom.List<'TDoc>(Query.find tableName, [], fromData<'TDoc>, sqlProps)
/// Retrieve all documents in the given table ordered by the given fields in the document
[<CompiledName "FSharpAllOrdered">]
let allOrdered<'TDoc> tableName orderFields sqlProps =
Custom.list<'TDoc> (Query.find tableName + Query.orderBy orderFields PostgreSQL) [] fromData<'TDoc> sqlProps
/// Retrieve all documents in the given table ordered by the given fields in the document
let AllOrdered<'TDoc>(tableName, orderFields, sqlProps) =
Custom.List<'TDoc>(
Query.find tableName + Query.orderBy orderFields PostgreSQL, [], fromData<'TDoc>, sqlProps)
/// Retrieve a document by its ID (returns None if not found) /// Retrieve a document by its ID (returns None if not found)
[<CompiledName "FSharpById">] [<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) sqlProps = let byId<'TKey, 'TDoc> tableName (docId: 'TKey) sqlProps =
@ -434,6 +444,23 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve documents matching JSON field comparisons (->> =) ordered by the given fields in the document
[<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
/// Retrieve documents matching JSON field comparisons (->> =) ordered by the given fields in the document
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)
/// Retrieve documents matching a JSON containment query (@>) /// Retrieve documents matching a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
let byContains<'TDoc> tableName (criteria: obj) sqlProps = let byContains<'TDoc> tableName (criteria: obj) sqlProps =
@ -448,6 +475,23 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
[<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
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
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)
/// Retrieve documents matching a JSON Path match query (@?) /// Retrieve documents matching a JSON Path match query (@?)
[<CompiledName "FSharpByJsonPath">] [<CompiledName "FSharpByJsonPath">]
let byJsonPath<'TDoc> tableName jsonPath sqlProps = let byJsonPath<'TDoc> tableName jsonPath sqlProps =
@ -462,6 +506,23 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
[<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
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
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)
/// Retrieve the first document matching JSON field comparisons (->> =); returns None if not found /// Retrieve the first document matching JSON field comparisons (->> =); returns None if not found
[<CompiledName "FSharpFirstByFields">] [<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields sqlProps = let firstByFields<'TDoc> tableName howMatched fields sqlProps =
@ -479,6 +540,25 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve the first document matching JSON field comparisons (->> =) ordered by the given fields in the
/// document; returns None if not found
[<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
/// Retrieve the first document matching JSON field comparisons (->> =) ordered by the given fields in the
/// document; returns null if not found
let FirstByFieldsOrdered<'TDoc when 'TDoc: null>(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)
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found /// Retrieve the first document matching a JSON containment query (@>); returns None if not found
[<CompiledName "FSharpFirstByContains">] [<CompiledName "FSharpFirstByContains">]
let firstByContains<'TDoc> tableName (criteria: obj) sqlProps = let firstByContains<'TDoc> tableName (criteria: obj) sqlProps =
@ -496,6 +576,25 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
/// document; returns None if not found
[<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
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the
/// document; returns null if not found
let FirstByContainsOrdered<'TDoc when 'TDoc: null>(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)
/// Retrieve the first document matching a JSON Path match query (@?); returns None if not found /// Retrieve the first document matching a JSON Path match query (@?); returns None if not found
[<CompiledName "FSharpFirstByJsonPath">] [<CompiledName "FSharpFirstByJsonPath">]
let firstByJsonPath<'TDoc> tableName jsonPath sqlProps = let firstByJsonPath<'TDoc> tableName jsonPath sqlProps =
@ -513,6 +612,25 @@ module WithProps =
fromData<'TDoc>, fromData<'TDoc>,
sqlProps) sqlProps)
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document; returns None if not found
[<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
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the
/// document; returns null if not found
let FirstByJsonPathOrdered<'TDoc when 'TDoc: null>(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)
/// Commands to update documents /// Commands to update documents
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module Update = module Update =
@ -761,6 +879,15 @@ module Find =
let All<'TDoc> tableName = let All<'TDoc> tableName =
WithProps.Find.All<'TDoc>(tableName, fromDataSource ()) WithProps.Find.All<'TDoc>(tableName, fromDataSource ())
/// Retrieve all documents in the given table ordered by the given fields in the document
[<CompiledName "FSharpAllOrdered">]
let allOrdered<'TDoc> tableName orderFields =
WithProps.Find.allOrdered<'TDoc> tableName orderFields (fromDataSource ())
/// Retrieve all documents in the given table ordered by the given fields in the document
let AllOrdered<'TDoc> tableName orderFields =
WithProps.Find.AllOrdered<'TDoc>(tableName, orderFields, fromDataSource ())
/// Retrieve a document by its ID; returns None if not found /// Retrieve a document by its ID; returns None if not found
[<CompiledName "FSharpById">] [<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName docId = let byId<'TKey, 'TDoc> tableName docId =
@ -779,6 +906,15 @@ module Find =
let ByFields<'TDoc>(tableName, howMatched, fields) = let ByFields<'TDoc>(tableName, howMatched, fields) =
WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ()) WithProps.Find.ByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
/// Retrieve documents matching a JSON field comparison query (->> =) ordered by the given fields in the document
[<CompiledName "FSharpByFieldsOrdered">]
let byFieldsOrdered<'TDoc> tableName howMatched queryField orderFields =
WithProps.Find.byFieldsOrdered<'TDoc> tableName howMatched queryField orderFields (fromDataSource ())
/// Retrieve documents matching a JSON field comparison query (->> =) ordered by the given fields in the document
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields) =
WithProps.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
/// Retrieve documents matching a JSON containment query (@>) /// Retrieve documents matching a JSON containment query (@>)
[<CompiledName "FSharpByContains">] [<CompiledName "FSharpByContains">]
let byContains<'TDoc> tableName (criteria: obj) = let byContains<'TDoc> tableName (criteria: obj) =
@ -788,6 +924,15 @@ module Find =
let ByContains<'TDoc>(tableName, criteria: obj) = let ByContains<'TDoc>(tableName, criteria: obj) =
WithProps.Find.ByContains<'TDoc>(tableName, criteria, fromDataSource ()) WithProps.Find.ByContains<'TDoc>(tableName, criteria, fromDataSource ())
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
[<CompiledName "FSharpByContainsOrdered">]
let byContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
WithProps.Find.byContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
/// Retrieve documents matching a JSON containment query (@>) ordered by the given fields in the document
let ByContainsOrdered<'TDoc>(tableName, criteria: obj, orderFields) =
WithProps.Find.ByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
/// Retrieve documents matching a JSON Path match query (@?) /// Retrieve documents matching a JSON Path match query (@?)
[<CompiledName "FSharpByJsonPath">] [<CompiledName "FSharpByJsonPath">]
let byJsonPath<'TDoc> tableName jsonPath = let byJsonPath<'TDoc> tableName jsonPath =
@ -797,6 +942,15 @@ module Find =
let ByJsonPath<'TDoc>(tableName, jsonPath) = let ByJsonPath<'TDoc>(tableName, jsonPath) =
WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ()) WithProps.Find.ByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
[<CompiledName "FSharpByJsonPathOrdered">]
let byJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
WithProps.Find.byJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
/// Retrieve documents matching a JSON Path match query (@?) ordered by the given fields in the document
let ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields) =
WithProps.Find.ByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
[<CompiledName "FSharpFirstByFields">] [<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields = let firstByFields<'TDoc> tableName howMatched fields =
@ -806,6 +960,17 @@ module Find =
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields) = let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields) =
WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ()) WithProps.Find.FirstByFields<'TDoc>(tableName, howMatched, fields, fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =) ordered by the given fields in the
/// document; returns None if not found
[<CompiledName "FSharpFirstByFieldsOrdered">]
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithProps.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields (fromDataSource ())
/// Retrieve the first document matching a JSON field comparison query (->> =) ordered by the given fields in the
/// document; returns null if not found
let FirstByFieldsOrdered<'TDoc when 'TDoc: null>(tableName, howMatched, queryFields, orderFields) =
WithProps.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, fromDataSource ())
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found /// Retrieve the first document matching a JSON containment query (@>); returns None if not found
[<CompiledName "FSharpFirstByContains">] [<CompiledName "FSharpFirstByContains">]
let firstByContains<'TDoc> tableName (criteria: obj) = let firstByContains<'TDoc> tableName (criteria: obj) =
@ -815,6 +980,17 @@ module Find =
let FirstByContains<'TDoc when 'TDoc: null>(tableName, criteria: obj) = let FirstByContains<'TDoc when 'TDoc: null>(tableName, criteria: obj) =
WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, fromDataSource ()) WithProps.Find.FirstByContains<'TDoc>(tableName, criteria, fromDataSource ())
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the document;
/// returns None if not found
[<CompiledName "FSharpFirstByContainsOrdered">]
let firstByContainsOrdered<'TDoc> tableName (criteria: obj) orderFields =
WithProps.Find.firstByContainsOrdered<'TDoc> tableName criteria orderFields (fromDataSource ())
/// Retrieve the first document matching a JSON containment query (@>) ordered by the given fields in the document;
/// returns null if not found
let FirstByContainsOrdered<'TDoc when 'TDoc: null>(tableName, criteria: obj, orderFields) =
WithProps.Find.FirstByContainsOrdered<'TDoc>(tableName, criteria, orderFields, fromDataSource ())
/// Retrieve the first document matching a JSON Path match query (@?); returns None if not found /// Retrieve the first document matching a JSON Path match query (@?); returns None if not found
[<CompiledName "FSharpFirstByJsonPath">] [<CompiledName "FSharpFirstByJsonPath">]
let firstByJsonPath<'TDoc> tableName jsonPath = let firstByJsonPath<'TDoc> tableName jsonPath =
@ -824,6 +1000,17 @@ module Find =
let FirstByJsonPath<'TDoc when 'TDoc: null>(tableName, jsonPath) = let FirstByJsonPath<'TDoc when 'TDoc: null>(tableName, jsonPath) =
WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ()) WithProps.Find.FirstByJsonPath<'TDoc>(tableName, jsonPath, fromDataSource ())
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the document;
/// returns None if not found
[<CompiledName "FSharpFirstByJsonPathOrdered">]
let firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields =
WithProps.Find.firstByJsonPathOrdered<'TDoc> tableName jsonPath orderFields (fromDataSource ())
/// Retrieve the first document matching a JSON Path match query (@?) ordered by the given fields in the document;
/// returns null if not found
let FirstByJsonPathOrdered<'TDoc when 'TDoc: null>(tableName, jsonPath, orderFields) =
WithProps.Find.FirstByJsonPathOrdered<'TDoc>(tableName, jsonPath, orderFields, fromDataSource ())
/// Commands to update documents /// Commands to update documents
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]

View File

@ -71,6 +71,10 @@ module Extensions =
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
member conn.findAllOrdered<'TDoc> tableName orderFields =
WithConn.Find.allOrdered<'TDoc> tableName orderFields conn
/// Retrieve a document by its ID /// Retrieve a document by its ID
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
@ -79,6 +83,10 @@ module Extensions =
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
member conn.findByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithConn.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
/// Retrieve documents via a comparison on a JSON field /// Retrieve documents via a comparison on a JSON field
[<System.Obsolete "Use findByFields instead; will be removed in v4">] [<System.Obsolete "Use findByFields instead; will be removed in v4">]
member conn.findByField<'TDoc> tableName field = member conn.findByField<'TDoc> tableName field =
@ -88,6 +96,11 @@ module Extensions =
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
/// only the first result
member conn.findFirstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
WithConn.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
/// Retrieve documents via a comparison on a JSON field, returning only the first result /// Retrieve documents via a comparison on a JSON field, returning only the first result
[<System.Obsolete "Use findFirstByFields instead; will be removed in v4">] [<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
member conn.findFirstByField<'TDoc> tableName field = member conn.findFirstByField<'TDoc> tableName field =
@ -225,6 +238,11 @@ type SqliteConnectionCSharpExtensions =
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
[<Extension>]
static member inline FindAllOrdered<'TDoc>(conn, tableName, orderFields) =
WithConn.Find.AllOrdered<'TDoc>(tableName, conn, orderFields)
/// Retrieve a document by its ID /// Retrieve a document by its ID
[<Extension>] [<Extension>]
static member inline FindById<'TKey, 'TDoc when 'TDoc: null>(conn, tableName, docId: 'TKey) = static member inline FindById<'TKey, 'TDoc when 'TDoc: null>(conn, tableName, docId: 'TKey) =
@ -235,6 +253,11 @@ type SqliteConnectionCSharpExtensions =
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
[<Extension>]
static member inline FindByFieldsOrdered<'TDoc>(conn, tableName, howMatched, queryFields, orderFields) =
WithConn.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
/// Retrieve documents via a comparison on a JSON field /// Retrieve documents via a comparison on a JSON field
[<Extension>] [<Extension>]
[<System.Obsolete "Use FindByFields instead; will be removed in v4">] [<System.Obsolete "Use FindByFields instead; will be removed in v4">]
@ -246,6 +269,13 @@ type SqliteConnectionCSharpExtensions =
static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) = static member inline FindFirstByFields<'TDoc when 'TDoc: null>(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
/// the first result
[<Extension>]
static member inline FindFirstByFieldsOrdered<'TDoc when 'TDoc: null>(
conn, tableName, howMatched, queryFields, orderFields) =
WithConn.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
/// Retrieve documents via a comparison on a JSON field, returning only the first result /// Retrieve documents via a comparison on a JSON field, returning only the first result
[<Extension>] [<Extension>]
[<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">] [<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">]

View File

@ -314,6 +314,15 @@ module WithConn =
let All<'TDoc>(tableName, conn) = let All<'TDoc>(tableName, conn) =
Custom.List(Query.find tableName, [], fromData<'TDoc>, conn) Custom.List(Query.find tableName, [], fromData<'TDoc>, conn)
/// Retrieve all documents in the given table ordered by the given fields in the document
[<CompiledName "FSharpAllOrdered">]
let allOrdered<'TDoc> tableName orderFields conn =
Custom.list<'TDoc> (Query.find tableName + Query.orderBy orderFields SQLite) [] fromData<'TDoc> conn
/// Retrieve all documents in the given table ordered by the given fields in the document
let AllOrdered<'TDoc>(tableName, orderFields, conn) =
Custom.List(Query.find tableName + Query.orderBy orderFields PostgreSQL, [], fromData<'TDoc>, conn)
/// Retrieve a document by its ID (returns None if not found) /// Retrieve a document by its ID (returns None if not found)
[<CompiledName "FSharpById">] [<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) conn = let byId<'TKey, 'TDoc> tableName (docId: 'TKey) conn =
@ -340,6 +349,23 @@ module WithConn =
fromData<'TDoc>, fromData<'TDoc>,
conn) conn)
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document
[<CompiledName "FSharpByFieldsOrdered">]
let byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn =
Custom.list<'TDoc>
(Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite)
(addFieldParams queryFields [])
fromData<'TDoc>
conn
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn) =
Custom.List<'TDoc>(
Query.byFields (Query.find tableName) howMatched queryFields + Query.orderBy orderFields SQLite,
addFieldParams queryFields [],
fromData<'TDoc>,
conn)
/// Retrieve documents via a comparison on JSON fields, returning only the first result /// Retrieve documents via a comparison on JSON fields, returning only the first result
[<CompiledName "FSharpFirstByFields">] [<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields conn = let firstByFields<'TDoc> tableName howMatched fields conn =
@ -357,6 +383,25 @@ module WithConn =
fromData<'TDoc>, fromData<'TDoc>,
conn) conn)
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document, returning
/// only the first result
[<CompiledName "FSharpFirstByFieldsOrdered">]
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn =
Custom.single
$"{Query.byFields (Query.find tableName) howMatched queryFields}{Query.orderBy orderFields SQLite} LIMIT 1"
(addFieldParams queryFields [])
fromData<'TDoc>
conn
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document, returning
/// only the first result
let FirstByFieldsOrdered<'TDoc when 'TDoc: null>(tableName, howMatched, queryFields, orderFields, conn) =
Custom.Single(
$"{Query.byFields (Query.find tableName) howMatched queryFields}{Query.orderBy orderFields SQLite} LIMIT 1",
addFieldParams queryFields [],
fromData<'TDoc>,
conn)
/// Commands to update documents /// Commands to update documents
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module Update = module Update =
@ -560,6 +605,17 @@ module Find =
use conn = Configuration.dbConn () use conn = Configuration.dbConn ()
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
[<CompiledName "FSharpAllOrdered">]
let allOrdered<'TDoc> tableName orderFields =
use conn = Configuration.dbConn ()
WithConn.Find.allOrdered<'TDoc> tableName orderFields conn
/// Retrieve all documents in the given table ordered by the given fields in the document
let AllOrdered<'TDoc> tableName orderFields =
use conn = Configuration.dbConn ()
WithConn.Find.AllOrdered<'TDoc>(tableName, orderFields, conn)
/// Retrieve a document by its ID (returns None if not found) /// Retrieve a document by its ID (returns None if not found)
[<CompiledName "FSharpById">] [<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName docId = let byId<'TKey, 'TDoc> tableName docId =
@ -582,6 +638,17 @@ module Find =
use conn = Configuration.dbConn () use conn = Configuration.dbConn ()
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
[<CompiledName "FSharpByFieldsOrdered">]
let byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
use conn = Configuration.dbConn ()
WithConn.Find.byFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document
let ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields) =
use conn = Configuration.dbConn ()
WithConn.Find.ByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
/// Retrieve documents via a comparison on JSON fields, returning only the first result /// Retrieve documents via a comparison on JSON fields, returning only the first result
[<CompiledName "FSharpFirstByFields">] [<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields = let firstByFields<'TDoc> tableName howMatched fields =
@ -593,6 +660,19 @@ module Find =
use conn = Configuration.dbConn () use conn = Configuration.dbConn ()
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
/// the first result
[<CompiledName "FSharpFirstByFieldsOrdered">]
let firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields =
use conn = Configuration.dbConn ()
WithConn.Find.firstByFieldsOrdered<'TDoc> tableName howMatched queryFields orderFields conn
/// Retrieve documents via a comparison on JSON fields ordered by the given fields in the document, returning only
/// the first result
let FirstByFieldsOrdered<'TDoc when 'TDoc: null>(tableName, howMatched, queryFields, orderFields) =
use conn = Configuration.dbConn ()
WithConn.Find.FirstByFieldsOrdered<'TDoc>(tableName, howMatched, queryFields, orderFields, conn)
/// Commands to update documents /// Commands to update documents
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]

View File

@ -174,6 +174,31 @@ public static class CommonCSharpTests
Expect.equal(field.Name, "Rad", "Field name incorrect"); Expect.equal(field.Name, "Rad", "Field name incorrect");
Expect.equal(field.Op, Op.NEX, "Operator incorrect"); Expect.equal(field.Op, Op.NEX, "Operator incorrect");
}), }),
TestList("NameToPath",
[
TestCase("succeeds for PostgreSQL and a simple name", () =>
{
Expect.equal("data->>'Simple'", Field.NameToPath("Simple", Dialect.PostgreSQL),
"Path not constructed correctly");
}),
TestCase("succeeds for SQLite and a simple name", () =>
{
Expect.equal("data->>'Simple'", Field.NameToPath("Simple", Dialect.SQLite),
"Path not constructed correctly");
}),
TestCase("succeeds for PostgreSQL and a nested name", () =>
{
Expect.equal("data#>>'{A,Long,Path,to,the,Property}'",
Field.NameToPath("A.Long.Path.to.the.Property", Dialect.PostgreSQL),
"Path not constructed correctly");
}),
TestCase("succeeds for SQLite and a nested name", () =>
{
Expect.equal("data->>'A'->>'Long'->>'Path'->>'to'->>'the'->>'Property'",
Field.NameToPath("A.Long.Path.to.the.Property", Dialect.SQLite),
"Path not constructed correctly");
})
]),
TestCase("WithParameterName succeeds", () => TestCase("WithParameterName succeeds", () =>
{ {
var field = Field.EQ("Bob", "Tom").WithParameterName("@name"); var field = Field.EQ("Bob", "Tom").WithParameterName("@name");
@ -356,7 +381,50 @@ public static class CommonCSharpTests
TestCase("Delete succeeds", () => TestCase("Delete succeeds", () =>
{ {
Expect.equal(Query.Delete("tbl"), "DELETE FROM tbl", "Delete query not correct"); Expect.equal(Query.Delete("tbl"), "DELETE FROM tbl", "Delete query not correct");
}),
TestList("OrderBy",
[
TestCase("succeeds for no fields", () =>
{
Expect.equal("", Query.OrderBy([], Dialect.PostgreSQL),
"Order By should have been blank (PostgreSQL)");
Expect.equal("", Query.OrderBy([], Dialect.SQLite), "Order By should have been blank (SQLite)");
}),
TestCase("succeeds for PostgreSQL with one field and no direction", () =>
{
Expect.equal(" ORDER BY data->>'TestField'",
Query.OrderBy([Field.Named("TestField")], Dialect.PostgreSQL),
"Order By not constructed correctly");
}),
TestCase("succeeds for SQLite with one field and no direction", () =>
{
Expect.equal(" ORDER BY data->>'TestField'",
Query.OrderBy([Field.Named("TestField")], Dialect.SQLite),
"Order By not constructed correctly");
}),
TestCase("succeeds for PostgreSQL with multiple fields and direction", () =>
{
Expect.equal(" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
Query.OrderBy(
[
Field.Named("Nested.Test.Field DESC"), Field.Named("AnotherField"),
Field.Named("It DESC")
],
Dialect.PostgreSQL), "Order By not constructed correctly");
}),
TestCase("succeeds for SQLite with multiple fields and direction", () =>
{
Expect.equal(
" ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
Query.OrderBy(
[
Field.Named("Nested.Test.Field DESC"), Field.Named("AnotherField"),
Field.Named("It DESC")
],
Dialect.SQLite),
"Order By not constructed correctly");
}) })
]) ])
])
]); ]);
} }

View File

@ -41,7 +41,7 @@ public class PostgresCSharpExtensionTests
await using var conn = MkConn(db); await using var conn = MkConn(db);
await LoadDocs(); await LoadDocs();
var docs = await conn.CustomList(Query.SelectFromTable(PostgresDb.TableName), Parameters.None, var docs = await conn.CustomList(Query.Find(PostgresDb.TableName), Parameters.None,
Results.FromData<JsonDocument>); Results.FromData<JsonDocument>);
Expect.equal(docs.Count, 5, "There should have been 5 documents returned"); Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
}), }),

View File

@ -400,7 +400,7 @@ public static class PostgresCSharpTests
await using var db = PostgresDb.BuildDb(); await using var db = PostgresDb.BuildDb();
await LoadDocs(); await LoadDocs();
var docs = await Custom.List(Query.SelectFromTable(PostgresDb.TableName), Parameters.None, var docs = await Custom.List(Query.Find(PostgresDb.TableName), Parameters.None,
Results.FromData<JsonDocument>); Results.FromData<JsonDocument>);
Expect.equal(docs.Count, 5, "There should have been 5 documents returned"); Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
}), }),

View File

@ -52,7 +52,7 @@ public static class SqliteCSharpExtensionTests
await using var conn = Sqlite.Configuration.DbConn(); await using var conn = Sqlite.Configuration.DbConn();
await LoadDocs(); await LoadDocs();
var docs = await conn.CustomList(Query.SelectFromTable(SqliteDb.TableName), Parameters.None, var docs = await conn.CustomList(Query.Find(SqliteDb.TableName), Parameters.None,
Results.FromData<JsonDocument>); Results.FromData<JsonDocument>);
Expect.equal(docs.Count, 5, "There should have been 5 documents returned"); Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
}), }),

View File

@ -194,7 +194,7 @@ public static class SqliteCSharpTests
await using var db = await SqliteDb.BuildDb(); await using var db = await SqliteDb.BuildDb();
await LoadDocs(); await LoadDocs();
var docs = await Custom.List(Query.SelectFromTable(SqliteDb.TableName), Parameters.None, var docs = await Custom.List(Query.Find(SqliteDb.TableName), Parameters.None,
Results.FromData<JsonDocument>); Results.FromData<JsonDocument>);
Expect.equal(docs.Count, 5, "There should have been 5 documents returned"); Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
}), }),

View File

@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<NoWarn>1182</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -109,6 +109,28 @@ let all =
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"
} }
testList "NameToPath" [
test "succeeds for PostgreSQL and a simple name" {
Expect.equal
"data->>'Simple'" (Field.NameToPath "Simple" PostgreSQL) "Path not constructed correctly"
}
test "succeeds for SQLite and a simple name" {
Expect.equal
"data->>'Simple'" (Field.NameToPath "Simple" SQLite) "Path not constructed correctly"
}
test "succeeds for PostgreSQL and a nested name" {
Expect.equal
"data#>>'{A,Long,Path,to,the,Property}'"
(Field.NameToPath "A.Long.Path.to.the.Property" PostgreSQL)
"Path not constructed correctly"
}
test "succeeds for SQLite and a nested name" {
Expect.equal
"data->>'A'->>'Long'->>'Path'->>'to'->>'the'->>'Property'"
(Field.NameToPath "A.Long.Path.to.the.Property" SQLite)
"Path not constructed correctly"
}
]
test "WithParameterName succeeds" { test "WithParameterName succeeds" {
let field = (Field.EQ "Bob" "Tom").WithParameterName "@name" let field = (Field.EQ "Bob" "Tom").WithParameterName "@name"
Expect.isSome field.ParameterName "The parameter name should have been filled" Expect.isSome field.ParameterName "The parameter name should have been filled"
@ -253,5 +275,39 @@ let all =
test "delete succeeds" { test "delete succeeds" {
Expect.equal (Query.delete tbl) $"DELETE FROM {tbl}" "Delete query not correct" Expect.equal (Query.delete tbl) $"DELETE FROM {tbl}" "Delete query not correct"
} }
testList "orderBy" [
test "succeeds for no fields" {
Expect.equal "" (Query.orderBy [] PostgreSQL) "Order By should have been blank (PostgreSQL)"
Expect.equal "" (Query.orderBy [] SQLite) "Order By should have been blank (SQLite)"
}
test "succeeds for PostgreSQL with one field and no direction" {
Expect.equal
" ORDER BY data->>'TestField'"
(Query.orderBy [ Field.Named "TestField" ] PostgreSQL)
"Order By not constructed correctly"
}
test "succeeds for SQLite with one field and no direction" {
Expect.equal
" ORDER BY data->>'TestField'"
(Query.orderBy [ Field.Named "TestField" ] SQLite)
"Order By not constructed correctly"
}
test "succeeds for PostgreSQL with multiple fields and direction" {
Expect.equal
" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC"
(Query.orderBy
[ Field.Named "Nested.Test.Field DESC"; Field.Named "AnotherField"; Field.Named "It DESC" ]
PostgreSQL)
"Order By not constructed correctly"
}
test "succeeds for SQLite with multiple fields and direction" {
Expect.equal
" ORDER BY data->>'Nested'->>'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC"
(Query.orderBy
[ Field.Named "Nested.Test.Field DESC"; Field.Named "AnotherField"; Field.Named "It DESC" ]
SQLite)
"Order By not constructed correctly"
}
]
] ]
] ]

View File

@ -602,6 +602,30 @@ let integrationTests =
Expect.equal results [] "There should have been no documents returned" Expect.equal results [] "There should have been no documents returned"
} }
] ]
testList "allOrdered" [
ptestTask "succeeds when ordering numerically" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> PostgresDb.TableName [ Field.EQ "NumValue" 0 ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
(results |> List.map _.Id |> String.concat "|")
"one|three|two|four|five"
"The documents were not ordered correctly"
}
testTask "succeeds when ordering alphabetically" {
use db = PostgresDb.BuildDb()
do! loadDocs ()
let! results = Find.allOrdered<JsonDocument> PostgresDb.TableName [ Field.Named "Id DESC" ]
Expect.hasLength results 5 "There should have been 5 documents returned"
Expect.equal
(results |> List.map _.Id |> String.concat "|")
"two|three|one|four|five"
"The documents were not ordered correctly"
}
]
testList "byId" [ testList "byId" [
testTask "succeeds when a document is found" { testTask "succeeds when a document is found" {
use db = PostgresDb.BuildDb() use db = PostgresDb.BuildDb()