Andreas Braun 10 лет назад
Родитель
Сommit
70c5a5d416

+ 10 - 2
README.md

@@ -109,14 +109,22 @@ return `0` as connection ID.
  - The [hasNext](https://php.net/manual/en/mongocursor.hasnext.php)
  method is not yet implemented.
  - The [info](https://php.net/manual/en/mongocursor.info.php) method does not
- reliably fill all fields in the cursor information. This includes the `at`, `numReturned`,
- and `server` keys once the cursor has started iterating.
+ reliably fill all fields in the cursor information. This includes the `numReturned`
+ and `server` keys once the cursor has started iterating. The `numReturned` field
+ will always show the same value as the `at` field. The `server` field is lacking
+ authentication information.
  - The [setFlag](https://php.net/manual/en/mongocursor.setflag.php)
  method is not yet implemented.
 
 ## MongoCommandCursor
  - The [createFromDocument](https://php.net/manual/en/mongocommandcursor.createfromdocument.php)
  method is not yet implemented.
+ - The [info](https://php.net/manual/en/mongocommandcursor.info.php) method does not
+ reliably fill all fields in the cursor information. This includes the `at`, `numReturned`,
+ `firstBatchAt` and `firstBatchNumReturned` fields. The `at` and `numReturned`
+ fields always return 0 for compatibility to MongoCursor. The `firstBatchAt` and
+ `firstBatchNumReturned` fields will contain the same value, which is the internal
+ position of the iterator.
 
 ## Types
 

+ 25 - 6
lib/Alcaeus/MongoDbAdapter/AbstractCursor.php

@@ -29,7 +29,7 @@ abstract class AbstractCursor
     /**
      * @var int
      */
-    protected $batchSize;
+    protected $batchSize = 0;
 
     /**
      * @var Collection
@@ -67,6 +67,11 @@ abstract class AbstractCursor
     protected $startedIterating = false;
 
     /**
+     * @var int
+     */
+    protected $position = 0;
+
+    /**
      * @var array
      */
     protected $optionNames = [
@@ -113,7 +118,10 @@ abstract class AbstractCursor
      */
     public function current()
     {
-        $this->startedIterating = true;
+        if (! $this->startedIterating) {
+            return null;
+        }
+
         $document = $this->ensureIterator()->current();
         if ($document !== null) {
             $document = TypeConverter::toLegacy($document);
@@ -129,6 +137,10 @@ abstract class AbstractCursor
      */
     public function key()
     {
+        if (! $this->startedIterating) {
+            return null;
+        }
+
         return $this->ensureIterator()->key();
     }
 
@@ -141,11 +153,12 @@ abstract class AbstractCursor
      */
     public function next()
     {
-        if (!$this->startedIterating) {
+        if (! $this->startedIterating) {
             $this->ensureIterator();
             $this->startedIterating = true;
         } else {
             $this->ensureIterator()->next();
+            $this->position++;
         }
 
         return $this->current();
@@ -162,6 +175,7 @@ abstract class AbstractCursor
         // We can recreate the cursor to allow it to be rewound
         $this->reset();
         $this->startedIterating = true;
+        $this->position = 0;
         $this->ensureIterator()->rewind();
     }
 
@@ -172,6 +186,10 @@ abstract class AbstractCursor
      */
     public function valid()
     {
+        if (! $this->startedIterating) {
+            return false;
+        }
+
         return $this->ensureIterator()->valid();
     }
 
@@ -323,10 +341,11 @@ abstract class AbstractCursor
                     $typeString = 'STANDALONE';
             }
 
+            $cursorId = (string) $this->cursor->getId();
             $iterationInfo += [
-                'id' => (string) $this->cursor->getId(),
-                'at' => null, // @todo Complete info for cursor that is iterating
-                'numReturned' => null, // @todo Complete info for cursor that is iterating
+                'id' => (int) $cursorId,
+                'at' => $this->position,
+                'numReturned' => $this->position, // This can't be obtained from the new cursor
                 'server' => sprintf('%s:%d;-;.;%d', $this->cursor->getServer()->getHost(), $this->cursor->getServer()->getPort(), getmypid()),
                 'host' => $this->cursor->getServer()->getHost(),
                 'port' => $this->cursor->getServer()->getPort(),

+ 1 - 1
lib/Mongo/MongoCollection.php

@@ -181,7 +181,7 @@ class MongoCollection
 
         // Convert cursor option
         if (! isset($options['cursor'])) {
-            $options['cursor'] = true;
+            $options['cursor'] = new \stdClass();
         }
 
         $command += $options;

+ 19 - 0
lib/Mongo/MongoCommandCursor.php

@@ -81,4 +81,23 @@ class MongoCommandCursor extends AbstractCursor implements MongoCursorInterface
             'fields' => null,
         ];
     }
+
+    /**
+     * @return array
+     */
+    protected function getIterationInfo()
+    {
+        $iterationInfo = parent::getIterationInfo();
+
+        if ($iterationInfo['started_iterating']) {
+            $iterationInfo += [
+                'firstBatchAt' => $iterationInfo['at'],
+                'firstBatchNumReturned' => $iterationInfo['numReturned'],
+            ];
+            $iterationInfo['at'] = 0;
+            $iterationInfo['numReturned'] = 0;
+        }
+
+        return $iterationInfo;
+    }
 }

+ 1 - 3
tests/Alcaeus/MongoDbAdapter/MongoCommandCursorTest.php

@@ -47,11 +47,9 @@ class MongoCommandCursorTest extends TestCase
             'host' => 'localhost',
             'port' => 27017,
             'connection_type_desc' => 'STANDALONE',
-            'firstBatchAt' => 2,
-            'firstBatchNumReturned' => 2,
         ];
 
-        $this->assertEquals($expected, $cursor->info());
+        $this->assertArraySubset($expected, $cursor->info());
 
         $i = 0;
         foreach ($array as $key => $value) {

+ 4 - 1
tests/Alcaeus/MongoDbAdapter/MongoCursorTest.php

@@ -20,10 +20,11 @@ class MongoCursorTest extends TestCase
 
         $iterated = 0;
         foreach ($cursor as $key => $item) {
-            $iterated++;
+            $this->assertSame($iterated, $cursor->info()['at']);
             $this->assertInstanceOf('MongoId', $item['_id']);
             $this->assertEquals($key, (string) $item['_id']);
             $this->assertSame('bar', $item['foo']);
+            $iterated++;
         }
 
         $this->assertSame(2, $iterated);
@@ -91,6 +92,8 @@ class MongoCursorTest extends TestCase
         $cursor = $collection->find(['foo' => 'bar']);
 
         $this->assertFalse($cursor->valid(), 'Cursor should be invalid to start with');
+        $this->assertNull($cursor->current(), 'Cursor should be invalid to start with');
+        $this->assertNull($cursor->key(), 'Cursor should be invalid to start with');
 
         $cursor->next();
         $this->assertTrue($cursor->valid(), 'Cursor should be valid');