Skip to content

PHPLIB-133: Support typeMap option in FindOne #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/Operation/FindOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace MongoDB\Operation;

use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentTypeException;

/**
* Operation for finding a single document with the find command.
Expand All @@ -15,6 +16,7 @@
class FindOne implements Executable
{
private $find;
private $options;

/**
* Constructs a find command for finding a single document.
Expand Down Expand Up @@ -42,6 +44,8 @@ class FindOne implements Executable
* "$orderby" also exists in the modifiers document, this option will
* take precedence.
*
* * typeMap (array): Type map for BSON deserialization.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
Expand All @@ -50,12 +54,18 @@ class FindOne implements Executable
*/
public function __construct($databaseName, $collectionName, $filter, array $options = array())
{
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
throw new InvalidArgumentTypeException('"typeMap" option', $options['typeMap'], 'array');
}

$this->find = new Find(
$databaseName,
$collectionName,
$filter,
array('limit' => -1) + $options
);

$this->options = $options;
}

/**
Expand All @@ -68,6 +78,11 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
public function execute(Server $server)
{
$cursor = $this->find->execute($server);

if (isset($this->options['typeMap'])) {
$cursor->setTypeMap($this->options['typeMap']);
}

$document = current($cursor->toArray());

return ($document === false) ? null : $document;
Expand Down
15 changes: 5 additions & 10 deletions src/Operation/FindOneAndDelete.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,23 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
throw new InvalidArgumentTypeException('$filter', $filter, 'array or object');
}

if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
}

if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
}

if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
if (isset($options['projection'])) {
$options['fields'] = $options['projection'];
}

unset($options['projection']);

$this->findAndModify = new FindAndModify(
$databaseName,
$collectionName,
array(
'fields' => isset($options['projection']) ? $options['projection'] : null,
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
'query' => $filter,
'remove' => true,
'sort' => isset($options['sort']) ? $options['sort'] : null,
)
) + $options
);
}

Expand Down
21 changes: 6 additions & 15 deletions src/Operation/FindOneAndReplace.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ public function __construct($databaseName, $collectionName, $filter, $replacemen
'upsert' => false,
);

if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
}

if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
}
Expand All @@ -85,26 +81,21 @@ public function __construct($databaseName, $collectionName, $filter, $replacemen
throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
}

if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
if (isset($options['projection'])) {
$options['fields'] = $options['projection'];
}

if ( ! is_bool($options['upsert'])) {
throw new InvalidArgumentTypeException('"upsert" option', $options['upsert'], 'boolean');
}
$options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;

unset($options['projection'], $options['returnDocument']);

$this->findAndModify = new FindAndModify(
$databaseName,
$collectionName,
array(
'fields' => isset($options['projection']) ? $options['projection'] : null,
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
'new' => $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER,
'query' => $filter,
'sort' => isset($options['sort']) ? $options['sort'] : null,
'update' => $replacement,
'upsert' => $options['upsert'],
)
) + $options
);
}

Expand Down
21 changes: 6 additions & 15 deletions src/Operation/FindOneAndUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ public function __construct($databaseName, $collectionName, $filter, $update, ar
'upsert' => false,
);

if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
}

if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
throw new InvalidArgumentTypeException('"projection" option', $options['projection'], 'array or object');
}
Expand All @@ -85,26 +81,21 @@ public function __construct($databaseName, $collectionName, $filter, $update, ar
throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
}

if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
throw new InvalidArgumentTypeException('"sort" option', $options['sort'], 'array or object');
if (isset($options['projection'])) {
$options['fields'] = $options['projection'];
}

if ( ! is_bool($options['upsert'])) {
throw new InvalidArgumentTypeException('"upsert" option', $options['upsert'], 'boolean');
}
$options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;

unset($options['projection'], $options['returnDocument']);

$this->findAndModify = new FindAndModify(
$databaseName,
$collectionName,
array(
'fields' => isset($options['projection']) ? $options['projection'] : null,
'maxTimeMS' => isset($options['maxTimeMS']) ? $options['maxTimeMS'] : null,
'new' => $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER,
'query' => $filter,
'sort' => isset($options['sort']) ? $options['sort'] : null,
'update' => $update,
'upsert' => $options['upsert'],
)
) + $options
);
}

Expand Down
7 changes: 5 additions & 2 deletions tests/Collection/CrudSpec/AggregateFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use MongoDB\Collection;
use MongoDB\Driver\ReadPreference;
use MongoDB\Operation\DropCollection;

/**
* CRUD spec functional tests for aggregate().
Expand Down Expand Up @@ -48,7 +49,8 @@ public function testAggregateWithOut()
}

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

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

// Manually clean up our output collection
$this->dropCollectionIfItExists($outputCollection);
$operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName());
$operation->execute($this->getPrimaryServer());
}
}
23 changes: 5 additions & 18 deletions tests/Collection/FunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace MongoDB\Tests\Collection;

use MongoDB\Collection;
use MongoDB\Database;
use MongoDB\Operation\DropCollection;
use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;

/**
Expand All @@ -18,7 +18,8 @@ public function setUp()
parent::setUp();

$this->collection = new Collection($this->manager, $this->getNamespace());
$this->dropCollectionIfItExists($this->collection);
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
$operation->execute($this->getPrimaryServer());
}

public function tearDown()
Expand All @@ -27,21 +28,7 @@ public function tearDown()
return;
}

$this->dropCollectionIfItExists($this->collection);
}

/**
* Drop the collection if it exists.
*
* @param Collection $collection
*/
protected function dropCollectionIfItExists(Collection $collection)
{
$database = new Database($this->manager, $collection->getDatabaseName());
$collections = $database->listCollections(array('filter' => array('name' => $collection->getCollectionName())));

if (iterator_count($collections) > 0) {
$this->assertCommandSucceeded($collection->drop());
}
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
$operation->execute($this->getPrimaryServer());
}
}
5 changes: 5 additions & 0 deletions tests/FunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ protected function assertSameDocuments(array $expectedDocuments, $actualDocument
);
}

protected function getPrimaryServer()
{
return $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
}

protected function getServerVersion(ReadPreference $readPreference = null)
{
$cursor = $this->manager->executeCommand(
Expand Down
18 changes: 18 additions & 0 deletions tests/Operation/AggregateFunctionalTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace MongoDB\Tests\Operation;

use MongoDB\Operation\Aggregate;

class AggregateFunctionalTest extends FunctionalTestCase
{
/**
* @expectedException MongoDB\Driver\Exception\RuntimeException
*/
public function testUnrecognizedPipelineState()
{
$server = $this->getPrimaryServer();
$operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), [['$foo' => 1]]);
$operation->execute($server);
}
}
3 changes: 3 additions & 0 deletions tests/Operation/DropDatabaseFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public function testDropNonexistentDatabase()
{
$server = $this->getPrimaryServer();

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

$this->assertDatabaseDoesNotExist($server, $this->getDatabaseName());

$operation = new DropDatabase($this->getDatabaseName());
Expand Down
65 changes: 65 additions & 0 deletions tests/Operation/FindAndModifyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace MongoDB\Tests\Operation;

use MongoDB\Operation\FindAndModify;

class FindAndModifyTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidConstructorOptions
*/
public function testConstructorOptionTypeChecks(array $options)
{
new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), $options);
}

public function provideInvalidConstructorOptions()
{
$options = [];

foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['fields' => $value];
}

foreach ($this->getInvalidIntegerValues() as $value) {
$options[][] = ['maxTimeMS' => $value];
}

foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['new' => $value];
}

foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['query' => $value];
}

foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['remove' => $value];
}

foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['sort' => $value];
}

foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['update' => $value];
}

foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['upsert' => $value];
}

return $options;
}

/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage The "remove" option must be true or an "update" document must be specified, but not both
*/
public function testConstructorUpdateAndRemoveOptionsAreMutuallyExclusive()
{
new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), ['remove' => true, 'update' => []]);
}
}
37 changes: 37 additions & 0 deletions tests/Operation/FindOneAndDeleteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace MongoDB\Tests\Operation;

use MongoDB\Operation\FindOneAndDelete;

class FindOneAndDeleteTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentValues
*/
public function testConstructorFilterArgumentTypeCheck($filter)
{
new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), $filter);
}

/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidConstructorOptions
*/
public function testConstructorOptionTypeChecks(array $options)
{
new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), [], $options);
}

public function provideInvalidConstructorOptions()
{
$options = [];

foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['projection' => $value];
}

return $options;
}
}
Loading