Skip to content

Commit 7665b36

Browse files
committed
Extract Collection::distinct() to an operation class
1 parent 509d993 commit 7665b36

File tree

2 files changed

+99
-19
lines changed

2 files changed

+99
-19
lines changed

src/Collection.php

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use MongoDB\Model\IndexInfoIteratorIterator;
1717
use MongoDB\Model\IndexInput;
1818
use MongoDB\Operation\Aggregate;
19+
use MongoDB\Operation\Distinct;
1920
use Traversable;
2021

2122
class Collection
@@ -358,30 +359,19 @@ public function deleteOne(array $filter)
358359
}
359360

360361
/**
361-
* Finds the distinct values for a specified field across the collection
362+
* Finds the distinct values for a specified field across the collection.
362363
*
363-
* @see http://docs.mongodb.org/manual/reference/command/distinct/
364-
* @see Collection::getDistinctOptions() for supported $options
365-
*
366-
* @param string $fieldName The fieldname to use
367-
* @param array $filter The find query to execute
368-
* @param array $options Additional options
369-
* @return integer
364+
* @param string $fieldName Field for which to return distinct values
365+
* @param array $filter Query by which to filter documents
366+
* @param array $options Command options
367+
* @return array
370368
*/
371369
public function distinct($fieldName, array $filter = array(), array $options = array())
372370
{
373-
$options = array_merge($this->getDistinctOptions(), $options);
374-
$cmd = array(
375-
"distinct" => $this->collname,
376-
"key" => $fieldName,
377-
"query" => (object) $filter,
378-
) + $options;
371+
$operation = new Distinct($this->dbname, $this->collname, $fieldName, $filter, $options);
372+
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
379373

380-
$doc = current($this->_runCommand($this->dbname, $cmd)->toArray());
381-
if ($doc["ok"]) {
382-
return $doc["values"];
383-
}
384-
throw $this->_generateCommandException($doc);
374+
return $operation->execute($server);
385375
}
386376

387377
/**

src/Operation/Distinct.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace MongoDB\Operation;
4+
5+
use MongoDB\Driver\Command;
6+
use MongoDB\Driver\Server;
7+
use MongoDB\Exception\InvalidArgumentException;
8+
use MongoDB\Exception\InvalidArgumentTypeException;
9+
use MongoDB\Exception\RuntimeException;
10+
use MongoDB\Exception\UnexpectedValueException;
11+
use ArrayIterator;
12+
use stdClass;
13+
14+
/**
15+
* Operation for the distinct command.
16+
*
17+
* @api
18+
* @see MongoDB\Collection::distinct()
19+
* @see http://docs.mongodb.org/manual/reference/command/distinct/
20+
*/
21+
class Distinct implements Executable
22+
{
23+
private $databaseName;
24+
private $collectionName;
25+
private $fieldName;
26+
private $filter;
27+
private $options;
28+
29+
/**
30+
* Constructs a distinct command.
31+
*
32+
* Supported options:
33+
*
34+
* * maxTimeMS (integer): The maximum amount of time to allow the query to
35+
* run.
36+
*
37+
* @param string $databaseName Database name
38+
* @param string $collectionName Collection name
39+
* @param string $fieldName Field for which to return distinct values
40+
* @param array $filter Query by which to filter documents
41+
* @param array $options Command options
42+
* @throws InvalidArgumentException
43+
*/
44+
public function __construct($databaseName, $collectionName, $fieldName, array $filter = array(), array $options = array())
45+
{
46+
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
47+
throw new InvalidArgumentTypeException('maxTimeMS option', $options['maxTimeMS'], 'integer');
48+
}
49+
50+
$this->databaseName = (string) $databaseName;
51+
$this->collectionName = (string) $collectionName;
52+
$this->fieldName = (string) $fieldName;
53+
$this->filter = $filter;
54+
$this->options = $options;
55+
}
56+
57+
/**
58+
* Execute the operation.
59+
*
60+
* @see Executable::execute()
61+
* @param Server $server
62+
* @return array
63+
*/
64+
public function execute(Server $server)
65+
{
66+
$cmd = array(
67+
'distinct' => $this->collectionName,
68+
'key' => $this->fieldName,
69+
);
70+
71+
if ( ! empty($this->filter)) {
72+
$cmd['query'] = (object) $this->filter;
73+
}
74+
75+
$cmd += $this->options;
76+
77+
$cursor = $server->executeCommand($this->databaseName, new Command($cmd));
78+
$result = current($cursor->toArray());
79+
80+
if (empty($result['ok'])) {
81+
throw new RuntimeException(isset($result['errmsg']) ? $result['errmsg'] : 'Unknown error');
82+
}
83+
84+
if ( ! isset($result['values']) || ! is_array($result['values'])) {
85+
throw new UnexpectedValueException('distinct command did not return a "values" array');
86+
}
87+
88+
return $result['values'];
89+
}
90+
}

0 commit comments

Comments
 (0)