Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Making the current branch more backward compatible.

  • Loading branch information...
commit 08516f92cfbe1dd275669d21af263703ba34a648 1 parent 44a4cd1
@samus authored
Showing with 1,761 additions and 474 deletions.
  1. +1 −1  MongoDB.Driver.Benchmark/Main.cs
  2. +6 −6 MongoDB.GridFS/GridFile.cs
  3. +5 −5 MongoDB.GridFS/GridFileStream.cs
  4. +5 −5 MongoDB.Linq.Tests/TestMongoDocumentQuerySyntax.cs
  5. +4 −4 MongoDB.Linq.Tests/TestQueryParsing.cs
  6. +2 −2 MongoDB.Linq/MongoLinqEx.cs
  7. +3 −3 MongoDB.Linq/MongoQueryProvider.cs
  8. +24 −24 MongoDB.Net-Tests/TestCollection.cs
  9. +1 −1  MongoDB.Net-Tests/TestCollectionMetaData.cs
  10. +5 −5 MongoDB.Net-Tests/TestCollectionSafeMode.cs
  11. +6 −6 MongoDB.Net-Tests/TestConcurrency.cs
  12. +8 −8 MongoDB.Net-Tests/TestCursor.cs
  13. +4 −4 MongoDB.Net-Tests/TestDatabase.cs
  14. +1 −1  MongoDB.Net-Tests/TestDatabaseJavascript.cs
  15. +1 −1  MongoDB.Net-Tests/TestMapReduce.cs
  16. +1 −1  MongoDB.Net-Tests/TestMapReduceBuilder.cs
  17. +35 −82 MongoDBDriver/Cursor.cs
  18. +1 −1  MongoDBDriver/DatabaseJavascript.cs
  19. +10 −10 MongoDBDriver/DatabaseMetaData.cs
  20. +388 −0 MongoDBDriver/Generic/Cursor.cs
  21. +25 −0 MongoDBDriver/Generic/ICursor.cs
  22. +396 −0 MongoDBDriver/Generic/IMongoCollection.cs
  23. +701 −0 MongoDBDriver/Generic/MongoCollection.cs
  24. +12 −17 MongoDBDriver/ICursor.cs
  25. +69 −215 MongoDBDriver/IMongoCollection.cs
  26. +4 −2 MongoDBDriver/IMongoDatabase.cs
  27. +2 −2 MongoDBDriver/MapReduce.cs
  28. +22 −59 MongoDBDriver/MongoCollection.cs
  29. +10 −2 MongoDBDriver/MongoDB.Driver.csproj
  30. +5 −3 MongoDBDriver/MongoDatabase.cs
  31. +2 −2 examples/Simple/Main.cs
  32. +2 −2 examples/SimpleVB/Application.vb
View
2  MongoDB.Driver.Benchmark/Main.cs
@@ -254,7 +254,7 @@ public static void Main (string[] args)
static void DoFind(MongoDatabase db, string col, Document spec){
for(int i = 0; i < perTrial; i++){
- ICursor<Document> cur = db[col].Find(spec);
+ ICursor cur = db[col].Find(spec);
foreach(Document d in cur.Documents){
}
}
View
12 MongoDB.GridFS/GridFile.cs
@@ -13,14 +13,14 @@ public class GridFile{
get { return name; }
}
- private IMongoCollection<Document> files;
- public IMongoCollection<Document> Files
+ private IMongoCollection files;
+ public IMongoCollection Files
{
get { return this.files; }
}
- private IMongoCollection<Document> chunks;
- public IMongoCollection<Document> Chunks
+ private IMongoCollection chunks;
+ public IMongoCollection Chunks
{
get { return this.chunks; }
}
@@ -35,11 +35,11 @@ public IMongoCollection<Document> Chunks
this.name = bucket;
}
- public ICursor<Document> ListFiles(){
+ public ICursor ListFiles(){
return this.ListFiles(new Document());
}
- public ICursor<Document> ListFiles(Document query)
+ public ICursor ListFiles(Document query)
{
return this.files.Find(new Document().Add("query", query)
.Add("orderby", new Document()
View
10 MongoDB.GridFS/GridFileStream.cs
@@ -19,8 +19,8 @@ namespace MongoDB.GridFS
public class GridFileStream : Stream
{
- private IMongoCollection<Document> files;
- private IMongoCollection<Document> chunks;
+ private IMongoCollection files;
+ private IMongoCollection chunks;
private Document chunk;
private bool chunkDirty;
private long chunkLower = -1;
@@ -65,8 +65,8 @@ public class GridFileStream : Stream
}
#endregion
- public GridFileStream (GridFileInfo gridfileinfo, IMongoCollection<Document> files,
- IMongoCollection<Document> chunks, FileAccess access)
+ public GridFileStream (GridFileInfo gridfileinfo, IMongoCollection files,
+ IMongoCollection chunks, FileAccess access)
{
switch (access) {
case FileAccess.Read:
@@ -364,7 +364,7 @@ private void EnsureNoHoles ()
Binary data = new Binary (this.blankBuffer);
int i = 0;
- using(ICursor<Document> cur = chunks.Find(new Document().Add("query", query).Add("sort", sort), 0, 0, fields)){
+ using(ICursor cur = chunks.Find(new Document().Add("query", query).Add("sort", sort), 0, 0, fields)){
foreach (Document doc in cur.Documents) {
int n = Convert.ToInt32 (doc["n"]);
if (i < n) {
View
10 MongoDB.Linq.Tests/TestMongoDocumentQuerySyntax.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Diagnostics;
using System.Linq;
using MongoDB.Driver;
@@ -11,14 +11,14 @@ namespace MongoDB.Linq.Tests {
public class TestMongoDocumentQuerySyntax {
private IMongoQuery queryable;
- private Mock<IMongoCollection<Document>> collectionMock;
- private Mock<ICursor<Document>> cursorMock;
+ private Mock<IMongoCollection> collectionMock;
+ private Mock<ICursor> cursorMock;
[SetUp]
public void Setup() {
Debug.WriteLine("initializing queryable");
- collectionMock = new Mock<IMongoCollection<Document>>();
- cursorMock = new Mock<ICursor<Document>>();
+ collectionMock = new Mock<IMongoCollection>();
+ cursorMock = new Mock<ICursor>();
collectionMock.Setup(c => c.Find(It.IsAny<Document>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<Document>())).Returns(cursorMock.Object);
queryable = new MongoQuery(new MongoQueryProvider(collectionMock.Object));
}
View
8 MongoDB.Linq.Tests/TestQueryParsing.cs
@@ -11,14 +11,14 @@ namespace MongoDB.Linq.Tests {
public class TestQueryParsing {
private IMongoQuery queryable;
- private Mock<IMongoCollection<Document>> collectionMock;
- private Mock<ICursor<Document>> cursorMock;
+ private Mock<IMongoCollection> collectionMock;
+ private Mock<ICursor> cursorMock;
[SetUp]
public void Setup() {
Debug.WriteLine("initializing queryable");
- collectionMock = new Mock<IMongoCollection<Document>>();
- cursorMock = new Mock<ICursor<Document>>();
+ collectionMock = new Mock<IMongoCollection>();
+ cursorMock = new Mock<ICursor>();
collectionMock.Setup(c => c.Find(It.IsAny<Document>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<Document>())).Returns(cursorMock.Object);
queryable = new MongoQuery(new MongoQueryProvider(collectionMock.Object));
}
View
4 MongoDB.Linq/MongoLinqEx.cs
@@ -1,11 +1,11 @@
-using System;
+using System;
using MongoDB.Driver;
namespace MongoDB.Linq
{
public static class MongoLinqEx
{
- public static IMongoQuery AsQueryable<T>(this T collection) where T : IMongoCollection<Document>
+ public static IMongoQuery AsQueryable<T>(this T collection) where T : IMongoCollection
{
return new MongoQuery(new MongoQueryProvider(collection));
}
View
6 MongoDB.Linq/MongoQueryProvider.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@@ -13,9 +13,9 @@ private struct Result {
public bool IsFirstCall;
}
- private readonly IMongoCollection<Document> collection;
+ private readonly IMongoCollection collection;
- public MongoQueryProvider(IMongoCollection<Document> collection)
+ public MongoQueryProvider(IMongoCollection collection)
{
this.collection = collection;
}
View
48 MongoDB.Net-Tests/TestCollection.cs
@@ -18,14 +18,14 @@ public class TestCollection : MongoTestBase
}
public override void OnInit (){
- IMongoCollection<Document> finds = DB["finds"];
+ IMongoCollection finds = DB["finds"];
for(int j = 1; j < 100; j++){
finds.Insert(new Document(){{"x", 4},{"h", "hi"},{"j", j}});
}
for(int j = 100; j < 105; j++){
finds.Insert(new Document(){{"x", 4},{"n", 1},{"j", j}});
}
- IMongoCollection<Document> charreads = DB["charreads"];
+ IMongoCollection charreads = DB["charreads"];
charreads.Insert(new Document(){{"test", "1234" + pound + "56"}});
}
@@ -64,7 +64,7 @@ public class TestCollection : MongoTestBase
Document fields = new Document();
fields["x"] = 1;
- ICursor<Document> c = DB["finds"].Find(query, -1, 0, fields);
+ ICursor c = DB["finds"].Find(query, -1, 0, fields);
foreach(Document result in c.Documents){
Assert.IsNotNull(result);
Assert.AreEqual(4, result["x"]);
@@ -77,7 +77,7 @@ public class TestCollection : MongoTestBase
Document query = new Document();
query["j"] = new Document().Add("$gt", 20);
- ICursor<Document> c = DB["finds"].Find(query);
+ ICursor c = DB["finds"].Find(query);
foreach(Document result in c.Documents){
Assert.IsNotNull(result);
Object j = result["j"];
@@ -88,7 +88,7 @@ public class TestCollection : MongoTestBase
[Test]
public void TestManualWhere(){
Document query = new Document().Add("$where", new Code("this.j % 2 == 0"));
- ICursor<Document> c = DB["finds"].Find(query);
+ ICursor c = DB["finds"].Find(query);
foreach(Document result in c.Documents){
Assert.IsNotNull(result);
Object j = result["j"];
@@ -97,7 +97,7 @@ public class TestCollection : MongoTestBase
}
[Test]
public void TestFindWhereEquivalency(){
- IMongoCollection<Document> col = DB["finds"];
+ IMongoCollection col = DB["finds"];
Document lt = new Document().Add("j", new Document().Add("$lt", 5));
string where = "this.j < 5";
Document explicitWhere = new Document().Add("$where", new Code(where));
@@ -110,7 +110,7 @@ public class TestCollection : MongoTestBase
Assert.AreEqual(4, CountDocs(col.Find(funcDoc)), "Function where didn't return 4 docs");
}
- private int CountDocs(ICursor<Document> cur)
+ private int CountDocs(ICursor cur)
{
int cnt = 0;
foreach(Document doc in cur.Documents){
@@ -120,7 +120,7 @@ private int CountDocs(ICursor<Document> cur)
}
[Test]
public void TestWhere(){
- ICursor<Document> c = DB["finds"].Find("this.j % 2 == 0");
+ ICursor c = DB["finds"].Find("this.j % 2 == 0");
foreach(Document result in c.Documents){
Assert.IsNotNull(result);
Object j = result["j"];
@@ -139,7 +139,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestSimpleInsert(){
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
Document indoc = new Document();
indoc["song"] = "Palmdale";
indoc["artist"] = "Afroman";
@@ -154,7 +154,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestReallySimpleInsert(){
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
Document indoc = new Document();
indoc["y"] = 1;
indoc["x"] = 2;
@@ -167,7 +167,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestPoundSymbolInsert(){
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
Document indoc = new Document().Add("x", "1234" + pound + "56").Add("y", 1);
inserts.Insert(indoc);
@@ -178,7 +178,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestArrayInsert(){
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
Document indoc1 = new Document();
indoc1["song"] = "The Axe";
indoc1["artist"] = "Tinsley Ellis";
@@ -203,7 +203,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestInsertOfArray(){
OidGenerator ogen = new OidGenerator();
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
Document album = new Document();
album["_id"] = ogen.Generate();
album["artist"] = "Popa Chubby";
@@ -227,7 +227,7 @@ private int CountDocs(ICursor<Document> cur)
public void TestInsertLargerThan4MBDocument(){
Binary b = new Binary(new byte[1024 * 1024]);
Document big = new Document(){{"name", "Big Document"}, {"b1", b}, {"b2", b}, {"b3", b}, {"b4", b}};
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
bool thrown = false;
try{
inserts.Insert(big);
@@ -242,7 +242,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestInsertBulkLargerThan4MBOfDocuments(){
Binary b = new Binary(new byte[1024 * 1024 * 2]);
- IMongoCollection<Document> inserts = DB["inserts"];
+ IMongoCollection inserts = DB["inserts"];
try{
Document[] docs = new Document[10];
//6MB+ of documents
@@ -259,7 +259,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestDelete(){
- IMongoCollection<Document> deletes = DB["deletes"];
+ IMongoCollection deletes = DB["deletes"];
Document doc = new Document();
doc["y"] = 1;
doc["x"] = 2;
@@ -279,7 +279,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestUpdateUpsertNotExisting(){
- IMongoCollection<Document> updates = DB["updates"];
+ IMongoCollection updates = DB["updates"];
Document doc = new Document();
doc["First"] = "Sam";
doc["Last"] = "CorderNE";
@@ -293,7 +293,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestUpdateUpsertExisting(){
- IMongoCollection<Document> updates = DB["updates"];
+ IMongoCollection updates = DB["updates"];
Document doc = new Document();
doc["First"] = "Mtt";
doc["Last"] = "Brewer";
@@ -317,14 +317,14 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestUpdateMany(){
- IMongoCollection<Document> updates = DB["updates"];
+ IMongoCollection updates = DB["updates"];
updates.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam"));
updates.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam2"));
updates.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam3"));
Document selector = new Document().Add("Last", "Cordr");
- ICursor<Document> results = updates.Find(selector);
+ ICursor results = updates.Find(selector);
bool found = false;
foreach(Document doc in results.Documents){
Assert.AreEqual("Cordr", doc["Last"]);
@@ -352,7 +352,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestUpdatePartial(){
- IMongoCollection<Document> updates = DB["updates"];
+ IMongoCollection updates = DB["updates"];
int coolness = 5;
Document einstein = new Document(){{"Last", "Einstien"},{"First", "Albert"},{"Coolness",coolness++}};
updates.Insert(einstein);
@@ -368,7 +368,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestCount(){
- IMongoCollection<Document> counts = DB["counts"];
+ IMongoCollection counts = DB["counts"];
int top = 100;
for(int i = 0; i < top; i++){
counts.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam").Add("cnt", i));
@@ -379,7 +379,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestCountWithSpec(){
- IMongoCollection<Document> counts = DB["counts_spec"];
+ IMongoCollection counts = DB["counts_spec"];
counts.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam").Add("cnt", 1));
counts.Insert(new Document().Add("Last", "Cordr").Add("First", "Sam").Add("cnt", 2));
counts.Insert(new Document().Add("Last", "Corder").Add("First", "Sam").Add("cnt", 3));
@@ -392,7 +392,7 @@ private int CountDocs(ICursor<Document> cur)
[Test]
public void TestCountInvalidCollection(){
- IMongoCollection<Document> counts = DB["counts_wtf"];
+ IMongoCollection counts = DB["counts_wtf"];
Assert.AreEqual(0, counts.Count());
}
}
View
2  MongoDB.Net-Tests/TestCollectionMetaData.cs
@@ -18,7 +18,7 @@ public class TestCollectionMetaData : MongoTestBase
}
public override void OnInit (){
- IMongoCollection<Document> its = DB["indextests"];
+ IMongoCollection its = DB["indextests"];
its.Insert(createDoc("S","A","Anderson","OH"));
its.Insert(createDoc("T","B","Delhi","OH"));
its.Insert(createDoc("F","B","Cincinnati","OH"));
View
10 MongoDB.Net-Tests/TestCollectionSafeMode.cs
@@ -18,7 +18,7 @@ public class TestCollectionSafeMode : MongoTestBase
[Test]
public void TestBadInsert(){
- IMongoCollection<Document> col = InitCollection("safeinsert");
+ IMongoCollection col = InitCollection("safeinsert");
bool thrown = false;
try{
col.Insert(new Document {{"x",1},{"y",2}},true);
@@ -32,7 +32,7 @@ public class TestCollectionSafeMode : MongoTestBase
[Test]
public void TestBadUpdate(){
- IMongoCollection<Document> col = InitCollection("safeupdate");
+ IMongoCollection col = InitCollection("safeupdate");
bool thrown = false;
try{
col.Update(new Document {{"x", 1}}, new Document{{"x",2}},true);
@@ -49,7 +49,7 @@ public class TestCollectionSafeMode : MongoTestBase
[Test]
public void TestMultiUpdate(){
- IMongoCollection<Document> col = InitCollection("safemupdate");
+ IMongoCollection col = InitCollection("safemupdate");
Document newy = new Document(){{"y", 2}};
col.UpdateAll(newy, new Document(){{"y",1}},true);
Assert.AreEqual(5, col.Count(newy));
@@ -68,9 +68,9 @@ public class TestCollectionSafeMode : MongoTestBase
Assert.IsTrue(thrown, "Exception not thrown.");
}
- protected IMongoCollection<Document> InitCollection(string name)
+ protected IMongoCollection InitCollection(string name)
{
- IMongoCollection<Document> col = DB[name];
+ IMongoCollection col = DB[name];
col.MetaData.CreateIndex(new Document{{"x", IndexOrder.Ascending}}, true);
for(int x = 0; x < 5; x++){
col.Insert(new Document{{"x", x}, {"y", 1}});
View
12 MongoDB.Net-Tests/TestConcurrency.cs
@@ -22,7 +22,7 @@ public class TestConcurrency :MongoTestBase
}
public override void OnInit (){
- var col = (MongoCollection<Document>)DB["threadsmallreads"];
+ var col = (IMongoCollection)DB["threadsmallreads"];
for(int j = 0; j < 4; j++){
col.Insert(new Document(){{"x", 4},{"j", j}});
}
@@ -34,7 +34,7 @@ public class TestConcurrency :MongoTestBase
Mongo db = new Mongo();
db.Connect();
- IMongoCollection<Document> col = DB["threadinserts"];
+ IMongoCollection col = DB["threadinserts"];
List<string> identifiers = new List<string>{"A", "B", "C", "D"};
List<Thread> threads = new List<Thread>();
@@ -91,7 +91,7 @@ public class TestConcurrency :MongoTestBase
Mongo db = new Mongo();
db.Connect();
- IMongoCollection<Document> col = DB["threadreadinserts"];
+ IMongoCollection col = DB["threadreadinserts"];
List<string> identifiers = new List<string>{"A", "B", "C", "D"};
List<string> colnames = new List<string>{"threadsmallreads", "threadsmallreads",
@@ -147,7 +147,7 @@ public class Inserter{
public int Iterations{get; set;}
public int Count{get;set;}
public String Identifier{get; set;}
- public IMongoCollection<Document> Collection { get; set; }
+ public IMongoCollection Collection { get; set; }
public void DoInserts(){
for(int x = 0; x < this.Iterations; x++){
@@ -165,12 +165,12 @@ public class Inserter{
public class Reader{
public int Iterations{get; set;}
public int Count{get;set;}
- public IMongoCollection<Document> Collection { get; set; }
+ public IMongoCollection Collection { get; set; }
public void DoReads(){
for(int x = 0; x < this.Iterations; x++){
try{
- using(ICursor<Document> c = this.Collection.FindAll())
+ using(ICursor c = this.Collection.FindAll())
{
//Just read one and do nothing with the Document.
foreach(Document d in c.Documents){
View
16 MongoDB.Net-Tests/TestCursor.cs
@@ -18,13 +18,13 @@ public class TestCursor : MongoTestBase
public override void OnInit (){
//smallreads
- IMongoCollection<Document> smallreads = DB["smallreads"];
+ IMongoCollection smallreads = DB["smallreads"];
for(int j = 1; j < 5; j++){
smallreads.Insert(new Document(){{"x", 4},{"j", j}});
}
smallreads.Insert(new Document(){{"x", 4}, {"j", 5}, {"n", 1}});
- IMongoCollection<Document> reads = DB["reads"];
+ IMongoCollection reads = DB["reads"];
for(int j = 1; j < 10000; j++){
reads.Insert(new Document(){{"x", 4},{"h", "hi"},{"j", j}});
}
@@ -34,7 +34,7 @@ public class TestCursor : MongoTestBase
[Test]
public void TestCanReadSmall()
{
- ICursor<Document> c = DB["smallreads"].FindAll();
+ ICursor c = DB["smallreads"].FindAll();
Assert.IsNotNull(c,"Cursor shouldn't be null");
int reads = 0;
@@ -47,7 +47,7 @@ public void TestCanReadSmall()
[Test]
public void TestCanReadMore(){
- Cursor<Document> c = (Cursor<Document>)DB["reads"].FindAll();
+ Cursor c = (Cursor)DB["reads"].FindAll();
Assert.IsNotNull(c,"Cursor shouldn't be null");
int reads = 0;
@@ -70,7 +70,7 @@ public void TestCanReadSmall()
[Test]
public void TestCanReadAndKillCursor()
{
- var c = (Cursor<Document>)DB["reads"].FindAll();
+ var c = (Cursor)DB["reads"].FindAll();
Assert.IsNotNull(c,"Cursor shouldn't be null");
foreach(Document doc in c.Documents){
@@ -82,7 +82,7 @@ public void TestCanReadAndKillCursor()
[Test]
public void TestCanLimit(){
- ICursor<Document> c = DB["reads"].FindAll().Limit(5);
+ ICursor c = DB["reads"].FindAll().Limit(5);
Assert.IsNotNull(c,"Cursor shouldn't be null");
int reads = 0;
@@ -95,7 +95,7 @@ public void TestCanReadAndKillCursor()
[Test]
public void TestSort(){
- IMongoCollection<Document> sorts = DB["sorts"];
+ IMongoCollection sorts = DB["sorts"];
int[] randoms = new int[]{4,6,8,9,1,3,2,5,7,0};
foreach(int x in randoms){
sorts.Insert(new Document().Add("x", randoms[x]));
@@ -125,7 +125,7 @@ public void TestCanReadAndKillCursor()
[Test]
public void TestHint(){
- IMongoCollection<Document> reads = DB["reads"];
+ IMongoCollection reads = DB["reads"];
Document hint = new Document().Add("x",IndexOrder.Ascending);
Document exp = reads.FindAll().Hint(hint).Explain();
View
8 MongoDB.Net-Tests/TestDatabase.cs
@@ -15,7 +15,7 @@ public class TestDatabase : MongoTestBase
[Test]
public void TestFollowReference(){
- IMongoCollection<Document> refs = DB["refs"];
+ IMongoCollection refs = DB["refs"];
Oid id = new Oid("4a7067c30a57000000008ecb");
string msg = "this has an oid key";
Document doc = new Document(){{"_id", id},{"msg", msg}};
@@ -40,7 +40,7 @@ public class TestDatabase : MongoTestBase
[Test]
public void TestReferenceNonOid(){
- IMongoCollection<Document> refs = DB["refs"];
+ IMongoCollection refs = DB["refs"];
Document doc = new Document().Add("_id",123).Add("msg", "this has a non oid key");
refs.Insert(doc);
@@ -96,7 +96,7 @@ public class TestDatabase : MongoTestBase
[Test]
public void TestGetLastError(){
- IMongoCollection<Document> errcol = DB["errcol"];
+ IMongoCollection errcol = DB["errcol"];
errcol.MetaData.CreateIndex(new Document(){{"x", IndexOrder.Ascending}}, true);
Document dup = new Document(){{"x",1},{"y",2}};
errcol.Insert(dup);
@@ -112,7 +112,7 @@ public class TestDatabase : MongoTestBase
[Test]
public void TestGetPrevError(){
- IMongoCollection<Document> col = DB["preverror"];
+ IMongoCollection col = DB["preverror"];
col.MetaData.CreateIndex(new Document(){{"x", IndexOrder.Ascending}},true);
List<Document> docs = new List<Document>();
for(int x = 0; x < 10; x++){
View
2  MongoDB.Net-Tests/TestDatabaseJavascript.cs
@@ -20,7 +20,7 @@ public class TestDatabaseJavascript : MongoTestBase
DB["system.js"].Delete(new Document());
js = DB.Javascript;
- IMongoCollection<Document> jsreads = DB["jsreads"];
+ IMongoCollection jsreads = DB["jsreads"];
for(int j = 1; j < 10; j++){
jsreads.Insert(new Document(){{"j", j}});
}
View
2  MongoDB.Net-Tests/TestMapReduce.cs
@@ -7,7 +7,7 @@ namespace MongoDB.Driver
[TestFixture()]
public class TestMapReduce : MongoTestBase
{
- IMongoCollection<Document> mrcol;
+ IMongoCollection mrcol;
string mapfunction = "function(){\n" +
" this.tags.forEach(\n" +
" function(z){\n" +
View
2  MongoDB.Net-Tests/TestMapReduceBuilder.cs
@@ -9,7 +9,7 @@ namespace MongoDB.Driver
[TestFixture()]
public class TestMapReduceBuilder : MongoTestBase
{
- IMongoCollection<Document> mrcol;
+ IMongoCollection mrcol;
string mapfunction = "function(){\n" +
" this.tags.forEach(\n" +
" function(z){\n" +
View
117 MongoDBDriver/Cursor.cs
@@ -7,17 +7,16 @@
namespace MongoDB.Driver
{
- public class Cursor<T> : ICursor<T>
- where T : class
+ public class Cursor : ICursor
{
private readonly Connection _connection;
private readonly Document _specOpts = new Document();
private bool _isModifiable = true;
- private object _spec;
- private object _fields;
+ private Document _spec;
+ private Document _fields;
private int _limit;
private QueryOptions _options;
- private ReplyMessage<T> _reply;
+ private ReplyMessage<Document> _reply;
private int _skip;
private readonly ISerializationFactory _serializationFactory = SerializationFactory.Default;
@@ -38,11 +37,8 @@ public class Cursor<T> : ICursor<T>
/// </summary>
/// <param name = "connection">The conn.</param>
/// <param name = "fullCollectionName">Full name of the collection.</param>
- /// <param name = "spec">The spec.</param>
- /// <param name = "limit">The limit.</param>
- /// <param name = "skip">The skip.</param>
- /// <param name = "fields">The fields.</param>
- public Cursor(Connection connection, string fullCollectionName, object spec, int limit, int skip, object fields)
+ [Obsolete("Use Cursor(Connection, fullCollectionName) and then call the Spec, Limit, Skip and Fields methods")]
+ public Cursor(Connection connection, string fullCollectionName, Document spec, int limit, int skip, Document fields)
: this(connection, fullCollectionName){
//Todo: should be internal
if(spec == null)
@@ -70,16 +66,7 @@ public Cursor(Connection connection, string fullCollectionName, object spec, int
/// </summary>
/// <param name="spec">The spec.</param>
/// <returns></returns>
- public ICursor<T> Spec(Document spec){
- return Spec((object)spec);
- }
-
- /// <summary>
- /// Specs the specified spec.
- /// </summary>
- /// <param name="spec">The spec.</param>
- /// <returns></returns>
- public ICursor<T> Spec(object spec){
+ public ICursor Spec(Document spec){
TryModify();
_spec = spec;
return this;
@@ -90,7 +77,7 @@ public Cursor(Connection connection, string fullCollectionName, object spec, int
/// </summary>
/// <param name="limit">The limit.</param>
/// <returns></returns>
- public ICursor<T> Limit(int limit){
+ public ICursor Limit(int limit){
TryModify();
_limit = limit;
return this;
@@ -101,87 +88,61 @@ public Cursor(Connection connection, string fullCollectionName, object spec, int
/// </summary>
/// <param name="skip">The skip.</param>
/// <returns></returns>
- public ICursor<T> Skip(int skip){
+ public ICursor Skip(int skip){
TryModify();
_skip = skip;
return this;
}
/// <summary>
- /// Fieldses the specified fields.
- /// </summary>
- /// <param name="fields">The fields.</param>
- /// <returns></returns>
- public ICursor<T> Fields(Document fields){
- return Fields((object)fields);
- }
-
- /// <summary>
- /// Fieldses the specified fields.
+ /// Limits the returned documents to the specified fields
/// </summary>
/// <param name="fields">The fields.</param>
/// <returns></returns>
- public ICursor<T> Fields(object fields){
+ public ICursor Fields(Document fields){
TryModify();
_fields = fields;
return this;
}
/// <summary>
- /// Sorts the specified field.
+ /// Sorts the specified ascending on the specified field name.
/// </summary>
/// <param name = "field">The field.</param>
/// <returns></returns>
- public ICursor<T> Sort(string field){
+ public ICursor Sort(string field){
return Sort(field, IndexOrder.Ascending);
}
/// <summary>
- /// Sorts the specified field.
+ /// Sorts on the specified field.
/// </summary>
/// <param name = "field">The field.</param>
/// <param name = "order">The order.</param>
/// <returns></returns>
- public ICursor<T> Sort(string field, IndexOrder order){
+ public ICursor Sort(string field, IndexOrder order){
return Sort(new Document().Add(field, order));
}
/// <summary>
- /// Sorts the specified fields.
- /// </summary>
- /// <param name="fields">The fields.</param>
- /// <returns></returns>
- public ICursor<T> Sort(Document fields){
- return Sort((object)fields);
- }
-
- /// <summary>
- /// Sorts the specified fields.
+ /// Document containing the fields to sort on and the order (ascending/descending)
/// </summary>
/// <param name="fields">The fields.</param>
/// <returns></returns>
- public ICursor<T> Sort(object fields)
+ public ICursor Sort(Document fields)
{
TryModify();
AddOrRemoveSpecOpt("$orderby", fields);
return this;
}
- /// <summary>
- /// Hints the specified index.
- /// </summary>
- /// <param name = "index">The index.</param>
- /// <returns></returns>
- public ICursor<T> Hint(Document index){
- return Hint((object)index);
- }
/// <summary>
- /// Hints the specified index.
+ /// Hint to use the specified index.
/// </summary>
/// <param name="index">The index.</param>
/// <returns></returns>
- public ICursor<T> Hint(object index)
+ public ICursor Hint(Document index)
{
TryModify();
AddOrRemoveSpecOpt("$hint", index);
@@ -189,23 +150,16 @@ public ICursor<T> Hint(object index)
}
/// <summary>
- /// Snapshots the specified index.
+ /// Snapshot mode assures that objects which update during the lifetime of a query are returned once
+ /// and only once. This is most important when doing a find-and-update loop that changes the size of
+ /// documents that are returned ($inc does not change size).
/// </summary>
/// <param name = "index">The index.</param>
- /// <returns></returns>
- public ICursor<T> Snapshot(Document index){
- return Snapshot((object)index);
- }
-
- /// <summary>
- /// Snapshots the specified index.
- /// </summary>
- /// <param name="index">The index.</param>
- /// <returns></returns>
- public ICursor<T> Snapshot(object index)
- {
+ /// <remarks>Because snapshot mode traverses the _id index, it may not be used with sorting or
+ /// explicit hints. It also cannot use any other index for the query.</remarks>
+ public ICursor Snapshot(){
TryModify();
- AddOrRemoveSpecOpt("$snapshot", index);
+ AddOrRemoveSpecOpt("$snapshot", true);
return this;
}
@@ -213,8 +167,7 @@ public ICursor<T> Snapshot(object index)
/// Explains this instance.
/// </summary>
/// <returns></returns>
- public T Explain(){
- //Todo: i am not sure that this will work now.
+ public Document Explain(){
TryModify();
_specOpts["$explain"] = true;
@@ -240,7 +193,7 @@ public ICursor<T> Snapshot(object index)
/// Gets the documents.
/// </summary>
/// <value>The documents.</value>
- public IEnumerable<T> Documents{
+ public IEnumerable<Document> Documents{
get{
if(_reply == null)
RetrieveData();
@@ -295,7 +248,7 @@ public ICursor<T> Snapshot(object index)
/// </summary>
/// <param name = "options">The options.</param>
/// <returns></returns>
- public ICursor<T> Options(QueryOptions options){
+ public ICursor Options(QueryOptions options){
TryModify();
_options = options;
return this;
@@ -305,9 +258,9 @@ public ICursor<T> Snapshot(object index)
/// Retrieves the data.
/// </summary>
private void RetrieveData(){
- var descriptor = _serializationFactory.GetBsonDescriptor(typeof(T), _connection);
+ var descriptor = _serializationFactory.GetBsonDescriptor(typeof(Document), _connection);
- var query = new QueryMessage<T>(descriptor){
+ var query = new QueryMessage<Document>(descriptor){
FullCollectionName = FullCollectionName,
Query = BuildSpec(),
NumberToReturn = _limit,
@@ -318,10 +271,10 @@ public ICursor<T> Snapshot(object index)
if(_fields != null)
query.ReturnFieldSelector = _fields;
- var builder = _serializationFactory.GetBsonBuilder(typeof(T), _connection);
+ var builder = _serializationFactory.GetBsonBuilder(typeof(Document), _connection);
try{
- _reply = _connection.SendTwoWayMessage<T>(query, builder);
+ _reply = _connection.SendTwoWayMessage<Document>(query, builder);
Id = _reply.CursorId;
if(_limit < 0)
_limit = _limit*-1;
@@ -338,10 +291,10 @@ public ICursor<T> Snapshot(object index)
private void RetrieveMoreData(){
var getMoreMessage = new GetMoreMessage(FullCollectionName, Id, _limit);
- var builder = _serializationFactory.GetBsonBuilder(typeof(T), _connection);
+ var builder = _serializationFactory.GetBsonBuilder(typeof(Document), _connection);
try{
- _reply = _connection.SendTwoWayMessage<T>(getMoreMessage, builder);
+ _reply = _connection.SendTwoWayMessage<Document>(getMoreMessage, builder);
Id = _reply.CursorId;
}
catch(IOException exception){
View
2  MongoDBDriver/DatabaseJavascript.cs
@@ -10,7 +10,7 @@ public class DatabaseJavascript : ICollection<Document>
{
//private Connection connection;
private MongoDatabase db;
- private IMongoCollection<Document> js;
+ private IMongoCollection js;
internal DatabaseJavascript (MongoDatabase db){
this.db = db;
View
20 MongoDBDriver/DatabaseMetaData.cs
@@ -18,20 +18,20 @@ public class DatabaseMetaData
this.db = new MongoDatabase(conn, name);
}
- public MongoCollection<Document> CreateCollection(String name){
+ public IMongoCollection CreateCollection(String name){
return this.CreateCollection(name,null);
}
- public MongoCollection<Document> CreateCollection(String name, Document options)
+ public IMongoCollection CreateCollection(String name, Document options)
{
Document cmd = new Document();
cmd.Add("create", name).Merge(options);
db.SendCommand(cmd);
- return new MongoCollection<Document>(connection, this.name, name);
+ return new MongoCollection(connection, this.name, name);
}
- public Boolean DropCollection(MongoCollection<Document> col)
+ public Boolean DropCollection(MongoCollection col)
{
return this.DropCollection(col.Name);
}
@@ -42,12 +42,12 @@ public Boolean DropCollection(MongoCollection<Document> col)
}
public Boolean DropDatabase(){
- Document result = db.SendCommand("dropDatabase");
- return result.Contains("ok") && ((double)result["ok"] == 1);
+ Document result = db.SendCommand("dropDatabase");
+ return result.Contains("ok") && ((double)result["ok"] == 1);
}
public void AddUser(string username, string password){
- IMongoCollection<Document> users = db["system.users"];
+ IMongoCollection users = db["system.users"];
string pwd = MongoDatabase.Hash(username + ":mongo:" + password);
Document user = new Document().Add("user", username).Add("pwd", pwd);
@@ -58,12 +58,12 @@ public Boolean DropCollection(MongoCollection<Document> col)
}
public void RemoveUser(string username){
- IMongoCollection<Document> users = db["system.users"];
+ IMongoCollection users = db["system.users"];
users.Delete(new Document().Add("user", username));
}
- public ICursor<Document> ListUsers(){
- IMongoCollection<Document> users = db["system.users"];
+ public ICursor ListUsers(){
+ IMongoCollection users = db["system.users"];
return users.FindAll();
}
View
388 MongoDBDriver/Generic/Cursor.cs
@@ -0,0 +1,388 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using MongoDB.Driver.Connections;
+using MongoDB.Driver.Protocol;
+using MongoDB.Driver.Serialization;
+
+namespace MongoDB.Driver.Generic
+{
+ public class Cursor<T> : ICursor<T>
+ where T : class
+ {
+ private readonly Connection _connection;
+ private readonly Document _specOpts = new Document();
+ private bool _isModifiable = true;
+ private object _spec;
+ private object _fields;
+ private int _limit;
+ private QueryOptions _options;
+ private ReplyMessage<T> _reply;
+ private int _skip;
+ private readonly ISerializationFactory _serializationFactory = SerializationFactory.Default;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref = "Cursor&lt;T&gt;" /> class.
+ /// </summary>
+ /// <param name = "connection">The conn.</param>
+ /// <param name = "fullCollectionName">Full name of the collection.</param>
+ public Cursor(Connection connection, string fullCollectionName){
+ //Todo: should be internal
+ Id = -1;
+ _connection = connection;
+ FullCollectionName = fullCollectionName;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref = "Cursor&lt;T&gt;" /> class.
+ /// </summary>
+ /// <param name = "connection">The conn.</param>
+ /// <param name = "fullCollectionName">Full name of the collection.</param>
+ /// <param name = "spec">The spec.</param>
+ /// <param name = "limit">The limit.</param>
+ /// <param name = "skip">The skip.</param>
+ /// <param name = "fields">The fields.</param>
+ public Cursor(Connection connection, string fullCollectionName, object spec, int limit, int skip, object fields)
+ : this(connection, fullCollectionName){
+ //Todo: should be internal
+ if(spec == null)
+ spec = new Document();
+ _spec = spec;
+ _limit = limit;
+ _skip = skip;
+ _fields = fields;
+ }
+
+ /// <summary>
+ /// Gets or sets the full name of the collection.
+ /// </summary>
+ /// <value>The full name of the collection.</value>
+ public string FullCollectionName { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <value>The id.</value>
+ public long Id { get; private set; }
+
+ /// <summary>
+ /// Specs the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ public ICursor<T> Spec(Document spec){
+ return Spec((object)spec);
+ }
+
+ /// <summary>
+ /// Specs the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ public ICursor<T> Spec(object spec){
+ TryModify();
+ _spec = spec;
+ return this;
+ }
+
+ /// <summary>
+ /// Limits the specified limit.
+ /// </summary>
+ /// <param name="limit">The limit.</param>
+ /// <returns></returns>
+ public ICursor<T> Limit(int limit){
+ TryModify();
+ _limit = limit;
+ return this;
+ }
+
+ /// <summary>
+ /// Skips the specified skip.
+ /// </summary>
+ /// <param name="skip">The skip.</param>
+ /// <returns></returns>
+ public ICursor<T> Skip(int skip){
+ TryModify();
+ _skip = skip;
+ return this;
+ }
+
+ /// <summary>
+ /// Fieldses the specified fields.
+ /// </summary>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Fields(Document fields){
+ return Fields((object)fields);
+ }
+
+ /// <summary>
+ /// Fieldses the specified fields.
+ /// </summary>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Fields(object fields){
+ TryModify();
+ _fields = fields;
+ return this;
+ }
+
+ /// <summary>
+ /// Sorts the specified field.
+ /// </summary>
+ /// <param name = "field">The field.</param>
+ /// <returns></returns>
+ public ICursor<T> Sort(string field){
+ return Sort(field, IndexOrder.Ascending);
+ }
+
+ /// <summary>
+ /// Sorts the specified field.
+ /// </summary>
+ /// <param name = "field">The field.</param>
+ /// <param name = "order">The order.</param>
+ /// <returns></returns>
+ public ICursor<T> Sort(string field, IndexOrder order){
+ return Sort(new Document().Add(field, order));
+ }
+
+ /// <summary>
+ /// Sorts the specified fields.
+ /// </summary>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Sort(Document fields){
+ return Sort((object)fields);
+ }
+
+ /// <summary>
+ /// Sorts the specified fields.
+ /// </summary>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Sort(object fields)
+ {
+ TryModify();
+ AddOrRemoveSpecOpt("$orderby", fields);
+ return this;
+ }
+
+ /// <summary>
+ /// Hints the specified index.
+ /// </summary>
+ /// <param name = "index">The index.</param>
+ /// <returns></returns>
+ public ICursor<T> Hint(Document index){
+ return Hint((object)index);
+ }
+
+ /// <summary>
+ /// Hints the specified index.
+ /// </summary>
+ /// <param name="index">The index.</param>
+ /// <returns></returns>
+ public ICursor<T> Hint(object index)
+ {
+ TryModify();
+ AddOrRemoveSpecOpt("$hint", index);
+ return this;
+ }
+
+ /// <summary>
+ /// Snapshots the specified index.
+ /// </summary>
+ /// <param name = "index">The index.</param>
+ /// <returns></returns>
+ public ICursor<T> Snapshot(Document index){
+ return Snapshot((object)index);
+ }
+
+ /// <summary>
+ /// Snapshots the specified index.
+ /// </summary>
+ /// <param name="index">The index.</param>
+ /// <returns></returns>
+ public ICursor<T> Snapshot(object index)
+ {
+ TryModify();
+ AddOrRemoveSpecOpt("$snapshot", index);
+ return this;
+ }
+
+ /// <summary>
+ /// Explains this instance.
+ /// </summary>
+ /// <returns></returns>
+ public T Explain(){
+ //Todo: i am not sure that this will work now.
+ TryModify();
+ _specOpts["$explain"] = true;
+
+ var documents = Documents;
+
+ using((IDisposable)documents){
+ foreach(var document in documents)
+ return document;
+ }
+
+ throw new InvalidOperationException("Explain failed.");
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this <see cref = "Cursor&lt;T&gt;" /> is modifiable.
+ /// </summary>
+ /// <value><c>true</c> if modifiable; otherwise, <c>false</c>.</value>
+ public bool IsModifiable{
+ get { return _isModifiable; }
+ }
+
+ /// <summary>
+ /// Gets the documents.
+ /// </summary>
+ /// <value>The documents.</value>
+ public IEnumerable<T> Documents{
+ get{
+ if(_reply == null)
+ RetrieveData();
+ if(_reply == null)
+ throw new InvalidOperationException("Expecting reply but get null");
+
+ var documents = _reply.Documents;
+ var documentCount = 0;
+ var shouldBreak = false;
+
+ while(!shouldBreak){
+ foreach(var document in documents)
+ if((_limit == 0) || (_limit != 0 && documentCount < _limit)){
+ documentCount++;
+ yield return document;
+ }
+ else
+ yield break;
+
+ if(Id != 0){
+ RetrieveMoreData();
+ documents = _reply.Documents;
+ if(documents == null)
+ shouldBreak = true;
+ }
+ else
+ shouldBreak = true;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose(){
+ if(Id == 0) //All server side resources disposed of.
+ return;
+
+ var killCursorsMessage = new KillCursorsMessage(Id);
+
+ try{
+ _connection.SendMessage(killCursorsMessage);
+ Id = 0;
+ }
+ catch(IOException exception){
+ throw new MongoCommException("Could not read data, communication failure", _connection, exception);
+ }
+ }
+
+ /// <summary>
+ /// Optionses the specified options.
+ /// </summary>
+ /// <param name = "options">The options.</param>
+ /// <returns></returns>
+ public ICursor<T> Options(QueryOptions options){
+ TryModify();
+ _options = options;
+ return this;
+ }
+
+ /// <summary>
+ /// Retrieves the data.
+ /// </summary>
+ private void RetrieveData(){
+ var descriptor = _serializationFactory.GetBsonDescriptor(typeof(T), _connection);
+
+ var query = new QueryMessage<T>(descriptor){
+ FullCollectionName = FullCollectionName,
+ Query = BuildSpec(),
+ NumberToReturn = _limit,
+ NumberToSkip = _skip,
+ Options = _options
+ };
+
+ if(_fields != null)
+ query.ReturnFieldSelector = _fields;
+
+ var builder = _serializationFactory.GetBsonBuilder(typeof(T), _connection);
+
+ try{
+ _reply = _connection.SendTwoWayMessage<T>(query, builder);
+ Id = _reply.CursorId;
+ if(_limit < 0)
+ _limit = _limit*-1;
+ _isModifiable = false;
+ }
+ catch(IOException exception){
+ throw new MongoCommException("Could not read data, communication failure", _connection, exception);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the more data.
+ /// </summary>
+ private void RetrieveMoreData(){
+ var getMoreMessage = new GetMoreMessage(FullCollectionName, Id, _limit);
+
+ var builder = _serializationFactory.GetBsonBuilder(typeof(T), _connection);
+
+ try{
+ _reply = _connection.SendTwoWayMessage<T>(getMoreMessage, builder);
+ Id = _reply.CursorId;
+ }
+ catch(IOException exception){
+ Id = 0;
+ throw new MongoCommException("Could not read data, communication failure", _connection, exception);
+ }
+ }
+
+ /// <summary>
+ /// Tries the modify.
+ /// </summary>
+ private void TryModify(){
+ if(_isModifiable)
+ return;
+ throw new InvalidOperationException("Cannot modify a cursor that has already returned documents.");
+ }
+
+ /// <summary>
+ /// Adds the or remove spec opt.
+ /// </summary>
+ /// <param name = "key">The key.</param>
+ /// <param name = "doc">The doc.</param>
+ private void AddOrRemoveSpecOpt(string key, object doc){
+ if(doc == null)
+ _specOpts.Remove(key);
+ else
+ _specOpts[key] = doc;
+ }
+
+ /// <summary>
+ /// Builds the spec.
+ /// </summary>
+ /// <returns></returns>
+ private object BuildSpec(){
+ if(_specOpts.Count == 0)
+ return _spec;
+
+ var document = new Document();
+ _specOpts.CopyTo(document);
+ document["$query"] = _spec;
+ return document;
+ }
+ }
+}
View
25 MongoDBDriver/Generic/ICursor.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace MongoDB.Driver.Generic {
+ public interface ICursor<T> : IDisposable
+ {
+ ICursor<T> Spec(Document spec);
+ ICursor<T> Spec(object spec);
+ ICursor<T> Limit(int limit);
+ ICursor<T> Skip(int skip);
+ ICursor<T> Fields(Document fields);
+ ICursor<T> Fields(object fields);
+ ICursor<T> Sort(string field);
+ ICursor<T> Sort(string field, IndexOrder order);
+ ICursor<T> Sort(Document fields);
+ ICursor<T> Sort(object fields);
+ ICursor<T> Hint(Document index);
+ ICursor<T> Hint(object index);
+ ICursor<T> Snapshot(Document index);
+ ICursor<T> Snapshot(object index);
+ T Explain();
+ bool IsModifiable { get; }
+ IEnumerable<T> Documents { get; }
+ }
+}
View
396 MongoDBDriver/Generic/IMongoCollection.cs
@@ -0,0 +1,396 @@
+using System;
+using System.Collections.Generic;
+
+namespace MongoDB.Driver.Generic
+{
+ public interface IMongoCollection<T> where T : class
+ {
+ /// <summary>
+ /// Gets the database.
+ /// </summary>
+ /// <value>The database.</value>
+ MongoDatabase Database { get; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ string Name { get; }
+
+ /// <summary>
+ /// Gets or sets the name of the database.
+ /// </summary>
+ /// <value>The name of the database.</value>
+ string DatabaseName { get; }
+
+ /// <summary>
+ /// Gets the full name including database name.
+ /// </summary>
+ /// <value>The full name.</value>
+ string FullName { get; }
+
+ /// <summary>
+ /// Gets the meta data.
+ /// </summary>
+ /// <value>The meta data.</value>
+ CollectionMetaData MetaData { get; }
+
+ /// <summary>
+ /// Finds and returns the first document in a query.
+ /// </summary>
+ /// <param name = "spec">A <see cref = "Document" /> representing the query.</param>
+ /// <returns>
+ /// A <see cref = "Document" /> from the collection.
+ /// </returns>
+ T FindOne(Document spec);
+
+ /// <summary>
+ /// Finds and returns the first document in a query.
+ /// </summary>
+ /// <param name = "spec">A <see cref = "Document" /> representing the query.</param>
+ /// <returns>
+ /// A <see cref = "Document" /> from the collection.
+ /// </returns>
+ T FindOne(object spec);
+
+ /// <summary>
+ /// Finds all.
+ /// </summary>
+ /// <returns></returns>
+ ICursor<T> FindAll();
+
+ /// <summary>
+ /// Finds the specified where.
+ /// </summary>
+ /// <param name = "where">The where.</param>
+ /// <returns></returns>
+ ICursor<T> Find(String where);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <returns></returns>
+ ICursor<T> Find(Document spec);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <returns></returns>
+ ICursor<T> Find(object spec);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <param name = "limit">The limit.</param>
+ /// <param name = "skip">The skip.</param>
+ /// <returns></returns>
+ ICursor<T> Find(Document spec, int limit, int skip);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <param name = "limit">The limit.</param>
+ /// <param name = "skip">The skip.</param>
+ /// <returns></returns>
+ ICursor<T> Find(object spec, int limit, int skip);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <param name = "limit">The limit.</param>
+ /// <param name = "skip">The skip.</param>
+ /// <param name = "fields">The fields.</param>
+ /// <returns></returns>
+ ICursor<T> Find(Document spec, int limit, int skip, Document fields);
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <param name = "limit">The limit.</param>
+ /// <param name = "skip">The skip.</param>
+ /// <param name = "fields">The fields.</param>
+ /// <returns></returns>
+ ICursor<T> Find(object spec, int limit, int skip, object fields);
+
+ /// <summary>
+ /// Entrypoint into executing a map/reduce query against the collection.
+ /// </summary>
+ /// <returns></returns>
+ MapReduce MapReduce();
+
+ /// <summary>
+ /// Maps the reduce builder.
+ /// </summary>
+ /// <returns></returns>
+ MapReduceBuilder MapReduceBuilder();
+
+ ///<summary>
+ /// Count all items in the collection.
+ ///</summary>
+ long Count();
+
+ /// <summary>
+ /// Count all items in a collection that match the query spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <returns></returns>
+ /// <remarks>
+ /// It will return 0 if the collection doesn't exist yet.
+ /// </remarks>
+ long Count(Document spec);
+
+ /// <summary>
+ /// Count all items in a collection that match the query spec.
+ /// </summary>
+ /// <param name = "spec">The spec.</param>
+ /// <returns></returns>
+ /// <remarks>
+ /// It will return 0 if the collection doesn't exist yet.
+ /// </remarks>
+ long Count(object spec);
+
+ /// <summary>
+ /// Inserts the Document into the collection.
+ /// </summary>
+ void Insert(Document document, bool safemode);
+
+ /// <summary>
+ /// Inserts the Document into the collection.
+ /// </summary>
+ void Insert(object document, bool safemode);
+
+ /// <summary>
+ /// Inserts the specified doc.
+ /// </summary>
+ /// <param name = "document">The doc.</param>
+ void Insert(Document document);
+
+ /// <summary>
+ /// Inserts the specified doc.
+ /// </summary>
+ /// <param name = "document">The doc.</param>
+ void Insert(object document);
+
+ /// <summary>
+ /// Inserts the specified documents.
+ /// </summary>
+ /// <param name = "documents">The documents.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Insert(IEnumerable<Document> documents, bool safemode);
+
+ /// <summary>
+ /// Inserts the specified documents.
+ /// </summary>
+ /// <param name = "documents">The documents.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Insert<TElement>(IEnumerable<TElement> documents, bool safemode);
+
+ /// <summary>
+ /// Inserts the specified documents.
+ /// </summary>
+ /// <param name = "documents">The documents.</param>
+ void Insert(IEnumerable<Document> documents);
+
+ /// <summary>
+ /// Inserts the specified documents.
+ /// </summary>
+ /// <param name = "documents">The documents.</param>
+ void Insert<TElement>(IEnumerable<TElement> documents);
+
+ /// <summary>
+ /// Deletes documents from the collection according to the spec.
+ /// </summary>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ /// <remarks>
+ /// An empty document will match all documents in the collection and effectively truncate it.
+ /// </remarks>
+ void Delete(Document selector, bool safemode);
+
+ /// <summary>
+ /// Deletes documents from the collection according to the spec.
+ /// </summary>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ /// <remarks>
+ /// An empty document will match all documents in the collection and effectively truncate it.
+ /// </remarks>
+ void Delete(object selector, bool safemode);
+
+ /// <summary>
+ /// Deletes documents from the collection according to the spec.
+ /// </summary>
+ /// <param name = "selector">The selector.</param>
+ /// <remarks>
+ /// An empty document will match all documents in the collection and effectively truncate it.
+ /// </remarks>
+ void Delete(Document selector);
+
+ /// <summary>
+ /// Deletes documents from the collection according to the spec.
+ /// </summary>
+ /// <param name = "selector">The selector.</param>
+ /// <remarks>
+ /// An empty document will match all documents in the collection and effectively truncate it.
+ /// </remarks>
+ void Delete(object selector);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(Document document, bool safemode);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(object document, bool safemode);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <remarks>
+ /// _id will be used in the document to create a selector. If it isn't in
+ /// the document then it is assumed that the document is new and an upsert is sent to the database
+ /// instead.
+ /// </remarks>
+ void Update(Document document);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <remarks>
+ /// _id will be used in the document to create a selector. If it isn't in
+ /// the document then it is assumed that the document is new and an upsert is sent to the database
+ /// instead.
+ /// </remarks>
+ void Update(object document);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(Document document, Document selector, bool safemode);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(object document, object selector, bool safemode);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ void Update(Document document, Document selector);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ void Update(object document, object selector);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "flags">The flags.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(Document document, Document selector, UpdateFlags flags, bool safemode);
+
+ /// <summary>
+ /// Updates the specified document.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "flags">The flags.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void Update(object document, object selector, UpdateFlags flags, bool safemode);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The <see cref = "Document" /> to update with</param>
+ /// <param name = "selector">The query spec to find the document to update.</param>
+ /// <param name = "flags"><see cref = "UpdateFlags" /></param>
+ void Update(Document document, Document selector, UpdateFlags flags);
+
+ /// <summary>
+ /// Updates a document with the data in doc as found by the selector.
+ /// </summary>
+ /// <param name = "document">The <see cref = "Document" /> to update with</param>
+ /// <param name = "selector">The query spec to find the document to update.</param>
+ /// <param name = "flags"><see cref = "UpdateFlags" /></param>
+ void Update(object document, object selector, UpdateFlags flags);
+
+ /// <summary>
+ /// Runs a multiple update query against the database. It will wrap any
+ /// doc with $set if the passed in doc doesn't contain any '$' ops.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ void UpdateAll(Document document, Document selector);
+
+ /// <summary>
+ /// Runs a multiple update query against the database. It will wrap any
+ /// doc with $set if the passed in doc doesn't contain any '$' ops.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ void UpdateAll(object document, object selector);
+
+ /// <summary>
+ /// Updates all.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void UpdateAll(Document document, Document selector, bool safemode);
+
+ /// <summary>
+ /// Updates all.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <param name = "selector">The selector.</param>
+ /// <param name = "safemode">if set to <c>true</c> [safemode].</param>
+ void UpdateAll(object document, object selector, bool safemode);
+
+ /// <summary>
+ /// Saves a document to the database using an upsert.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <remarks>
+ /// The document will contain the _id that is saved to the database. This is really just an alias
+ /// to Update(Document) to maintain consistency between drivers.
+ /// </remarks>
+ void Save(Document document);
+
+ /// <summary>
+ /// Saves a document to the database using an upsert.
+ /// </summary>
+ /// <param name = "document">The document.</param>
+ /// <remarks>
+ /// The document will contain the _id that is saved to the database. This is really just an alias
+ /// to Update(Document) to maintain consistency between drivers.
+ /// </remarks>
+ void Save(object document);
+ }
+}
View
701 MongoDBDriver/Generic/MongoCollection.cs
@@ -0,0 +1,701 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using MongoDB.Driver.Connections;
+using MongoDB.Driver.Protocol;
+using MongoDB.Driver.Serialization;
+
+namespace MongoDB.Driver.Generic
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class MongoCollection<T> : IMongoCollection<T>
+ where T : class
+ {
+ private readonly Connection _connection;
+ private MongoDatabase _database;
+ private CollectionMetaData _metaData;
+ private readonly ISerializationFactory _serializationFactory = SerializationFactory.Default;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MongoCollection&lt;T&gt;"/> class.
+ /// </summary>
+ /// <param name="connection">The connection.</param>
+ /// <param name="databaseName">Name of the database.</param>
+ /// <param name="name">The name.</param>
+ public MongoCollection(Connection connection, string databaseName, string name){
+ //Todo: This should be internal
+ Name = name;
+ DatabaseName = databaseName;
+ _connection = connection;
+ }
+
+ /// <summary>
+ /// Gets the database.
+ /// </summary>
+ /// <value>The database.</value>
+ public MongoDatabase Database{
+ get { return _database ?? (_database = new MongoDatabase(_connection, DatabaseName)); }
+ }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the name of the database.
+ /// </summary>
+ /// <value>The name of the database.</value>
+ public string DatabaseName { get; private set; }
+
+ /// <summary>
+ /// Gets the full name including database name.
+ /// </summary>
+ /// <value>The full name.</value>
+ public string FullName{
+ get { return DatabaseName + "." + Name; }
+ }
+
+ /// <summary>
+ /// Gets the meta data.
+ /// </summary>
+ /// <value>The meta data.</value>
+ public CollectionMetaData MetaData{
+ get { return _metaData ?? (_metaData = new CollectionMetaData(DatabaseName, Name, _connection)); }
+ }
+
+ /// <summary>
+ /// Finds and returns the first document in a query.
+ /// </summary>
+ /// <param name="spec">A <see cref="Document"/> representing the query.</param>
+ /// <returns>
+ /// A <see cref="Document"/> from the collection.
+ /// </returns>
+ public T FindOne(Document spec)
+ {
+ return FindOne((object)spec);
+ }
+
+ /// <summary>
+ /// Finds and returns the first document in a query.
+ /// </summary>
+ /// <param name="spec">A <see cref="Document"/> representing the query.</param>
+ /// <returns>
+ /// A <see cref="Document"/> from the collection.
+ /// </returns>
+ public T FindOne(object spec)
+ {
+ var cursor = Find(spec, -1, 0, null);
+ foreach(var document in cursor.Documents)
+ {
+ cursor.Dispose();
+ return document;
+ }
+ //FIXME Decide if this should throw a not found exception instead of returning null.
+ return null; //this.Find(spec, -1, 0, null)[0];
+ }
+
+ /// <summary>
+ /// Finds all.
+ /// </summary>
+ /// <returns></returns>
+ public ICursor<T> FindAll()
+ {
+ var spec = new Document();
+ return Find(spec, 0, 0, null);
+ }
+
+ /// <summary>
+ /// Finds the specified where.
+ /// </summary>
+ /// <param name="where">The where.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(String where)
+ {
+ var spec = new Document{{"$where", new Code(where)}};
+ return Find(spec, 0, 0, null);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(Document spec)
+ {
+ return Find((object)spec);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(object spec)
+ {
+ return Find(spec, 0, 0, null);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <param name="limit">The limit.</param>
+ /// <param name="skip">The skip.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(Document spec, int limit, int skip)
+ {
+ return Find((object)spec, limit, skip, null);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <param name="limit">The limit.</param>
+ /// <param name="skip">The skip.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(object spec, int limit, int skip)
+ {
+ return Find(spec, limit, skip, null);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <param name="limit">The limit.</param>
+ /// <param name="skip">The skip.</param>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(Document spec, int limit, int skip, Document fields)
+ {
+ return Find((object)spec, limit, skip, (object)fields);
+ }
+
+ /// <summary>
+ /// Finds the specified spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <param name="limit">The limit.</param>
+ /// <param name="skip">The skip.</param>
+ /// <param name="fields">The fields.</param>
+ /// <returns></returns>
+ public ICursor<T> Find(object spec, int limit, int skip, object fields)
+ {
+ if(spec == null)
+ spec = new Document();
+ return new Cursor<T>(_connection, FullName, spec, limit, skip, fields);
+ }
+
+ /// <summary>
+ /// Entrypoint into executing a map/reduce query against the collection.
+ /// </summary>
+ /// <returns>A <see cref="MapReduce"/></returns>
+ public MapReduce MapReduce(){
+ return new MapReduce(Database, Name);
+ }
+
+ /// <summary>
+ /// Maps the reduce builder.
+ /// </summary>
+ /// <returns></returns>
+ public MapReduceBuilder MapReduceBuilder(){
+ return new MapReduceBuilder(MapReduce());
+ }
+
+ ///<summary>
+ /// Count all items in the collection.
+ ///</summary>
+ public long Count(){
+ return Count(new Document());
+ }
+
+ /// <summary>
+ /// Count all items in a collection that match the query spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ /// <remarks>
+ /// It will return 0 if the collection doesn't exist yet.
+ /// </remarks>
+ public long Count(Document spec){
+ return Count((object)spec);
+ }
+
+ /// <summary>
+ /// Count all items in a collection that match the query spec.
+ /// </summary>
+ /// <param name="spec">The spec.</param>
+ /// <returns></returns>
+ /// <remarks>
+ /// It will return 0 if the collection doesn't exist yet.
+ /// </remarks>
+ public long Count(object spec)
+ {
+ try
+ {
+ var response = Database.SendCommand(new Document().Add("count", Name).Add("query", spec));
+ return Convert.ToInt64((double)response["n"]);
+ }
+ catch(MongoCommandException)
+ {
+ //FIXME This is an exception condition when the namespace is missing.
+ //-1 might be better here but the console returns 0.
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// Inserts the Document into the collection.
+ /// </summary>
+ public void Insert(Document document, bool safemode){
+ Insert((object)document,safemode);
+ }
+
+ /// <summary>
+ /// Inserts the Document into the collection.
+ /// </summary>
+ public void Insert(object document, bool safemode)
+ {
+ Insert(document);
+ CheckError(safemode);
+ }
+
+ /// <summary>
+ /// Inserts the specified doc.
+ /// </summary>
+ /// <param name="document">The doc.</param>
+ public void Insert(Document document){
+ Insert((object)document);
+ }
+
+ /// <summary>
+ /// Inserts the specified doc.
+ /// </summary>