Skip to content

Commit cb5cf0b

Browse files
committed
Merge pull request #68
2 parents ff9d54c + fc71a5c commit cb5cf0b

16 files changed

+247
-12
lines changed

src/Collection.php

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use MongoDB\Driver\Command;
66
use MongoDB\Driver\Cursor;
77
use MongoDB\Driver\Manager;
8+
use MongoDB\Driver\ReadConcern;
89
use MongoDB\Driver\ReadPreference;
910
use MongoDB\Driver\Server;
1011
use MongoDB\Driver\WriteConcern;
@@ -42,6 +43,7 @@ class Collection
4243
private $collectionName;
4344
private $databaseName;
4445
private $manager;
46+
private $readConcern;
4547
private $readPreference;
4648
private $writeConcern;
4749

@@ -53,6 +55,9 @@ class Collection
5355
*
5456
* Supported options:
5557
*
58+
* * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
59+
* use for collection operations. Defaults to the Manager's read concern.
60+
*
5661
* * readPreference (MongoDB\Driver\ReadPreference): The default read
5762
* preference to use for collection operations. Defaults to the Manager's
5863
* read preference.
@@ -77,6 +82,10 @@ public function __construct(Manager $manager, $namespace, array $options = [])
7782
$this->databaseName = $parts[0];
7883
$this->collectionName = $parts[1];
7984

85+
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
86+
throw new InvalidArgumentTypeException('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
87+
}
88+
8089
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
8190
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
8291
}
@@ -86,6 +95,7 @@ public function __construct(Manager $manager, $namespace, array $options = [])
8695
}
8796

8897
$this->manager = $manager;
98+
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
8999
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
90100
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
91101
}
@@ -102,6 +112,7 @@ public function __debugInfo()
102112
'collectionName' => $this->collectionName,
103113
'databaseName' => $this->databaseName,
104114
'manager' => $this->manager,
115+
'readConcern' => $this->readConcern,
105116
'readPreference' => $this->readPreference,
106117
'writeConcern' => $this->writeConcern,
107118
];
@@ -132,11 +143,20 @@ public function __toString()
132143
*/
133144
public function aggregate(array $pipeline, array $options = [])
134145
{
146+
$hasOutStage = \MongoDB\is_last_pipeline_operator_out($pipeline);
147+
148+
/* A "majority" read concern is not compatible with the $out stage, so
149+
* avoid providing the Collection's read concern if it would conflict.
150+
*/
151+
if ( ! isset($options['readConcern']) && ! ($hasOutStage && $this->readConcern->getLevel() === ReadConcern::MAJORITY)) {
152+
$options['readConcern'] = $this->readConcern;
153+
}
154+
135155
if ( ! isset($options['readPreference'])) {
136156
$options['readPreference'] = $this->readPreference;
137157
}
138158

139-
if (\MongoDB\is_last_pipeline_operator_out($pipeline)) {
159+
if ($hasOutStage) {
140160
$options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
141161
}
142162

@@ -176,6 +196,10 @@ public function bulkWrite(array $operations, array $options = [])
176196
*/
177197
public function count($filter = [], array $options = [])
178198
{
199+
if ( ! isset($options['readConcern'])) {
200+
$options['readConcern'] = $this->readConcern;
201+
}
202+
179203
if ( ! isset($options['readPreference'])) {
180204
$options['readPreference'] = $this->readPreference;
181205
}
@@ -284,6 +308,10 @@ public function deleteOne($filter, array $options = [])
284308
*/
285309
public function distinct($fieldName, $filter = [], array $options = [])
286310
{
311+
if ( ! isset($options['readConcern'])) {
312+
$options['readConcern'] = $this->readConcern;
313+
}
314+
287315
if ( ! isset($options['readPreference'])) {
288316
$options['readPreference'] = $this->readPreference;
289317
}
@@ -352,6 +380,10 @@ public function dropIndexes()
352380
*/
353381
public function find($filter = [], array $options = [])
354382
{
383+
if ( ! isset($options['readConcern'])) {
384+
$options['readConcern'] = $this->readConcern;
385+
}
386+
355387
if ( ! isset($options['readPreference'])) {
356388
$options['readPreference'] = $this->readPreference;
357389
}
@@ -373,6 +405,10 @@ public function find($filter = [], array $options = [])
373405
*/
374406
public function findOne($filter = [], array $options = [])
375407
{
408+
if ( ! isset($options['readConcern'])) {
409+
$options['readConcern'] = $this->readConcern;
410+
}
411+
376412
if ( ! isset($options['readPreference'])) {
377413
$options['readPreference'] = $this->readPreference;
378414
}
@@ -621,6 +657,10 @@ public function updateOne($filter, $update, array $options = [])
621657
*
622658
* Supported options:
623659
*
660+
* * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
661+
* use for collection operations. Defaults to this Collection's read
662+
* concern.
663+
*
624664
* * readPreference (MongoDB\Driver\ReadPreference): The default read
625665
* preference to use for collection operations. Defaults to this
626666
* Collection's read preference.
@@ -634,6 +674,10 @@ public function updateOne($filter, $update, array $options = [])
634674
*/
635675
public function withOptions(array $options = [])
636676
{
677+
if ( ! isset($options['readConcern'])) {
678+
$options['readConcern'] = $this->readConcern;
679+
}
680+
637681
if ( ! isset($options['readPreference'])) {
638682
$options['readPreference'] = $this->readPreference;
639683
}

src/Database.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use MongoDB\Driver\Cursor;
88
use MongoDB\Driver\Manager;
99
use MongoDB\Driver\Query;
10+
use MongoDB\Driver\ReadConcern;
1011
use MongoDB\Driver\ReadPreference;
1112
use MongoDB\Driver\Server;
1213
use MongoDB\Driver\WriteConcern;
@@ -22,6 +23,7 @@ class Database
2223
{
2324
private $databaseName;
2425
private $manager;
26+
private $readConcern;
2527
private $readPreference;
2628
private $writeConcern;
2729

@@ -33,6 +35,10 @@ class Database
3335
*
3436
* Supported options:
3537
*
38+
* * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
39+
* use for database operations and selected collections. Defaults to the
40+
* Manager's read concern.
41+
*
3642
* * readPreference (MongoDB\Driver\ReadPreference): The default read
3743
* preference to use for database operations and selected collections.
3844
* Defaults to the Manager's read preference.
@@ -52,6 +58,10 @@ public function __construct(Manager $manager, $databaseName, array $options = []
5258
throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName);
5359
}
5460

61+
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
62+
throw new InvalidArgumentTypeException('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
63+
}
64+
5565
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
5666
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
5767
}
@@ -62,6 +72,7 @@ public function __construct(Manager $manager, $databaseName, array $options = []
6272

6373
$this->manager = $manager;
6474
$this->databaseName = (string) $databaseName;
75+
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
6576
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
6677
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
6778
}
@@ -77,6 +88,7 @@ public function __debugInfo()
7788
return [
7889
'databaseName' => $this->databaseName,
7990
'manager' => $this->manager,
91+
'readConcern' => $this->readConcern,
8092
'readPreference' => $this->readPreference,
8193
'writeConcern' => $this->writeConcern,
8294
];
@@ -191,6 +203,10 @@ public function listCollections(array $options = [])
191203
*
192204
* Supported options:
193205
*
206+
* * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
207+
* use for collection operations. Defaults to the Database's read
208+
* concern.
209+
*
194210
* * readPreference (MongoDB\Driver\ReadPreference): The default read
195211
* preference to use for collection operations. Defaults to the
196212
* Database's read preference.
@@ -205,6 +221,10 @@ public function listCollections(array $options = [])
205221
*/
206222
public function selectCollection($collectionName, array $options = [])
207223
{
224+
if ( ! isset($options['readConcern'])) {
225+
$options['readConcern'] = $this->readConcern;
226+
}
227+
208228
if ( ! isset($options['readPreference'])) {
209229
$options['readPreference'] = $this->readPreference;
210230
}
@@ -221,6 +241,10 @@ public function selectCollection($collectionName, array $options = [])
221241
*
222242
* Supported options:
223243
*
244+
* * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
245+
* use for database operations and selected collections. Defaults to this
246+
* Database's read concern.
247+
*
224248
* * readPreference (MongoDB\Driver\ReadPreference): The default read
225249
* preference to use for database operations and selected collections.
226250
* Defaults to this Database's read preference.
@@ -234,6 +258,10 @@ public function selectCollection($collectionName, array $options = [])
234258
*/
235259
public function withOptions(array $options = [])
236260
{
261+
if ( ! isset($options['readConcern'])) {
262+
$options['readConcern'] = $this->readConcern;
263+
}
264+
237265
if ( ! isset($options['readPreference'])) {
238266
$options['readPreference'] = $this->readPreference;
239267
}

src/Operation/Aggregate.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MongoDB\Operation;
44

55
use MongoDB\Driver\Command;
6+
use MongoDB\Driver\ReadConcern;
67
use MongoDB\Driver\ReadPreference;
78
use MongoDB\Driver\Server;
89
use MongoDB\Exception\InvalidArgumentException;
@@ -23,6 +24,7 @@ class Aggregate implements Executable
2324
{
2425
private static $wireVersionForCursor = 2;
2526
private static $wireVersionForDocumentLevelValidation = 4;
27+
private static $wireVersionForReadConcern = 4;
2628

2729
private $databaseName;
2830
private $collectionName;
@@ -50,6 +52,12 @@ class Aggregate implements Executable
5052
* * maxTimeMS (integer): The maximum amount of time to allow the query to
5153
* run.
5254
*
55+
* * readConcern (MongoDB\Driver\ReadConcern): Read concern. Note that a
56+
* "majority" read concern is not compatible with the $out stage.
57+
*
58+
* For servers < 3.2, this option is ignored as read concern is not
59+
* available.
60+
*
5361
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
5462
*
5563
* * useCursor (boolean): Indicates whether the command will request that
@@ -108,6 +116,10 @@ public function __construct($databaseName, $collectionName, array $pipeline, arr
108116
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
109117
}
110118

119+
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
120+
throw new InvalidArgumentTypeException('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
121+
}
122+
111123
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
112124
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
113125
}
@@ -183,6 +195,10 @@ private function createCommand(Server $server, $isCursorSupported)
183195
$cmd['maxTimeMS'] = $this->options['maxTimeMS'];
184196
}
185197

198+
if (isset($this->options['readConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForReadConcern)) {
199+
$cmd['readConcern'] = \MongoDB\read_concern_as_document($this->options['readConcern']);
200+
}
201+
186202
if ($this->options['useCursor']) {
187203
$cmd['cursor'] = isset($this->options["batchSize"])
188204
? ['batchSize' => $this->options["batchSize"]]

src/Operation/Count.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MongoDB\Operation;
44

55
use MongoDB\Driver\Command;
6+
use MongoDB\Driver\ReadConcern;
67
use MongoDB\Driver\ReadPreference;
78
use MongoDB\Driver\Server;
89
use MongoDB\Exception\InvalidArgumentException;
@@ -18,6 +19,8 @@
1819
*/
1920
class Count implements Executable
2021
{
22+
private static $wireVersionForReadConcern = 4;
23+
2124
private $databaseName;
2225
private $collectionName;
2326
private $filter;
@@ -36,6 +39,11 @@ class Count implements Executable
3639
* * maxTimeMS (integer): The maximum amount of time to allow the query to
3740
* run.
3841
*
42+
* * readConcern (MongoDB\Driver\ReadConcern): Read concern.
43+
*
44+
* For servers < 3.2, this option is ignored as read concern is not
45+
* available.
46+
*
3947
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
4048
*
4149
* * skip (integer): The number of documents to skip before returning the
@@ -71,6 +79,10 @@ public function __construct($databaseName, $collectionName, $filter = [], array
7179
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
7280
}
7381

82+
if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
83+
throw new InvalidArgumentTypeException('"readConcern" option', $options['readConcern'], 'MongoDB\Driver\ReadConcern');
84+
}
85+
7486
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
7587
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
7688
}
@@ -96,7 +108,7 @@ public function execute(Server $server)
96108
{
97109
$readPreference = isset($this->options['readPreference']) ? $this->options['readPreference'] : null;
98110

99-
$cursor = $server->executeCommand($this->databaseName, $this->createCommand(), $readPreference);
111+
$cursor = $server->executeCommand($this->databaseName, $this->createCommand($server), $readPreference);
100112
$result = current($cursor->toArray());
101113

102114
// Older server versions may return a float
@@ -110,9 +122,10 @@ public function execute(Server $server)
110122
/**
111123
* Create the count command.
112124
*
125+
* @param Server $server
113126
* @return Command
114127
*/
115-
private function createCommand()
128+
private function createCommand(Server $server)
116129
{
117130
$cmd = ['count' => $this->collectionName];
118131

@@ -126,6 +139,10 @@ private function createCommand()
126139
}
127140
}
128141

142+
if (isset($this->options['readConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForReadConcern)) {
143+
$cmd['readConcern'] = \MongoDB\read_concern_as_document($this->options['readConcern']);
144+
}
145+
129146
return new Command($cmd);
130147
}
131148
}

0 commit comments

Comments
 (0)