Skip to content

Commit ccb0088

Browse files
committed
Merge pull request alcaeus#34 from bashofmann/master
Fix iterator methods of MongoCursor
2 parents d6a902f + 00797e7 commit ccb0088

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

lib/Alcaeus/MongoDbAdapter/AbstractCursor.php

+15-2
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,30 @@ protected function getOptions($optionNames = null)
246246
}
247247

248248
/**
249-
* @return \IteratorIterator
249+
* @return \Generator
250250
*/
251251
protected function ensureIterator()
252252
{
253253
if ($this->iterator === null) {
254-
$this->iterator = new \IteratorIterator($this->ensureCursor());
254+
// MongoDB\Driver\Cursor needs to be wrapped into a \Generator so that a valid \Iterator with working implementations of
255+
// next, current, valid, key and rewind is returned. These methods don't work if we wrap the Cursor inside an \IteratorIterator
256+
$this->iterator = $this->wrapTraversable($this->ensureCursor());
255257
}
256258

257259
return $this->iterator;
258260
}
259261

262+
/**
263+
* @param \Traversable $traversable
264+
* @return \Generator
265+
*/
266+
private function wrapTraversable(\Traversable $traversable)
267+
{
268+
foreach ($traversable as $key => $value) {
269+
yield $key => $value;
270+
}
271+
}
272+
260273
/**
261274
* @throws \MongoCursorException
262275
*/

tests/Alcaeus/MongoDbAdapter/MongoCursorTest.php

+34
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,40 @@ public function testCountCannotConnect()
4949
$cursor->count();
5050
}
5151

52+
public function testIteratorInterface()
53+
{
54+
$this->prepareData();
55+
56+
$collection = $this->getCollection();
57+
$cursor = $collection->find(['foo' => 'bar']);
58+
59+
$this->assertTrue($cursor->valid(), 'Cursor should be valid');
60+
61+
$item = $cursor->current();
62+
$this->assertNotNull($item);
63+
$this->assertInstanceOf('MongoId', $item['_id']);
64+
$this->assertSame('bar', $item['foo']);
65+
66+
$cursor->next();
67+
68+
$item = $cursor->current();
69+
$this->assertNotNull($item);
70+
$this->assertInstanceOf('MongoId', $item['_id']);
71+
$this->assertSame('bar', $item['foo']);
72+
73+
$cursor->next();
74+
75+
$this->assertNull($cursor->current(), 'Cursor should return null at the end');
76+
$this->assertFalse($cursor->valid(), 'Cursor should be invalid');
77+
78+
$cursor->rewind();
79+
80+
$item = $cursor->current();
81+
$this->assertNotNull($item);
82+
$this->assertInstanceOf('MongoId', $item['_id']);
83+
$this->assertSame('bar', $item['foo']);
84+
}
85+
5286
/**
5387
* @dataProvider getCursorOptions
5488
*/

0 commit comments

Comments
 (0)