Просмотр исходного кода

Fix wrong behavior of hasNext()

Fixes #91.
Andreas Braun 9 лет назад
Родитель
Сommit
0b27c0ee07

+ 2 - 0
CHANGELOG-1.0.md

@@ -12,6 +12,8 @@ milestone.
 
  * [#90](https://github.com/alcaeus/mongo-php-adapter/pull/90) ensures that database
  and collection names are properly cast to string on creation.
+ * [#94](https://github.com/alcaeus/mongo-php-adapter/pull/94) fixes an error in
+ `MongoCursor::hasNext` that led to wrong data being returned.
 
 1.0.1 (2016-04-01)
 ------------------

+ 1 - 1
lib/Alcaeus/MongoDbAdapter/AbstractCursor.php

@@ -400,7 +400,7 @@ abstract class AbstractCursor
      * This is necessary because hasNext() might advance the iterator but we still
      * need to be able to return the current object.
      */
-    private function storeIteratorState()
+    protected function storeIteratorState()
     {
         if (! $this->startedIterating) {
             $this->current = null;

+ 6 - 1
lib/Mongo/MongoCursor.php

@@ -221,7 +221,12 @@ class MongoCursor extends AbstractCursor implements Iterator
      */
     public function hasNext()
     {
-        if ($this->cursorNeedsAdvancing) {
+        if (! $this->startedIterating) {
+            $this->ensureIterator();
+            $this->startedIterating = true;
+            $this->storeIteratorState();
+            $this->cursorNeedsAdvancing = false;
+        } elseif ($this->cursorNeedsAdvancing) {
             $this->ensureIterator()->next();
             $this->cursorNeedsAdvancing = false;
         }

+ 22 - 0
tests/Alcaeus/MongoDbAdapter/Mongo/MongoCollectionTest.php

@@ -1488,6 +1488,28 @@ class MongoCollectionTest extends TestCase
         $collection = $client->selectCollection($database, 'test');
         $this->assertSame('mongo-php-adapter.test', (string) $collection);
     }
+
+    public function testHasNextLoop()
+    {
+        $collection = $this->getCollection();
+        for ($i = 0; $i < 5; $i++) {
+            $document = ['i' => $i];
+            $collection->insert($document);
+        }
+
+        $cursor = $collection->find()->sort(['i' => 1]);
+        $data = [];
+        $i = 0;
+        while ($cursor->hasNext()) {
+            $this->assertSame($i < 5, $cursor->hasNext());
+            $row = $cursor->getNext();
+            $this->assertSame($i, $row['i']);
+            $data[] = $row;
+            $i++;
+        }
+
+        $this->assertCount(5, $data);
+    }
 }
 
 class PrivatePropertiesStub