Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software 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.DataStores;
15 : using cdmdotnet.Logging;
16 : using MongoDB.Driver;
17 : using MongoDB.Driver.Linq;
18 : using Cqrs.Entities;
19 : using MongoDB.Driver.Builders;
20 :
21 : namespace Cqrs.Mongo.DataStores
22 : {
23 : /// <summary>
24 : /// A <see cref="IDataStore{TData}"/> that uses MongoDB for storage.
25 : /// </summary>
26 : /// <typeparam name="TData">The <see cref="Type"/> of <see cref="IEntity"/> the <see cref="IDataStore{TData}"/> will contain.</typeparam>
27 : public class MongoDataStore<TData> : IDataStore<TData>
28 : where TData : Entity
29 1 : {
30 : /// <summary>
31 : /// Gets or sets the <see cref="MongoCollection"/>
32 : /// </summary>
33 : protected MongoCollection<TData> MongoCollection { get; private set; }
34 :
35 : /// <summary>
36 : /// Gets or sets the <see cref="ILogger"/>
37 : /// </summary>
38 : protected ILogger Logger { get; private set; }
39 :
40 : /// <summary>
41 : /// Instantiates and Initialises a new instance of the <see cref="MongoDataStore{TData}"/> class.
42 : /// </summary>
43 1 : public MongoDataStore(ILogger logger, MongoCollection<TData> mongoCollection)
44 : {
45 : Logger = logger;
46 : MongoCollection = mongoCollection;
47 : MongoCollection.Database.RequestStart();
48 : }
49 :
50 : #region Implementation of IEnumerable
51 :
52 : /// <summary>
53 : /// Returns an enumerator that iterates through the collection.
54 : /// </summary>
55 : /// <returns>
56 : /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
57 : /// </returns>
58 : /// <filterpriority>1</filterpriority>
59 1 : public IEnumerator<TData> GetEnumerator()
60 : {
61 : return MongoCollection.AsQueryable().GetEnumerator();
62 : }
63 :
64 : /// <summary>
65 : /// Returns an enumerator that iterates through a collection.
66 : /// </summary>
67 : /// <returns>
68 : /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
69 : /// </returns>
70 : /// <filterpriority>2</filterpriority>
71 : IEnumerator IEnumerable.GetEnumerator()
72 : {
73 : return GetEnumerator();
74 : }
75 :
76 : #endregion
77 :
78 : #region Implementation of IQueryable
79 :
80 : /// <summary>
81 : /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable"/>.
82 : /// </summary>
83 : /// <returns>
84 : /// The <see cref="T:System.Linq.Expressions.Expression"/> that is associated with this instance of <see cref="T:System.Linq.IQueryable"/>.
85 : /// </returns>
86 : public Expression Expression
87 : {
88 : get { return MongoCollection.AsQueryable().Expression; }
89 : }
90 :
91 : /// <summary>
92 : /// 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.
93 : /// </summary>
94 : /// <returns>
95 : /// 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.
96 : /// </returns>
97 : public Type ElementType
98 : {
99 : get { return MongoCollection.AsQueryable().ElementType; }
100 : }
101 :
102 : /// <summary>
103 : /// Gets the singleResultQuery provider that is associated with this data source.
104 : /// </summary>
105 : /// <returns>
106 : /// The <see cref="T:System.Linq.IQueryProvider"/> that is associated with this data source.
107 : /// </returns>
108 : public IQueryProvider Provider
109 : {
110 : get { return MongoCollection.AsQueryable().Provider; }
111 : }
112 :
113 : #endregion
114 :
115 : #region Implementation of IDataStore<TData>
116 :
117 : /// <summary>
118 : /// Add the provided <paramref name="data"/> to the data store and persist the change.
119 : /// </summary>
120 1 : public virtual void Add(TData data)
121 : {
122 : Logger.LogDebug("Adding data to the Mongo database", "MongoDataStore\\Add");
123 : try
124 : {
125 : DateTime start = DateTime.Now;
126 : MongoCollection.Insert(data);
127 : DateTime end = DateTime.Now;
128 : Logger.LogDebug(string.Format("Adding data in the Mongo database took {0}.", end - start), "MongoDataStore\\Add");
129 : }
130 : finally
131 : {
132 : Logger.LogDebug("Adding data to the Mongo database... Done", "MongoDataStore\\Add");
133 : }
134 : }
135 :
136 : /// <summary>
137 : /// Add the provided <paramref name="data"/> to the data store and persist the change.
138 : /// </summary>
139 1 : public virtual void Add(IEnumerable<TData> data)
140 : {
141 : Logger.LogDebug("Adding data collection to the Mongo database", "MongoDataStore\\Add");
142 : try
143 : {
144 : MongoCollection.InsertBatch(data);
145 : }
146 : finally
147 : {
148 : Logger.LogDebug("Adding data collection to the Mongo database... Done", "MongoDataStore\\Add");
149 : }
150 : }
151 :
152 : /// <summary>
153 : /// Will mark the <paramref name="data"/> as logically (or soft) by setting <see cref="Entity.IsLogicallyDeleted"/> to true
154 : /// </summary>
155 1 : public virtual void Remove(TData data)
156 : {
157 : Logger.LogDebug("Removing data from the Mongo database", "MongoDataStore\\Remove");
158 : try
159 : {
160 : data.IsLogicallyDeleted = true;
161 : Update(data);
162 : }
163 : finally
164 : {
165 : Logger.LogDebug("Removing data from the Mongo database... Done", "MongoDataStore\\Remove");
166 : }
167 : }
168 :
169 : /// <summary>
170 : /// Remove the provided <paramref name="data"/> (normally by <see cref="IEntity.Rsn"/>) from the data store and persist the change.
171 : /// </summary>
172 1 : public void Destroy(TData data)
173 : {
174 : Logger.LogDebug("Destroying data in the Mongo database", "MongoDataStore\\Destroy");
175 : try
176 : {
177 : DateTime start = DateTime.Now;
178 : MongoCollection.Remove(Query.EQ("Rsn", data.Rsn));
179 : DateTime end = DateTime.Now;
180 : Logger.LogDebug(string.Format("Destroying data in the Mongo database took {0}.", end - start), "MongoDataStore\\Destroy");
181 : }
182 : finally
183 : {
184 : Logger.LogDebug("Destroying data to the Mongo database... Done", "MongoDataStore\\Destroy");
185 : }
186 : }
187 :
188 : /// <summary>
189 : /// Remove all contents (normally by use of a truncate operation) from the data store and persist the change.
190 : /// </summary>
191 1 : public virtual void RemoveAll()
192 : {
193 : Logger.LogDebug("Removing all from the Mongo database", "MongoDataStore\\RemoveAll");
194 : try
195 : {
196 : MongoCollection.RemoveAll();
197 : }
198 : finally
199 : {
200 : Logger.LogDebug("Removing all from the Mongo database... Done", "MongoDataStore\\RemoveAll");
201 : }
202 : }
203 :
204 : /// <summary>
205 : /// Update the provided <paramref name="data"/> in the data store and persist the change.
206 : /// </summary>
207 1 : public virtual void Update(TData data)
208 : {
209 : Logger.LogDebug("Updating data in the Mongo database", "MongoDataStore\\Update");
210 : try
211 : {
212 : DateTime start = DateTime.Now;
213 : MongoCollection.Save(data);
214 : DateTime end = DateTime.Now;
215 : Logger.LogDebug(string.Format("Updating data in the Mongo database took {0}.", end - start), "MongoDataStore\\Update");
216 : }
217 : finally
218 : {
219 : Logger.LogDebug("Updating data to the Mongo database... Done", "MongoDataStore\\Update");
220 : }
221 : }
222 :
223 : #endregion
224 :
225 : #region Implementation of IDisposable
226 :
227 : /// <summary>
228 : /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
229 : /// </summary>
230 1 : public virtual void Dispose()
231 : {
232 : MongoCollection.Database.RequestDone();
233 : }
234 :
235 : #endregion
236 :
237 : /// <summary>
238 : /// Executes the "repairDatabase" command on the current database.
239 : /// </summary>
240 1 : public void Repair()
241 : {
242 : Logger.LogDebug("Repairing the Mongo database", "MongoDataStore\\Repair");
243 : try
244 : {
245 : DateTime start = DateTime.Now;
246 : MongoCollection.Database.RunCommand(new CommandDocument("repairDatabase", 1));
247 : DateTime end = DateTime.Now;
248 : Logger.LogDebug(string.Format("Repairing the Mongo database took {0}.", end - start), "MongoDataStore\\Repair");
249 : }
250 : finally
251 : {
252 : Logger.LogDebug("Repairing the Mongo database... Done", "MongoDataStore\\Repair");
253 : }
254 : }
255 : }
256 : }
|