Skip to content
This repository was archived by the owner on Jun 7, 2024. It is now read-only.

Commit 06daa4e

Browse files
V3 rc2 (#2)
- Implements `Field` type for by-field actions (**BREAKING**) - Adds `RemoveFields*` functions/methods for removing fields from documents
1 parent 68ad874 commit 06daa4e

19 files changed

+1701
-291
lines changed

src/Common/BitBadger.Documents.Common.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<PackageReleaseNotes>Initial release (RC 1)</PackageReleaseNotes>
4+
<PackageReleaseNotes>Added Field type for by-field operations</PackageReleaseNotes>
55
<PackageTags>JSON Document SQL</PackageTags>
66
</PropertyGroup>
77

src/Common/Library.fs

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,51 @@ type Op =
3232
| NEX -> "IS NULL"
3333

3434

35+
/// Criteria for a field WHERE clause
36+
type Field = {
37+
/// The name of the field
38+
Name: string
39+
40+
/// The operation by which the field will be compared
41+
Op: Op
42+
43+
/// The value of the field
44+
Value: obj
45+
} with
46+
47+
/// Create an equals (=) field criterion
48+
static member EQ name (value: obj) =
49+
{ Name = name; Op = EQ; Value = value }
50+
51+
/// Create a greater than (>) field criterion
52+
static member GT name (value: obj) =
53+
{ Name = name; Op = GT; Value = value }
54+
55+
/// Create a greater than or equal to (>=) field criterion
56+
static member GE name (value: obj) =
57+
{ Name = name; Op = GE; Value = value }
58+
59+
/// Create a less than (<) field criterion
60+
static member LT name (value: obj) =
61+
{ Name = name; Op = LT; Value = value }
62+
63+
/// Create a less than or equal to (<=) field criterion
64+
static member LE name (value: obj) =
65+
{ Name = name; Op = LE; Value = value }
66+
67+
/// Create a not equals (<>) field criterion
68+
static member NE name (value: obj) =
69+
{ Name = name; Op = NE; Value = value }
70+
71+
/// Create an exists (IS NOT NULL) field criterion
72+
static member EX name =
73+
{ Name = name; Op = EX; Value = obj () }
74+
75+
/// Create an not exists (IS NULL) field criterion
76+
static member NEX name =
77+
{ Name = name; Op = NEX; Value = obj () }
78+
79+
3580
/// The required document serialization implementation
3681
type IDocumentSerializer =
3782

@@ -107,17 +152,14 @@ module Query =
107152

108153
/// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
109154
[<CompiledName "WhereByField">]
110-
let whereByField fieldName op paramName =
111-
let theRest =
112-
match op with
113-
| EX | NEX -> string op
114-
| _ -> $"{op} %s{paramName}"
115-
$"data ->> '%s{fieldName}' {theRest}"
155+
let whereByField field paramName =
156+
let theRest = match field.Op with EX | NEX -> string field.Op | _ -> $"{field.Op} %s{paramName}"
157+
$"data ->> '%s{field.Name}' {theRest}"
116158

117159
/// Create a WHERE clause fragment to implement an ID-based query
118160
[<CompiledName "WhereById">]
119161
let whereById paramName =
120-
whereByField (Configuration.idField ()) EQ paramName
162+
whereByField (Field.EQ (Configuration.idField ()) 0) paramName
121163

122164
/// Queries to define tables and indexes
123165
module Definition =
@@ -178,8 +220,8 @@ module Query =
178220

179221
/// Query to count matching documents using a text comparison on a JSON field
180222
[<CompiledName "ByField">]
181-
let byField tableName fieldName op =
182-
$"""SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByField fieldName op "@field"}"""
223+
let byField tableName field =
224+
$"""SELECT COUNT(*) AS it FROM %s{tableName} WHERE {whereByField field "@field"}"""
183225

184226
/// Queries for determining document existence
185227
module Exists =
@@ -191,8 +233,8 @@ module Query =
191233

192234
/// Query to determine if documents exist using a comparison on a JSON field
193235
[<CompiledName "ByField">]
194-
let byField tableName fieldName op =
195-
$"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereByField fieldName op "@field"}) AS it"""
236+
let byField tableName field =
237+
$"""SELECT EXISTS (SELECT 1 FROM %s{tableName} WHERE {whereByField field "@field"}) AS it"""
196238

197239
/// Queries for retrieving documents
198240
module Find =
@@ -204,8 +246,8 @@ module Query =
204246

205247
/// Query to retrieve documents using a comparison on a JSON field
206248
[<CompiledName "ByField">]
207-
let byField tableName fieldName op =
208-
$"""{selectFromTable tableName} WHERE {whereByField fieldName op "@field"}"""
249+
let byField tableName field =
250+
$"""{selectFromTable tableName} WHERE {whereByField field "@field"}"""
209251

210252
/// Queries to delete documents
211253
module Delete =
@@ -217,5 +259,5 @@ module Query =
217259

218260
/// Query to delete documents using a comparison on a JSON field
219261
[<CompiledName "ByField">]
220-
let byField tableName fieldName op =
221-
$"""DELETE FROM %s{tableName} WHERE {whereByField fieldName op "@field"}"""
262+
let byField tableName field =
263+
$"""DELETE FROM %s{tableName} WHERE {whereByField field "@field"}"""

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<AssemblyVersion>3.0.0.0</AssemblyVersion>
77
<FileVersion>3.0.0.0</FileVersion>
88
<VersionPrefix>3.0.0</VersionPrefix>
9-
<VersionSuffix>rc-1</VersionSuffix>
9+
<VersionSuffix>rc-2</VersionSuffix>
1010
<Authors>danieljsummers</Authors>
1111
<Company>Bit Badger Solutions</Company>
1212
<PackageReadmeFile>README.md</PackageReadmeFile>

src/Postgres/BitBadger.Documents.Postgres.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<PackageReleaseNotes>Initial release; migrated from BitBadger.Npgsql.Documents, with field and extension additions (RC 1)</PackageReleaseNotes>
4+
<PackageReleaseNotes>Adds Field type for by-field operations (BREAKING from rc-1); adds RemoveFields* functions</PackageReleaseNotes>
55
<PackageTags>JSON Document PostgreSQL Npgsql</PackageTags>
66
</PropertyGroup>
77

src/Postgres/Extensions.fs

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ module Extensions =
5050
WithProps.Count.all tableName (Sql.existingConnection conn)
5151

5252
/// Count matching documents using a JSON field comparison query (->> =)
53-
member conn.countByField tableName fieldName op (value: obj) =
54-
WithProps.Count.byField tableName fieldName op value (Sql.existingConnection conn)
53+
member conn.countByField tableName field =
54+
WithProps.Count.byField tableName field (Sql.existingConnection conn)
5555

5656
/// Count matching documents using a JSON containment query (@>)
5757
member conn.countByContains tableName criteria =
@@ -66,8 +66,8 @@ module Extensions =
6666
WithProps.Exists.byId tableName docId (Sql.existingConnection conn)
6767

6868
/// Determine if documents exist using a JSON field comparison query (->> =)
69-
member conn.existsByField tableName fieldName op (value: obj) =
70-
WithProps.Exists.byField tableName fieldName op value (Sql.existingConnection conn)
69+
member conn.existsByField tableName field =
70+
WithProps.Exists.byField tableName field (Sql.existingConnection conn)
7171

7272
/// Determine if documents exist using a JSON containment query (@>)
7373
member conn.existsByContains tableName criteria =
@@ -86,8 +86,8 @@ module Extensions =
8686
WithProps.Find.byId<'TKey, 'TDoc> tableName docId (Sql.existingConnection conn)
8787

8888
/// Retrieve documents matching a JSON field comparison query (->> =)
89-
member conn.findByField<'TDoc> tableName fieldName op (value: obj) =
90-
WithProps.Find.byField<'TDoc> tableName fieldName op value (Sql.existingConnection conn)
89+
member conn.findByField<'TDoc> tableName field =
90+
WithProps.Find.byField<'TDoc> tableName field (Sql.existingConnection conn)
9191

9292
/// Retrieve documents matching a JSON containment query (@>)
9393
member conn.findByContains<'TDoc> tableName (criteria: obj) =
@@ -98,8 +98,8 @@ module Extensions =
9898
WithProps.Find.byJsonPath<'TDoc> tableName jsonPath (Sql.existingConnection conn)
9999

100100
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
101-
member conn.findFirstByField<'TDoc> tableName fieldName op (value: obj) =
102-
WithProps.Find.firstByField<'TDoc> tableName fieldName op value (Sql.existingConnection conn)
101+
member conn.findFirstByField<'TDoc> tableName field =
102+
WithProps.Find.firstByField<'TDoc> tableName field (Sql.existingConnection conn)
103103

104104
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found
105105
member conn.findFirstByContains<'TDoc> tableName (criteria: obj) =
@@ -122,8 +122,8 @@ module Extensions =
122122
WithProps.Patch.byId tableName docId patch (Sql.existingConnection conn)
123123

124124
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
125-
member conn.patchByField tableName fieldName op (value: obj) (patch: 'TPatch) =
126-
WithProps.Patch.byField tableName fieldName op value patch (Sql.existingConnection conn)
125+
member conn.patchByField tableName field (patch: 'TPatch) =
126+
WithProps.Patch.byField tableName field patch (Sql.existingConnection conn)
127127

128128
/// Patch documents using a JSON containment query in the WHERE clause (@>)
129129
member conn.patchByContains tableName (criteria: 'TCriteria) (patch: 'TPatch) =
@@ -133,13 +133,29 @@ module Extensions =
133133
member conn.patchByJsonPath tableName jsonPath (patch: 'TPatch) =
134134
WithProps.Patch.byJsonPath tableName jsonPath patch (Sql.existingConnection conn)
135135

136+
/// Remove fields from a document by the document's ID
137+
member conn.removeFieldsById tableName (docId: 'TKey) fieldNames =
138+
WithProps.RemoveFields.byId tableName docId fieldNames (Sql.existingConnection conn)
139+
140+
/// Remove fields from documents via a comparison on a JSON field in the document
141+
member conn.removeFieldsByField tableName field fieldNames =
142+
WithProps.RemoveFields.byField tableName field fieldNames (Sql.existingConnection conn)
143+
144+
/// Remove fields from documents via a JSON containment query (@>)
145+
member conn.removeFieldsByContains tableName (criteria: 'TContains) fieldNames =
146+
WithProps.RemoveFields.byContains tableName criteria fieldNames (Sql.existingConnection conn)
147+
148+
/// Remove fields from documents via a JSON Path match query (@?)
149+
member conn.removeFieldsByJsonPath tableName jsonPath fieldNames =
150+
WithProps.RemoveFields.byJsonPath tableName jsonPath fieldNames (Sql.existingConnection conn)
151+
136152
/// Delete a document by its ID
137153
member conn.deleteById tableName (docId: 'TKey) =
138154
WithProps.Delete.byId tableName docId (Sql.existingConnection conn)
139155

140156
/// Delete documents by matching a JSON field comparison query (->> =)
141-
member conn.deleteByField tableName fieldName op (value: obj) =
142-
WithProps.Delete.byField tableName fieldName op value (Sql.existingConnection conn)
157+
member conn.deleteByField tableName field =
158+
WithProps.Delete.byField tableName field (Sql.existingConnection conn)
143159

144160
/// Delete documents by matching a JSON containment query (@>)
145161
member conn.deleteByContains tableName (criteria: 'TContains) =
@@ -209,8 +225,8 @@ type NpgsqlConnectionCSharpExtensions =
209225

210226
/// Count matching documents using a JSON field comparison query (->> =)
211227
[<Extension>]
212-
static member inline CountByField(conn, tableName, fieldName, op, value: obj) =
213-
WithProps.Count.byField tableName fieldName op value (Sql.existingConnection conn)
228+
static member inline CountByField(conn, tableName, field) =
229+
WithProps.Count.byField tableName field (Sql.existingConnection conn)
214230

215231
/// Count matching documents using a JSON containment query (@>)
216232
[<Extension>]
@@ -229,8 +245,8 @@ type NpgsqlConnectionCSharpExtensions =
229245

230246
/// Determine if documents exist using a JSON field comparison query (->> =)
231247
[<Extension>]
232-
static member inline ExistsByField(conn, tableName, fieldName, op, value: obj) =
233-
WithProps.Exists.byField tableName fieldName op value (Sql.existingConnection conn)
248+
static member inline ExistsByField(conn, tableName, field) =
249+
WithProps.Exists.byField tableName field (Sql.existingConnection conn)
234250

235251
/// Determine if documents exist using a JSON containment query (@>)
236252
[<Extension>]
@@ -254,8 +270,8 @@ type NpgsqlConnectionCSharpExtensions =
254270

255271
/// Retrieve documents matching a JSON field comparison query (->> =)
256272
[<Extension>]
257-
static member inline FindByField<'TDoc>(conn, tableName, fieldName, op, value: obj) =
258-
WithProps.Find.ByField<'TDoc>(tableName, fieldName, op, value, Sql.existingConnection conn)
273+
static member inline FindByField<'TDoc>(conn, tableName, field) =
274+
WithProps.Find.ByField<'TDoc>(tableName, field, Sql.existingConnection conn)
259275

260276
/// Retrieve documents matching a JSON containment query (@>)
261277
[<Extension>]
@@ -269,8 +285,8 @@ type NpgsqlConnectionCSharpExtensions =
269285

270286
/// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
271287
[<Extension>]
272-
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, fieldName, op, value: obj) =
273-
WithProps.Find.FirstByField<'TDoc>(tableName, fieldName, op, value, Sql.existingConnection conn)
288+
static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
289+
WithProps.Find.FirstByField<'TDoc>(tableName, field, Sql.existingConnection conn)
274290

275291
/// Retrieve the first document matching a JSON containment query (@>); returns None if not found
276292
[<Extension>]
@@ -299,8 +315,8 @@ type NpgsqlConnectionCSharpExtensions =
299315

300316
/// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
301317
[<Extension>]
302-
static member inline PatchByField(conn, tableName, fieldName, op, value: obj, patch: 'TPatch) =
303-
WithProps.Patch.byField tableName fieldName op value patch (Sql.existingConnection conn)
318+
static member inline PatchByField(conn, tableName, field, patch: 'TPatch) =
319+
WithProps.Patch.byField tableName field patch (Sql.existingConnection conn)
304320

305321
/// Patch documents using a JSON containment query in the WHERE clause (@>)
306322
[<Extension>]
@@ -312,15 +328,35 @@ type NpgsqlConnectionCSharpExtensions =
312328
static member inline PatchByJsonPath(conn, tableName, jsonPath, patch: 'TPatch) =
313329
WithProps.Patch.byJsonPath tableName jsonPath patch (Sql.existingConnection conn)
314330

331+
/// Remove fields from a document by the document's ID
332+
[<Extension>]
333+
static member inline RemoveFieldsById(conn, tableName, docId: 'TKey, fieldNames) =
334+
WithProps.RemoveFields.ById(tableName, docId, fieldNames, Sql.existingConnection conn)
335+
336+
/// Remove fields from documents via a comparison on a JSON field in the document
337+
[<Extension>]
338+
static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) =
339+
WithProps.RemoveFields.ByField(tableName, field, fieldNames, Sql.existingConnection conn)
340+
341+
/// Remove fields from documents via a JSON containment query (@>)
342+
[<Extension>]
343+
static member inline RemoveFieldsByContains(conn, tableName, criteria: 'TContains, fieldNames) =
344+
WithProps.RemoveFields.ByContains(tableName, criteria, fieldNames, Sql.existingConnection conn)
345+
346+
/// Remove fields from documents via a JSON Path match query (@?)
347+
[<Extension>]
348+
static member inline RemoveFieldsByJsonPath(conn, tableName, jsonPath, fieldNames) =
349+
WithProps.RemoveFields.ByJsonPath(tableName, jsonPath, fieldNames, Sql.existingConnection conn)
350+
315351
/// Delete a document by its ID
316352
[<Extension>]
317353
static member inline DeleteById(conn, tableName, docId: 'TKey) =
318354
WithProps.Delete.byId tableName docId (Sql.existingConnection conn)
319355

320356
/// Delete documents by matching a JSON field comparison query (->> =)
321357
[<Extension>]
322-
static member inline DeleteByField(conn, tableName, fieldName, op, value: obj) =
323-
WithProps.Delete.byField tableName fieldName op value (Sql.existingConnection conn)
358+
static member inline DeleteByField(conn, tableName, field) =
359+
WithProps.Delete.byField tableName field (Sql.existingConnection conn)
324360

325361
/// Delete documents by matching a JSON containment query (@>)
326362
[<Extension>]

0 commit comments

Comments
 (0)