Commit cbb7fc7c authored by Katherine Walker's avatar Katherine Walker

Handle modifiers and clean up function names

parent ad4f3e6c
...@@ -117,8 +117,6 @@ class Delete implements Executable, Explainable ...@@ -117,8 +117,6 @@ class Delete implements Executable, Explainable
throw UnsupportedException::collationNotSupported(); throw UnsupportedException::collationNotSupported();
} }
$deleteOptions = $this->createDeleteOptions();
$bulk = new Bulk(); $bulk = new Bulk();
$bulk->delete($this->filter, $this->createDeleteOptions()); $bulk->delete($this->filter, $this->createDeleteOptions());
...@@ -136,7 +134,7 @@ class Delete implements Executable, Explainable ...@@ -136,7 +134,7 @@ class Delete implements Executable, Explainable
* Create options for the delete command. * Create options for the delete command.
* *
* Note that these options are different from the bulk write options, which * Note that these options are different from the bulk write options, which
* are created in createOptions(). * are created in createExecuteOptions().
* *
* @return array * @return array
*/ */
......
...@@ -284,7 +284,7 @@ class Find implements Executable, Explainable ...@@ -284,7 +284,7 @@ class Find implements Executable, Explainable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createFindOptions()), $this->createOptions()); $cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createQueryOptions()), $this->createExecuteOptions());
if (isset($this->options['typeMap'])) { if (isset($this->options['typeMap'])) {
$cursor->setTypeMap($this->options['typeMap']); $cursor->setTypeMap($this->options['typeMap']);
...@@ -303,9 +303,9 @@ class Find implements Executable, Explainable ...@@ -303,9 +303,9 @@ class Find implements Executable, Explainable
*/ */
private function createCommandDocument() private function createCommandDocument()
{ {
$cmd = ['find' => $this->collectionName, 'filter' => new BSONDocument($this->filter)]; $cmd = ['find' => $this->collectionName, 'filter' => (object) $this->filter];
$options = $this->createFindOptions(); $options = $this->createQueryOptions();
if (empty($options)) { if (empty($options)) {
return $cmd; return $cmd;
...@@ -314,28 +314,60 @@ class Find implements Executable, Explainable ...@@ -314,28 +314,60 @@ class Find implements Executable, Explainable
// maxAwaitTimeMS is a Query level option so should not be considered here // maxAwaitTimeMS is a Query level option so should not be considered here
unset($options['maxAwaitTimeMS']); unset($options['maxAwaitTimeMS']);
if (isset($options['cursorType'])) { $modifierFallback = [
if ($options['cursorType'] === self::TAILABLE) { ['allowPartialResults' , 'partial'],
$cmd['tailable'] = true; ['comment' , '$comment'],
} ['hint' , '$hint'],
if ($options['cursorType'] === self::TAILABLE_AWAIT) { ['maxScan' , '$maxScan'],
$cmd['tailable'] = true; ['max' , '$max'],
$cmd['awaitData'] = true; ['maxTimeMS' , '$maxTimeMS'],
['min' , '$min'],
['returnKey' , '$returnKey'],
['showRecordId' , '$showDiskLoc'],
['sort' , '$orderby'],
['snapshot' , '$snapshot'],
];
foreach ($modifierFallback as $modifier) {
if ( ! isset($options[$modifier[0]]) && isset($options['modifiers'][$modifier[1]])) {
$options[$modifier[0]] = $options['modifiers'][$modifier[1]];
} }
} }
unset($options['modifiers']);
return $cmd + $options; return $cmd + $options;
} }
/**
* Create options for executing the command.
*
* @see http://php.net/manual/en/mongodb-driver-server.executequery.php
* @return array
*/
private function createExecuteOptions()
{
$options = [];
if (isset($this->options['readPreference'])) {
$options['readPreference'] = $this->options['readPreference'];
}
if (isset($this->options['session'])) {
$options['session'] = $this->options['session'];
}
return $options;
}
/** /**
* Create options for the find query. * Create options for the find query.
* *
* Note that these are separate from the options for executing the command, * Note that these are separate from the options for executing the command,
* which are created in createOptions(). * which are created in createExecuteOptions().
* *
* @return array * @return array
*/ */
private function createFindOptions() private function createQueryOptions()
{ {
$options = []; $options = [];
...@@ -369,25 +401,4 @@ class Find implements Executable, Explainable ...@@ -369,25 +401,4 @@ class Find implements Executable, Explainable
return $options; return $options;
} }
/**
* Create options for executing the command.
*
* @see http://php.net/manual/en/mongodb-driver-server.executequery.php
* @return array
*/
private function createOptions()
{
$options = [];
if (isset($this->options['readPreference'])) {
$options['readPreference'] = $this->options['readPreference'];
}
if (isset($this->options['session'])) {
$options['session'] = $this->options['session'];
}
return $options;
}
} }
...@@ -183,7 +183,7 @@ class Update implements Executable, Explainable ...@@ -183,7 +183,7 @@ class Update implements Executable, Explainable
public function getCommandDocument() public function getCommandDocument()
{ {
return ['update' => $this->collectionName, 'updates' => [['q' => $this->filter] + ['u' => $this->update] + $this->createUpdateOptions()]]; return ['update' => $this->collectionName, 'updates' => [['q' => $this->filter, 'u' => $this->update] + $this->createUpdateOptions()]];
} }
/** /**
...@@ -211,7 +211,7 @@ class Update implements Executable, Explainable ...@@ -211,7 +211,7 @@ class Update implements Executable, Explainable
* Create options for the update command. * Create options for the update command.
* *
* Note that these options are different from the bulk write options, which * Note that these options are different from the bulk write options, which
* are created in createOptions(). * are created in createExecuteOptions().
* *
* @return array * @return array
*/ */
......
...@@ -12,8 +12,9 @@ use MongoDB\Operation\Explain; ...@@ -12,8 +12,9 @@ use MongoDB\Operation\Explain;
use MongoDB\Operation\Find; use MongoDB\Operation\Find;
use MongoDB\Operation\FindAndModify; use MongoDB\Operation\FindAndModify;
use MongoDB\Operation\FindOne; use MongoDB\Operation\FindOne;
use MongoDB\Operation\InsertMany;
use MongoDB\Operation\Update; use MongoDB\Operation\Update;
use MongoDB\Tests\CommandObserver;
use stdClass;
class ExplainFunctionalTest extends FunctionalTestCase class ExplainFunctionalTest extends FunctionalTestCase
{ {
...@@ -30,13 +31,7 @@ class ExplainFunctionalTest extends FunctionalTestCase ...@@ -30,13 +31,7 @@ class ExplainFunctionalTest extends FunctionalTestCase
*/ */
public function testCount($verbosity, $executionStatsExpected, $allPlansExecutionExpected) public function testCount($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
{ {
$insertMany = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [ $this->createFixtures(3);
['x' => 0],
['x' => 1],
['x' => 2],
['y' => 3]
]);
$insertMany->execute($this->getPrimaryServer());
$operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []); $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []);
...@@ -114,10 +109,7 @@ class ExplainFunctionalTest extends FunctionalTestCase ...@@ -114,10 +109,7 @@ class ExplainFunctionalTest extends FunctionalTestCase
$this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected); $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
} }
/** public function testFindMaxAwait()
* @dataProvider provideVerbosityInformation
*/
public function testFindMaxAwait($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
{ {
if (version_compare($this->getServerVersion(), '3.2.0', '<')) { if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
$this->markTestSkipped('maxAwaitTimeMS option is not supported'); $this->markTestSkipped('maxAwaitTimeMS option is not supported');
...@@ -142,20 +134,47 @@ class ExplainFunctionalTest extends FunctionalTestCase ...@@ -142,20 +134,47 @@ class ExplainFunctionalTest extends FunctionalTestCase
$operation = new CreateCollection($databaseName, $cappedCollectionName, $cappedCollectionOptions); $operation = new CreateCollection($databaseName, $cappedCollectionName, $cappedCollectionOptions);
$operation->execute($this->getPrimaryServer()); $operation->execute($this->getPrimaryServer());
// Insert documents into the capped collection. $this->createFixtures(2);
$bulkWrite = new BulkWrite(['ordered' => true]);
$bulkWrite->insert(['_id' => 1]);
$bulkWrite->insert(['_id' => 2]);
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
$operation = new Find($databaseName, $cappedCollectionName, [], ['cursorType' => Find::TAILABLE_AWAIT, 'maxAwaitTimeMS' => $maxAwaitTimeMS]); $operation = new Find($databaseName, $cappedCollectionName, [], ['cursorType' => Find::TAILABLE_AWAIT, 'maxAwaitTimeMS' => $maxAwaitTimeMS]);
$explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]); (new CommandObserver)->observe(
$result = $explainOperation->execute($this->getPrimaryServer()); function() use ($operation) {
$explainOperation = new Explain($this->getDatabaseName(), $operation, ['typeMap' => ['root' => 'array', 'document' => 'array']]);
$explainOperation->execute($this->getPrimaryServer());
},
function(stdClass $command) {
$this->assertObjectNotHasAttribute('maxAwaitTimeMS', $command->explain);
$this->assertObjectHasAttribute('tailable', $command->explain);
$this->assertObjectHasAttribute('awaitData', $command->explain);
}
);
}
$this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected); public function testFindModifiers()
{
$this->createFixtures(3);
$operation = new Find(
$this->getDatabaseName(),
$this->getCollectionName(),
[],
['readConcern' => $this->createDefaultReadConcern(), 'modifiers' => ['$max' => ['_id' => 2.2]]]
);
(new CommandObserver)->observe(
function() use ($operation) {
$explainOperation = new Explain($this->getDatabaseName(), $operation, ['typeMap' => ['root' => 'array', 'document' => 'array']]);
$explainOperation->execute($this->getPrimaryServer());
},
function(stdClass $command) {
$this->assertObjectHasAttribute('max', $command->explain);
$this->assertObjectNotHasAttribute('modifiers', $command->explain);
}
);
} }
/** /**
* @dataProvider provideVerbosityInformation * @dataProvider provideVerbosityInformation
*/ */
...@@ -194,7 +213,7 @@ class ExplainFunctionalTest extends FunctionalTestCase ...@@ -194,7 +213,7 @@ class ExplainFunctionalTest extends FunctionalTestCase
return [ return [
[Explain::VERBOSITY_ALL_PLANS, true, true], [Explain::VERBOSITY_ALL_PLANS, true, true],
[Explain::VERBOSITY_EXEC_STATS, true, false], [Explain::VERBOSITY_EXEC_STATS, true, false],
[Explain::VERBOSITY_QUERY, false, false] [Explain::VERBOSITY_QUERY, false, false],
]; ];
} }
......
...@@ -9,6 +9,7 @@ use MongoDB\Operation\Explain; ...@@ -9,6 +9,7 @@ use MongoDB\Operation\Explain;
class ExplainTest extends TestCase class ExplainTest extends TestCase
{ {
/** /**
* @requires PHPUnit 5.4.0
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidConstructorOptions * @dataProvider provideInvalidConstructorOptions
*/ */
......
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