Skip to content

Commit 88ce851

Browse files
committed
PHPLIB-219: Fix BSON serialization of findAndModify write concern
1 parent 71a3b88 commit 88ce851

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

src/Operation/FindAndModify.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private function createCommand(Server $server)
191191
}
192192

193193
if (isset($this->options['writeConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForWriteConcern)) {
194-
$cmd['writeConcern'] = $this->options['writeConcern'];
194+
$cmd['writeConcern'] = \MongoDB\write_concern_as_document($this->options['writeConcern']);
195195
}
196196

197197
return new Command($cmd);

src/functions.php

+28
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use MongoDB\BSON\Serializable;
66
use MongoDB\Driver\ReadConcern;
77
use MongoDB\Driver\Server;
8+
use MongoDB\Driver\WriteConcern;
89
use MongoDB\Exception\InvalidArgumentException;
910
use stdClass;
1011

@@ -140,3 +141,30 @@ function server_supports_feature(Server $server, $feature)
140141

141142
return ($minWireVersion <= $feature && $maxWireVersion >= $feature);
142143
}
144+
145+
/**
146+
* Converts a WriteConcern instance to a stdClass for use in a BSON document.
147+
*
148+
* @internal
149+
* @see https://jira.mongodb.org/browse/PHPC-498
150+
* @param WriteConcern $writeConcern Write concern
151+
* @return stdClass
152+
*/
153+
function write_concern_as_document(WriteConcern $writeConcern)
154+
{
155+
$document = [];
156+
157+
if ($writeConcern->getW() !== null) {
158+
$document['w'] = $writeConcern->getW();
159+
}
160+
161+
if ($writeConcern->getJournal() !== null) {
162+
$document['j'] = $writeConcern->getJournal();
163+
}
164+
165+
if ($writeConcern->getWtimeout() !== 0) {
166+
$document['wtimeout'] = $writeConcern->getWtimeout();
167+
}
168+
169+
return (object) $document;
170+
}

tests/FunctionsTest.php

+29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MongoDB\Tests;
44

55
use MongoDB\Driver\ReadConcern;
6+
use MongoDB\Driver\WriteConcern;
67

78
/**
89
* Unit tests for utility functions.
@@ -25,4 +26,32 @@ public function provideReadConcernsAndDocuments()
2526
[ new ReadConcern(ReadConcern::MAJORITY), (object) ['level' => ReadConcern::MAJORITY] ],
2627
];
2728
}
29+
30+
/**
31+
* @dataProvider provideWriteConcernsAndDocuments
32+
*/
33+
public function testWriteConcernAsDocument(WriteConcern $writeConcern, $expectedDocument)
34+
{
35+
$this->assertEquals($expectedDocument, \MongoDB\write_concern_as_document($writeConcern));
36+
}
37+
38+
public function provideWriteConcernsAndDocuments()
39+
{
40+
return [
41+
[ new WriteConcern(-3), (object) ['w' => 'majority'] ], // MONGOC_WRITE_CONCERN_W_MAJORITY
42+
[ new WriteConcern(-2), (object) [] ], // MONGOC_WRITE_CONCERN_W_DEFAULT
43+
[ new WriteConcern(-1), (object) ['w' => -1] ],
44+
[ new WriteConcern(0), (object) ['w' => 0] ],
45+
[ new WriteConcern(1), (object) ['w' => 1] ],
46+
[ new WriteConcern('majority'), (object) ['w' => 'majority'] ],
47+
[ new WriteConcern('tag'), (object) ['w' => 'tag'] ],
48+
[ new WriteConcern(1, 0), (object) ['w' => 1] ],
49+
[ new WriteConcern(1, 0, false), (object) ['w' => 1, 'j' => false] ],
50+
[ new WriteConcern(1, 1000), (object) ['w' => 1, 'wtimeout' => 1000] ],
51+
[ new WriteConcern(1, 1000, true), (object) ['w' => 1, 'wtimeout' => 1000, 'j' => true] ],
52+
[ new WriteConcern(-2, 0, true), (object) ['j' => true] ],
53+
// Note: wtimeout is only applicable applies for w > 1
54+
[ new WriteConcern(-2, 1000), (object) ['wtimeout' => 1000] ],
55+
];
56+
}
2857
}

0 commit comments

Comments
 (0)