-
Notifications
You must be signed in to change notification settings - Fork 175
Expand file tree
/
Copy pathMongoDbStorage.cs
More file actions
114 lines (99 loc) · 4.8 KB
/
MongoDbStorage.cs
File metadata and controls
114 lines (99 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Extensions.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
using Newtonsoft.Json.Linq;
namespace Bot.Builder.Community.Storage.MongoDB
{
public class MongoDbStorage: IStorage
{
private readonly MongoDbStorageOptions _options;
private readonly MongoClient _mongoClient;
/// <summary>
/// Initializes a new instance of the <see cref="MongoDbStorage"/> class.
/// </summary>
/// <param name="options">MongoDb options <see cref="MongoDbStorage"/> class.</param>
public MongoDbStorage(MongoDbStorageOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
if (string.IsNullOrEmpty(options.ConnectionString))
{
throw new ArgumentNullException(nameof(options.ConnectionString));
}
_options = options;
_mongoClient = new MongoClient(options.ConnectionString);
}
/// <summary>
/// Reads storage items from storage.
/// </summary>
/// <param name="keys">keys of the <see cref="IStoreItem"/> objects to read.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A task that represents the work queued to execute.</returns>
/// <remarks>If the activities are successfully sent, the task result contains
/// the items read, indexed by key.</remarks>
/// <seealso cref="DeleteAsync(string[], CancellationToken)"/>
/// <seealso cref="WriteAsync(IDictionary{string, object}, CancellationToken)"/>
public async Task<IDictionary<string, object>> ReadAsync(string[] keys, CancellationToken cancellationToken = new CancellationToken())
{
var filter = Builders<StorageEntry>.Filter
.In(o => o.Id, keys);
var result = await GetCollection().Find(filter).ToListAsync(cancellationToken: cancellationToken);
return result.ToDictionary(x => x.Id, x => x.Data);
}
/// <summary>
/// Writes storage items to storage.
/// </summary>
/// <param name="changes">The items to write, indexed by key.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A task that represents the work queued to execute.</returns>
/// <seealso cref="DeleteAsync(string[], CancellationToken)"/>
/// <seealso cref="ReadAsync(string[], CancellationToken)"/>
public async Task WriteAsync(IDictionary<string, object> changes, CancellationToken cancellationToken = new CancellationToken())
{
var collection = GetCollection();
foreach (var change in changes)
{
var filter = Builders<StorageEntry>.Filter.Eq(o => o.Id, change.Key);
var update = Builders<StorageEntry>.Update.Set(o => o.Data, change.Value);
var options = new UpdateOptions { IsUpsert = true };
await collection.UpdateOneAsync(filter, update, options, cancellationToken);
}
}
/// <summary>
/// Writes storage items to storage.
/// </summary>
/// <param name="changes">The items to write, indexed by key.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A task that represents the work queued to execute.</returns>
/// <seealso cref="DeleteAsync(string[], CancellationToken)"/>
/// <seealso cref="ReadAsync(string[], CancellationToken)"/>
public Task DeleteAsync(string[] keys, CancellationToken cancellationToken = new CancellationToken())
{
var filter = Builders<StorageEntry>.Filter
.In(restaurant => restaurant.Id, keys);
return GetCollection().DeleteManyAsync(filter, cancellationToken);
}
private IMongoCollection<StorageEntry> GetCollection()
{
var database = _mongoClient.GetDatabase(_options.DatabaseName);
var collection = database.GetCollection<StorageEntry>(_options.CollectionName);
return collection;
}
private class StorageEntry
{
public string Id { get; set; }
public object Data { get; set; }
}
}
}