Skip to content
This repository has been archived by the owner on Nov 11, 2020. It is now read-only.

Commit

Permalink
Include all cursor methods in cursor interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Braun committed Aug 17, 2015
1 parent 1f66600 commit bfb6350
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 5 deletions.
6 changes: 4 additions & 2 deletions lib/Doctrine/MongoDB/Cursor.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ public function explain()
/**
* Wrapper method for MongoCursor::fields().
*
* @param array $f Fields to return (or not return).
*
* @see http://php.net/manual/en/mongocursor.fields.php
* @return self
*/
Expand Down Expand Up @@ -406,7 +408,7 @@ public function next()
{
$cursor = $this;
$this->retry(function() use ($cursor) {
return $cursor->getMongoCursor()->next();
$cursor->getMongoCursor()->next();
}, false);
}

Expand Down Expand Up @@ -480,7 +482,7 @@ public function rewind()
{
$cursor = $this;
$this->retry(function() use ($cursor) {
return $cursor->getMongoCursor()->rewind();
$cursor->getMongoCursor()->rewind();
}, false);
}

Expand Down
48 changes: 45 additions & 3 deletions lib/Doctrine/MongoDB/CursorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@

namespace Doctrine\MongoDB;

use Doctrine\MongoDB\Util\ReadPreference;

/**
* Wrapper for the PHP MongoCursor class.
*
* @since 1.0
* @since 1.2
* @author alcaeus <alcaeus@alcaeus.org>
*/
interface CursorInterface extends Iterator
Expand Down Expand Up @@ -76,11 +74,42 @@ public function explain();
/**
* Wrapper method for MongoCursor::fields().
*
* @param array $f Fields to return (or not return).
*
* @see http://php.net/manual/en/mongocursor.fields.php
* @return self
*/
public function fields(array $f);

/**
* Return the collection for this cursor.
*
* @return Collection
*/
public function getCollection();

/**
* Return the selected fields (projection).
*
* @return array
*/
public function getFields();

/**
* Wrapper method for MongoCursor::getNext().
*
* @see http://php.net/manual/en/mongocursor.getnext.php
* @return array|null
*/
public function getNext();

/**
* Return the query criteria.
*
* @return array
*/
public function getQuery();

/**
* Wrapper method for MongoCursor::getReadPreference().
*
Expand All @@ -99,6 +128,14 @@ public function getReadPreference();
*/
public function setReadPreference($readPreference, array $tags = null);

/**
* Wrapper method for MongoCursor::hasNext().
*
* @see http://php.net/manual/en/mongocursor.hasnext.php
* @return boolean
*/
public function hasNext();

/**
* Wrapper method for MongoCursor::hint().
*
Expand Down Expand Up @@ -134,6 +171,11 @@ public function info();
*/
public function limit($num);

/**
* Recreates the internal MongoCursor.
*/
public function recreate();

/**
* Wrapper method for MongoCursor::reset().
*
Expand Down
81 changes: 81 additions & 0 deletions lib/Doctrine/MongoDB/EagerCursor.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ class EagerCursor implements CursorInterface
*/
protected $useKeys = true;

/**
* Whether the cursor started iterating.
*
* This is necessary to get getNext() and hasNext() to work properly
*
* @var boolean
*/
private $iterating = false;

/**
* Constructor.
*
Expand Down Expand Up @@ -144,6 +153,7 @@ public function isInitialized()
public function key()
{
$this->initialize();
$this->iterating = true;

return key($this->data);
}
Expand All @@ -154,6 +164,7 @@ public function key()
public function next()
{
$this->initialize();
$this->iterating = true;
next($this->data);
}

Expand All @@ -163,6 +174,7 @@ public function next()
public function rewind()
{
$this->initialize();
$this->iterating = false;
reset($this->data);
}

Expand All @@ -182,6 +194,7 @@ public function toArray()
public function valid()
{
$this->initialize();
$this->iterating = true;

return key($this->data) !== null;
}
Expand Down Expand Up @@ -232,6 +245,43 @@ public function fields(array $f)
return $this;
}

/**
* {@inheritDoc}
*/
public function getCollection()
{
return $this->cursor->getCollection();
}

/**
* {@inheritDoc}
*/
public function getFields()
{
return $this->cursor->getFields();
}

/**
* {@inheritDoc}
*/
public function getNext()
{
$this->initialize();

$next = ($this->iterating) ? next($this->data) : current($this->data);
$this->iterating = true;

return ($next !== false) ? $next : null;
}

/**
* {@inheritDoc}
*/
public function getQuery()
{
return $this->cursor->getQuery();
}

/**
* {@inheritdoc}
*/
Expand All @@ -250,6 +300,26 @@ public function setReadPreference($readPreference, array $tags = null)
return $this;
}

/**
* {@inheritDoc}
*/
public function hasNext()
{
$this->initialize();

$wasIterating = $this->iterating;
$hasNext = $this->getNext() !== null;

// Reset the internal cursor if we weren't iterating
if ($wasIterating) {
prev($this->data);
} else {
$this->iterating = false;
}

return $hasNext;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -288,6 +358,17 @@ public function limit($num)
return $this;
}

/**
* {@inheritDoc}
*/
public function recreate()
{
$this->initialized = false;
$this->data = array();
$this->iterating = false;
$this->cursor->recreate();
}

/**
* {@inheritdoc}
*/
Expand Down
30 changes: 30 additions & 0 deletions tests/Doctrine/MongoDB/Tests/EagerCursorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,36 @@ public function testIterationMethods()
}
}

public function testGetNextHasNext()
{
$results = array(
array('_id' => 1, 'x' => 'foo'),
array('_id' => 2, 'x' => 'bar'),
);

$cursor = $this->getMockCursor();

$cursor->expects($this->once())
->method('toArray')
->will($this->returnValue($results));

$eagerCursor = new EagerCursor($cursor);

$this->assertTrue($eagerCursor->hasNext());
$this->assertEquals($results[0], $eagerCursor->getNext());

$this->assertTrue($eagerCursor->hasNext());
$this->assertEquals($results[0], $eagerCursor->current(), 'hasNext does not advance internal cursor');
$this->assertEquals($results[1], $eagerCursor->getNext());

$this->assertFalse($eagerCursor->hasNext());
$this->assertNull($eagerCursor->getNext());

$eagerCursor->rewind();
$this->assertTrue($eagerCursor->hasNext());
$this->assertEquals($results[0], $eagerCursor->getNext());
}

/**
* @return \Doctrine\MongoDB\Cursor
*/
Expand Down

0 comments on commit bfb6350

Please sign in to comment.