Skip to content

Commit fbb10fe

Browse files
committed
Merge pull request #36
2 parents ed4cfa1 + 4146fac commit fbb10fe

18 files changed

+421
-63
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;

src/Operation/FindOneAndDelete.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,23 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
4444
throw new InvalidArgumentTypeException('$filter', $filter, 'array or object');
4545
}
4646

47-
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
48-
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
49-
}
50-
5147
if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
5248
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
5349
}
5450

55-
if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
56-
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
51+
if (isset($options['projection'])) {
52+
$options['fields'] = $options['projection'];
5753
}
5854

55+
unset($options['projection']);
56+
5957
$this->findAndModify = new FindAndModify(
6058
$databaseName,
6159
$collectionName,
6260
array(
63-
'fields' => isset($options['projection']) ? $options['projection'] : null,
64-
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
6561
'query' => $filter,
6662
'remove' => true,
67-
'sort' => isset($options['sort']) ? $options['sort'] : null,
68-
)
63+
) + $options
6964
);
7065
}
7166

src/Operation/FindOneAndReplace.php

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ public function __construct($databaseName, $collectionName, $filter, $replacemen
6868
'upsert' => false,
6969
);
7070

71-
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
72-
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
73-
}
74-
7571
if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
7672
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
7773
}
@@ -85,26 +81,21 @@ public function __construct($databaseName, $collectionName, $filter, $replacemen
8581
throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
8682
}
8783

88-
if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
89-
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
84+
if (isset($options['projection'])) {
85+
$options['fields'] = $options['projection'];
9086
}
9187

92-
if ( ! is_bool($options['upsert'])) {
93-
throw new InvalidArgumentTypeException('"upsert" option', $options['upsert'], 'boolean');
94-
}
88+
$options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;
89+
90+
unset($options['projection'], $options['returnDocument']);
9591

9692
$this->findAndModify = new FindAndModify(
9793
$databaseName,
9894
$collectionName,
9995
array(
100-
'fields' => isset($options['projection']) ? $options['projection'] : null,
101-
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
102-
'new' => $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER,
10396
'query' => $filter,
104-
'sort' => isset($options['sort']) ? $options['sort'] : null,
10597
'update' => $replacement,
106-
'upsert' => $options['upsert'],
107-
)
98+
) + $options
10899
);
109100
}
110101

src/Operation/FindOneAndUpdate.php

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ public function __construct($databaseName, $collectionName, $filter, $update, ar
6868
'upsert' => false,
6969
);
7070

71-
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
72-
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
73-
}
74-
7571
if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
7672
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
7773
}
@@ -85,26 +81,21 @@ public function __construct($databaseName, $collectionName, $filter, $update, ar
8581
throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
8682
}
8783

88-
if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
89-
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
84+
if (isset($options['projection'])) {
85+
$options['fields'] = $options['projection'];
9086
}
9187

92-
if ( ! is_bool($options['upsert'])) {
93-
throw new InvalidArgumentTypeException('"upsert" option', $options['upsert'], 'boolean');
94-
}
88+
$options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;
89+
90+
unset($options['projection'], $options['returnDocument']);
9591

9692
$this->findAndModify = new FindAndModify(
9793
$databaseName,
9894
$collectionName,
9995
array(
100-
'fields' => isset($options['projection']) ? $options['projection'] : null,
101-
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
102-
'new' => $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER,
10396
'query' => $filter,
104-
'sort' => isset($options['sort']) ? $options['sort'] : null,
10597
'update' => $update,
106-
'upsert' => $options['upsert'],
107-
)
98+
) + $options
10899
);
109100
}
110101

tests/Collection/CrudSpec/AggregateFunctionalTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use MongoDB\Collection;
66
use MongoDB\Driver\ReadPreference;
7+
use MongoDB\Operation\DropCollection;
78

89
/**
910
* CRUD spec functional tests for aggregate().
@@ -48,7 +49,8 @@ public function testAggregateWithOut()
4849
}
4950

5051
$outputCollection = new Collection($this->manager, $this->getNamespace() . '_output');
51-
$this->dropCollectionIfItExists($outputCollection);
52+
$operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName());
53+
$operation->execute($this->getPrimaryServer());
5254

5355
$this->collection->aggregate(
5456
array(
@@ -66,6 +68,7 @@ public function testAggregateWithOut()
6668
$this->assertSameDocuments($expected, $outputCollection->find());
6769

6870
// Manually clean up our output collection
69-
$this->dropCollectionIfItExists($outputCollection);
71+
$operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName());
72+
$operation->execute($this->getPrimaryServer());
7073
}
7174
}

tests/Collection/FunctionalTestCase.php

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace MongoDB\Tests\Collection;
44

55
use MongoDB\Collection;
6-
use MongoDB\Database;
6+
use MongoDB\Operation\DropCollection;
77
use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
88

99
/**
@@ -18,7 +18,8 @@ public function setUp()
1818
parent::setUp();
1919

2020
$this->collection = new Collection($this->manager, $this->getNamespace());
21-
$this->dropCollectionIfItExists($this->collection);
21+
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
22+
$operation->execute($this->getPrimaryServer());
2223
}
2324

2425
public function tearDown()
@@ -27,21 +28,7 @@ public function tearDown()
2728
return;
2829
}
2930

30-
$this->dropCollectionIfItExists($this->collection);
31-
}
32-
33-
/**
34-
* Drop the collection if it exists.
35-
*
36-
* @param Collection $collection
37-
*/
38-
protected function dropCollectionIfItExists(Collection $collection)
39-
{
40-
$database = new Database($this->manager, $collection->getDatabaseName());
41-
$collections = $database->listCollections(array('filter' => array('name' => $collection->getCollectionName())));
42-
43-
if (iterator_count($collections) > 0) {
44-
$this->assertCommandSucceeded($collection->drop());
45-
}
31+
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
32+
$operation->execute($this->getPrimaryServer());
4633
}
4734
}

tests/FunctionalTestCase.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ protected function assertSameDocuments(array $expectedDocuments, $actualDocument
6868
);
6969
}
7070

71+
protected function getPrimaryServer()
72+
{
73+
return $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
74+
}
75+
7176
protected function getServerVersion(ReadPreference $readPreference = null)
7277
{
7378
$cursor = $this->manager->executeCommand(
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Operation\Aggregate;
6+
7+
class AggregateFunctionalTest extends FunctionalTestCase
8+
{
9+
/**
10+
* @expectedException MongoDB\Driver\Exception\RuntimeException
11+
*/
12+
public function testUnrecognizedPipelineState()
13+
{
14+
$server = $this->getPrimaryServer();
15+
$operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), [['$foo' => 1]]);
16+
$operation->execute($server);
17+
}
18+
}

tests/Operation/DropDatabaseFunctionalTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public function testDropNonexistentDatabase()
2727
{
2828
$server = $this->getPrimaryServer();
2929

30+
$operation = new DropDatabase($this->getDatabaseName());
31+
$operation->execute($server);
32+
3033
$this->assertDatabaseDoesNotExist($server, $this->getDatabaseName());
3134

3235
$operation = new DropDatabase($this->getDatabaseName());

tests/Operation/FindAndModifyTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Operation\FindAndModify;
6+
7+
class FindAndModifyTest extends TestCase
8+
{
9+
/**
10+
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
11+
* @dataProvider provideInvalidConstructorOptions
12+
*/
13+
public function testConstructorOptionTypeChecks(array $options)
14+
{
15+
new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), $options);
16+
}
17+
18+
public function provideInvalidConstructorOptions()
19+
{
20+
$options = [];
21+
22+
foreach ($this->getInvalidDocumentValues() as $value) {
23+
$options[][] = ['fields' => $value];
24+
}
25+
26+
foreach ($this->getInvalidIntegerValues() as $value) {
27+
$options[][] = ['maxTimeMS' => $value];
28+
}
29+
30+
foreach ($this->getInvalidBooleanValues() as $value) {
31+
$options[][] = ['new' => $value];
32+
}
33+
34+
foreach ($this->getInvalidDocumentValues() as $value) {
35+
$options[][] = ['query' => $value];
36+
}
37+
38+
foreach ($this->getInvalidBooleanValues() as $value) {
39+
$options[][] = ['remove' => $value];
40+
}
41+
42+
foreach ($this->getInvalidDocumentValues() as $value) {
43+
$options[][] = ['sort' => $value];
44+
}
45+
46+
foreach ($this->getInvalidDocumentValues() as $value) {
47+
$options[][] = ['update' => $value];
48+
}
49+
50+
foreach ($this->getInvalidBooleanValues() as $value) {
51+
$options[][] = ['upsert' => $value];
52+
}
53+
54+
return $options;
55+
}
56+
57+
/**
58+
* @expectedException MongoDB\Exception\InvalidArgumentException
59+
* @expectedExceptionMessage The "remove" option must be true or an "update" document must be specified, but not both
60+
*/
61+
public function testConstructorUpdateAndRemoveOptionsAreMutuallyExclusive()
62+
{
63+
new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), ['remove' => true, 'update' => []]);
64+
}
65+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Operation\FindOneAndDelete;
6+
7+
class FindOneAndDeleteTest extends TestCase
8+
{
9+
/**
10+
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
11+
* @dataProvider provideInvalidDocumentValues
12+
*/
13+
public function testConstructorFilterArgumentTypeCheck($filter)
14+
{
15+
new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), $filter);
16+
}
17+
18+
/**
19+
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
20+
* @dataProvider provideInvalidConstructorOptions
21+
*/
22+
public function testConstructorOptionTypeChecks(array $options)
23+
{
24+
new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), [], $options);
25+
}
26+
27+
public function provideInvalidConstructorOptions()
28+
{
29+
$options = [];
30+
31+
foreach ($this->getInvalidDocumentValues() as $value) {
32+
$options[][] = ['projection' => $value];
33+
}
34+
35+
return $options;
36+
}
37+
}

0 commit comments

Comments
 (0)