Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections;
11 : using System.Collections.Generic;
12 : using System.Linq;
13 : using System.Linq.Expressions;
14 : using Cqrs.Azure.DocumentDb.Entities;
15 : using Cqrs.DataStores;
16 : using cdmdotnet.Logging;
17 : using Cqrs.Entities;
18 : using Microsoft.Azure.Documents;
19 : using Microsoft.Azure.Documents.Client;
20 : using Microsoft.Azure.Documents.Linq;
21 :
22 : namespace Cqrs.Azure.DocumentDb.DataStores
23 : {
24 : public class AzureDocumentDbDataStore<TData> : IDataStore<TData>
25 : where TData : AzureDocumentDbEntity
26 0 : {
27 : protected DocumentClient AzureDocumentDbClient { get; private set; }
28 :
29 : protected Database AzureDocumentDbDatabase { get; private set; }
30 :
31 : protected DocumentCollection AzureDocumentDbCollection { get; private set; }
32 :
33 : protected IOrderedQueryable<TData> AzureDocumentDbQuery { get; private set; }
34 :
35 : protected IAzureDocumentDbHelper AzureDocumentDbHelper { get; private set; }
36 :
37 : protected ILogger Logger { get; private set; }
38 :
39 0 : public AzureDocumentDbDataStore(ILogger logger, DocumentClient azureDocumentDbClient, Database azureDocumentDbDatabase, DocumentCollection azureDocumentDbCollection, IOrderedQueryable<TData> azureDocumentDbQuery, IAzureDocumentDbHelper azureDocumentDbHelper)
40 : {
41 : Logger = logger;
42 : AzureDocumentDbClient = azureDocumentDbClient;
43 : AzureDocumentDbDatabase = azureDocumentDbDatabase;
44 : AzureDocumentDbCollection = azureDocumentDbCollection;
45 : AzureDocumentDbQuery = azureDocumentDbQuery;
46 : AzureDocumentDbHelper = azureDocumentDbHelper;
47 : }
48 :
49 : #region Implementation of IEnumerable
50 :
51 : /// <summary>
52 : /// Returns an enumerator that iterates through the collection.
53 : /// </summary>
54 : /// <returns>
55 : /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
56 : /// </returns>
57 : /// <filterpriority>1</filterpriority>
58 1 : public IEnumerator<TData> GetEnumerator()
59 : {
60 : Logger.LogDebug("Getting the enumerator for an Azure database query", "AzureDocumentDbDataStore\\GetEnumerator");
61 : try
62 : {
63 : DateTime start = DateTime.Now;
64 : IEnumerator<TData> result = AzureDocumentDbHelper.ExecuteFaultTollerantFunction(() => AzureDocumentDbQuery.GetEnumerator());
65 : DateTime end = DateTime.Now;
66 : Logger.LogDebug(string.Format("Getting the enumerator for an Azure database query took {0}", end - start), "AzureDocumentDbDataStore\\GetEnumerator");
67 : return result;
68 : }
69 : finally
70 : {
71 : Logger.LogDebug("Getting the enumerator for an Azure database query... Done", "AzureDocumentDbDataStore\\GetEnumerator");
72 : }
73 : }
74 :
75 : /// <summary>
76 : /// Returns an enumerator that iterates through a collection.
77 : /// </summary>
78 : /// <returns>
79 : /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
80 : /// </returns>
81 : /// <filterpriority>2</filterpriority>
82 : IEnumerator IEnumerable.GetEnumerator()
83 : {
84 : return GetEnumerator();
85 : }
86 :
87 : #endregion
88 :
89 : #region Implementation of IQueryable
90 :
91 : /// <summary>
92 : /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable"/>.
93 : /// </summary>
94 : /// <returns>
95 : /// The <see cref="T:System.Linq.Expressions.Expression"/> that is associated with this instance of <see cref="T:System.Linq.IQueryable"/>.
96 : /// </returns>
97 : public Expression Expression
98 : {
99 : get { return AzureDocumentDbQuery.Expression; }
100 : }
101 :
102 : /// <summary>
103 : /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable"/> is executed.
104 : /// </summary>
105 : /// <returns>
106 : /// A <see cref="T:System.Type"/> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.
107 : /// </returns>
108 : public Type ElementType
109 : {
110 : get { return AzureDocumentDbQuery.ElementType; }
111 : }
112 :
113 : /// <summary>
114 : /// Gets the singleResultQuery provider that is associated with this data source.
115 : /// </summary>
116 : /// <returns>
117 : /// The <see cref="T:System.Linq.IQueryProvider"/> that is associated with this data source.
118 : /// </returns>
119 : public IQueryProvider Provider
120 : {
121 : get { return AzureDocumentDbQuery.Provider; }
122 : }
123 :
124 : #endregion
125 :
126 : #region Implementation of IDataStore<TData>
127 :
128 1 : public void Add(TData data)
129 : {
130 : Logger.LogDebug("Adding data to the Azure database", "AzureDocumentDbDataStore\\Add");
131 : try
132 : {
133 : DateTime start = DateTime.Now;
134 : ResourceResponse<Document> result = AzureDocumentDbHelper.ExecuteFaultTollerantFunction(() => AzureDocumentDbClient.CreateDocumentAsync((AzureDocumentDbCollection).SelfLink, data).Result);
135 : DateTime end = DateTime.Now;
136 : Logger.LogDebug(string.Format("Adding data in the Azure database took {0} and cost:r\n{1}", end - start, result), "AzureDocumentDbDataStore\\Add");
137 : }
138 : finally
139 : {
140 : Logger.LogDebug("Adding data to the Azure database... Done", "AzureDocumentDbDataStore\\Add");
141 : }
142 : }
143 :
144 1 : public void Add(IEnumerable<TData> data)
145 : {
146 : Logger.LogDebug("Adding data collection to the Azure database", "AzureDocumentDbDataStore\\Add");
147 : try
148 : {
149 : foreach (TData model in data)
150 : {
151 : Add(model);
152 : }
153 : }
154 : finally
155 : {
156 : Logger.LogDebug("Adding data collection to the Azure database... Done", "AzureDocumentDbDataStore\\Add");
157 : }
158 : }
159 :
160 : /// <summary>
161 : /// Will mark the <paramref name="data"/> as logically (or soft) by setting <see cref="Entity.IsLogicallyDeleted"/> to true
162 : /// </summary>
163 1 : public void Remove(TData data)
164 : {
165 : Logger.LogDebug("Removing data from the Azure database", "AzureDocumentDbDataStore\\Remove");
166 : try
167 : {
168 : data.IsLogicallyDeleted = true;
169 : Update(data);
170 : }
171 : finally
172 : {
173 : Logger.LogDebug("Removing data from the Azure database... Done", "AzureDocumentDbDataStore\\Remove");
174 : }
175 : }
176 :
177 1 : public void Destroy(TData data)
178 : {
179 : Logger.LogDebug("Destroying data from the Azure database", "AzureDocumentDbDataStore\\Destroy");
180 : try
181 : {
182 : Logger.LogDebug("Getting existing document from the Azure database", "AzureDocumentDbDataStore\\Destroy");
183 : DateTime start = DateTime.Now;
184 : Document documentToUpdate = AzureDocumentDbClient.CreateDocumentQuery(AzureDocumentDbCollection.DocumentsLink)
185 : .Where(d => d.Id == data.id)
186 : .AsEnumerable()
187 : .Single();
188 : DateTime mid = DateTime.Now;
189 : Logger.LogDebug(string.Format("Getting existing document from the Azure database took {0}", mid - start), "AzureDocumentDbDataStore\\Destroy");
190 : Logger.LogDebug("Destroying existing document in the Azure database", "AzureDocumentDbDataStore\\Destroy");
191 : ResourceResponse<Document> result = AzureDocumentDbHelper.ExecuteFaultTollerantFunction(() => AzureDocumentDbClient.DeleteDocumentAsync(documentToUpdate.SelfLink).Result);
192 : DateTime end = DateTime.Now;
193 : Logger.LogDebug(string.Format("Destroying existing document in the Azure database took {0} and cost:r\n{1}", end - mid, result), "AzureDocumentDbDataStore\\Destroy");
194 : }
195 : finally
196 : {
197 : Logger.LogDebug("Destroying data from the Azure database... Done", "AzureDocumentDbDataStore\\Destroy");
198 : }
199 : }
200 :
201 1 : public void RemoveAll()
202 : {
203 : Logger.LogDebug("Removing all from the Azure database", "AzureDocumentDbDataStore\\RemoveAll");
204 : try
205 : {
206 : ResourceResponse<DocumentCollection> result = AzureDocumentDbHelper.ExecuteFaultTollerantFunction(() => AzureDocumentDbClient.DeleteDocumentCollectionAsync(AzureDocumentDbCollection.SelfLink, new RequestOptions()).Result);
207 : }
208 : finally
209 : {
210 : Logger.LogDebug("Removing all from the Azure database... Done", "AzureDocumentDbDataStore\\RemoveAll");
211 : }
212 : }
213 :
214 1 : public void Update(TData data)
215 : {
216 : Logger.LogDebug("Updating data in the Azure database", "AzureDocumentDbDataStore\\Update");
217 : try
218 : {
219 : Logger.LogDebug("Getting existing document from the Azure database", "AzureDocumentDbDataStore\\Update");
220 : DateTime start = DateTime.Now;
221 : Document documentToUpdate = AzureDocumentDbClient.CreateDocumentQuery(AzureDocumentDbCollection.DocumentsLink)
222 : .Where(d => d.Id == data.id)
223 : .AsEnumerable()
224 : .Single();
225 : DateTime mid = DateTime.Now;
226 : Logger.LogDebug(string.Format("Getting existing document from the Azure database took {0}", mid - start), "AzureDocumentDbDataStore\\Update");
227 : Logger.LogDebug("Replacing existing document in the Azure database", "AzureDocumentDbDataStore\\Update");
228 : ResourceResponse<Document> result = AzureDocumentDbHelper.ExecuteFaultTollerantFunction(() => AzureDocumentDbClient.ReplaceDocumentAsync(documentToUpdate.SelfLink, data).Result);
229 : DateTime end = DateTime.Now;
230 : Logger.LogDebug(string.Format("Replacing existing document in the Azure database took {0} and cost:r\n{1}", end - mid, result), "AzureDocumentDbDataStore\\Update");
231 : }
232 : finally
233 : {
234 : Logger.LogDebug("Updating data in the Azure database... Done", "AzureDocumentDbDataStore\\Update");
235 : }
236 : }
237 :
238 : #endregion
239 :
240 : #region Implementation of IDisposable
241 :
242 : /// <summary>
243 : /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
244 : /// </summary>
245 1 : public void Dispose()
246 : {
247 : AzureDocumentDbClient.Dispose();
248 : }
249 :
250 : #endregion
251 :
252 : /// <summary>
253 : /// Returns the instance as an <see cref="IEnumerable{T}"/>.
254 : /// </summary>
255 : /// <returns></returns>
256 1 : public IEnumerable<TData> AsEnumerable()
257 : {
258 : return AzureDocumentDbQuery.AsEnumerable();
259 : }
260 : }
261 : }
|