Skip to content

Commit 2bef71f

Browse files
committed
Merge branch 'main' into emulator-integration
2 parents 3c11a84 + b6d5dab commit 2bef71f

6 files changed

Lines changed: 248 additions & 155 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog for `FSharp.CosmosDb`
22

3+
## [1.1.0] - 2022-07-18
4+
5+
### Added
6+
7+
- Can now delete a container, thanks to [#64](https://github.com/aaronpowell/FSharp.CosmosDb/pull/64)
8+
- Can now create a container (to be inline with delete features)
9+
310
## [1.0.0] - 2022-04-16
411

512
**This release has breaking changes from pre-v1**

paket.lock

Lines changed: 91 additions & 108 deletions
Large diffs are not rendered by default.

src/FSharp.CosmosDb.Analyzer/CosmosCodeAnalysis.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ module CosmosCodeAnalysis =
284284
match ctx.ParseTree with
285285
| ParsedInput.ImplFile input ->
286286
match input with
287-
| ParsedImplFileInput (_, _, _, _, _, modules, _) ->
287+
| ParsedImplFileInput (_, _, _, _, _, modules, _, _) ->
288288
for parsedModule in modules do
289289
match parsedModule with
290290
| SynModuleOrNamespace (_, _, _, declarations, _, _, _, _) ->

src/FSharp.CosmosDb/Cosmos.fs

Lines changed: 80 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,22 @@ module Cosmos =
1616

1717
let fromConnectionString connString =
1818
{ defaultConnectionOp () with
19-
FromConnectionString = true
20-
ConnectionString = Some connString }
19+
FromConnectionString = true
20+
ConnectionString = Some connString }
2121

2222
let fromConnectionStringWithOptions connString op =
2323
{ defaultConnectionOp () with
24-
Options = Some op
25-
FromConnectionString = true
26-
ConnectionString = Some connString }
24+
Options = Some op
25+
FromConnectionString = true
26+
ConnectionString = Some connString }
2727

2828
let host endpoint =
29-
{ defaultConnectionOp () with
30-
Endpoint = Some endpoint }
29+
{ defaultConnectionOp () with Endpoint = Some endpoint }
3130

3231
let connectWithOptions options accessKey op =
3332
{ op with
34-
Options = Some options
35-
AccessKey = accessKey }
33+
Options = Some options
34+
AccessKey = accessKey }
3635

3736
let connect accessKey op = { op with AccessKey = Some accessKey }
3837

@@ -49,31 +48,35 @@ module Cosmos =
4948

5049
let query<'T> query op : QueryOp<'T> =
5150
{ defaultQueryOp () with
52-
Query = Some query
53-
Connection = op }
51+
Query = Some query
52+
Connection = op }
5453

5554
let parameters arr op =
5655
{ op with QueryOp.Parameters = op.Parameters @ arr }
57-
56+
5857
// --- DATABASE EXISTS --- //
5958
let databaseExists<'T> op =
6059
{ CheckIfDatabaseExistsOp.Connection = op }
6160

6261
// --- INSERT --- //
6362

6463
let insertMany<'T> (values: 'T list) op =
65-
{ InsertOp.Connection = op; Values = values }
64+
{ InsertOp.Connection = op
65+
Values = values }
6666

6767
let insert<'T> (value: 'T) op =
68-
{ InsertOp.Connection = op; Values = [ value ] }
68+
{ InsertOp.Connection = op
69+
Values = [ value ] }
6970

7071
// --- INSERT --- //
7172

7273
let upsertMany<'T> (values: 'T list) op =
73-
{ UpsertOp.Connection = op; Values = values }
74+
{ UpsertOp.Connection = op
75+
Values = values }
7476

7577
let upsert<'T> (value: 'T) op =
76-
{ UpsertOp.Connection = op; Values = [ value ] }
78+
{ UpsertOp.Connection = op
79+
Values = [ value ] }
7780

7881
// --- UPDATE --- //
7982

@@ -89,19 +92,24 @@ module Cosmos =
8992
{ DeleteItemOp.Connection = op
9093
Id = id
9194
PartitionKey = partitionKey }
92-
95+
9396
// --- GET CONTAINER PROPERTIES --- //
9497
let getContainerProperties op =
9598
{ GetContainerPropertiesOp.Connection = op }
96-
99+
97100
// --- CONTAINER EXISTS --- //
98101
let containerExists op =
99102
{ CheckIfContainerExistsOp.Connection = op }
100-
103+
104+
// --- CREATE CONTAINER --- //
105+
let createContainer<'T> op : CreateContainerOp<'T> = { CreateContainerOp.Connection = op }
106+
107+
let createContainerIfNotExists<'T> op : CreateContainerIfNotExistsOp<'T> =
108+
{ CreateContainerIfNotExistsOp.Connection = op }
109+
101110
// --- DELETE CONTAINER --- //
102111

103-
let deleteContainer<'T> op : DeleteContainerOp<'T> =
104-
{ DeleteContainerOp.Connection = op }
112+
let deleteContainer<'T> op : DeleteContainerOp<'T> = { DeleteContainerOp.Connection = op }
105113

106114
// --- DELETE CONTAINER IF EXISTS --- //
107115

@@ -118,7 +126,8 @@ module Cosmos =
118126
// --- REPLACE --- //
119127

120128
let replace<'T> (item: 'T) op =
121-
{ ReplaceOp.Connection = op; Item = item }
129+
{ ReplaceOp.Connection = op
130+
Item = item }
122131

123132
// --- Execute --- //
124133

@@ -170,24 +179,19 @@ module Cosmos =
170179
MaxItems = None }
171180

172181
let withInstanceName<'T> name changeFeedInfo : ChangeFeedOptions<'T> =
173-
{ changeFeedInfo with
174-
InstanceName = Some name }
182+
{ changeFeedInfo with InstanceName = Some name }
175183

176184
let leaseContainer<'T> leaseContainerInfo changeFeedInfo : ChangeFeedOptions<'T> =
177-
{ changeFeedInfo with
178-
LeaseContainer = Some leaseContainerInfo }
185+
{ changeFeedInfo with LeaseContainer = Some leaseContainerInfo }
179186

180187
let pollingInterval<'T> interval changeFeedInfo : ChangeFeedOptions<'T> =
181-
{ changeFeedInfo with
182-
PollingInterval = Some interval }
188+
{ changeFeedInfo with PollingInterval = Some interval }
183189

184190
let startTime<'T> startTime changeFeedInfo : ChangeFeedOptions<'T> =
185-
{ changeFeedInfo with
186-
StartTime = Some startTime }
191+
{ changeFeedInfo with StartTime = Some startTime }
187192

188193
let maxItems<'T> maxItems changeFeedInfo : ChangeFeedOptions<'T> =
189-
{ changeFeedInfo with
190-
MaxItems = Some maxItems }
194+
{ changeFeedInfo with MaxItems = Some maxItems }
191195

192196
let build<'T> changeFeedInfo =
193197
let processor =
@@ -233,18 +237,48 @@ module Cosmos =
233237
processor.Build()
234238
| None ->
235239
failwith "Unable to connect the change feed. Ensure the container and lease container info is all set"
236-
240+
237241
type Cosmos =
238-
static member private getClient (connInfo: ConnectionOperation) = connInfo.GetClient()
239-
static member execAsync (op: QueryOp<'T>) = OperationHandling.execQuery Cosmos.getClient op
240-
static member execAsync op = OperationHandling.execCheckIfDatabaseExists Cosmos.getClient op
241-
static member execAsync op = OperationHandling.execInsert Cosmos.getClient op
242-
static member execAsync op = OperationHandling.execUpdate Cosmos.getClient op
243-
static member execAsync op = OperationHandling.execDeleteItem Cosmos.getClient op
244-
static member execAsync op = OperationHandling.execGetContainerProperties Cosmos.getClient op
245-
static member execAsync op = OperationHandling.execCheckIfContainerExists Cosmos.getClient op
246-
static member execAsync op = OperationHandling.execDeleteContainer Cosmos.getClient op
247-
static member execAsync op = OperationHandling.execDeleteContainerIfExists Cosmos.getClient op
248-
static member execAsync op = OperationHandling.execUpsert Cosmos.getClient op
249-
static member execAsync op = OperationHandling.execRead Cosmos.getClient op
250-
static member execAsync op = OperationHandling.execReplace Cosmos.getClient op
242+
static member private getClient(connInfo: ConnectionOperation) = connInfo.GetClient()
243+
244+
static member execAsync(op: QueryOp<'T>) =
245+
OperationHandling.execQuery Cosmos.getClient op
246+
247+
static member execAsync op =
248+
OperationHandling.execCheckIfDatabaseExists Cosmos.getClient op
249+
250+
static member execAsync op =
251+
OperationHandling.execInsert Cosmos.getClient op
252+
253+
static member execAsync op =
254+
OperationHandling.execUpdate Cosmos.getClient op
255+
256+
static member execAsync op =
257+
OperationHandling.execDeleteItem Cosmos.getClient op
258+
259+
static member execAsync op =
260+
OperationHandling.execGetContainerProperties Cosmos.getClient op
261+
262+
static member execAsync op =
263+
OperationHandling.execCheckIfContainerExists Cosmos.getClient op
264+
265+
static member execAsync op =
266+
OperationHandling.execDeleteContainer Cosmos.getClient op
267+
268+
static member execAsync op =
269+
OperationHandling.execDeleteContainerIfExists Cosmos.getClient op
270+
271+
static member execAsync op =
272+
OperationHandling.execUpsert Cosmos.getClient op
273+
274+
static member execAsync op =
275+
OperationHandling.execRead Cosmos.getClient op
276+
277+
static member execAsync op =
278+
OperationHandling.execReplace Cosmos.getClient op
279+
280+
static member execAsync op =
281+
OperationHandling.execCreateContainer Cosmos.getClient op
282+
283+
static member execAsync op =
284+
OperationHandling.execCreateContainerIfNotExists Cosmos.getClient op

src/FSharp.CosmosDb/OperationHandling.fs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,68 @@ let execReplace (getClient: ConnectionOperation -> CosmosClient) (op: ReplaceOp<
360360
} ]
361361
|> AsyncSeq.ofSeqAsync
362362
| None -> failwith "Unable to read from the container to replace item"
363+
364+
let execCreateContainer (getClient: ConnectionOperation -> CosmosClient) (op: CreateContainerOp<'T>) =
365+
let connInfo = op.Connection
366+
let client = getClient connInfo
367+
368+
let result =
369+
maybe {
370+
let! databaseId = connInfo.DatabaseId
371+
let! containerName = connInfo.ContainerName
372+
373+
let db = client.GetDatabase databaseId
374+
375+
let! partitionKey = PartitionKeyAttributeTools.findPartitionKey<'T> ()
376+
377+
let properties = ContainerProperties(containerName, sprintf "/%s" partitionKey.Name)
378+
379+
return
380+
db.CreateContainerAsync properties
381+
|> Async.AwaitTask
382+
}
383+
384+
match result with
385+
| Some result ->
386+
[ async {
387+
let! res = result
388+
return res.Resource
389+
} ]
390+
|> AsyncSeq.ofSeqAsync
391+
| None ->
392+
failwith
393+
"Unable to create the container. Ensure the name is valid and there is a partition key defined on the type"
394+
395+
let execCreateContainerIfNotExists
396+
(getClient: ConnectionOperation -> CosmosClient)
397+
(op: CreateContainerIfNotExistsOp<'T>)
398+
=
399+
let connInfo = op.Connection
400+
let client = getClient connInfo
401+
402+
let result =
403+
maybe {
404+
let! databaseId = connInfo.DatabaseId
405+
let! containerName = connInfo.ContainerName
406+
407+
let db = client.GetDatabase databaseId
408+
409+
let! partitionKey = PartitionKeyAttributeTools.findPartitionKey<'T> ()
410+
411+
let properties = ContainerProperties(containerName, sprintf "/%s" partitionKey.Name)
412+
413+
return
414+
db.CreateContainerIfNotExistsAsync properties
415+
|> Async.AwaitTask
416+
}
417+
418+
match result with
419+
| Some result ->
420+
[ async {
421+
let! res = result
422+
return res.Resource
423+
} ]
424+
|> AsyncSeq.ofSeqAsync
425+
| None ->
426+
failwith
427+
"Unable to create the container. Ensure the name is valid and there is a partition key defined on the type"

src/FSharp.CosmosDb/Types.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ type GetContainerPropertiesOp = { Connection: ConnectionOperation }
109109

110110
type CheckIfContainerExistsOp = { Connection: ConnectionOperation }
111111

112+
type CreateContainerOp<'T> = { Connection: ConnectionOperation }
113+
114+
type CreateContainerIfNotExistsOp<'T> = { Connection: ConnectionOperation }
115+
112116
type DeleteContainerOp<'T> = { Connection: ConnectionOperation }
113117

114118
type DeleteContainerIfExistsOp = { Connection: ConnectionOperation }

0 commit comments

Comments
 (0)