Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added range for MongoCursor #172

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 69 additions & 5 deletions source/vibe/db/mongo/cursor.d
Expand Up @@ -42,18 +42,28 @@ struct MongoCursor {
}
}

/*
Access same cursor data via range interface
*/
@property MongoCursorRange range()
{
return MongoCursorRange(m_data);
}

/**
Returns true if there are more documents for this cursor.

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.hasNext();
}
/**
Iterates over all remaining documents.

Throws: An exception if there is a query or communication error.
*/
*/
int opApply(int delegate(ref Bson doc) del)
{
if( !m_data ) return 0;
Expand All @@ -67,7 +77,7 @@ struct MongoCursor {
}

/**
Iterates over all remaining documents.
Iterates over all remaining documents providing also index.

Throws: An exception if there is a query or communication error.
*/
Expand All @@ -85,6 +95,60 @@ struct MongoCursor {
}
}

/*
InputRange interface for MongoCursor
*/
struct MongoCursorRange
{
import std.range;
static assert (isInputRange!(typeof(this)));

private
{
MongoCursorData m_data;
bool m_empty;
Bson m_doc;
}

this(MongoCursorData data)
{
m_data = data;
m_empty = !data || !data.hasNext();
if (!m_empty)
m_doc = m_data.getNext();
}

/**
Returns true if there are more documents for this cursor.

Throws: An exception if there is a query or communication error.
*/
@property bool empty()
{
return !m_data || m_empty;
}

/**
Access last retrived Bson document
*/
@property const(Bson) front()
{
assert(!empty);
return m_doc;
}

/**
Move to the next Bson document
*/
void popFront()
{
assert(!empty);
m_empty = !m_data.hasNext();
if (!empty)
m_doc = m_data.getNext();
}
}


/**
Internal class exposed through MongoCursor.
Expand Down
24 changes: 17 additions & 7 deletions tests/source/tests/mongodb.d
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.range, data2.range).map!( a => a[0].key1.get!string() ~ a[1].key1.get!string() )();
assert(!converted.empty);
assert(converted.front == "value1value2");
}