Commit 9746ccd2 authored by Jeremy Mikola's avatar Jeremy Mikola

Extract Collection::distinct() to an operation class

parent 7973b380
...@@ -16,6 +16,7 @@ use MongoDB\Model\IndexInfoIterator; ...@@ -16,6 +16,7 @@ use MongoDB\Model\IndexInfoIterator;
use MongoDB\Model\IndexInfoIteratorIterator; use MongoDB\Model\IndexInfoIteratorIterator;
use MongoDB\Model\IndexInput; use MongoDB\Model\IndexInput;
use MongoDB\Operation\Aggregate; use MongoDB\Operation\Aggregate;
use MongoDB\Operation\Distinct;
use Traversable; use Traversable;
class Collection class Collection
...@@ -356,30 +357,20 @@ class Collection ...@@ -356,30 +357,20 @@ class Collection
} }
/** /**
* Finds the distinct values for a specified field across the collection * Finds the distinct values for a specified field across the collection.
* *
* @see http://docs.mongodb.org/manual/reference/command/distinct/ * @see Distinct::__construct() for supported options
* @see Collection::getDistinctOptions() for supported $options * @param string $fieldName Field for which to return distinct values
* * @param array $filter Query by which to filter documents
* @param string $fieldName The fieldname to use * @param array $options Command options
* @param array $filter The find query to execute * @return mixed[]
* @param array $options Additional options
* @return integer
*/ */
public function distinct($fieldName, array $filter = array(), array $options = array()) public function distinct($fieldName, array $filter = array(), array $options = array())
{ {
$options = array_merge($this->getDistinctOptions(), $options); $operation = new Distinct($this->dbname, $this->collname, $fieldName, $filter, $options);
$cmd = array( $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
"distinct" => $this->collname,
"key" => $fieldName,
"query" => (object) $filter,
) + $options;
$doc = current($this->_runCommand($this->dbname, $cmd)->toArray()); return $operation->execute($server);
if ($doc["ok"]) {
return $doc["values"];
}
throw $this->_generateCommandException($doc);
} }
/** /**
...@@ -657,23 +648,6 @@ class Collection ...@@ -657,23 +648,6 @@ class Collection
return $this->dbname; return $this->dbname;
} }
/**
* Retrieves all distinct options with their default values.
*
* @return array of Collection::distinct() options
*/
public function getDistinctOptions()
{
return array(
/**
* The maximum amount of time to allow the query to run. The default is infinite.
*
* @see http://docs.mongodb.org/manual/reference/command/distinct/
*/
"maxTimeMS" => 0,
);
}
/** /**
* Retrieves all findOneDelete options with their default values. * Retrieves all findOneDelete options with their default values.
* *
......
<?php
namespace MongoDB\Operation;
use MongoDB\Driver\Command;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedValueException;
/**
* Operation for the distinct command.
*
* @api
* @see MongoDB\Collection::distinct()
* @see http://docs.mongodb.org/manual/reference/command/distinct/
*/
class Distinct implements Executable
{
private $databaseName;
private $collectionName;
private $fieldName;
private $filter;
private $options;
/**
* Constructs a distinct command.
*
* Supported options:
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param string $fieldName Field for which to return distinct values
* @param array $filter Query by which to filter documents
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $fieldName, array $filter = array(), array $options = array())
{
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
}
$this->databaseName = (string) $databaseName;
$this->collectionName = (string) $collectionName;
$this->fieldName = (string) $fieldName;
$this->filter = $filter;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return mixed[]
*/
public function execute(Server $server)
{
$cursor = $server->executeCommand($this->databaseName, $this->createCommand());
$result = current($cursor->toArray());
if (empty($result['ok'])) {
throw new RuntimeException(isset($result['errmsg']) ? $result['errmsg'] : 'Unknown error');
}
if ( ! isset($result['values']) || ! is_array($result['values'])) {
throw new UnexpectedValueException('distinct command did not return a "values" array');
}
return $result['values'];
}
/**
* Create the distinct command.
*
* @return Command
*/
private function createCommand()
{
$cmd = array(
'distinct' => $this->collectionName,
'key' => $this->fieldName,
);
if ( ! empty($this->filter)) {
$cmd['query'] = (object) $this->filter;
}
if (isset($this->options['maxTimeMS'])) {
$cmd[$option] = $this->options['maxTimeMS'];
}
return new Command($cmd);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment