Skip to content

Commit e232ace

Browse files
committed
Extract Collection::distinct() to an operation class
1 parent 9c60ffe commit e232ace

File tree

2 files changed

+97
-19
lines changed

2 files changed

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

0 commit comments

Comments
 (0)