Version 4 #6

Merged
danieljsummers merged 30 commits from version-four into main 2024-08-19 23:30:39 +00:00
13 changed files with 536 additions and 7 deletions
Showing only changes of commit bac3bd2ef0 - Show all commits

View File

@ -105,6 +105,10 @@ type Field = {
else $"->>'{name}'"
$"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
member this.WithParameterName name =
{ this with ParameterName = Some name }
@ -300,7 +304,10 @@ module Query =
else
fields
|> Seq.map (fun it ->
let direction = if it.Name.Contains ' ' then $" {(it.Name.Split ' ')[1]}" else ""
it.Path dialect + direction)
if it.Name.Contains ' ' then
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 ", "
|> function it -> $" ORDER BY {it}"

View File

@ -92,6 +92,10 @@ module Extensions =
member conn.findAll<'TDoc> tableName =
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
member conn.findById<'TKey, 'TDoc> tableName docId =
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn)
@ -100,6 +104,12 @@ module Extensions =
member conn.findByFields<'TDoc> tableName howMatched fields =
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 (->> =)
[<System.Obsolete "Use findByFields instead; will be removed in v4">]
member conn.findByField<'TDoc> tableName field =
@ -109,14 +119,28 @@ module Extensions =
member conn.findByContains<'TDoc> tableName (criteria: obj) =
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 (@?)
member conn.findByJsonPath<'TDoc> tableName jsonPath =
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
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
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
[<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
member conn.findFirstByField<'TDoc> tableName field =
@ -126,10 +150,20 @@ module Extensions =
member conn.findFirstByContains<'TDoc> tableName (criteria: obj) =
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
member conn.findFirstByJsonPath<'TDoc> tableName jsonPath =
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
member conn.updateById tableName (docId: 'TKey) (document: 'TDoc) =
WithProps.Update.byId tableName docId document (Sql.existingConnection conn)
@ -310,6 +344,11 @@ type NpgsqlConnectionCSharpExtensions =
static member inline FindAll<'TDoc>(conn, tableName) =
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
[<Extension>]
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) =
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 (->> =)
[<Extension>]
[<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) =
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 (@?)
[<Extension>]
static member inline FindByJsonPath<'TDoc>(conn, tableName, jsonPath) =
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
[<Extension>]
static member inline FindFirstByFields<'TDoc when 'TDoc: null>(conn, tableName, howMatched, fields) =
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
[<Extension>]
[<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) =
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
[<Extension>]
static member inline FindFirstByJsonPath<'TDoc when 'TDoc: null>(conn, tableName, jsonPath) =
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
[<Extension>]
static member inline UpdateById(conn, tableName, docId: 'TKey, document: 'TDoc) =

View File

@ -407,6 +407,16 @@ module WithProps =
let All<'TDoc>(tableName, 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)
[<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) sqlProps =
@ -434,6 +444,23 @@ module WithProps =
fromData<'TDoc>,
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 (@>)
[<CompiledName "FSharpByContains">]
let byContains<'TDoc> tableName (criteria: obj) sqlProps =
@ -448,6 +475,23 @@ module WithProps =
fromData<'TDoc>,
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 (@?)
[<CompiledName "FSharpByJsonPath">]
let byJsonPath<'TDoc> tableName jsonPath sqlProps =
@ -462,6 +506,23 @@ module WithProps =
fromData<'TDoc>,
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
[<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields sqlProps =
@ -479,6 +540,25 @@ module WithProps =
fromData<'TDoc>,
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
[<CompiledName "FSharpFirstByContains">]
let firstByContains<'TDoc> tableName (criteria: obj) sqlProps =
@ -496,6 +576,25 @@ module WithProps =
fromData<'TDoc>,
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
[<CompiledName "FSharpFirstByJsonPath">]
let firstByJsonPath<'TDoc> tableName jsonPath sqlProps =
@ -513,6 +612,25 @@ module WithProps =
fromData<'TDoc>,
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
[<RequireQualifiedAccess>]
module Update =
@ -761,6 +879,15 @@ module Find =
let All<'TDoc> tableName =
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
[<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName docId =
@ -779,6 +906,15 @@ module Find =
let ByFields<'TDoc>(tableName, howMatched, fields) =
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 (@>)
[<CompiledName "FSharpByContains">]
let byContains<'TDoc> tableName (criteria: obj) =
@ -788,6 +924,15 @@ module Find =
let ByContains<'TDoc>(tableName, criteria: obj) =
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 (@?)
[<CompiledName "FSharpByJsonPath">]
let byJsonPath<'TDoc> tableName jsonPath =
@ -797,6 +942,15 @@ module Find =
let ByJsonPath<'TDoc>(tableName, jsonPath) =
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
[<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields =
@ -806,6 +960,17 @@ module Find =
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields) =
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
[<CompiledName "FSharpFirstByContains">]
let firstByContains<'TDoc> tableName (criteria: obj) =
@ -815,6 +980,17 @@ module Find =
let FirstByContains<'TDoc when 'TDoc: null>(tableName, criteria: obj) =
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
[<CompiledName "FSharpFirstByJsonPath">]
let firstByJsonPath<'TDoc> tableName jsonPath =
@ -824,6 +1000,17 @@ module Find =
let FirstByJsonPath<'TDoc when 'TDoc: null>(tableName, jsonPath) =
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
[<RequireQualifiedAccess>]

View File

@ -71,6 +71,10 @@ module Extensions =
member conn.findAll<'TDoc> tableName =
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
member conn.findById<'TKey, 'TDoc> tableName (docId: 'TKey) =
WithConn.Find.byId<'TKey, 'TDoc> tableName docId conn
@ -79,6 +83,10 @@ module Extensions =
member conn.findByFields<'TDoc> tableName howMatched fields =
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
[<System.Obsolete "Use findByFields instead; will be removed in v4">]
member conn.findByField<'TDoc> tableName field =
@ -88,6 +96,11 @@ module Extensions =
member conn.findFirstByFields<'TDoc> tableName howMatched fields =
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
[<System.Obsolete "Use findFirstByFields instead; will be removed in v4">]
member conn.findFirstByField<'TDoc> tableName field =
@ -225,6 +238,11 @@ type SqliteConnectionCSharpExtensions =
static member inline FindAll<'TDoc>(conn, tableName) =
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
[<Extension>]
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) =
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
[<Extension>]
[<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) =
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
[<Extension>]
[<System.Obsolete "Use FindFirstByFields instead; will be removed in v4">]

View File

@ -314,6 +314,15 @@ module WithConn =
let All<'TDoc>(tableName, 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)
[<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) conn =
@ -340,6 +349,23 @@ module WithConn =
fromData<'TDoc>,
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
[<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields conn =
@ -357,6 +383,25 @@ module WithConn =
fromData<'TDoc>,
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
[<RequireQualifiedAccess>]
module Update =
@ -560,6 +605,17 @@ module Find =
use conn = Configuration.dbConn ()
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)
[<CompiledName "FSharpById">]
let byId<'TKey, 'TDoc> tableName docId =
@ -582,6 +638,17 @@ module Find =
use conn = Configuration.dbConn ()
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
[<CompiledName "FSharpFirstByFields">]
let firstByFields<'TDoc> tableName howMatched fields =
@ -593,6 +660,19 @@ module Find =
use conn = Configuration.dbConn ()
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
[<RequireQualifiedAccess>]

View File

@ -174,6 +174,31 @@ public static class CommonCSharpTests
Expect.equal(field.Name, "Rad", "Field name 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", () =>
{
var field = Field.EQ("Bob", "Tom").WithParameterName("@name");
@ -356,7 +381,50 @@ public static class CommonCSharpTests
TestCase("Delete succeeds", () =>
{
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 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>);
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 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>);
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 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>);
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 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>);
Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
}),

View File

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

View File

@ -109,6 +109,28 @@ let all =
Expect.isNone field.ParameterName "The default parameter name 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" {
let field = (Field.EQ "Bob" "Tom").WithParameterName "@name"
Expect.isSome field.ParameterName "The parameter name should have been filled"
@ -253,5 +275,39 @@ let all =
test "delete succeeds" {
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"
}
]
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" [
testTask "succeeds when a document is found" {
use db = PostgresDb.BuildDb()