Skip to content

Commit 97b0508

Browse files
committed
Replace generators with a custom iterator
1 parent 9f06836 commit 97b0508

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

lib/Alcaeus/MongoDbAdapter/AbstractCursor.php

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ abstract class AbstractCursor
5252
protected $db;
5353

5454
/**
55-
* @var \Iterator
55+
* @var CursorIterator
5656
*/
5757
protected $iterator;
5858

@@ -131,11 +131,6 @@ public function __construct(\MongoClient $connection, $ns)
131131
}
132132
}
133133

134-
public function __destruct()
135-
{
136-
$this->iterator = null;
137-
}
138-
139134
/**
140135
* Returns the current element
141136
* @link http://www.php.net/manual/en/mongocursor.current.php
@@ -297,23 +292,20 @@ protected function getOptions($optionNames = null)
297292
protected function ensureIterator()
298293
{
299294
if ($this->iterator === null) {
300-
// MongoDB\Driver\Cursor needs to be wrapped into a \Generator so that a valid \Iterator with working implementations of
301-
// next, current, valid, key and rewind is returned. These methods don't work if we wrap the Cursor inside an \IteratorIterator
302295
$this->iterator = $this->wrapTraversable($this->ensureCursor());
296+
$this->iterator->rewind();
303297
}
304298

305299
return $this->iterator;
306300
}
307301

308302
/**
309303
* @param \Traversable $traversable
310-
* @return \Generator
304+
* @return CursorIterator
311305
*/
312306
protected function wrapTraversable(\Traversable $traversable)
313307
{
314-
foreach ($traversable as $key => $value) {
315-
yield $key => $value;
316-
}
308+
return new CursorIterator($traversable);
317309
}
318310

319311
/**
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Alcaeus\MongoDbAdapter;
4+
5+
use IteratorIterator;
6+
use MongoDB\BSON\ObjectID;
7+
use Traversable;
8+
9+
/**
10+
* @internal
11+
*/
12+
final class CursorIterator extends IteratorIterator
13+
{
14+
/** @var bool */
15+
private $useIdAsKey;
16+
17+
public function __construct(Traversable $iterator, $useIdAsKey = false)
18+
{
19+
parent::__construct($iterator);
20+
21+
$this->useIdAsKey = $useIdAsKey;
22+
}
23+
24+
public function key()
25+
{
26+
if (!$this->useIdAsKey) {
27+
return parent::key();
28+
}
29+
30+
$current = $this->current();
31+
32+
if (!isset($current->_id) || (is_object($current->_id) && !$current->_id instanceof ObjectID)) {
33+
return parent::key();
34+
}
35+
36+
return (string) $current->_id;
37+
}
38+
}

lib/Mongo/MongoCursor.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
}
1919

2020
use Alcaeus\MongoDbAdapter\AbstractCursor;
21+
use Alcaeus\MongoDbAdapter\CursorIterator;
2122
use Alcaeus\MongoDbAdapter\TypeConverter;
2223
use Alcaeus\MongoDbAdapter\ExceptionConverter;
2324
use MongoDB\Driver\Cursor;
@@ -472,16 +473,11 @@ protected function ensureCursor()
472473

473474
/**
474475
* @param \Traversable $traversable
475-
* @return \Generator
476+
* @return CursorIterator
476477
*/
477478
protected function wrapTraversable(\Traversable $traversable)
478479
{
479-
foreach ($traversable as $key => $value) {
480-
if (isset($value->_id) && ($value->_id instanceof \MongoDB\BSON\ObjectID || !is_object($value->_id))) {
481-
$key = (string) $value->_id;
482-
}
483-
yield $key => $value;
484-
}
480+
return new CursorIterator($traversable, true);
485481
}
486482

487483
/**

0 commit comments

Comments
 (0)