Skip to content

Commit 7439f55

Browse files
committed
Collection::distinct() method, refactoring
1 parent 28c26c8 commit 7439f55

23 files changed

+136
-51
lines changed

src/BulkCompiler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function add($writeModels)
4545
if (!$model instanceof WriteModelInterface) {
4646
throw new InvalidArgumentException(
4747
sprintf(
48-
'Each write model must be an instance of "%s", "%s" given in $writeModels[%d]',
48+
'Each write model must be an instance of "%s", "%s" given in $writeModels[%d].',
4949
WriteModelInterface::class,
5050
getType($model),
5151
$i

src/Client.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public function listDatabases()
110110

111111
if (isset($result['databases']) && is_array($result['databases'])) {
112112
throw new UnexpectedResultException(
113-
'Command "listDatabases" did not return expected "databases" array'
113+
'Command "listDatabases" did not return expected "databases" array.'
114114
);
115115
}
116116

src/Collection.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Tequila\MongoDB\OptionsResolver\Command\AggregateResolver;
99
use Tequila\MongoDB\OptionsResolver\Command\CountResolver;
1010
use Tequila\MongoDB\OptionsResolver\Command\CreateIndexesResolver;
11+
use Tequila\MongoDB\OptionsResolver\Command\DistinctResolver;
1112
use Tequila\MongoDB\OptionsResolver\Command\DropCollectionResolver;
1213
use Tequila\MongoDB\OptionsResolver\Command\DropIndexesResolver;
1314
use Tequila\MongoDB\OptionsResolver\Command\FindAndModifyResolver;
@@ -227,6 +228,43 @@ public function deleteOne($filter, array $options = [])
227228
return new DeleteResult($bulkWriteResult);
228229
}
229230

231+
/**
232+
* @param $fieldName
233+
* @param array $filter
234+
* @param array $options
235+
* @return array
236+
*/
237+
public function distinct($fieldName, array $filter = [], array $options = [])
238+
{
239+
if (!is_string($fieldName)) {
240+
throw new InvalidArgumentException('$fieldName must be a string.');
241+
}
242+
243+
if (!$fieldName) {
244+
throw new InvalidArgumentException('$fieldName cannot be empty.');
245+
}
246+
247+
$command = ['distinct' => $this->collectionName, 'key' => $fieldName];
248+
if ($filter) {
249+
$command['query'] = (object)$filter;
250+
}
251+
252+
$cursor = $this->executeCommand(
253+
$command,
254+
$options,
255+
DistinctResolver::class
256+
);
257+
258+
$result = $cursor->current();
259+
if (!isset($result['values'])) {
260+
throw new UnexpectedResultException(
261+
'Command "distinct" did not return expected "values" array.'
262+
);
263+
}
264+
265+
return $result['values'];
266+
}
267+
230268
/**
231269
* @param array $options
232270
* @return array
@@ -328,7 +366,7 @@ public function findOneAndReplace(array $filter, $replacement, array $options =
328366
if (!is_array($replacement) && !is_object($replacement)) {
329367
throw new InvalidArgumentException(
330368
sprintf(
331-
'$replacement must be an array or an object, %s given',
369+
'$replacement must be an array or an object, "%s" given.',
332370
getType($replacement)
333371
)
334372
);

src/CommandOptions.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use MongoDB\Driver\WriteConcern;
77
use Tequila\MongoDB\Exception\RuntimeException;
88
use Tequila\MongoDB\Exception\UnsupportedException;
9-
use Tequila\MongoDB\Server;
109

1110
class CommandOptions extends \ArrayObject
1211
{
@@ -21,7 +20,7 @@ class CommandOptions extends \ArrayObject
2120
public function getServer()
2221
{
2322
if (null === $this->server) {
24-
throw new RuntimeException('Server was not set on this instance');
23+
throw new RuntimeException('Server was not set on this instance.');
2524
}
2625

2726
return $this->server;
@@ -43,7 +42,7 @@ public function resolveDocumentValidation()
4342
if (isset($this['bypassDocumentValidation'])) {
4443
if (!$this->getServer()->supportsDocumentValidation()) {
4544
throw new UnsupportedException(
46-
'Option "bypassDocumentValidation" is not supported by the server'
45+
'Option "bypassDocumentValidation" is not supported by the server.'
4746
);
4847
}
4948
}
@@ -60,7 +59,7 @@ public function resolveDocumentValidation()
6059
public function resolveCollation()
6160
{
6261
if (isset($this['collation']) && !$this->server->supportsCollation()) {
63-
throw new UnsupportedException('Option "collation" is not supported by the server');
62+
throw new UnsupportedException('Option "collation" is not supported by the server.');
6463
}
6564

6665
return $this;
@@ -91,7 +90,7 @@ public function resolveReadConcern(ReadConcern $defaultValue = null)
9190

9291
if (isset($this['readConcern']) && !$server->supportsReadConcern()) {
9392
throw new UnsupportedException(
94-
'Option "readConcern" is not supported by the server'
93+
'Option "readConcern" is not supported by the server.'
9594
);
9695
}
9796

src/Index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Index
2525
public function __construct(array $key, array $options = [])
2626
{
2727
if (empty($key)) {
28-
throw new InvalidArgumentException('$key document cannot be empty');
28+
throw new InvalidArgumentException('$key document cannot be empty.');
2929
}
3030

3131
$options = ResolverFactory::get(IndexOptionsResolver::class)->resolve($options);

src/OptionsResolver/Command/AggregateResolver.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Tequila\MongoDB\OptionsResolver\Configurator\CollationConfigurator;
1111
use Tequila\MongoDB\Exception\InvalidArgumentException;
1212
use Tequila\MongoDB\OptionsResolver\Configurator\DocumentValidationConfigurator;
13+
use Tequila\MongoDB\OptionsResolver\Configurator\MaxTimeConfigurator;
1314
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
1415
use Tequila\MongoDB\CommandOptions;
1516

@@ -28,6 +29,7 @@ public function configureOptions()
2829
{
2930
CollationConfigurator::configure($this);
3031
DocumentValidationConfigurator::configure($this);
32+
MaxTimeConfigurator::configure($this);
3133

3234
$this
3335
->setRequired('pipeline')
@@ -39,14 +41,12 @@ public function configureOptions()
3941
$this->setDefined([
4042
'allowDiskUse',
4143
'batchSize',
42-
'maxTimeMS',
4344
'useCursor',
4445
]);
4546

4647
$this
4748
->setAllowedTypes('allowDiskUse', 'bool')
4849
->setAllowedTypes('batchSize', 'integer')
49-
->setAllowedTypes('maxTimeMS', 'integer')
5050
->setAllowedTypes('useCursor', 'bool');
5151

5252
$this->setDefault('useCursor', true);
@@ -66,14 +66,14 @@ public function resolve(array $options = array())
6666
$readConcern = $options['readConcern'];
6767
if ($hasOutStage && ReadConcern::MAJORITY === $readConcern->getLevel()) {
6868
throw new InvalidArgumentException(
69-
'Specifying "readConcern" option with "majority" level is prohibited when pipeline has $out stage'
69+
'Specifying "readConcern" option with "majority" level is prohibited when pipeline has $out stage.'
7070
);
7171
}
7272
}
7373

7474
if (isset($options['writeConcern']) && !$hasOutStage) {
7575
throw new InvalidArgumentException(
76-
'Option "writeConcern" is meaningless until aggregation pipeline has $out stage'
76+
'Option "writeConcern" is meaningless until aggregation pipeline has $out stage.'
7777
);
7878
}
7979

@@ -89,7 +89,7 @@ public function resolve(array $options = array())
8989
} else {
9090
if (isset($options['batchSize'])) {
9191
throw new InvalidArgumentException(
92-
'Option "batchSize" is meaningless unless option "useCursor" is set to true'
92+
'Option "batchSize" is meaningless unless option "useCursor" is set to true.'
9393
);
9494
}
9595
}

src/OptionsResolver/Command/CreateCollectionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function configureOptions()
5555
if ($value && (!isset($options['capped']) || false === $options['capped'])) {
5656
throw new InvalidArgumentException(
5757
sprintf(
58-
'The "%s" option is meaningless until "capped" option has been set to true',
58+
'The "%s" option is meaningless until "capped" option has been set to true.',
5959
$optionName
6060
)
6161
);
@@ -77,7 +77,7 @@ public function resolve(array $options = array())
7777
$options = parent::resolve($options);
7878
if (!isset($options['size']) && isset($options['capped']) && true === $options['capped']) {
7979
throw new InvalidArgumentException(
80-
'The option "size" is required for capped collections'
80+
'The option "size" is required for capped collections.'
8181
);
8282
}
8383

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Tequila\MongoDB\OptionsResolver\Command;
4+
5+
use MongoDB\Driver\ReadPreference;
6+
use Tequila\MongoDB\CommandOptions;
7+
use Tequila\MongoDB\OptionsResolver\Command\Traits\ReadConcernTrait;
8+
use Tequila\MongoDB\OptionsResolver\Configurator\CollationConfigurator;
9+
use Tequila\MongoDB\OptionsResolver\Configurator\MaxTimeConfigurator;
10+
use Tequila\MongoDB\OptionsResolver\Configurator\ReadConcernConfigurator;
11+
use Tequila\MongoDB\OptionsResolver\Configurator\ReadPreferenceConfigurator;
12+
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
13+
14+
class DistinctResolver extends OptionsResolver implements
15+
ReadConcernAwareInterface,
16+
ReadPreferenceResolverInterface,
17+
CompatibilityResolverInterface
18+
{
19+
use ReadConcernTrait;
20+
21+
public function configureOptions()
22+
{
23+
CollationConfigurator::configure($this);
24+
MaxTimeConfigurator::configure($this);
25+
ReadConcernConfigurator::configure($this);
26+
ReadPreferenceConfigurator::configure($this);
27+
}
28+
29+
public function resolveCompatibilities(CommandOptions $options)
30+
{
31+
$options
32+
->resolveCollation()
33+
->resolveReadConcern($this->readConcern);
34+
}
35+
36+
public function resolveReadPreference(array $options, ReadPreference $defaultReadPreference)
37+
{
38+
return isset($options['readPreference']) ? $options['readPreference'] : $defaultReadPreference;
39+
}
40+
}

src/OptionsResolver/Command/FindAndModifyResolver.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Tequila\MongoDB\Exception\InvalidArgumentException;
77
use Tequila\MongoDB\OptionsResolver\Configurator\CollationConfigurator;
88
use Tequila\MongoDB\OptionsResolver\Configurator\DocumentValidationConfigurator;
9+
use Tequila\MongoDB\OptionsResolver\Configurator\MaxTimeConfigurator;
910
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
1011
use Tequila\MongoDB\CommandOptions;
1112

@@ -17,6 +18,7 @@ public function configureOptions()
1718
{
1819
CollationConfigurator::configure($this);
1920
DocumentValidationConfigurator::configure($this);
21+
MaxTimeConfigurator::configure($this);
2022

2123
$this->setDefined([
2224
'sort',
@@ -25,7 +27,6 @@ public function configureOptions()
2527
'new',
2628
'fields',
2729
'upsert',
28-
'maxTimeMS',
2930
]);
3031

3132
$documentTypes = ['array', 'object'];
@@ -36,8 +37,7 @@ public function configureOptions()
3637
->setAllowedTypes('update', $documentTypes)
3738
->setAllowedTypes('new', 'bool')
3839
->setAllowedTypes('fields', $documentTypes)
39-
->setAllowedTypes('upsert', 'bool')
40-
->setAllowedTypes('maxTimeMS', 'integer');
40+
->setAllowedTypes('upsert', 'bool');
4141
}
4242

4343
public function resolve(array $options = array())
@@ -46,13 +46,13 @@ public function resolve(array $options = array())
4646

4747
if ((!isset($options['remove']) || false === $options['remove']) && !isset($options['update'])) {
4848
throw new InvalidArgumentException(
49-
'Option "update" is required when option "remove" is not set or set to false'
49+
'Option "update" is required when option "remove" is not set or set to false.'
5050
);
5151
}
5252

5353
if (isset($options['remove']) && true === $options['remove'] && isset($options['update'])) {
5454
throw new InvalidArgumentException(
55-
'Option "update" is not allowed when option "remove" is set to true'
55+
'Option "update" is not allowed when option "remove" is set to true.'
5656
);
5757
}
5858

src/OptionsResolver/Command/FindOneAndDeleteResolver.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tequila\MongoDB\OptionsResolver\Command;
44

55
use Tequila\MongoDB\OptionsResolver\Configurator\CollationConfigurator;
6+
use Tequila\MongoDB\OptionsResolver\Configurator\MaxTimeConfigurator;
67
use Tequila\MongoDB\OptionsResolver\Configurator\WriteConcernConfigurator;
78
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
89

@@ -12,9 +13,9 @@ public function configureOptions()
1213
{
1314
CollationConfigurator::configure($this);
1415
WriteConcernConfigurator::configure($this);
16+
MaxTimeConfigurator::configure($this);
1517

1618
$this->setDefined([
17-
'maxTimeMS',
1819
'projection',
1920
'sort',
2021
]);

src/OptionsResolver/Command/FindOneAndUpdateResolver.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Tequila\MongoDB\OptionsResolver\Configurator\CollationConfigurator;
66
use Tequila\MongoDB\OptionsResolver\Configurator\DocumentValidationConfigurator;
7+
use Tequila\MongoDB\OptionsResolver\Configurator\MaxTimeConfigurator;
78
use Tequila\MongoDB\OptionsResolver\Configurator\WriteConcernConfigurator;
89
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
910

@@ -17,9 +18,9 @@ public function configureOptions()
1718
CollationConfigurator::configure($this);
1819
DocumentValidationConfigurator::configure($this);
1920
WriteConcernConfigurator::configure($this);
21+
MaxTimeConfigurator::configure($this);
2022

2123
$this->setDefined([
22-
'maxTimeMS',
2324
'projection',
2425
'returnDocument',
2526
'sort',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tequila\MongoDB\OptionsResolver\Configurator;
4+
5+
use Tequila\MongoDB\OptionsResolver\OptionsResolver;
6+
7+
class MaxTimeConfigurator
8+
{
9+
public static function configure(OptionsResolver $resolver)
10+
{
11+
$resolver
12+
->setDefined('maxTimeMS')
13+
->setAllowedTypes('maxTimeMS', 'integer');
14+
}
15+
}

0 commit comments

Comments
 (0)