Skip to content

Commit 82a44c5

Browse files
committed
PHPLIB-133: Support typeMap option in FindOne
1 parent 5f24d92 commit 82a44c5

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed

src/Operation/FindOne.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MongoDB\Operation;
44

55
use MongoDB\Driver\Server;
6+
use MongoDB\Exception\InvalidArgumentTypeException;
67

78
/**
89
* Operation for finding a single document with the find command.
@@ -15,6 +16,7 @@
1516
class FindOne implements Executable
1617
{
1718
private $find;
19+
private $options;
1820

1921
/**
2022
* Constructs a find command for finding a single document.
@@ -42,6 +44,8 @@ class FindOne implements Executable
4244
* "$orderby" also exists in the modifiers document, this option will
4345
* take precedence.
4446
*
47+
* * typeMap (array): Type map for BSON deserialization.
48+
*
4549
* @param string $databaseName Database name
4650
* @param string $collectionName Collection name
4751
* @param array|object $filter Query by which to filter documents
@@ -50,12 +54,18 @@ class FindOne implements Executable
5054
*/
5155
public function __construct($databaseName, $collectionName, $filter, array $options = array())
5256
{
57+
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
58+
throw new InvalidArgumentTypeException('"typeMap" option', $options['typeMap'], 'array');
59+
}
60+
5361
$this->find = new Find(
5462
$databaseName,
5563
$collectionName,
5664
$filter,
5765
array('limit' => -1) + $options
5866
);
67+
68+
$this->options = $options;
5969
}
6070

6171
/**
@@ -68,6 +78,11 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
6878
public function execute(Server $server)
6979
{
7080
$cursor = $this->find->execute($server);
81+
82+
if (isset($this->options['typeMap'])) {
83+
$cursor->setTypeMap($this->options['typeMap']);
84+
}
85+
7186
$document = current($cursor->toArray());
7287

7388
return ($document === false) ? null : $document;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Driver\BulkWrite;
6+
use MongoDB\Operation\FindOne;
7+
8+
class FindOneFunctionalTest extends FunctionalTestCase
9+
{
10+
/**
11+
* @dataProvider provideTypeMapOptionsAndExpectedDocument
12+
*/
13+
public function testTypeMapOption(array $typeMap, $expectedDocument)
14+
{
15+
$this->createFixtures(1);
16+
17+
$operation = new FindOne($this->getDatabaseName(), $this->getCollectionName(), [], ['typeMap' => $typeMap]);
18+
$document = $operation->execute($this->getPrimaryServer());
19+
20+
$this->assertEquals($expectedDocument, $document);
21+
}
22+
23+
public function provideTypeMapOptionsAndExpectedDocument()
24+
{
25+
return [
26+
[
27+
['root' => 'array', 'document' => 'array'],
28+
['_id' => 1, 'x' => ['foo' => 'bar']],
29+
],
30+
[
31+
['root' => 'object', 'document' => 'array'],
32+
(object) ['_id' => 1, 'x' => ['foo' => 'bar']],
33+
],
34+
[
35+
['root' => 'array', 'document' => 'stdClass'],
36+
['_id' => 1, 'x' => (object) ['foo' => 'bar']],
37+
],
38+
];
39+
}
40+
41+
/**
42+
* Create data fixtures.
43+
*
44+
* @param integer $n
45+
*/
46+
private function createFixtures($n)
47+
{
48+
$bulkWrite = new BulkWrite(true);
49+
50+
for ($i = 1; $i <= $n; $i++) {
51+
$bulkWrite->insert([
52+
'_id' => $i,
53+
'x' => (object) ['foo' => 'bar'],
54+
]);
55+
}
56+
57+
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
58+
59+
$this->assertEquals($n, $result->getInsertedCount());
60+
}
61+
}

tests/Operation/FindOneTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Operation\FindOne;
6+
7+
class FindOneTest extends TestCase
8+
{
9+
/**
10+
* @expectedException MongoDB\Exception\InvalidArgumentException
11+
* @dataProvider provideInvalidConstructorTypeMapOptions
12+
*/
13+
public function testConstructorTypeMapOption($typeMap)
14+
{
15+
new FindOne($this->getDatabaseName(), $this->getCollectionName(), [], ['typeMap' => $typeMap]);
16+
}
17+
18+
public function provideInvalidConstructorTypeMapOptions()
19+
{
20+
return $this->wrapValuesForDataProvider($this->getInvalidArrayValues());
21+
}
22+
}

tests/Operation/TestCase.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public function provideInvalidBooleanValues()
2020
return $this->wrapValuesForDataProvider($this->getInvalidBooleanValues());
2121
}
2222

23+
protected function getInvalidArrayValues()
24+
{
25+
return array(123, 3.14, 'foo', true, new stdClass);
26+
}
27+
2328
protected function getInvalidBooleanValues()
2429
{
2530
return array(123, 3.14, 'foo', array(), new stdClass);

0 commit comments

Comments
 (0)