Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added sort, explain, hint and snapshot.

  • Loading branch information...
commit 865764cc57f6c829746abee5dd2d61881d709acd 1 parent 4ce6397
@samus authored
View
72 MongoDB.Net-Tests/TestCursor.cs
@@ -12,11 +12,6 @@ public class TestCursor
{
Mongo db = new Mongo();
- [TestFixtureSetUp]
- public void Setup(){
- db.Connect();
- }
-
[Test]
public void TestCanReadSmall()
{
@@ -78,5 +73,72 @@ public void TestCanReadAndKillCursor()
Assert.IsTrue(reads > 0, "No documents were returned.");
Assert.AreEqual(5, reads);
}
+
+ [Test]
+ public void TestSort(){
+ IMongoCollection sorts = db["tests"]["sorts"];
+ int[] randoms = new int[]{4,6,8,9,1,3,2,5,7,0};
+ foreach(int x in randoms){
+ sorts.Insert(new Document().Append("x", randoms[x]));
+ }
+ Assert.AreEqual(randoms.Length, sorts.Count());
+
+ int exp = 0;
+ foreach(Document doc in sorts.FindAll().Sort("x", IndexOrder.Ascending).Documents){
+ Assert.AreEqual(exp, Convert.ToInt32(doc["x"]));
+ exp++;
+ }
+
+ exp = 9;
+ foreach(Document doc in sorts.FindAll().Sort("x", IndexOrder.Descending).Documents){
+ Assert.AreEqual(exp, Convert.ToInt32(doc["x"]));
+ exp--;
+ }
+ }
+
+ [Test]
+ public void TestExplain(){
+ Document exp = db["tests"]["reads"].FindAll().Limit(5).Skip(5).Sort("x").Explain();
+ Assert.IsTrue(exp.Contains("cursor"));
+ Assert.IsTrue(exp.Contains("n"));
+ Assert.IsTrue(exp.Contains("nscanned"));
+ }
+
+ [Test]
+ public void TestHint(){
+ IMongoCollection reads = db["tests"]["reads"];
+ Document hint = new Document().Append("x",IndexOrder.Ascending);
+
+ Document exp = reads.FindAll().Hint(hint).Explain();
+ Assert.IsTrue(exp.Contains("$err"), "No error found");
+
+ reads.MetaData.CreateIndex("hintindex",hint,false);
+ exp = reads.FindAll().Hint(hint).Explain();
+
+ Assert.IsTrue(exp.Contains("cursor"));
+ Assert.IsTrue(exp.Contains("n"));
+ Assert.IsTrue(exp.Contains("nscanned"));
+ }
+
+ [TestFixtureSetUp]
+ public void Init(){
+ db.Connect();
+ cleanDB();
+ }
+
+ [TestFixtureTearDown]
+ public void Dispose(){
+ db.Disconnect();
+ }
+
+ protected void cleanDB(){
+ try{
+ db["tests"].MetaData.DropCollection("sorts");
+ }catch(Exception){}
+ try{
+ db["tests"]["reads"].MetaData.DropIndex("hintindex");
+ }catch(Exception){}
+
+ }
}
}
View
71 MongoDBDriver/Cursor.cs
@@ -49,6 +49,56 @@ public class Cursor : ICursor {
return this;
}
+ private QueryOptions options;
+ public ICursor Options(QueryOptions options){
+ TryModify();
+ this.options = options;
+ return this;
+ }
+
+ #region "Spec Options"
+ private Document specOpts = new Document();
+
+ public ICursor Sort(string field){
+ return this.Sort(field, IndexOrder.Ascending);
+ }
+
+ public ICursor Sort(string field, IndexOrder order){
+ return this.Sort(new Document().Append(field, order));
+ }
+
+ public ICursor Sort(Document fields){
+ TryModify();
+ AddOrRemoveSpecOpt("$orderby", fields);
+ return this;
+ }
+
+ public ICursor Hint(Document index){
+ TryModify();
+ AddOrRemoveSpecOpt("$hint", index);
+ return this;
+ }
+
+ public ICursor Snapshot(Document index){
+ TryModify();
+ AddOrRemoveSpecOpt("$snapshot", index);
+ return this;
+ }
+
+ public Document Explain(){
+ TryModify();
+ specOpts["$explain"] = true;
+
+ IEnumerable<Document> docs = this.Documents;
+ using((IDisposable)docs){
+ foreach(Document doc in docs){
+ return doc;
+ }
+ }
+ throw new InvalidOperationException("Explain failed.");
+ }
+
+ #endregion
private bool modifiable = true;
public bool Modifiable{
@@ -105,9 +155,11 @@ public class Cursor : ICursor {
private void RetrieveData(){
QueryMessage query = new QueryMessage();
query.FullCollectionName = this.FullCollectionName;
- query.Query = this.spec;
+ query.Query = BuildSpec();
query.NumberToReturn = this.limit;
query.NumberToSkip = this.skip;
+ query.Options = options;
+
if(this.fields != null){
query.ReturnFieldSelector = this.fields;
}
@@ -148,5 +200,22 @@ public class Cursor : ICursor {
if(this.modifiable) return;
throw new InvalidOperationException("Cannot modify a cursor that has already returned documents.");
}
+
+ private void AddOrRemoveSpecOpt(string key, Document doc){
+ if(doc == null){
+ specOpts.Remove(key);
+ }else{
+ specOpts[key] = doc;
+ }
+ }
+
+ private Document BuildSpec(){
+ if(this.specOpts.Count == 0) return this.spec;
+ Document doc = new Document();
+ this.specOpts.CopyTo(doc);
+ doc["$query"] = this.spec;
+ return doc;
+ }
+
}
}
View
13 MongoDBDriver/ICursor.cs
@@ -10,7 +10,20 @@ public interface ICursor : IDisposable {
ICursor Limit(int limit);
ICursor Skip(int skip);
ICursor Fields (Document fields);
+ ICursor Sort(string field);
+ ICursor Sort(string field, IndexOrder order);
+ ICursor Sort(Document fields);
+ ICursor Hint(Document index);
+ ICursor Snapshot(Document index);
+ Document Explain();
bool Modifiable { get; }
IEnumerable<Document> Documents { get; }
}
+
+ public enum QueryOptions:int{
+ None = 0,
+ TailableCursor = 2,
+ SlaveOK = 4,
+ NoCursorTimeout = 16
+ }
}
View
7 MongoDBDriver/IO/QueryMessage.cs
@@ -19,12 +19,7 @@ public class QueryMessage : RequestMessage
// int32 numberToReturn; // number of documents to return in the first OP_REPLY
// BSON query ; // query object. See below for details.
// [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details.
- public enum QueryOptions:int{
- None = 0,
- TailableCursor = 2,
- SlaveOK = 4,
- NoCursorTimeout = 16
- }
+
#region "Properties"
private QueryOptions options;
Please sign in to comment.
Something went wrong with that request. Please try again.