-
Notifications
You must be signed in to change notification settings - Fork 0
/
CosmosDbDataProvider.cs
159 lines (139 loc) · 5.74 KB
/
CosmosDbDataProvider.cs
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
namespace AskForMasksCoreVue
{
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Spatial;
using Microsoft.Extensions.Configuration;
using Models;
public interface IDataProvider
{
MaskRequest[] GetRequests(int count);
ZipSearchResult[] GetRequestsByZipCode(Point point, string originZip, int radiusInMiles);
Brag[] GetBrags(int count);
int GetRequestCount();
Task SaveRequest(MaskRequest request);
Task SaveBrag(Brag brag);
Task SaveMessage(Message message);
Task BulkImport(BulkImportRequest bulk);
}
public class CosmosDbDataProvider : IDataProvider
{
private readonly IGeocodingProvider _geocodingProvider;
private readonly Container _requestContainer;
private readonly Container _bragContainer;
private readonly Container _messageContainer;
private int _maxRecordsToReturn = 100;
public CosmosDbDataProvider(IConfiguration config, IGeocodingProvider geocodingProvider)
{
_geocodingProvider = geocodingProvider;
var cosmosClient = new CosmosClient(config["EndpointUri"], config["PrimaryKey"], new CosmosClientOptions
{
ApplicationName = "AskForMasks",
SerializerOptions = new CosmosSerializationOptions
{
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
}
});
_requestContainer = cosmosClient.GetContainer(config["DatabaseId"], config["RequestContainerId"]);
_bragContainer = cosmosClient.GetContainer(config["DatabaseId"], config["BragContainerId"]);
_messageContainer = cosmosClient.GetContainer(config["DatabaseId"], config["MessageContainerId"]);
}
public MaskRequest[] GetRequests(int count = 100)
{
var results = _requestContainer
.GetItemLinqQueryable<MaskRequest>(true)
.OrderByDescending(x => x.RequestDate)
.Take(Math.Min(count, _maxRecordsToReturn))
.ToArray();
return results;
}
public ZipSearchResult[] GetRequestsByZipCode(Point point, string originZip, int radiusInMiles)
{
var searchResults = _requestContainer
.GetItemLinqQueryable<MaskRequest>(true)
.Where(r => r.Organization.Geolocation.Distance(point) < radiusInMiles * 1609.34)
.Select(r => new ZipSearchResult
{
OriginZip = originZip,
DistanceInMiles = r.Organization.Geolocation.Distance(point) / 1609.34,
Request = r
})
.ToList();
searchResults.ForEach(s => s.DistanceInMiles = Math.Round(s.DistanceInMiles, MidpointRounding.AwayFromZero));
return searchResults
.OrderBy(r => r.DistanceInMiles)
.Take(_maxRecordsToReturn)
.ToArray();
}
public Brag[] GetBrags(int count = 100)
{
var brags = _bragContainer
.GetItemLinqQueryable<Brag>(true)
.OrderByDescending(x => x.SubmittedDate)
.Take(Math.Min(count, _maxRecordsToReturn))
.ToArray();
return brags;
}
public int GetRequestCount()
{
return _requestContainer
.GetItemLinqQueryable<object>(true)
.Count();
}
public async Task SaveRequest(MaskRequest request)
{
if (string.IsNullOrEmpty(request.Id))
{
request.Id = Guid.NewGuid().ToString();
request.RequestDate = DateTime.Now;
}
await _geocodingProvider.Locate(request);
await _requestContainer.UpsertItemAsync(request);
}
public async Task SaveBrag(Brag brag)
{
brag.Id = Guid.NewGuid().ToString();
brag.SubmittedDate = DateTime.Now;
await _bragContainer.CreateItemAsync(brag);
}
public async Task SaveMessage(Message message)
{
message.Id = Guid.NewGuid().ToString();
message.SubmittedDate = DateTime.Now;
await _messageContainer.CreateItemAsync(message);
}
public async Task BulkImport(BulkImportRequest bulk)
{
foreach (var request in bulk.Requests)
{
var name = request.Organization.Name;
var city = request.Organization.City;
var state = request.Organization.State;
var existing = _requestContainer
.GetItemLinqQueryable<MaskRequest>(true)
.Where(x => x.Organization.Name == name
&& x.Organization.City == city
&& x.Organization.State == state)
.Select(x => x)
.ToList();
if (existing.Any())
{
var source = existing.First();
request.Id = source.Id;
request.RequestDate = source.RequestDate;
request.Organization.Geolocation = source.Organization.Geolocation;
await _requestContainer.UpsertItemAsync(request);
}
else
{
request.Id = Guid.NewGuid().ToString();
request.RequestDate = DateTime.Now;
await _geocodingProvider.Locate(request);
await _requestContainer.UpsertItemAsync(request);
}
}
}
}
}