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

Convert BSON types in query projections

Fixes #97.
Andreas Braun 9 лет назад
Родитель
Сommit
d851097cc1

+ 3 - 1
CHANGELOG-1.0.md

@@ -3,7 +3,7 @@ CHANGELOG
 
 This changelog references the relevant changes done in minor version updates.
 
-1.0.2 (????-??-??)
+1.0.3 (????-??-??)
 ------------------
 
 All issues and pull requests under this release may be found under the
@@ -14,6 +14,8 @@ milestone.
  calling `count` on a cursor that has been iterated fully. The fix removes a
  performance improvement when calling `count` on a cursor that has been opened.
  `MongoCursor::count` now always re-issues a `count` command to the server.
+ * [#98](https://github.com/alcaeus/mongo-php-adapter/pull/98) fixes an error
+ where using BSON types in a query projection would result in wrong results.
 
 1.0.2 (2016-04-08)
 ------------------

+ 1 - 1
lib/Mongo/MongoCollection.php

@@ -551,7 +551,7 @@ class MongoCollection
             return;
         }
 
-        $options = ['projection' => $fields] + $options;
+        $options = ['projection' => TypeConverter::fromLegacy($fields)] + $options;
         try {
             $document = $this->collection->findOne(TypeConverter::fromLegacy($query), $options);
         } catch (\MongoDB\Driver\Exception\Exception $e) {

+ 11 - 0
lib/Mongo/MongoCursor.php

@@ -408,6 +408,9 @@ class MongoCursor extends AbstractCursor implements Iterator
         return $this->awaitData ? Find::TAILABLE_AWAIT : Find::TAILABLE;
     }
 
+    /**
+     * @return array
+     */
     protected function convertModifiers()
     {
         $modifiers = array_key_exists('modifiers', $this->options) ? $this->options['modifiers'] : [];
@@ -424,6 +427,14 @@ class MongoCursor extends AbstractCursor implements Iterator
     }
 
     /**
+     * @return array
+     */
+    protected function convertProjection()
+    {
+        return TypeConverter::fromLegacy($this->projection);
+    }
+
+    /**
      * @return Cursor
      */
     protected function ensureCursor()

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

@@ -1510,6 +1510,48 @@ class MongoCollectionTest extends TestCase
 
         $this->assertCount(5, $data);
     }
+
+    public function testProjectionWithBSONTypes()
+    {
+        $collection = $this->getCollection();
+
+        $id = new \MongoId();
+        $referencedId = new \MongoId();
+
+        $data = [
+            '_id' => $id,
+            'loveItems' => [
+                [
+                    'sellable' => [
+                        '$ref' => 'sellables',
+                        '$id' => $referencedId,
+                    ]
+                ],
+                [
+                    'sellable' => [
+                        '$ref' => 'sellables',
+                        '$id' => new \MongoId(),
+                    ]
+                ]
+            ]
+        ];
+        $collection->insert($data);
+
+        $item = $collection->findOne(
+            ['_id' => $id],
+            ['loveItems' => ['$elemMatch' => ['sellable.$id' => $referencedId]]]
+        );
+        $this->assertArrayHasKey('loveItems', $item);
+        $this->assertCount(1, $item['loveItems']);
+
+        $cursor = $collection->find(
+            ['_id' => $id],
+            ['loveItems' => ['$elemMatch' => ['sellable.$id' => $referencedId]]]
+        );
+        $items = iterator_to_array($cursor, false);
+        $this->assertCount(1, $items);
+        $this->assertCount(1, $items[0]['loveItems']);
+    }
 }
 
 class PrivatePropertiesStub

+ 3 - 2
tests/Alcaeus/MongoDbAdapter/Mongo/MongoCursorTest.php

@@ -5,6 +5,7 @@ namespace Alcaeus\MongoDbAdapter\Tests\Mongo;
 use Alcaeus\MongoDbAdapter\Tests\TestCase;
 use Alcaeus\MongoDbAdapter\TypeConverter;
 use MongoDB\Driver\ReadPreference;
+use MongoDB\Model\BSONDocument;
 use MongoDB\Operation\Find;
 
 /**
@@ -282,10 +283,10 @@ class MongoCursorTest extends TestCase
                 },
             ],
             'projectionDefaultFields' => [
-                getBasicCheckCallback(['_id' => false, 'foo' => true], 'projection'),
+                getBasicCheckCallback(new BSONDocument(['_id' => false, 'foo' => true]), 'projection'),
             ],
             'projectionDifferentFields' => [
-                getBasicCheckCallback(['_id' => false, 'foo' => true, 'bar' => true], 'projection'),
+                getBasicCheckCallback(new BSONDocument(['_id' => false, 'foo' => true, 'bar' => true]), 'projection'),
                 function (\MongoCursor $cursor) {
                     $cursor->fields(['_id' => false, 'foo' => true, 'bar' => true]);
                 },