Explorar el Código

Ensure correct return values in MongoCollection

Andreas Braun hace 10 años
padre
commit
16bb5fb05e

+ 13 - 3
lib/Alcaeus/MongoDbAdapter/Helper/WriteConcern.php

@@ -51,9 +51,9 @@ trait WriteConcern
     /**
      * @param string|int $wstring
      * @param int $wtimeout
-     * @return bool
+     * @return \MongoDB\Driver\WriteConcern
      */
-    protected function setWriteConcernFromParameters($wstring, $wtimeout = 0)
+    protected function createWriteConcernFromParameters($wstring, $wtimeout)
     {
         if (! is_string($wstring) && ! is_int($wstring)) {
             trigger_error("w for WriteConcern must be a string or integer", E_WARNING);
@@ -61,7 +61,17 @@ trait WriteConcern
         }
 
         // Ensure wtimeout is not < 0
-        $this->writeConcern = new \MongoDB\Driver\WriteConcern($wstring, max($wtimeout, 0));
+        return new \MongoDB\Driver\WriteConcern($wstring, max($wtimeout, 0));
+    }
+
+    /**
+     * @param string|int $wstring
+     * @param int $wtimeout
+     * @return bool
+     */
+    protected function setWriteConcernFromParameters($wstring, $wtimeout = 0)
+    {
+        $this->writeConcern = $this->createWriteConcernFromParameters($wstring, $wtimeout);
 
         return true;
     }

+ 88 - 7
lib/Mongo/MongoCollection.php

@@ -177,7 +177,7 @@ class MongoCollection
 
         $command += $options;
 
-        $cursor = new MongoCommandCursor($this->db->getConnection(), (string)$this, $command);
+        $cursor = new MongoCommandCursor($this->db->getConnection(), (string) $this, $command);
         $cursor->setReadPreference($this->getReadPreference());
 
         return $cursor;
@@ -224,7 +224,7 @@ class MongoCollection
      */
     public function drop()
     {
-        return $this->collection->drop();
+        return TypeConverter::convertObjectToLegacyArray($this->collection->drop());
     }
 
     /**
@@ -257,7 +257,21 @@ class MongoCollection
      */
     public function insert($a, array $options = [])
     {
-        return $this->collection->insertOne(TypeConverter::convertLegacyArrayToObject($a), $options);
+        $result = $this->collection->insertOne(
+            TypeConverter::convertLegacyArrayToObject($a),
+            $this->convertWriteConcernOptions($options)
+        );
+
+        if (! $result->isAcknowledged()) {
+            return true;
+        }
+
+        return [
+            'ok' => 1.0,
+            'n' => 0,
+            'err' => null,
+            'errmsg' => null,
+        ];
     }
 
     /**
@@ -267,11 +281,27 @@ class MongoCollection
      * @param array $a An array of arrays.
      * @param array $options Options for the inserts.
      * @throws MongoCursorException
-     * @return mixed f "safe" is set, returns an associative array with the status of the inserts ("ok") and any error that may have occured ("err"). Otherwise, returns TRUE if the batch insert was successfully sent, FALSE otherwise.
+     * @return mixed If "safe" is set, returns an associative array with the status of the inserts ("ok") and any error that may have occured ("err"). Otherwise, returns TRUE if the batch insert was successfully sent, FALSE otherwise.
      */
     public function batchInsert(array $a, array $options = [])
     {
-        return $this->collection->insertMany($a, $options);
+        $result = $this->collection->insertMany(
+            TypeConverter::convertLegacyArrayToObject($a),
+            $this->convertWriteConcernOptions($options)
+        );
+
+        if (! $result->isAcknowledged()) {
+            return true;
+        }
+
+        return [
+            'connectionId' => 0,
+            'n' => 0,
+            'syncMillis' => 0,
+            'writtenTo' => null,
+            'err' => null,
+            'errmsg' => null,
+        ];
     }
 
     /**
@@ -286,10 +316,29 @@ class MongoCollection
      */
     public function update(array $criteria , array $newobj, array $options = [])
     {
-        $multiple = ($options['multiple']) ? $options['multiple'] : false;
+        $multiple = isset($options['multiple']) ? $options['multiple'] : false;
         $method = $multiple ? 'updateMany' : 'updateOne';
+        unset($options['multiple']);
+
+        /** @var \MongoDB\UpdateResult $result */
+        $result = $this->collection->$method(
+            TypeConverter::convertLegacyArrayToObject($criteria),
+            TypeConverter::convertLegacyArrayToObject($newobj),
+            $this->convertWriteConcernOptions($options)
+        );
+
+        if (! $result->isAcknowledged()) {
+            return true;
+        }
 
-        return $this->collection->$method($criteria, $newobj, $options);
+        return [
+            'ok' => 1.0,
+            'nModified' => $result->getModifiedCount(),
+            'n' => $result->getMatchedCount(),
+            'err' => null,
+            'errmsg' => null,
+            'updatedExisting' => $result->getUpsertedCount() == 0,
+        ];
     }
 
     /**
@@ -634,5 +683,37 @@ class MongoCollection
             $this->collection = $this->collection->withOptions($options);
         }
     }
+
+    /**
+     * @param array $options
+     * @return array
+     */
+    private function convertWriteConcernOptions(array $options)
+    {
+        if (isset($options['safe'])) {
+            $options['w'] = ($options['safe']) ? 1 : 0;
+        }
+
+        if (isset($options['wtimeout']) && !isset($options['wTimeoutMS'])) {
+            $options['wTimeoutMS'] = $options['wtimeout'];
+        }
+
+        if (isset($options['w']) || !isset($options['wTimeoutMS'])) {
+            $collectionWriteConcern = $this->getWriteConcern();
+            $writeConcern = $this->createWriteConcernFromParameters(
+                isset($options['w']) ? $options['w'] : $collectionWriteConcern['w'],
+                isset($options['wTimeoutMS']) ? $options['wTimeoutMS'] : $collectionWriteConcern['wtimeout']
+            );
+
+            $options['writeConcern'] = $writeConcern;
+        }
+
+        unset($options['safe']);
+        unset($options['w']);
+        unset($options['wTimeout']);
+        unset($options['wTimeoutMS']);
+
+        return $options;
+    }
 }
 

+ 76 - 1
tests/Alcaeus/MongoDbAdapter/MongoCollectionTest.php

@@ -19,7 +19,13 @@ class MongoCollectionTest extends TestCase
         $id = '54203e08d51d4a1f868b456e';
         $collection = $this->getCollection();
 
-        $collection->insert(['_id' => new \MongoId($id), 'foo' => 'bar']);
+        $expected = [
+            'ok' => 1.0,
+            'n' => 0,
+            'err' => null,
+            'errmsg' => null,
+        ];
+        $this->assertSame($expected, $collection->insert(['_id' => new \MongoId($id), 'foo' => 'bar']));
 
         $newCollection = $this->getCheckDatabase()->selectCollection('test');
         $this->assertSame(1, $newCollection->count());
@@ -32,6 +38,64 @@ class MongoCollectionTest extends TestCase
         $this->assertAttributeSame('bar', 'foo', $object);
     }
 
+    public function testUnacknowledgedWrite()
+    {
+        $this->assertTrue($this->getCollection()->insert(['foo' => 'bar'], ['w' => 0]));
+    }
+
+    public function testInsertMany()
+    {
+        $expected = [
+            'connectionId' => 0,
+            'n' => 0,
+            'syncMillis' => 0,
+            'writtenTo' => null,
+            'err' => null,
+            'errmsg' => null
+        ];
+
+        $documents = [
+            ['foo' => 'bar'],
+            ['bar' => 'foo']
+        ];
+        $this->assertSame($expected, $this->getCollection()->batchInsert($documents));
+    }
+
+    public function testUpdateOne()
+    {
+        $this->getCollection()->insert(['foo' => 'bar']);
+        $this->getCollection()->insert(['foo' => 'bar']);
+        $expected = [
+            'ok' => 1.0,
+            'nModified' => 1,
+            'n' => 1,
+            'err' => null,
+            'errmsg' => null,
+            'updatedExisting' => true,
+        ];
+
+        $result = $this->getCollection()->update(['foo' => 'bar'], ['$set' => ['foo' => 'foo']]);
+        $this->assertSame($expected, $result);
+    }
+
+    public function testUpdateMany()
+    {
+        $this->getCollection()->insert(['change' => true, 'foo' => 'bar']);
+        $this->getCollection()->insert(['change' => true, 'foo' => 'bar']);
+        $this->getCollection()->insert(['change' => true, 'foo' => 'foo']);
+        $expected = [
+            'ok' => 1.0,
+            'nModified' => 2,
+            'n' => 3,
+            'err' => null,
+            'errmsg' => null,
+            'updatedExisting' => true,
+        ];
+
+        $result = $this->getCollection()->update(['change' => true], ['$set' => ['foo' => 'foo']], ['multiple' => true]);
+        $this->assertSame($expected, $result);
+    }
+
     public function testFindReturnsCursor()
     {
         $this->prepareData();
@@ -479,6 +543,17 @@ class MongoCollectionTest extends TestCase
         );
     }
 
+    public function testDrop()
+    {
+        $this->getCollection()->insert(['foo' => 'bar']);
+        $expected = [
+            'ns' => (string) $this->getCollection(),
+            'nIndexesWas' => 1,
+            'ok' => 1.0
+        ];
+        $this->assertSame($expected, $this->getCollection()->drop());
+    }
+
     /**
      * @return \MongoCollection
      */