Skip to content

Commit 32cfb9b

Browse files
authored
Merge pull request #688 from alcaeus/phplib-485
PHPLIB-485: Inherit collection's typeMap in distinct
2 parents b6b972c + f088c10 commit 32cfb9b

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/Collection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,10 @@ public function distinct($fieldName, $filter = [], array $options = [])
470470
$options['readPreference'] = $this->readPreference;
471471
}
472472

473+
if (! isset($options['typeMap'])) {
474+
$options['typeMap'] = $this->typeMap;
475+
}
476+
473477
$server = select_server($this->manager, $options);
474478

475479
if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {

tests/Collection/CollectionFunctionalTest.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
use MongoDB\Tests\CommandObserver;
1717
use function array_filter;
1818
use function call_user_func;
19+
use function is_scalar;
20+
use function json_encode;
1921
use function strchr;
22+
use function usort;
2023
use function version_compare;
2124

2225
/**
@@ -170,6 +173,88 @@ function (array $event) {
170173
);
171174
}
172175

176+
/**
177+
* @dataProvider provideTypeMapOptionsAndExpectedDocuments
178+
*/
179+
public function testDistinctWithTypeMap(array $typeMap, array $expectedDocuments)
180+
{
181+
$bulkWrite = new BulkWrite(['ordered' => true]);
182+
$bulkWrite->insert([
183+
'x' => (object) ['foo' => 'bar'],
184+
]);
185+
$bulkWrite->insert(['x' => 4]);
186+
$bulkWrite->insert([
187+
'x' => (object) ['foo' => ['foo' => 'bar']],
188+
]);
189+
$this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
190+
191+
$values = $this->collection->withOptions(['typeMap' => $typeMap])->distinct('x');
192+
193+
/* This sort callable sorts all scalars to the front of the list. All
194+
* non-scalar values are sorted by running json_encode on them and
195+
* comparing their string representations.
196+
*/
197+
$sort = function ($a, $b) {
198+
if (is_scalar($a) && ! is_scalar($b)) {
199+
return -1;
200+
}
201+
202+
if (! is_scalar($a)) {
203+
if (is_scalar($b)) {
204+
return 1;
205+
}
206+
207+
$a = json_encode($a);
208+
$b = json_encode($b);
209+
}
210+
211+
return $a < $b ? -1 : 1;
212+
};
213+
214+
usort($expectedDocuments, $sort);
215+
usort($values, $sort);
216+
217+
$this->assertEquals($expectedDocuments, $values);
218+
}
219+
220+
public function provideTypeMapOptionsAndExpectedDocuments()
221+
{
222+
return [
223+
'No type map' => [
224+
['root' => 'array', 'document' => 'array'],
225+
[
226+
['foo' => 'bar'],
227+
4,
228+
['foo' => ['foo' => 'bar']],
229+
],
230+
],
231+
'array/array' => [
232+
['root' => 'array', 'document' => 'array'],
233+
[
234+
['foo' => 'bar'],
235+
4,
236+
['foo' => ['foo' => 'bar']],
237+
],
238+
],
239+
'object/array' => [
240+
['root' => 'object', 'document' => 'array'],
241+
[
242+
(object) ['foo' => 'bar'],
243+
4,
244+
(object) ['foo' => ['foo' => 'bar']],
245+
],
246+
],
247+
'array/stdClass' => [
248+
['root' => 'array', 'document' => 'stdClass'],
249+
[
250+
['foo' => 'bar'],
251+
4,
252+
['foo' => (object) ['foo' => 'bar']],
253+
],
254+
],
255+
];
256+
}
257+
173258
public function testDrop()
174259
{
175260
$writeResult = $this->collection->insertOne(['x' => 1]);

0 commit comments

Comments
 (0)