From 88ce8510a40f9b398b10eea1c5ed0bc7418163ac Mon Sep 17 00:00:00 2001 From: Jeremy Mikola Date: Thu, 22 Sep 2016 18:47:53 -0400 Subject: [PATCH] PHPLIB-219: Fix BSON serialization of findAndModify write concern --- src/Operation/FindAndModify.php | 2 +- src/functions.php | 28 ++++++++++++++++++++++++++++ tests/FunctionsTest.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index 431fac4ae..46aa4194d 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -191,7 +191,7 @@ private function createCommand(Server $server) } if (isset($this->options['writeConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForWriteConcern)) { - $cmd['writeConcern'] = $this->options['writeConcern']; + $cmd['writeConcern'] = \MongoDB\write_concern_as_document($this->options['writeConcern']); } return new Command($cmd); diff --git a/src/functions.php b/src/functions.php index 78fe64c33..1439a5b5d 100644 --- a/src/functions.php +++ b/src/functions.php @@ -5,6 +5,7 @@ use MongoDB\BSON\Serializable; use MongoDB\Driver\ReadConcern; use MongoDB\Driver\Server; +use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; use stdClass; @@ -140,3 +141,30 @@ function server_supports_feature(Server $server, $feature) return ($minWireVersion <= $feature && $maxWireVersion >= $feature); } + +/** + * Converts a WriteConcern instance to a stdClass for use in a BSON document. + * + * @internal + * @see https://jira.mongodb.org/browse/PHPC-498 + * @param WriteConcern $writeConcern Write concern + * @return stdClass + */ +function write_concern_as_document(WriteConcern $writeConcern) +{ + $document = []; + + if ($writeConcern->getW() !== null) { + $document['w'] = $writeConcern->getW(); + } + + if ($writeConcern->getJournal() !== null) { + $document['j'] = $writeConcern->getJournal(); + } + + if ($writeConcern->getWtimeout() !== 0) { + $document['wtimeout'] = $writeConcern->getWtimeout(); + } + + return (object) $document; +} diff --git a/tests/FunctionsTest.php b/tests/FunctionsTest.php index 176a3b934..5a03bd7a5 100644 --- a/tests/FunctionsTest.php +++ b/tests/FunctionsTest.php @@ -3,6 +3,7 @@ namespace MongoDB\Tests; use MongoDB\Driver\ReadConcern; +use MongoDB\Driver\WriteConcern; /** * Unit tests for utility functions. @@ -25,4 +26,32 @@ public function provideReadConcernsAndDocuments() [ new ReadConcern(ReadConcern::MAJORITY), (object) ['level' => ReadConcern::MAJORITY] ], ]; } + + /** + * @dataProvider provideWriteConcernsAndDocuments + */ + public function testWriteConcernAsDocument(WriteConcern $writeConcern, $expectedDocument) + { + $this->assertEquals($expectedDocument, \MongoDB\write_concern_as_document($writeConcern)); + } + + public function provideWriteConcernsAndDocuments() + { + return [ + [ new WriteConcern(-3), (object) ['w' => 'majority'] ], // MONGOC_WRITE_CONCERN_W_MAJORITY + [ new WriteConcern(-2), (object) [] ], // MONGOC_WRITE_CONCERN_W_DEFAULT + [ new WriteConcern(-1), (object) ['w' => -1] ], + [ new WriteConcern(0), (object) ['w' => 0] ], + [ new WriteConcern(1), (object) ['w' => 1] ], + [ new WriteConcern('majority'), (object) ['w' => 'majority'] ], + [ new WriteConcern('tag'), (object) ['w' => 'tag'] ], + [ new WriteConcern(1, 0), (object) ['w' => 1] ], + [ new WriteConcern(1, 0, false), (object) ['w' => 1, 'j' => false] ], + [ new WriteConcern(1, 1000), (object) ['w' => 1, 'wtimeout' => 1000] ], + [ new WriteConcern(1, 1000, true), (object) ['w' => 1, 'wtimeout' => 1000, 'j' => true] ], + [ new WriteConcern(-2, 0, true), (object) ['j' => true] ], + // Note: wtimeout is only applicable applies for w > 1 + [ new WriteConcern(-2, 1000), (object) ['wtimeout' => 1000] ], + ]; + } }