/MongoDB/source/MongoDB/MongoDatabase.cs

https://github.com/fusspawn/sobriety · C# · 314 lines · 144 code · 29 blank · 141 comment · 10 complexity · b305d4a451fd7d4246693d7fa9d2d51f MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using MongoDB.Configuration;
  5. using MongoDB.Connections;
  6. using MongoDB.Results;
  7. namespace MongoDB
  8. {
  9. /// <summary>
  10. /// </summary>
  11. public class MongoDatabase : IMongoDatabase
  12. {
  13. private readonly MongoConfiguration _configuration;
  14. private readonly Connection _connection;
  15. private DatabaseJavascript _javascript;
  16. private DatabaseMetadata _metadata;
  17. /// <summary>
  18. /// Initializes a new instance of the <see cref="MongoDatabase"/> class.
  19. /// </summary>
  20. /// <param name="connectionString">The connection string.</param>
  21. public MongoDatabase(string connectionString)
  22. : this(new MongoConfiguration {ConnectionString = connectionString})
  23. {
  24. }
  25. /// <summary>
  26. /// Initializes a new instance of the <see cref="MongoDatabase"/> class.
  27. /// </summary>
  28. /// <param name="configuration">The configuration.</param>
  29. public MongoDatabase(MongoConfiguration configuration)
  30. : this(configuration,
  31. ConnectionFactoryFactory.GetConnection(configuration.ConnectionString),
  32. new MongoConnectionStringBuilder(configuration.ConnectionString).Database)
  33. {
  34. //Todo: Add check for null
  35. }
  36. /// <summary>
  37. /// Initializes a new instance of the <see cref="MongoDatabase"/> class.
  38. /// </summary>
  39. /// <param name="configuration">The configuration.</param>
  40. /// <param name="connection">The conn.</param>
  41. /// <param name="name">The name.</param>
  42. internal MongoDatabase(MongoConfiguration configuration, Connection connection, string name)
  43. {
  44. if(configuration == null)
  45. throw new ArgumentNullException("configuration");
  46. if(connection == null)
  47. throw new ArgumentNullException("connection");
  48. if(name == null)
  49. throw new ArgumentNullException("name");
  50. Name = name;
  51. _configuration = configuration;
  52. _connection = connection;
  53. }
  54. /// <summary>
  55. /// Gets or sets the name.
  56. /// </summary>
  57. /// <value>The name.</value>
  58. public string Name { get; private set; }
  59. /// <summary>
  60. /// Gets the meta data.
  61. /// </summary>
  62. /// <value>The meta data.</value>
  63. public DatabaseMetadata Metadata
  64. {
  65. get { return _metadata ?? (_metadata = new DatabaseMetadata(_configuration, Name, _connection)); }
  66. }
  67. /// <summary>
  68. /// Gets the javascript.
  69. /// </summary>
  70. /// <value>The javascript.</value>
  71. public DatabaseJavascript Javascript
  72. {
  73. get { return _javascript ?? (_javascript = new DatabaseJavascript(this)); }
  74. }
  75. /// <summary>
  76. /// Gets the <see cref = "MongoDB.IMongoCollection" /> with the specified name.
  77. /// </summary>
  78. /// <value></value>
  79. public IMongoCollection this[String name]
  80. {
  81. get { return GetCollection(name); }
  82. }
  83. /// <summary>
  84. /// Gets the collection names.
  85. /// </summary>
  86. /// <returns></returns>
  87. public List<String> GetCollectionNames()
  88. {
  89. var namespaces = this["system.namespaces"];
  90. var cursor = namespaces.Find(new Document());
  91. //Todo: Should filter built-ins
  92. return cursor.Documents.Select(d => (String)d["name"]).ToList();
  93. }
  94. /// <summary>
  95. /// Gets the collection.
  96. /// </summary>
  97. /// <param name = "name">The name.</param>
  98. /// <returns></returns>
  99. public IMongoCollection GetCollection(string name)
  100. {
  101. return new MongoCollection(_configuration, _connection, Name, name);
  102. }
  103. /// <summary>
  104. /// Gets the collection.
  105. /// </summary>
  106. /// <typeparam name = "T"></typeparam>
  107. /// <param name = "name">The name.</param>
  108. /// <returns></returns>
  109. public IMongoCollection<T> GetCollection<T>(String name) where T : class
  110. {
  111. return new MongoCollection<T>(_configuration, _connection, Name, name);
  112. }
  113. /// <summary>
  114. /// Gets the collection.
  115. /// </summary>
  116. /// <typeparam name = "T"></typeparam>
  117. /// <returns></returns>
  118. public IMongoCollection<T> GetCollection<T>() where T : class
  119. {
  120. var collectionName = _configuration.SerializationFactory.GetCollectionName(typeof(T));
  121. return GetCollection<T>(collectionName);
  122. }
  123. /// <summary>
  124. /// Gets the document that a reference is pointing to.
  125. /// </summary>
  126. /// <param name = "reference">The reference.</param>
  127. /// <returns></returns>
  128. public Document FollowReference(DBRef reference)
  129. {
  130. if(reference == null)
  131. throw new ArgumentNullException("reference", "cannot be null");
  132. var query = new Document().Add("_id", reference.Id);
  133. return this[reference.CollectionName].FindOne(query);
  134. }
  135. /// <summary>
  136. /// Follows the reference.
  137. /// </summary>
  138. /// <typeparam name = "T"></typeparam>
  139. /// <param name = "reference">The reference.</param>
  140. /// <returns></returns>
  141. public T FollowReference<T>(DBRef reference) where T : class
  142. {
  143. if(reference == null)
  144. throw new ArgumentNullException("reference", "cannot be null");
  145. var query = new Document().Add("_id", reference.Id);
  146. return GetCollection<T>(reference.CollectionName).FindOne(query);
  147. }
  148. /// <summary>
  149. /// Most operations do not have a return code in order to save the client from having to wait for results.
  150. /// GetLastError can be called to retrieve the return code if clients want one.
  151. /// </summary>
  152. /// <returns></returns>
  153. public Document GetLastError()
  154. {
  155. return SendCommand("getlasterror");
  156. }
  157. /// <summary>
  158. /// Retrieves the last error and forces the database to fsync all files before returning.
  159. /// </summary>
  160. /// <param name = "fsync">if set to <c>true</c> [fsync].</param>
  161. /// <returns></returns>
  162. /// <remarks>
  163. /// Server version 1.3+
  164. /// </remarks>
  165. public Document GetLastError(bool fsync)
  166. {
  167. return SendCommand(new Document {{"getlasterror", 1.0}, {"fsync", fsync}});
  168. }
  169. /// <summary>
  170. /// Call after sending a bulk operation to the database.
  171. /// </summary>
  172. /// <returns></returns>
  173. public Document GetPreviousError()
  174. {
  175. return SendCommand("getpreverror");
  176. }
  177. /// <summary>
  178. /// Gets the sister database on the same Mongo connection with the given name.
  179. /// </summary>
  180. /// <param name = "sisterDatabaseName">Name of the sister database.</param>
  181. /// <returns></returns>
  182. public MongoDatabase GetSisterDatabase(string sisterDatabaseName)
  183. {
  184. return new MongoDatabase(_configuration, _connection, sisterDatabaseName);
  185. }
  186. /// <summary>
  187. /// Resets last error. This is good to call before a bulk operation.
  188. /// </summary>
  189. public void ResetError()
  190. {
  191. SendCommand("reseterror");
  192. }
  193. /// <summary>
  194. /// Evals the specified javascript.
  195. /// </summary>
  196. /// <param name = "javascript">The javascript.</param>
  197. /// <returns></returns>
  198. public Document Eval(string javascript)
  199. {
  200. return Eval(javascript, new Document());
  201. }
  202. /// <summary>
  203. /// Evals the specified javascript.
  204. /// </summary>
  205. /// <param name = "javascript">The javascript.</param>
  206. /// <param name = "scope">The scope.</param>
  207. /// <returns></returns>
  208. public Document Eval(string javascript, Document scope)
  209. {
  210. return Eval(new CodeWScope(javascript, scope));
  211. }
  212. /// <summary>
  213. /// Evals the specified code scope.
  214. /// </summary>
  215. /// <param name = "codeScope">The code scope.</param>
  216. /// <returns></returns>
  217. public Document Eval(CodeWScope codeScope)
  218. {
  219. var cmd = new Document().Add("$eval", codeScope);
  220. return SendCommand(cmd);
  221. }
  222. /// <summary>
  223. /// Sends the command.
  224. /// </summary>
  225. /// <param name = "commandName">The command name.</param>
  226. /// <returns></returns>
  227. public Document SendCommand(string commandName)
  228. {
  229. return SendCommand(new Document().Add(commandName, 1.0));
  230. }
  231. /// <summary>
  232. /// Sends the command.
  233. /// </summary>
  234. /// <param name = "command">The CMD.</param>
  235. /// <returns></returns>
  236. public Document SendCommand(Document command)
  237. {
  238. return SendCommand(typeof(Document), command);
  239. }
  240. /// <summary>
  241. /// Sends the command.
  242. /// </summary>
  243. /// <param name = "rootType">Type of serialization root.</param>
  244. /// <param name = "command">The CMD.</param>
  245. /// <returns></returns>
  246. public Document SendCommand(Type rootType, Document command)
  247. {
  248. return _connection.SendCommand(_configuration.SerializationFactory, Name, rootType, command);
  249. }
  250. /// <summary>
  251. /// Sends the command.
  252. /// </summary>
  253. /// <typeparam name = "T"></typeparam>
  254. /// <param name = "commandName">Name of the command.</param>
  255. /// <returns></returns>
  256. public T SendCommand<T>(string commandName)
  257. where T : CommandResultBase
  258. {
  259. return SendCommand<T>(new Document().Add(commandName, 1.0));
  260. }
  261. /// <summary>
  262. /// Sends the command.
  263. /// </summary>
  264. /// <typeparam name = "T"></typeparam>
  265. /// <param name = "command">The command.</param>
  266. /// <returns></returns>
  267. public T SendCommand<T>(object command)
  268. where T : CommandResultBase
  269. {
  270. return _connection.SendCommand<T>(_configuration.SerializationFactory, Name, typeof(T), command);
  271. }
  272. /// <summary>
  273. /// Sends the command.
  274. /// </summary>
  275. /// <typeparam name = "T"></typeparam>
  276. /// <param name = "rootType">Type of serialization root.</param>
  277. /// <param name = "command">The command.</param>
  278. /// <returns></returns>
  279. public T SendCommand<T>(Type rootType, object command)
  280. where T : CommandResultBase
  281. {
  282. return _connection.SendCommand<T>(_configuration.SerializationFactory, Name, rootType, command);
  283. }
  284. }
  285. }