PHPLIB-242: Add typeMap support for distinct

parent 3c9064a8
......@@ -19,4 +19,10 @@ source:
ref: session
post: |
.. versionadded:: 1.3
---
source:
file: apiargs-MongoDBCollection-common-option.yaml
ref: typeMap
post: |
.. versionadded:: 1.5
...
......@@ -69,6 +69,8 @@ class Distinct implements Executable, Explainable
*
* Sessions are not supported for server versions < 3.6.
*
* * typeMap (array): Type map for BSON deserialization.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param string $fieldName Field for which to return distinct values
......@@ -102,6 +104,10 @@ class Distinct implements Executable, Explainable
throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
}
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
}
if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
unset($options['readConcern']);
}
......@@ -139,6 +145,11 @@ class Distinct implements Executable, Explainable
}
$cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
if (isset($this->options['typeMap'])) {
$cursor->setTypeMap(\MongoDB\create_field_path_type_map($this->options['typeMap'], 'values.$'));
}
$result = current($cursor->toArray());
if ( ! isset($result->values) || ! is_array($result->values)) {
......
......@@ -2,6 +2,7 @@
namespace MongoDB\Tests\Operation;
use MongoDB\Driver\BulkWrite;
use MongoDB\Operation\Distinct;
use MongoDB\Tests\CommandObserver;
use stdClass;
......@@ -51,4 +52,89 @@ class DistinctFunctionalTest extends FunctionalTestCase
}
);
}
/**
* @dataProvider provideTypeMapOptionsAndExpectedDocuments
*/
public function testTypeMapOption(array $typeMap, array $expectedDocuments)
{
$bulkWrite = new BulkWrite(['ordered' => true]);
$bulkWrite->insert([
'x' => (object) ['foo' => 'bar'],
]);
$bulkWrite->insert([
'x' => 4,
]);
$bulkWrite->insert([
'x' => (object) ['foo' => ['foo' => 'bar']],
]);
$this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
$distinct = new Distinct($this->getDatabaseName(), $this->getCollectionName(), 'x', [], ['typeMap' => $typeMap]);
$values = $distinct->execute($this->getPrimaryServer());
/* This sort callable sorts all scalars to the front of the list. All
* non-scalar values are sorted by running json_encode on them and
* comparing their string representations.
*/
$sort = function ($a, $b) {
if (is_scalar($a) && ! is_scalar($b)) {
return -1;
}
if (! is_scalar($a)) {
if (is_scalar($b)) {
return 1;
}
$a = json_encode($a);
$b = json_encode($b);
}
return $a < $b ? -1 : 1;
};
usort($expectedDocuments, $sort);
usort($values, $sort);
$this->assertEquals($expectedDocuments, $values);
}
public function provideTypeMapOptionsAndExpectedDocuments()
{
return [
'No type map' => [
['root' => 'array', 'document' => 'array'],
[
['foo' => 'bar'],
4,
['foo' => ['foo' => 'bar']],
],
],
'array/array' => [
['root' => 'array', 'document' => 'array'],
[
['foo' => 'bar'],
4,
['foo' => ['foo' => 'bar']],
],
],
'object/array' => [
['root' => 'object', 'document' => 'array'],
[
(object) ['foo' => 'bar'],
4,
(object) ['foo' => ['foo' => 'bar']],
],
],
'array/stdClass' => [
['root' => 'array', 'document' => 'stdClass'],
[
['foo' => 'bar'],
4,
['foo' => (object) ['foo' => 'bar']],
],
],
];
}
}
......@@ -49,6 +49,10 @@ class DistinctTest extends TestCase
$options[][] = ['session' => $value];
}
foreach ($this->getInvalidArrayValues() as $value) {
$options[][] = ['typeMap' => $value];
}
return $options;
}
}
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