Skip to content

Commit

Permalink
Added an input range interface to MongoCursor. This is a redo of pull #…
Browse files Browse the repository at this point in the history
…172.

The range interface is added directly to MongoCursor in the version instead
of introducing an extra range type. Original pull by Михаил Страшун (Dicebot).
  • Loading branch information
s-ludwig committed Jan 29, 2013
1 parent f515f77 commit 82a5de3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
44 changes: 29 additions & 15 deletions source/vibe/db/mongo/cursor.d
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ struct MongoCursor {
Throws: An exception if there is a query or communication error.
*/
bool empty() { return m_data ? !m_data.hasNext() : true; }
@property bool empty() { return m_data ? m_data.empty() : true; }

@property Bson front() { return m_data.front; }

void popFront() { m_data.popFront(); }

/**
Iterates over all remaining documents.
Expand All @@ -58,8 +62,9 @@ struct MongoCursor {
{
if( !m_data ) return 0;

while( m_data.hasNext() ){
auto doc = m_data.getNext();
while( !m_data.empty ){
auto doc = m_data.front;
m_data.popFront();
if( auto ret = del(doc) )
return ret;
}
Expand All @@ -75,9 +80,10 @@ struct MongoCursor {
{
if( !m_data ) return 0;

while( m_data.hasNext() ){
auto idx = m_data.getNextIndex();
auto doc = m_data.getNext();
while( !m_data.empty ){
auto idx = m_data.index;
auto doc = m_data.front;
m_data.popFront();
if( auto ret = del(idx, doc) )
return ret;
}
Expand Down Expand Up @@ -110,26 +116,34 @@ private class MongoCursorData {
handleReply(first_chunk);
}

bool hasNext(){
@property bool empty()
{
if( m_currentDoc < m_documents.length )
return true;
if( m_cursor == 0 )
return false;
if( m_cursor == 0 )
return true;

auto conn = m_client.lockConnection();
auto reply = conn.getMore(m_collection, m_nret, m_cursor);
handleReply(reply);
return m_currentDoc < m_documents.length;
return m_currentDoc >= m_documents.length;
}

size_t getNextIndex(){
enforce(hasNext(), "Cursor has no more data.");
@property size_t index()
{
enforce(!empty(), "Cursor has no more data.");
return m_offset + m_currentDoc;
}

Bson getNext(){
enforce(hasNext(), "Cursor has no more data.");
return m_documents[m_currentDoc++];
@property Bson front()
{
enforce(!empty(), "Cursor has no more data.");
return m_documents[m_currentDoc];
}

void popFront()
{
m_currentDoc++;
}

private void destroy()
Expand Down
22 changes: 16 additions & 6 deletions tests/source/tests/mongodb.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@ void test_mongodb_general()
coll.insert([ "key1" : "value1", "key2" : "value2"]);
coll.update(["key1" : "value1"], [ "key1" : "value1", "key2" : "1337"]);
assert(coll.database.getLastError().n == 1);
auto data = coll.find(["key1" : true]);
foreach (doc; data)
{
assert(doc.length == 1);
assert(doc.key2.get!string() == "1337");
}
auto data = coll.findOne(["key1" : "value1"]);
assert(!data.isNull());
assert(data.key2.get!string() == "1337");
coll.database.fsync();
auto logBson = client.getDatabase("admin").getLog("global");
assert(!logBson.isNull());

// testing cursor range interface
coll.remove();
coll.insert(["key1" : "value1"]);
coll.insert(["key1" : "value2"]);
coll.insert(["key1" : "value2"]);
auto data1 = coll.find(["key1" : "value1"]);
auto data2 = coll.find(["key1" : "value2"]);

import std.range;
auto converted = zip(data1, data2).map!( a => a[0].key1.get!string() ~ a[1].key1.get!string() )();
assert(!converted.empty);
assert(converted.front == "value1value2");
}

0 comments on commit 82a5de3

Please sign in to comment.