Version 4 #6
@ -214,11 +214,6 @@ module Query =
|
||||
let statementWhere statement where =
|
||||
$"%s{statement} WHERE %s{where}"
|
||||
|
||||
/// Create a SELECT clause to retrieve the document data from the given table
|
||||
[<CompiledName "SelectFromTable">]
|
||||
let selectFromTable tableName =
|
||||
$"SELECT data FROM %s{tableName}"
|
||||
|
||||
/// Queries to define tables and indexes
|
||||
module Definition =
|
||||
|
||||
@ -263,11 +258,6 @@ module Query =
|
||||
"INSERT INTO %s VALUES (@data) ON CONFLICT ((data->>'%s')) DO UPDATE SET data = EXCLUDED.data"
|
||||
tableName (Configuration.idField ())
|
||||
|
||||
/// Query to update a document (no WHERE clause)
|
||||
[<CompiledName "Update">]
|
||||
let update tableName =
|
||||
$"UPDATE %s{tableName} SET data = @data"
|
||||
|
||||
/// Query to count documents in a table (no WHERE clause)
|
||||
[<CompiledName "Count">]
|
||||
let count tableName =
|
||||
@ -277,3 +267,24 @@ module Query =
|
||||
[<CompiledName "Exists">]
|
||||
let exists tableName where =
|
||||
$"SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE %s{where}) AS it"
|
||||
|
||||
/// Query to select documents from a table (no WHERE clause)
|
||||
[<CompiledName "Find">]
|
||||
let find tableName =
|
||||
$"SELECT data FROM %s{tableName}"
|
||||
|
||||
/// Query to update a document (no WHERE clause)
|
||||
[<CompiledName "Update">]
|
||||
let update tableName =
|
||||
$"UPDATE %s{tableName} SET data = @data"
|
||||
|
||||
/// Query to delete documents from a table (no WHERE clause)
|
||||
[<CompiledName "Delete">]
|
||||
let delete tableName =
|
||||
$"DELETE FROM %s{tableName}"
|
||||
|
||||
/// Create a SELECT clause to retrieve the document data from the given table
|
||||
[<CompiledName "SelectFromTable">]
|
||||
[<System.Obsolete "Use Find instead">]
|
||||
let selectFromTable tableName =
|
||||
find tableName
|
||||
|
@ -396,7 +396,7 @@ type NpgsqlConnectionCSharpExtensions =
|
||||
/// Remove fields from a document by the document's ID
|
||||
[<Extension>]
|
||||
static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) =
|
||||
WithProps.RemoveFields.ById(tableName, docId, fieldNames, Sql.existingConnection conn)
|
||||
WithProps.RemoveFields.byId tableName docId fieldNames (Sql.existingConnection conn)
|
||||
|
||||
/// Remove fields from documents via a comparison on JSON fields in the document
|
||||
[<Extension>]
|
||||
@ -412,12 +412,12 @@ type NpgsqlConnectionCSharpExtensions =
|
||||
/// Remove fields from documents via a JSON containment query (@>)
|
||||
[<Extension>]
|
||||
static member inline RemoveFieldsByContains(conn, tableName, criteria: 'TContains, fieldNames) =
|
||||
WithProps.RemoveFields.ByContains(tableName, criteria, fieldNames, Sql.existingConnection conn)
|
||||
WithProps.RemoveFields.byContains tableName criteria fieldNames (Sql.existingConnection conn)
|
||||
|
||||
/// Remove fields from documents via a JSON Path match query (@?)
|
||||
[<Extension>]
|
||||
static member inline RemoveFieldsByJsonPath(conn, tableName, jsonPath, fieldNames) =
|
||||
WithProps.RemoveFields.ByJsonPath(tableName, jsonPath, fieldNames, Sql.existingConnection conn)
|
||||
WithProps.RemoveFields.byJsonPath tableName jsonPath fieldNames (Sql.existingConnection conn)
|
||||
|
||||
/// Delete a document by its ID
|
||||
[<Extension>]
|
||||
|
@ -56,6 +56,7 @@ module Parameters =
|
||||
/// Create an ID parameter (name "@id", key will be treated as a string)
|
||||
[<CompiledName "Id">]
|
||||
let idParam (key: 'TKey) =
|
||||
// TODO: bind key by numeric types
|
||||
"@id", Sql.string (string key)
|
||||
|
||||
/// Create a parameter with a JSON value
|
||||
@ -170,141 +171,37 @@ module Query =
|
||||
let whereJsonPathMatches paramName =
|
||||
$"data @? %s{paramName}::jsonpath"
|
||||
|
||||
/// Create an UPDATE statement to patch documents
|
||||
[<CompiledName "Patch">]
|
||||
let patch tableName =
|
||||
$"UPDATE %s{tableName} SET data = data || @data"
|
||||
|
||||
/// Create an UPDATE statement to remove fields from documents
|
||||
[<CompiledName "RemoveFields">]
|
||||
let removeFields tableName =
|
||||
$"UPDATE %s{tableName} SET data = data - @name"
|
||||
|
||||
/// Create a query by a document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId<'TKey> statement (docId: 'TKey) =
|
||||
Query.statementWhere
|
||||
statement
|
||||
(whereByFields Any [ { Field.EQ (Configuration.idField ()) docId with ParameterName = Some "@id" } ])
|
||||
|
||||
/// Create a query on JSON fields
|
||||
let fieldQuery statement howMatched fields =
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields statement howMatched fields =
|
||||
Query.statementWhere statement (whereByFields howMatched fields)
|
||||
|
||||
/// Create a JSON containment query
|
||||
let containQuery statement =
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains statement =
|
||||
Query.statementWhere statement (whereDataContains "@criteria")
|
||||
|
||||
/// Create a JSON Path match query
|
||||
let pathMatchQuery statement =
|
||||
[<CompiledName "ByPathMatch">]
|
||||
let byPathMatch statement =
|
||||
Query.statementWhere statement (whereJsonPathMatches "@path")
|
||||
|
||||
/// Queries for retrieving documents
|
||||
module Find =
|
||||
|
||||
/// Query to retrieve a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to retrieve documents using a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
$"{Query.selectFromTable tableName} WHERE {whereByFields howMatched fields}"
|
||||
|
||||
/// Query to retrieve documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Query to retrieve documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereDataContains "@criteria"}"""
|
||||
|
||||
/// Query to retrieve documents using a JSON Path match (@?)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereJsonPathMatches "@path"}"""
|
||||
|
||||
/// Queries to patch (partially update) documents
|
||||
module Patch =
|
||||
|
||||
/// Create an UPDATE statement to patch documents
|
||||
let private update tableName whereClause =
|
||||
$"UPDATE %s{tableName} SET data = data || @data WHERE {whereClause}"
|
||||
|
||||
/// Query to patch a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
whereById "@id" |> update tableName
|
||||
|
||||
/// Query to patch documents match JSON field comparisons (->> =)
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
whereByFields howMatched fields |> update tableName
|
||||
|
||||
/// Query to patch documents match a JSON field comparison (->> =)
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
whereDataContains "@criteria" |> update tableName
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName =
|
||||
whereJsonPathMatches "@path" |> update tableName
|
||||
|
||||
/// Queries to remove fields from documents
|
||||
module RemoveFields =
|
||||
|
||||
/// Create an UPDATE statement to remove parameters
|
||||
let private update tableName whereClause =
|
||||
$"UPDATE %s{tableName} SET data = data - @name WHERE {whereClause}"
|
||||
|
||||
/// Query to remove fields from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
whereById "@id" |> update tableName
|
||||
|
||||
/// Query to remove fields from documents via a comparison on JSON fields within the document
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
whereByFields howMatched fields |> update tableName
|
||||
|
||||
/// Query to remove fields from documents via a comparison on a JSON field within the document
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
whereDataContains "@criteria" |> update tableName
|
||||
|
||||
/// Query to patch documents matching a JSON containment query (@>)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName =
|
||||
whereJsonPathMatches "@path" |> update tableName
|
||||
|
||||
/// Queries to delete documents
|
||||
module Delete =
|
||||
|
||||
/// Query to delete a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to delete documents using a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
$"DELETE FROM %s{tableName} WHERE {whereByFields howMatched fields}"
|
||||
|
||||
/// Query to delete documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Query to delete documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereDataContains "@criteria"}"""
|
||||
|
||||
/// Query to delete documents using a JSON Path match (@?)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereJsonPathMatches "@path"}"""
|
||||
|
||||
|
||||
/// Functions for dealing with results
|
||||
@ -434,19 +331,19 @@ module WithProps =
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields sqlProps =
|
||||
Custom.scalar
|
||||
(Query.fieldQuery (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount sqlProps
|
||||
(Query.byFields (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount sqlProps
|
||||
|
||||
/// Count matching documents using a JSON containment query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName (criteria: 'TContains) sqlProps =
|
||||
Custom.scalar
|
||||
(Query.containQuery (Query.count tableName)) [ jsonParam "@criteria" criteria ] toCount sqlProps
|
||||
(Query.byContains (Query.count tableName)) [ jsonParam "@criteria" criteria ] toCount sqlProps
|
||||
|
||||
/// Count matching documents using a JSON Path match query (@?)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName jsonPath sqlProps =
|
||||
Custom.scalar
|
||||
(Query.pathMatchQuery (Query.count tableName)) [ "@path", Sql.string jsonPath ] toCount sqlProps
|
||||
(Query.byPathMatch (Query.count tableName)) [ "@path", Sql.string jsonPath ] toCount sqlProps
|
||||
|
||||
/// Commands to determine if documents exist
|
||||
[<RequireQualifiedAccess>]
|
||||
@ -491,27 +388,31 @@ module WithProps =
|
||||
/// Retrieve all documents in the given table
|
||||
[<CompiledName "FSharpAll">]
|
||||
let all<'TDoc> tableName sqlProps =
|
||||
Custom.list<'TDoc> (Query.selectFromTable tableName) [] fromData<'TDoc> sqlProps
|
||||
Custom.list<'TDoc> (Query.find tableName) [] fromData<'TDoc> sqlProps
|
||||
|
||||
/// Retrieve all documents in the given table
|
||||
let All<'TDoc>(tableName, sqlProps) =
|
||||
Custom.List<'TDoc>(Query.selectFromTable tableName, [], fromData<'TDoc>, sqlProps)
|
||||
Custom.List<'TDoc>(Query.find tableName, [], fromData<'TDoc>, sqlProps)
|
||||
|
||||
/// Retrieve a document by its ID (returns None if not found)
|
||||
[<CompiledName "FSharpById">]
|
||||
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) sqlProps =
|
||||
Custom.single (Query.Find.byId tableName) [ idParam docId ] fromData<'TDoc> sqlProps
|
||||
Custom.single (Query.byId (Query.find tableName) docId) [ idParam docId ] fromData<'TDoc> sqlProps
|
||||
|
||||
/// Retrieve a document by its ID (returns null if not found)
|
||||
let ById<'TKey, 'TDoc when 'TDoc: null>(tableName, docId: 'TKey, sqlProps) =
|
||||
Custom.Single<'TDoc>(Query.Find.byId tableName, [ idParam docId ], fromData<'TDoc>, sqlProps)
|
||||
Custom.Single<'TDoc>(
|
||||
Query.byId (Query.find tableName) docId, [ idParam docId ], fromData<'TDoc>, sqlProps)
|
||||
|
||||
/// Retrieve documents matching JSON field comparisons (->> =)
|
||||
[<CompiledName "FSharpByFields">]
|
||||
let byFields<'TDoc> tableName howMatched fields sqlProps =
|
||||
Custom.list<'TDoc>
|
||||
(Query.Find.byFields tableName howMatched fields) (addFieldParams fields []) fromData<'TDoc> sqlProps
|
||||
|
||||
(Query.byFields (Query.find tableName) howMatched fields)
|
||||
(addFieldParams fields [])
|
||||
fromData<'TDoc>
|
||||
sqlProps
|
||||
|
||||
/// Retrieve documents matching a JSON field comparison (->> =)
|
||||
[<CompiledName "FSharpByField">]
|
||||
[<System.Obsolete "Use byFields instead; will be removed in v4">]
|
||||
@ -521,7 +422,10 @@ module WithProps =
|
||||
/// Retrieve documents matching JSON field comparisons (->> =)
|
||||
let ByFields<'TDoc>(tableName, howMatched, fields, sqlProps) =
|
||||
Custom.List<'TDoc>(
|
||||
Query.Find.byFields tableName howMatched fields, addFieldParams fields [], fromData<'TDoc>, sqlProps)
|
||||
Query.byFields (Query.find tableName) howMatched fields,
|
||||
addFieldParams fields [],
|
||||
fromData<'TDoc>,
|
||||
sqlProps)
|
||||
|
||||
/// Retrieve documents matching a JSON field comparison (->> =)
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
@ -532,29 +436,35 @@ module WithProps =
|
||||
[<CompiledName "FSharpByContains">]
|
||||
let byContains<'TDoc> tableName (criteria: obj) sqlProps =
|
||||
Custom.list<'TDoc>
|
||||
(Query.Find.byContains tableName) [ jsonParam "@criteria" criteria ] fromData<'TDoc> sqlProps
|
||||
(Query.byContains (Query.find tableName)) [ jsonParam "@criteria" criteria ] fromData<'TDoc> sqlProps
|
||||
|
||||
/// Retrieve documents matching a JSON containment query (@>)
|
||||
let ByContains<'TDoc>(tableName, criteria: obj, sqlProps) =
|
||||
Custom.List<'TDoc>(
|
||||
Query.Find.byContains tableName, [ jsonParam "@criteria" criteria ], fromData<'TDoc>, sqlProps)
|
||||
Query.byContains (Query.find tableName),
|
||||
[ jsonParam "@criteria" criteria ],
|
||||
fromData<'TDoc>,
|
||||
sqlProps)
|
||||
|
||||
/// Retrieve documents matching a JSON Path match query (@?)
|
||||
[<CompiledName "FSharpByJsonPath">]
|
||||
let byJsonPath<'TDoc> tableName jsonPath sqlProps =
|
||||
Custom.list<'TDoc>
|
||||
(Query.Find.byJsonPath tableName) [ "@path", Sql.string jsonPath ] fromData<'TDoc> sqlProps
|
||||
(Query.byPathMatch (Query.find tableName)) [ "@path", Sql.string jsonPath ] fromData<'TDoc> sqlProps
|
||||
|
||||
/// Retrieve documents matching a JSON Path match query (@?)
|
||||
let ByJsonPath<'TDoc>(tableName, jsonPath, sqlProps) =
|
||||
Custom.List<'TDoc>(
|
||||
Query.Find.byJsonPath tableName, [ "@path", Sql.string jsonPath ], fromData<'TDoc>, sqlProps)
|
||||
Query.byPathMatch (Query.find tableName),
|
||||
[ "@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 =
|
||||
Custom.single<'TDoc>
|
||||
$"{Query.Find.byFields tableName howMatched fields} LIMIT 1"
|
||||
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1"
|
||||
(addFieldParams fields [])
|
||||
fromData<'TDoc>
|
||||
sqlProps
|
||||
@ -568,7 +478,7 @@ module WithProps =
|
||||
/// Retrieve the first document matching JSON field comparisons (->> =); returns null if not found
|
||||
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields, sqlProps) =
|
||||
Custom.Single<'TDoc>(
|
||||
$"{Query.Find.byFields tableName howMatched fields} LIMIT 1",
|
||||
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1",
|
||||
addFieldParams fields [],
|
||||
fromData<'TDoc>,
|
||||
sqlProps)
|
||||
@ -582,12 +492,15 @@ module WithProps =
|
||||
[<CompiledName "FSharpFirstByContains">]
|
||||
let firstByContains<'TDoc> tableName (criteria: obj) sqlProps =
|
||||
Custom.single<'TDoc>
|
||||
$"{Query.Find.byContains tableName} LIMIT 1" [ jsonParam "@criteria" criteria ] fromData<'TDoc> sqlProps
|
||||
$"{Query.byContains (Query.find tableName)} LIMIT 1"
|
||||
[ jsonParam "@criteria" criteria ]
|
||||
fromData<'TDoc>
|
||||
sqlProps
|
||||
|
||||
/// Retrieve the first document matching a JSON containment query (@>); returns null if not found
|
||||
let FirstByContains<'TDoc when 'TDoc: null>(tableName, criteria: obj, sqlProps) =
|
||||
Custom.Single<'TDoc>(
|
||||
$"{Query.Find.byContains tableName} LIMIT 1",
|
||||
$"{Query.byContains (Query.find tableName)} LIMIT 1",
|
||||
[ jsonParam "@criteria" criteria ],
|
||||
fromData<'TDoc>,
|
||||
sqlProps)
|
||||
@ -596,12 +509,15 @@ module WithProps =
|
||||
[<CompiledName "FSharpFirstByJsonPath">]
|
||||
let firstByJsonPath<'TDoc> tableName jsonPath sqlProps =
|
||||
Custom.single<'TDoc>
|
||||
$"{Query.Find.byJsonPath tableName} LIMIT 1" [ "@path", Sql.string jsonPath ] fromData<'TDoc> sqlProps
|
||||
$"{Query.byPathMatch (Query.find tableName)} LIMIT 1"
|
||||
[ "@path", Sql.string jsonPath ]
|
||||
fromData<'TDoc>
|
||||
sqlProps
|
||||
|
||||
/// Retrieve the first document matching a JSON Path match query (@?); returns null if not found
|
||||
let FirstByJsonPath<'TDoc when 'TDoc: null>(tableName, jsonPath, sqlProps) =
|
||||
Custom.Single<'TDoc>(
|
||||
$"{Query.Find.byJsonPath tableName} LIMIT 1",
|
||||
$"{Query.byPathMatch (Query.find tableName)} LIMIT 1",
|
||||
[ "@path", Sql.string jsonPath ],
|
||||
fromData<'TDoc>,
|
||||
sqlProps)
|
||||
@ -634,13 +550,14 @@ module WithProps =
|
||||
/// Patch a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) (patch: 'TPatch) sqlProps =
|
||||
Custom.nonQuery (Query.Patch.byId tableName) [ idParam docId; jsonParam "@data" patch ] sqlProps
|
||||
Custom.nonQuery
|
||||
(Query.byId (Query.patch tableName) docId) [ idParam docId; jsonParam "@data" patch ] sqlProps
|
||||
|
||||
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields (patch: 'TPatch) sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.Patch.byFields tableName howMatched fields)
|
||||
(Query.byFields (Query.patch tableName) howMatched fields)
|
||||
(addFieldParams fields [ jsonParam "@data" patch ])
|
||||
sqlProps
|
||||
|
||||
@ -654,32 +571,33 @@ module WithProps =
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName (criteria: 'TContains) (patch: 'TPatch) sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.Patch.byContains tableName) [ jsonParam "@data" patch; jsonParam "@criteria" criteria ] sqlProps
|
||||
(Query.byContains (Query.patch tableName))
|
||||
[ jsonParam "@data" patch; jsonParam "@criteria" criteria ]
|
||||
sqlProps
|
||||
|
||||
/// Patch documents using a JSON Path match query in the WHERE clause (@?)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName jsonPath (patch: 'TPatch) sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.Patch.byJsonPath tableName) [ jsonParam "@data" patch; "@path", Sql.string jsonPath ] sqlProps
|
||||
(Query.byPathMatch (Query.patch tableName))
|
||||
[ jsonParam "@data" patch; "@path", Sql.string jsonPath ]
|
||||
sqlProps
|
||||
|
||||
/// Commands to remove fields from documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module RemoveFields =
|
||||
|
||||
/// Remove fields from a document by the document's ID
|
||||
[<CompiledName "FSharpById">]
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) fieldNames sqlProps =
|
||||
Custom.nonQuery (Query.RemoveFields.byId tableName) [ idParam docId; fieldNameParams fieldNames ] sqlProps
|
||||
|
||||
/// Remove fields from a document by the document's ID
|
||||
let ById(tableName, docId: 'TKey, fieldNames, sqlProps) =
|
||||
byId tableName docId (List.ofSeq fieldNames) sqlProps
|
||||
Custom.nonQuery
|
||||
(Query.byId (Query.removeFields tableName) docId) [ idParam docId; fieldNameParams fieldNames ] sqlProps
|
||||
|
||||
/// Remove fields from documents via a comparison on JSON fields in the document
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields fieldNames sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.RemoveFields.byFields tableName howMatched fields)
|
||||
(Query.byFields (Query.removeFields tableName) howMatched fields)
|
||||
(addFieldParams fields [ fieldNameParams fieldNames ])
|
||||
sqlProps
|
||||
|
||||
@ -690,29 +608,21 @@ module WithProps =
|
||||
byFields tableName Any [ field ] fieldNames sqlProps
|
||||
|
||||
/// Remove fields from documents via a JSON containment query (@>)
|
||||
[<CompiledName "FSharpByContains">]
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName (criteria: 'TContains) fieldNames sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.RemoveFields.byContains tableName)
|
||||
(Query.byContains (Query.removeFields tableName))
|
||||
[ jsonParam "@criteria" criteria; fieldNameParams fieldNames ]
|
||||
sqlProps
|
||||
|
||||
/// Remove fields from documents via a JSON containment query (@>)
|
||||
let ByContains(tableName, criteria: 'TContains, fieldNames, sqlProps) =
|
||||
byContains tableName criteria (List.ofSeq fieldNames) sqlProps
|
||||
|
||||
|
||||
/// Remove fields from documents via a JSON Path match query (@?)
|
||||
[<CompiledName "FSharpByJsonPath">]
|
||||
let byJsonPath tableName jsonPath fieldNames sqlProps =
|
||||
Custom.nonQuery
|
||||
(Query.RemoveFields.byJsonPath tableName)
|
||||
(Query.byPathMatch (Query.removeFields tableName))
|
||||
[ "@path", Sql.string jsonPath; fieldNameParams fieldNames ]
|
||||
sqlProps
|
||||
|
||||
/// Remove fields from documents via a JSON Path match query (@?)
|
||||
let ByJsonPath(tableName, jsonPath, fieldNames, sqlProps) =
|
||||
byJsonPath tableName jsonPath (List.ofSeq fieldNames) sqlProps
|
||||
|
||||
/// Commands to delete documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module Delete =
|
||||
@ -720,12 +630,13 @@ module WithProps =
|
||||
/// Delete a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) sqlProps =
|
||||
Custom.nonQuery (Query.Delete.byId tableName) [ idParam docId ] sqlProps
|
||||
Custom.nonQuery (Query.byId (Query.delete tableName) docId) [ idParam docId ] sqlProps
|
||||
|
||||
/// Delete documents by matching a JSON field comparison query (->> =)
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields sqlProps =
|
||||
Custom.nonQuery (Query.Delete.byFields tableName howMatched fields) (addFieldParams fields []) sqlProps
|
||||
Custom.nonQuery
|
||||
(Query.byFields (Query.delete tableName) howMatched fields) (addFieldParams fields []) sqlProps
|
||||
|
||||
/// Delete documents by matching a JSON field comparison query (->> =)
|
||||
[<CompiledName "ByField">]
|
||||
@ -736,14 +647,14 @@ module WithProps =
|
||||
/// Delete documents by matching a JSON contains query (@>)
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName (criteria: 'TCriteria) sqlProps =
|
||||
Custom.nonQuery (Query.Delete.byContains tableName) [ jsonParam "@criteria" criteria ] sqlProps
|
||||
Custom.nonQuery (Query.byContains (Query.delete tableName)) [ jsonParam "@criteria" criteria ] sqlProps
|
||||
|
||||
/// Delete documents by matching a JSON Path match query (@?)
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName path sqlProps =
|
||||
Custom.nonQuery (Query.Delete.byJsonPath tableName) [ "@path", Sql.string path ] sqlProps
|
||||
|
||||
|
||||
Custom.nonQuery (Query.byPathMatch (Query.delete tableName)) [ "@path", Sql.string path ] sqlProps
|
||||
|
||||
|
||||
/// Commands to execute custom SQL queries
|
||||
[<RequireQualifiedAccess>]
|
||||
module Custom =
|
||||
@ -1032,14 +943,10 @@ module Patch =
|
||||
module RemoveFields =
|
||||
|
||||
/// Remove fields from a document by the document's ID
|
||||
[<CompiledName "FSharpById">]
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) fieldNames =
|
||||
WithProps.RemoveFields.byId tableName docId fieldNames (fromDataSource ())
|
||||
|
||||
/// Remove fields from a document by the document's ID
|
||||
let ById(tableName, docId: 'TKey, fieldNames) =
|
||||
WithProps.RemoveFields.ById(tableName, docId, fieldNames, fromDataSource ())
|
||||
|
||||
/// Remove fields from documents via a comparison on JSON fields in the document
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields fieldNames =
|
||||
@ -1052,24 +959,16 @@ module RemoveFields =
|
||||
byFields tableName Any [ field ] fieldNames
|
||||
|
||||
/// Remove fields from documents via a JSON containment query (@>)
|
||||
[<CompiledName "FSharpByContains">]
|
||||
[<CompiledName "ByContains">]
|
||||
let byContains tableName (criteria: 'TContains) fieldNames =
|
||||
WithProps.RemoveFields.byContains tableName criteria fieldNames (fromDataSource ())
|
||||
|
||||
/// Remove fields from documents via a JSON containment query (@>)
|
||||
let ByContains(tableName, criteria: 'TContains, fieldNames) =
|
||||
WithProps.RemoveFields.ByContains(tableName, criteria, fieldNames, fromDataSource ())
|
||||
|
||||
/// Remove fields from documents via a JSON Path match query (@?)
|
||||
[<CompiledName "FSharpByJsonPath">]
|
||||
[<CompiledName "ByJsonPath">]
|
||||
let byJsonPath tableName jsonPath fieldNames =
|
||||
WithProps.RemoveFields.byJsonPath tableName jsonPath fieldNames (fromDataSource ())
|
||||
|
||||
/// Remove fields from documents via a JSON Path match query (@?)
|
||||
let ByJsonPath(tableName, jsonPath, fieldNames) =
|
||||
WithProps.RemoveFields.ByJsonPath(tableName, jsonPath, fieldNames, fromDataSource ())
|
||||
|
||||
|
||||
/// Commands to delete documents
|
||||
[<RequireQualifiedAccess>]
|
||||
module Delete =
|
||||
|
@ -56,6 +56,29 @@ module Query =
|
||||
let whereById paramName =
|
||||
whereByFields Any [ { Field.EQ (Configuration.idField ()) 0 with ParameterName = Some paramName } ]
|
||||
|
||||
/// Create an UPDATE statement to patch documents
|
||||
[<CompiledName "Patch">]
|
||||
let patch tableName =
|
||||
$"UPDATE %s{tableName} SET data = json_patch(data, json(@data))"
|
||||
|
||||
/// Create an UPDATE statement to remove fields from documents
|
||||
[<CompiledName "RemoveFields">]
|
||||
let removeFields tableName (parameters: SqliteParameter seq) =
|
||||
let paramNames = parameters |> Seq.map _.ParameterName |> String.concat ", "
|
||||
$"UPDATE %s{tableName} SET data = json_remove(data, {paramNames})"
|
||||
|
||||
/// Create a query by a document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId<'TKey> statement (docId: 'TKey) =
|
||||
Query.statementWhere
|
||||
statement
|
||||
(whereByFields Any [ { Field.EQ (Configuration.idField ()) docId with ParameterName = Some "@id" } ])
|
||||
|
||||
/// Create a query on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields statement howMatched fields =
|
||||
Query.statementWhere statement (whereByFields howMatched fields)
|
||||
|
||||
/// Data definition
|
||||
module Definition =
|
||||
|
||||
@ -63,92 +86,7 @@ module Query =
|
||||
[<CompiledName "EnsureTable">]
|
||||
let ensureTable name =
|
||||
Query.Definition.ensureTableFor name "TEXT"
|
||||
|
||||
/// Queries for retrieving documents
|
||||
module Find =
|
||||
|
||||
/// Query to retrieve a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""{Query.selectFromTable tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to retrieve documents using a comparison on JSON fields
|
||||
[<CompiledName "ByField">]
|
||||
let byFields tableName howMatched fields =
|
||||
$"{Query.selectFromTable tableName} WHERE {whereByFields howMatched fields}"
|
||||
|
||||
/// Query to retrieve documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Document patching (partial update) queries
|
||||
module Patch =
|
||||
|
||||
/// Create an UPDATE statement to patch documents
|
||||
let internal update tableName whereClause =
|
||||
$"UPDATE %s{tableName} SET data = json_patch(data, json(@data)) WHERE %s{whereClause}"
|
||||
|
||||
/// Query to patch (partially update) a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
whereById "@id" |> update tableName
|
||||
|
||||
/// Query to patch (partially update) a document via a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
whereByFields howMatched fields |> update tableName
|
||||
|
||||
/// Query to patch (partially update) a document via a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
/// Queries to remove fields from documents
|
||||
module RemoveFields =
|
||||
|
||||
/// Create an UPDATE statement to remove parameters
|
||||
let internal update tableName (parameters: SqliteParameter seq) whereClause =
|
||||
let paramNames = parameters |> Seq.map _.ParameterName |> String.concat ", "
|
||||
$"UPDATE %s{tableName} SET data = json_remove(data, {paramNames}) WHERE %s{whereClause}"
|
||||
|
||||
/// Query to remove fields from a document by the document's ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName parameters =
|
||||
whereById "@id" |> update tableName parameters
|
||||
|
||||
/// Query to remove fields from documents via a comparison on JSON fields within the document
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields parameters =
|
||||
whereByFields howMatched fields |> update tableName parameters
|
||||
|
||||
/// Query to remove fields from documents via a comparison on a JSON field within the document
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field parameters =
|
||||
byFields tableName Any [ field ] parameters
|
||||
|
||||
/// Queries to delete documents
|
||||
module Delete =
|
||||
|
||||
/// Query to delete a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName =
|
||||
$"""DELETE FROM %s{tableName} WHERE {whereById "@id"}"""
|
||||
|
||||
/// Query to delete documents using a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields =
|
||||
$"DELETE FROM %s{tableName} WHERE {whereByFields howMatched fields}"
|
||||
|
||||
/// Query to delete documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let byField tableName field =
|
||||
byFields tableName Any [ field ]
|
||||
|
||||
|
||||
/// Parameter handling helpers
|
||||
[<AutoOpen>]
|
||||
@ -349,10 +287,7 @@ module WithConn =
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields conn =
|
||||
Custom.scalar
|
||||
(Query.statementWhere (Query.count tableName) (Query.whereByFields howMatched fields))
|
||||
(addFieldParams fields [])
|
||||
toCount
|
||||
conn
|
||||
(Query.byFields (Query.count tableName) howMatched fields) (addFieldParams fields []) toCount conn
|
||||
|
||||
/// Commands to determine if documents exist
|
||||
[<RequireQualifiedAccess>]
|
||||
@ -379,27 +314,30 @@ module WithConn =
|
||||
/// Retrieve all documents in the given table
|
||||
[<CompiledName "FSharpAll">]
|
||||
let all<'TDoc> tableName conn =
|
||||
Custom.list<'TDoc> (Query.selectFromTable tableName) [] fromData<'TDoc> conn
|
||||
Custom.list<'TDoc> (Query.find tableName) [] fromData<'TDoc> conn
|
||||
|
||||
/// Retrieve all documents in the given table
|
||||
let All<'TDoc>(tableName, conn) =
|
||||
Custom.List(Query.selectFromTable tableName, [], fromData<'TDoc>, conn)
|
||||
Custom.List(Query.find tableName, [], fromData<'TDoc>, conn)
|
||||
|
||||
/// Retrieve a document by its ID (returns None if not found)
|
||||
[<CompiledName "FSharpById">]
|
||||
let byId<'TKey, 'TDoc> tableName (docId: 'TKey) conn =
|
||||
Custom.single<'TDoc> (Query.Find.byId tableName) [ idParam docId ] fromData<'TDoc> conn
|
||||
Custom.single<'TDoc> (Query.byId (Query.find tableName) docId) [ idParam docId ] fromData<'TDoc> conn
|
||||
|
||||
/// Retrieve a document by its ID (returns null if not found)
|
||||
let ById<'TKey, 'TDoc when 'TDoc: null>(tableName, docId: 'TKey, conn) =
|
||||
Custom.Single<'TDoc>(Query.Find.byId tableName, [ idParam docId ], fromData<'TDoc>, conn)
|
||||
Custom.Single<'TDoc>(Query.byId (Query.find tableName) docId, [ idParam docId ], fromData<'TDoc>, conn)
|
||||
|
||||
/// Retrieve documents via a comparison on JSON fields
|
||||
[<CompiledName "FSharpByFields">]
|
||||
let byFields<'TDoc> tableName howMatched fields conn =
|
||||
Custom.list<'TDoc>
|
||||
(Query.Find.byFields tableName howMatched fields) (addFieldParams fields []) fromData<'TDoc> conn
|
||||
|
||||
(Query.byFields (Query.find tableName) howMatched fields)
|
||||
(addFieldParams fields [])
|
||||
fromData<'TDoc>
|
||||
conn
|
||||
|
||||
/// Retrieve documents via a comparison on a JSON field
|
||||
[<CompiledName "FSharpByField">]
|
||||
[<System.Obsolete "Use byFields instead; will be removed in v4">]
|
||||
@ -409,8 +347,11 @@ module WithConn =
|
||||
/// Retrieve documents via a comparison on JSON fields
|
||||
let ByFields<'TDoc>(tableName, howMatched, fields, conn) =
|
||||
Custom.List<'TDoc>(
|
||||
Query.Find.byFields tableName howMatched fields, addFieldParams fields [], fromData<'TDoc>, conn)
|
||||
|
||||
Query.byFields (Query.find tableName) howMatched fields,
|
||||
addFieldParams fields [],
|
||||
fromData<'TDoc>,
|
||||
conn)
|
||||
|
||||
/// Retrieve documents via a comparison on a JSON field
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
let ByField<'TDoc>(tableName, field, conn) =
|
||||
@ -420,7 +361,7 @@ module WithConn =
|
||||
[<CompiledName "FSharpFirstByFields">]
|
||||
let firstByFields<'TDoc> tableName howMatched fields conn =
|
||||
Custom.single
|
||||
$"{Query.Find.byFields tableName howMatched fields} LIMIT 1"
|
||||
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1"
|
||||
(addFieldParams fields [])
|
||||
fromData<'TDoc>
|
||||
conn
|
||||
@ -434,7 +375,7 @@ module WithConn =
|
||||
/// Retrieve documents via a comparison on JSON fields, returning only the first result
|
||||
let FirstByFields<'TDoc when 'TDoc: null>(tableName, howMatched, fields, conn) =
|
||||
Custom.Single(
|
||||
$"{Query.Find.byFields tableName howMatched fields} LIMIT 1",
|
||||
$"{Query.byFields (Query.find tableName) howMatched fields} LIMIT 1",
|
||||
addFieldParams fields [],
|
||||
fromData<'TDoc>,
|
||||
conn)
|
||||
@ -472,13 +413,14 @@ module WithConn =
|
||||
/// Patch a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) (patch: 'TPatch) conn =
|
||||
Custom.nonQuery (Query.Patch.byId tableName) [ idParam docId; jsonParam "@data" patch ] conn
|
||||
Custom.nonQuery
|
||||
(Query.byId (Query.patch tableName) docId) [ idParam docId; jsonParam "@data" patch ] conn
|
||||
|
||||
/// Patch documents using a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields (patch: 'TPatch) conn =
|
||||
Custom.nonQuery
|
||||
(Query.Patch.byFields tableName howMatched fields)
|
||||
(Query.byFields (Query.patch tableName) howMatched fields)
|
||||
(addFieldParams fields [ jsonParam "@data" patch ])
|
||||
conn
|
||||
|
||||
@ -497,7 +439,7 @@ module WithConn =
|
||||
let byId tableName (docId: 'TKey) fieldNames conn =
|
||||
let nameParams = fieldNameParams "@name" fieldNames
|
||||
Custom.nonQuery
|
||||
(Query.RemoveFields.byId tableName nameParams)
|
||||
(Query.byId (Query.removeFields tableName nameParams) docId)
|
||||
(idParam docId |> Seq.singleton |> Seq.append nameParams)
|
||||
conn
|
||||
|
||||
@ -506,10 +448,10 @@ module WithConn =
|
||||
let byFields tableName howMatched fields fieldNames conn =
|
||||
let nameParams = fieldNameParams "@name" fieldNames
|
||||
Custom.nonQuery
|
||||
(Query.RemoveFields.byFields tableName howMatched fields nameParams)
|
||||
(Query.byFields (Query.removeFields tableName nameParams) howMatched fields)
|
||||
(addFieldParams fields nameParams)
|
||||
conn
|
||||
|
||||
|
||||
/// Remove fields from documents via a comparison on a JSON field in the document
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
@ -523,13 +465,13 @@ module WithConn =
|
||||
/// Delete a document by its ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) conn =
|
||||
Custom.nonQuery (Query.Delete.byId tableName) [ idParam docId ] conn
|
||||
Custom.nonQuery (Query.byId (Query.delete tableName) docId) [ idParam docId ] conn
|
||||
|
||||
/// Delete documents by matching a comparison on JSON fields
|
||||
[<CompiledName "ByFields">]
|
||||
let byFields tableName howMatched fields conn =
|
||||
Custom.nonQuery (Query.Delete.byFields tableName howMatched fields) (addFieldParams fields []) conn
|
||||
|
||||
Custom.nonQuery (Query.byFields (Query.delete tableName) howMatched fields) (addFieldParams fields []) conn
|
||||
|
||||
/// Delete documents by matching a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
[<System.Obsolete "Use ByFields instead; will be removed in v4">]
|
||||
|
@ -238,10 +238,9 @@ public static class CommonCSharpTests
|
||||
]),
|
||||
TestList("Query",
|
||||
[
|
||||
TestCase("SelectFromTable succeeds", () =>
|
||||
TestCase("StatementWhere succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.SelectFromTable("test.table"), "SELECT data FROM test.table",
|
||||
"SELECT statement not correct");
|
||||
Expect.equal(Query.StatementWhere("q", "r"), "q WHERE r", "Statements not combined correctly");
|
||||
}),
|
||||
TestList("Definition",
|
||||
[
|
||||
@ -266,15 +265,32 @@ public static class CommonCSharpTests
|
||||
"CREATE INDEX for key statement without schema not constructed correctly");
|
||||
})
|
||||
]),
|
||||
TestCase("EnsureIndexOn succeeds for multiple fields and directions", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Query.Definition.EnsureIndexOn("test.table", "gibberish",
|
||||
new[] { "taco", "guac DESC", "salsa ASC" }, Dialect.SQLite),
|
||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
||||
+ "((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||
"CREATE INDEX for multiple field statement incorrect");
|
||||
})
|
||||
TestList("EnsureIndexOn",
|
||||
[
|
||||
TestCase("succeeds for multiple fields and directions", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Query.Definition.EnsureIndexOn("test.table", "gibberish",
|
||||
new[] { "taco", "guac DESC", "salsa ASC" }, Dialect.SQLite),
|
||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
||||
+ "((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||
"CREATE INDEX for multiple field statement incorrect");
|
||||
}),
|
||||
TestCase("succeeds for nested PostgreSQL field", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Query.Definition.EnsureIndexOn("tbl", "nest", ["a.b.c"], Dialect.PostgreSQL),
|
||||
"CREATE INDEX IF NOT EXISTS idx_tbl_nest ON tbl ((data#>>'{a,b,c}'))",
|
||||
"CREATE INDEX for nested PostgreSQL field incorrect");
|
||||
}),
|
||||
TestCase("succeeds for nested SQLite field", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Query.Definition.EnsureIndexOn("tbl", "nest", ["a.b.c"], Dialect.SQLite),
|
||||
"CREATE INDEX IF NOT EXISTS idx_tbl_nest ON tbl ((data->>'a'->>'b'->>'c'))",
|
||||
"CREATE INDEX for nested SQLite field incorrect");
|
||||
})
|
||||
])
|
||||
]),
|
||||
TestCase("Insert succeeds", () =>
|
||||
{
|
||||
@ -285,6 +301,27 @@ public static class CommonCSharpTests
|
||||
Expect.equal(Query.Save("tbl"),
|
||||
"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data->>'Id')) DO UPDATE SET data = EXCLUDED.data",
|
||||
"INSERT ON CONFLICT UPDATE statement not correct");
|
||||
}),
|
||||
TestCase("Count succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Count("tbl"), "SELECT COUNT(*) AS it FROM tbl", "Count query not correct");
|
||||
}),
|
||||
TestCase("Exists succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Exists("tbl", "chicken"), "SELECT EXISTS (SELECT 1 FROM tbl WHERE chicken) AS it",
|
||||
"Exists query not correct");
|
||||
}),
|
||||
TestCase("Find succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Find("test.table"), "SELECT data FROM test.table", "Find query not correct");
|
||||
}),
|
||||
TestCase("Update succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Update("tbl"), "UPDATE tbl SET data = @data", "Update query not correct");
|
||||
}),
|
||||
TestCase("Delete succeeds", () =>
|
||||
{
|
||||
Expect.equal(Query.Delete("tbl"), "DELETE FROM tbl", "Delete query not correct");
|
||||
})
|
||||
])
|
||||
]);
|
||||
|
@ -279,153 +279,7 @@ public static class PostgresCSharpTests
|
||||
{
|
||||
Expect.equal(Postgres.Query.WhereJsonPathMatches("@path"), "data @? @path::jsonpath",
|
||||
"WHERE clause not correct");
|
||||
}),
|
||||
TestList("Find",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Find.ById(PostgresDb.TableName),
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Id' = @id",
|
||||
"SELECT by ID query not correct");
|
||||
}),
|
||||
TestCase("ByFields succeeds", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Postgres.Query.Find.ByFields("x", FieldMatch.Any, [Field.GE("Golf", 0), Field.LE("Flog", 1)]),
|
||||
$"SELECT data FROM x WHERE data->>'Golf' >= @field0 OR data->>'Flog' <= @field1",
|
||||
"SELECT by JSON comparison query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Find.ByField(PostgresDb.TableName, Field.GE("Golf", 0)),
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field0",
|
||||
"SELECT by JSON comparison query not correct");
|
||||
}),
|
||||
#pragma warning restore CS0618
|
||||
TestCase("byContains succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Find.ByContains(PostgresDb.TableName),
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data @> @criteria",
|
||||
"SELECT by JSON containment query not correct");
|
||||
}),
|
||||
TestCase("byJsonPath succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Find.ByJsonPath(PostgresDb.TableName),
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
|
||||
"SELECT by JSON Path match query not correct");
|
||||
})
|
||||
]),
|
||||
TestList("Patch",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Patch.ById(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Id' = @id",
|
||||
"UPDATE partial by ID statement not correct");
|
||||
}),
|
||||
TestCase("ByFields succeeds", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Postgres.Query.Patch.ByFields("x", FieldMatch.All,
|
||||
[Field.LT("Snail", 0), Field.BT("Slug", 8, 14)]),
|
||||
$"UPDATE x SET data = data || @data WHERE data->>'Snail' < @field0 AND (data->>'Slug')::numeric BETWEEN @field1min AND @field1max",
|
||||
"UPDATE partial by ID statement not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Patch.ByField(PostgresDb.TableName, Field.LT("Snail", 0)),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field0",
|
||||
"UPDATE partial by ID statement not correct");
|
||||
}),
|
||||
#pragma warning restore CS0618
|
||||
TestCase("ByContains succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Patch.ByContains(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria",
|
||||
"UPDATE partial by JSON containment statement not correct");
|
||||
}),
|
||||
TestCase("ByJsonPath succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Patch.ByJsonPath(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath",
|
||||
"UPDATE partial by JSON Path statement not correct");
|
||||
})
|
||||
]),
|
||||
TestList("RemoveFields",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.RemoveFields.ById(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Id' = @id",
|
||||
"Remove field by ID query not correct");
|
||||
}),
|
||||
TestCase("ByFields succeeds", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Postgres.Query.RemoveFields.ByFields("x", FieldMatch.Any,
|
||||
[Field.LT("Fly", 0), Field.LT("Ant", 2)]),
|
||||
$"UPDATE x SET data = data - @name WHERE data->>'Fly' < @field0 OR data->>'Ant' < @field1",
|
||||
"Remove field by field query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.RemoveFields.ByField(PostgresDb.TableName, Field.LT("Fly", 0)),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Fly' < @field0",
|
||||
"Remove field by field query not correct");
|
||||
}),
|
||||
#pragma warning restore CS0618
|
||||
TestCase("ByContains succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.RemoveFields.ByContains(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data @> @criteria",
|
||||
"Remove field by contains query not correct");
|
||||
}),
|
||||
TestCase("ByJsonPath succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.RemoveFields.ByJsonPath(PostgresDb.TableName),
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data @? @path::jsonpath",
|
||||
"Remove field by JSON path query not correct");
|
||||
})
|
||||
]),
|
||||
TestList("Delete",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Delete.ById(PostgresDb.TableName),
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data->>'Id' = @id",
|
||||
"DELETE by ID query not correct");
|
||||
}),
|
||||
TestCase("ByFields succeeds", () =>
|
||||
{
|
||||
Expect.equal(
|
||||
Postgres.Query.Delete.ByFields("tbl", FieldMatch.All, [Field.NEX("gone"), Field.EX("here")]),
|
||||
$"DELETE FROM tbl WHERE data->>'gone' IS NULL AND data->>'here' IS NOT NULL",
|
||||
"DELETE by JSON comparison query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Delete.ByField(PostgresDb.TableName, Field.NEX("gone")),
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data->>'gone' IS NULL",
|
||||
"DELETE by JSON comparison query not correct");
|
||||
}),
|
||||
#pragma warning restore CS0618
|
||||
TestCase("byContains succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Delete.ByContains(PostgresDb.TableName),
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data @> @criteria",
|
||||
"DELETE by JSON containment query not correct");
|
||||
}),
|
||||
TestCase("byJsonPath succeeds", () =>
|
||||
{
|
||||
Expect.equal(Postgres.Query.Delete.ByJsonPath(PostgresDb.TableName),
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath",
|
||||
"DELETE by JSON Path match query not correct");
|
||||
})
|
||||
])
|
||||
})
|
||||
])
|
||||
]);
|
||||
|
||||
|
@ -91,73 +91,7 @@ public static class SqliteCSharpTests
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"),
|
||||
"CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)", "CREATE TABLE statement not correct");
|
||||
}),
|
||||
TestList("Find",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Find.ById("tbl"), "SELECT data FROM tbl WHERE data->>'Id' = @id",
|
||||
"SELECT by ID query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Find.ByField("tbl", Field.GE("Golf", 0)),
|
||||
"SELECT data FROM tbl WHERE data->>'Golf' >= @field0",
|
||||
"SELECT by JSON comparison query not correct");
|
||||
})
|
||||
#pragma warning restore CS0618
|
||||
]),
|
||||
TestList("Patch",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Patch.ById("tbl"),
|
||||
"UPDATE tbl SET data = json_patch(data, json(@data)) WHERE data->>'Id' = @id",
|
||||
"UPDATE partial by ID statement not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Patch.ByField("tbl", Field.NE("Part", 0)),
|
||||
"UPDATE tbl SET data = json_patch(data, json(@data)) WHERE data->>'Part' <> @field0",
|
||||
"UPDATE partial by JSON comparison query not correct");
|
||||
})
|
||||
#pragma warning restore CS0618
|
||||
]),
|
||||
TestList("RemoveFields",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.RemoveFields.ById("tbl", new[] { new SqliteParameter("@name", "one") }),
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data->>'Id' = @id",
|
||||
"Remove field by ID query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.RemoveFields.ByField("tbl", Field.LT("Fly", 0),
|
||||
new[] { new SqliteParameter("@name0", "one"), new SqliteParameter("@name1", "two") }),
|
||||
"UPDATE tbl SET data = json_remove(data, @name0, @name1) WHERE data->>'Fly' < @field0",
|
||||
"Remove field by field query not correct");
|
||||
})
|
||||
#pragma warning restore CS0618
|
||||
]),
|
||||
TestList("Delete",
|
||||
[
|
||||
TestCase("ById succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Delete.ById("tbl"), "DELETE FROM tbl WHERE data->>'Id' = @id",
|
||||
"DELETE by ID query not correct");
|
||||
}),
|
||||
#pragma warning disable CS0618
|
||||
TestCase("ByField succeeds", () =>
|
||||
{
|
||||
Expect.equal(Sqlite.Query.Delete.ByField("tbl", Field.NEX("gone")),
|
||||
"DELETE FROM tbl WHERE data->>'gone' IS NULL", "DELETE by JSON comparison query not correct");
|
||||
})
|
||||
#pragma warning restore CS0618
|
||||
])
|
||||
})
|
||||
]),
|
||||
TestList("Parameters",
|
||||
[
|
||||
|
@ -170,8 +170,8 @@ let all =
|
||||
}
|
||||
]
|
||||
testList "Query" [
|
||||
test "selectFromTable succeeds" {
|
||||
Expect.equal (Query.selectFromTable tbl) $"SELECT data FROM {tbl}" "SELECT statement not correct"
|
||||
test "statementWhere succeeds" {
|
||||
Expect.equal (Query.statementWhere "x" "y") "x WHERE y" "Statements not combined correctly"
|
||||
}
|
||||
testList "Definition" [
|
||||
test "ensureTableFor succeeds" {
|
||||
@ -194,15 +194,29 @@ let all =
|
||||
"CREATE INDEX for key statement without schema not constructed correctly"
|
||||
}
|
||||
]
|
||||
test "ensureIndexOn succeeds for multiple fields and directions" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureIndexOn
|
||||
"test.table" "gibberish" [ "taco"; "guac DESC"; "salsa ASC" ] PostgreSQL)
|
||||
([ "CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
||||
"((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)" ]
|
||||
|> String.concat "")
|
||||
"CREATE INDEX for multiple field statement incorrect"
|
||||
}
|
||||
testList "ensureIndexOn" [
|
||||
test "succeeds for multiple fields and directions" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureIndexOn
|
||||
"test.table" "gibberish" [ "taco"; "guac DESC"; "salsa ASC" ] PostgreSQL)
|
||||
([ "CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
||||
"((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)" ]
|
||||
|> String.concat "")
|
||||
"CREATE INDEX for multiple field statement incorrect"
|
||||
}
|
||||
test "succeeds for nested PostgreSQL field" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureIndexOn tbl "nest" [ "a.b.c" ] PostgreSQL)
|
||||
$"CREATE INDEX IF NOT EXISTS idx_{tbl}_nest ON {tbl} ((data#>>'{{a,b,c}}'))"
|
||||
"CREATE INDEX for nested PostgreSQL field incorrect"
|
||||
}
|
||||
test "succeeds for nested SQLite field" {
|
||||
Expect.equal
|
||||
(Query.Definition.ensureIndexOn tbl "nest" [ "a.b.c" ] SQLite)
|
||||
$"CREATE INDEX IF NOT EXISTS idx_{tbl}_nest ON {tbl} ((data->>'a'->>'b'->>'c'))"
|
||||
"CREATE INDEX for nested SQLite field incorrect"
|
||||
}
|
||||
]
|
||||
]
|
||||
test "insert succeeds" {
|
||||
Expect.equal (Query.insert tbl) $"INSERT INTO {tbl} VALUES (@data)" "INSERT statement not correct"
|
||||
@ -214,7 +228,22 @@ let all =
|
||||
"INSERT ON CONFLICT UPDATE statement not correct"
|
||||
}
|
||||
test "count succeeds" {
|
||||
Expect.equal (Query.count "a_table") "SELECT COUNT(*) AS it FROM a_table" "Count query not correct"
|
||||
Expect.equal (Query.count tbl) $"SELECT COUNT(*) AS it FROM {tbl}" "Count query not correct"
|
||||
}
|
||||
test "exists succeeds" {
|
||||
Expect.equal
|
||||
(Query.exists tbl "turkey")
|
||||
$"SELECT EXISTS (SELECT 1 FROM {tbl} WHERE turkey) AS it"
|
||||
"Exists query not correct"
|
||||
}
|
||||
test "find succeeds" {
|
||||
Expect.equal (Query.find tbl) $"SELECT data FROM {tbl}" "Find query not correct"
|
||||
}
|
||||
test "update succeeds" {
|
||||
Expect.equal (Query.update tbl) $"UPDATE {tbl} SET data = @data" "Update query not correct"
|
||||
}
|
||||
test "delete succeeds" {
|
||||
Expect.equal (Query.delete tbl) $"DELETE FROM {tbl}" "Delete query not correct"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -252,132 +252,6 @@ let unitTests =
|
||||
test "whereJsonPathMatches succeeds" {
|
||||
Expect.equal (Query.whereJsonPathMatches "@path") "data @? @path::jsonpath" "WHERE clause not correct"
|
||||
}
|
||||
testList "Find" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byId PostgresDb.TableName)
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Id' = @id"
|
||||
"SELECT by ID query not correct"
|
||||
}
|
||||
test "byFields succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byFields "tbl" Any [ Field.GE "Golf" 0; Field.LE "Flog" 1 ])
|
||||
$"SELECT data FROM tbl WHERE data->>'Golf' >= @field0 OR data->>'Flog' <= @field1"
|
||||
"SELECT by JSON comparison query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byField PostgresDb.TableName (Field.GE "Golf" 0))
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data->>'Golf' >= @field0"
|
||||
"SELECT by JSON comparison query not correct"
|
||||
}
|
||||
test "byContains succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byContains PostgresDb.TableName)
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data @> @criteria"
|
||||
"SELECT by JSON containment query not correct"
|
||||
}
|
||||
test "byJsonPath succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byJsonPath PostgresDb.TableName)
|
||||
$"SELECT data FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
|
||||
"SELECT by JSON Path match query not correct"
|
||||
}
|
||||
]
|
||||
testList "Patch" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byId PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Id' = @id"
|
||||
"UPDATE partial by ID statement not correct"
|
||||
}
|
||||
test "byFields succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byFields "x" All [ Field.LT "Snail" 0; Field.BT "Slug" 8 12 ])
|
||||
$"UPDATE x SET data = data || @data WHERE data->>'Snail' < @field0 AND (data->>'Slug')::numeric BETWEEN @field1min AND @field1max"
|
||||
"UPDATE partial by ID statement not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byField PostgresDb.TableName (Field.LT "Snail" 0))
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data->>'Snail' < @field0"
|
||||
"UPDATE partial by ID statement not correct"
|
||||
}
|
||||
test "byContains succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byContains PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @> @criteria"
|
||||
"UPDATE partial by JSON containment statement not correct"
|
||||
}
|
||||
test "byJsonPath succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byJsonPath PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data || @data WHERE data @? @path::jsonpath"
|
||||
"UPDATE partial by JSON Path statement not correct"
|
||||
}
|
||||
]
|
||||
testList "RemoveFields" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byId PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Id' = @id"
|
||||
"Remove field by ID query not correct"
|
||||
}
|
||||
test "byFields succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byFields "tbl" Any [ Field.LT "Fly" 0; Field.LT "Ant" 2 ])
|
||||
"UPDATE tbl SET data = data - @name WHERE data->>'Fly' < @field0 OR data->>'Ant' < @field1"
|
||||
"Remove field by field query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byField PostgresDb.TableName (Field.LT "Fly" 0))
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data->>'Fly' < @field0"
|
||||
"Remove field by field query not correct"
|
||||
}
|
||||
test "byContains succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byContains PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data @> @criteria"
|
||||
"Remove field by contains query not correct"
|
||||
}
|
||||
test "byJsonPath succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byJsonPath PostgresDb.TableName)
|
||||
$"UPDATE {PostgresDb.TableName} SET data = data - @name WHERE data @? @path::jsonpath"
|
||||
"Remove field by JSON path query not correct"
|
||||
}
|
||||
]
|
||||
testList "Delete" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Delete.byId PostgresDb.TableName)
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data->>'Id' = @id"
|
||||
"DELETE by ID query not correct"
|
||||
}
|
||||
test "byFields succeeds" {
|
||||
Expect.equal
|
||||
(Query.Delete.byFields PostgresDb.TableName All [ Field.NEX "gone"; Field.EX "here" ])
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data->>'gone' IS NULL AND data->>'here' IS NOT NULL"
|
||||
"DELETE by JSON comparison query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Delete.byField PostgresDb.TableName (Field.NEX "gone"))
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data->>'gone' IS NULL"
|
||||
"DELETE by JSON comparison query not correct"
|
||||
}
|
||||
test "byContains succeeds" {
|
||||
Expect.equal (Query.Delete.byContains PostgresDb.TableName)
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data @> @criteria"
|
||||
"DELETE by JSON containment query not correct"
|
||||
}
|
||||
test "byJsonPath succeeds" {
|
||||
Expect.equal (Query.Delete.byJsonPath PostgresDb.TableName)
|
||||
$"DELETE FROM {PostgresDb.TableName} WHERE data @? @path::jsonpath"
|
||||
"DELETE by JSON Path match query not correct"
|
||||
}
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -81,65 +81,6 @@ let unitTests =
|
||||
"CREATE TABLE IF NOT EXISTS tbl (data TEXT NOT NULL)"
|
||||
"CREATE TABLE statement not correct"
|
||||
}
|
||||
testList "Find" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byId "tbl")
|
||||
"SELECT data FROM tbl WHERE data->>'Id' = @id"
|
||||
"SELECT by ID query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Find.byField "tbl" (Field.GE "Golf" 0))
|
||||
"SELECT data FROM tbl WHERE data->>'Golf' >= @field0"
|
||||
"SELECT by JSON comparison query not correct"
|
||||
}
|
||||
]
|
||||
testList "Patch" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byId "tbl")
|
||||
"UPDATE tbl SET data = json_patch(data, json(@data)) WHERE data->>'Id' = @id"
|
||||
"UPDATE partial by ID statement not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Patch.byField "tbl" (Field.NE "Part" 0))
|
||||
"UPDATE tbl SET data = json_patch(data, json(@data)) WHERE data->>'Part' <> @field0"
|
||||
"UPDATE partial by JSON comparison query not correct"
|
||||
}
|
||||
]
|
||||
testList "RemoveFields" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byId "tbl" [ SqliteParameter("@name", "one") ])
|
||||
"UPDATE tbl SET data = json_remove(data, @name) WHERE data->>'Id' = @id"
|
||||
"Remove field by ID query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.RemoveFields.byField
|
||||
"tbl"
|
||||
(Field.GT "Fly" 0)
|
||||
[ SqliteParameter("@name0", "one"); SqliteParameter("@name1", "two") ])
|
||||
"UPDATE tbl SET data = json_remove(data, @name0, @name1) WHERE data->>'Fly' > @field0"
|
||||
"Remove field by field query not correct"
|
||||
}
|
||||
]
|
||||
testList "Delete" [
|
||||
test "byId succeeds" {
|
||||
Expect.equal
|
||||
(Query.Delete.byId "tbl")
|
||||
"DELETE FROM tbl WHERE data->>'Id' = @id"
|
||||
"DELETE by ID query not correct"
|
||||
}
|
||||
test "byField succeeds" {
|
||||
Expect.equal
|
||||
(Query.Delete.byField "tbl" (Field.NEX "gone"))
|
||||
"DELETE FROM tbl WHERE data->>'gone' IS NULL"
|
||||
"DELETE by JSON comparison query not correct"
|
||||
}
|
||||
]
|
||||
]
|
||||
testList "Parameters" [
|
||||
test "idParam succeeds" {
|
||||
|
Loading…
Reference in New Issue
Block a user