From 7b2561863cf8d0003689e8c141943b5d0fa3bc6b Mon Sep 17 00:00:00 2001 From: Steve Wagner Date: Thu, 6 May 2010 21:41:38 +0200 Subject: [PATCH] Fix Explain and Hint. --- source/MongoDB/Cursor_1.cs | 119 +++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 44 deletions(-) diff --git a/source/MongoDB/Cursor_1.cs b/source/MongoDB/Cursor_1.cs index edce7d43..8ee28aab 100644 --- a/source/MongoDB/Cursor_1.cs +++ b/source/MongoDB/Cursor_1.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.IO; -using MongoDB.Bson; using MongoDB.Connections; using MongoDB.Protocol; -using MongoDB.Serialization; - +using MongoDB.Serialization; +using System.Linq; + namespace MongoDB { /// @@ -13,7 +13,7 @@ namespace MongoDB /// /// public class Cursor : ICursor where T : class - { + { private readonly Connection _connection; private readonly Document _specOpts = new Document(); private bool _isModifiable = true; @@ -175,17 +175,23 @@ public Cursor(ISerializationFactory serializationFactory, Connection connection, public Document Explain(){ //Fixme Return a single Document and not T TryModify(); - _specOpts["$explain"] = true; - -// var documents = Documents; - - return null; -// using((IDisposable)documents){ -// foreach(var document in documents) -// return document; -// } - -// throw new InvalidOperationException("Explain failed."); + _specOpts["$explain"] = true; + + var explainResult = GetQueryRepley(); + try + { + var explain = explainResult.Documents.FirstOrDefault(); + + if(explain==null) + throw new InvalidOperationException("Explain failed. No documents where returned."); + + return explain; + } + finally + { + if(explainResult.CursorId > 0) + KillCursor(explainResult.CursorId); + } } /// @@ -233,21 +239,30 @@ public Cursor(ISerializationFactory serializationFactory, Connection connection, /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// - public void Dispose(){ + public void Dispose() + { if (Id == 0) //All server side resources disposed of. - return; - - var killCursorsMessage = new KillCursorsMessage(Id); + return; + + KillCursor(Id); + } + + /// + /// Kills the cursor. + /// + private void KillCursor(long cursorId) + { + var killCursorsMessage = new KillCursorsMessage(cursorId); try { _connection.SendMessage(killCursorsMessage); Id = 0; } catch (IOException exception) { throw new MongoConnectionException("Could not read data, communication failure", _connection, exception); - } - } - + } + } + /// /// Optionses the specified options. /// @@ -257,12 +272,15 @@ public Cursor(ISerializationFactory serializationFactory, Connection connection, TryModify(); _options = options; return this; - } - - /// - /// Retrieves the data. - /// - private void RetrieveData(){ + } + + /// + /// Gets the query repley. + /// + /// The type of the reply. + /// + private ReplyMessage GetQueryRepley() where TReply : class + { var writerSettings = _serializationFactory.GetBsonWriterSettings(typeof(T)); var query = new QueryMessage(writerSettings) @@ -272,22 +290,35 @@ public Cursor(ISerializationFactory serializationFactory, Connection connection, NumberToReturn = _limit, NumberToSkip = _skip, Options = _options - }; - - if (_fields != null) - query.ReturnFieldSelector = _fields; - - var readerSettings = _serializationFactory.GetBsonReaderSettings(typeof(T)); - - try { - _reply = _connection.SendTwoWayMessage(query, readerSettings); - Id = _reply.CursorId; - if (_limit < 0) - _limit = _limit * -1; - _isModifiable = false; - } catch (IOException exception) { - throw new MongoConnectionException("Could not read data, communication failure", _connection, exception); - } + }; + + if(_fields != null) + query.ReturnFieldSelector = _fields; + + var readerSettings = _serializationFactory.GetBsonReaderSettings(typeof(T)); + + try + { + return _connection.SendTwoWayMessage(query, readerSettings); + } + catch(IOException exception) + { + throw new MongoConnectionException("Could not read data, communication failure", _connection, exception); + } + } + + /// + /// Retrieves the data. + /// + private void RetrieveData(){ + _reply = GetQueryRepley(); + + Id = _reply.CursorId; + + if(_limit < 0) + _limit = _limit * -1; + + _isModifiable = false; } ///