Skip to content

Commit

Permalink
PHPLIB-1511: Remove deprecated query options
Browse files Browse the repository at this point in the history
  • Loading branch information
alcaeus committed Sep 26, 2024
1 parent e746f09 commit 7f67f26
Show file tree
Hide file tree
Showing 8 changed files with 10 additions and 156 deletions.
2 changes: 2 additions & 0 deletions UPGRADE-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ UPGRADE FROM 1.x to 2.0
* The `MongoDB\Operation\Watch::FULL_DOCUMENT_DEFAULT` constant has been
removed.
* The `MongoDB\Model\IndexInfo::isGeoHaystack` method has been removed.
* The `maxScan`, `modifiers`, `oplogReplay`, and `snapshot` options for `find`
and `findOne` operations have been removed.

GridFS
------
Expand Down
4 changes: 0 additions & 4 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -708,11 +708,7 @@
<code><![CDATA[$this->options['codec']]]></code>
<code><![CDATA[$this->options['typeMap']]]></code>
</MixedArgument>
<MixedArrayAccess>
<code><![CDATA[$options['modifiers'][$modifier[1]]]]></code>
</MixedArrayAccess>
<MixedAssignment>
<code><![CDATA[$options[$modifier[0]]]]></code>
<code><![CDATA[$options[$option]]]></code>
<code><![CDATA[$options['readPreference']]]></code>
<code><![CDATA[$options['session']]]></code>
Expand Down
71 changes: 3 additions & 68 deletions src/Operation/Find.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
use function is_integer;
use function is_object;
use function is_string;
use function MongoDB\document_to_array;
use function MongoDB\is_document;

/**
Expand Down Expand Up @@ -88,28 +87,15 @@ final class Find implements Executable, Explainable
* * maxAwaitTimeMS (integer): The maxium amount of time for the server to wait
* on new documents to satisfy a query, if cursorType is TAILABLE_AWAIT.
*
* * maxScan (integer): Maximum number of documents or index keys to scan
* when executing the query.
*
* This option has been deprecated since version 1.4.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run. If "$maxTimeMS" also exists in the modifiers document, this
* option will take precedence.
* run.
*
* * min (document): The inclusive upper bound for a specific index.
*
* * modifiers (document): Meta operators that modify the output or
* behavior of a query. Use of these operators is deprecated in favor of
* named options.
*
* * noCursorTimeout (boolean): The server normally times out idle cursors
* after an inactivity period (10 minutes) to prevent excess memory use.
* Set this option to prevent that.
*
* * oplogReplay (boolean): Internal replication use only. The driver
* should not set this. This option is deprecated as of MongoDB 4.4.
*
* * projection (document): Limits the fields to return for the matching
* document.
*
Expand All @@ -128,14 +114,7 @@ final class Find implements Executable, Explainable
*
* * skip (integer): The number of documents to skip before returning.
*
* * snapshot (boolean): Prevents the cursor from returning a document more
* than once because of an intervening write operation.
*
* This options has been deprecated since version 1.4.
*
* * sort (document): The order in which to return matching documents. If
* "$orderby" also exists in the modifiers document, this option will
* take precedence.
* * sort (document): The order in which to return matching documents.
*
* * let (document): Map of parameter names and values. Values must be
* constant or closed expressions that do not reference document fields.
Expand Down Expand Up @@ -207,10 +186,6 @@ public function __construct(private string $databaseName, private string $collec
throw InvalidArgumentException::invalidType('"maxAwaitTimeMS" option', $this->options['maxAwaitTimeMS'], 'integer');
}

if (isset($this->options['maxScan']) && ! is_integer($this->options['maxScan'])) {
throw InvalidArgumentException::invalidType('"maxScan" option', $this->options['maxScan'], 'integer');
}

if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) {
throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer');
}
Expand All @@ -219,18 +194,10 @@ public function __construct(private string $databaseName, private string $collec
throw InvalidArgumentException::expectedDocumentType('"min" option', $this->options['min']);
}

if (isset($this->options['modifiers']) && ! is_document($this->options['modifiers'])) {
throw InvalidArgumentException::expectedDocumentType('"modifiers" option', $this->options['modifiers']);
}

if (isset($this->options['noCursorTimeout']) && ! is_bool($this->options['noCursorTimeout'])) {
throw InvalidArgumentException::invalidType('"noCursorTimeout" option', $this->options['noCursorTimeout'], 'boolean');
}

if (isset($this->options['oplogReplay']) && ! is_bool($this->options['oplogReplay'])) {
throw InvalidArgumentException::invalidType('"oplogReplay" option', $this->options['oplogReplay'], 'boolean');
}

if (isset($this->options['projection']) && ! is_document($this->options['projection'])) {
throw InvalidArgumentException::expectedDocumentType('"projection" option', $this->options['projection']);
}
Expand Down Expand Up @@ -259,10 +226,6 @@ public function __construct(private string $databaseName, private string $collec
throw InvalidArgumentException::invalidType('"skip" option', $this->options['skip'], 'integer');
}

if (isset($this->options['snapshot']) && ! is_bool($this->options['snapshot'])) {
throw InvalidArgumentException::invalidType('"snapshot" option', $this->options['snapshot'], 'boolean');
}

if (isset($this->options['sort']) && ! is_document($this->options['sort'])) {
throw InvalidArgumentException::expectedDocumentType('"sort" option', $this->options['sort']);
}
Expand Down Expand Up @@ -329,28 +292,6 @@ public function getCommandDocument(): array
// maxAwaitTimeMS is a Query level option so should not be considered here
unset($options['maxAwaitTimeMS']);

$modifierFallback = [
['allowPartialResults', 'partial'],
['comment', '$comment'],
['hint', '$hint'],
['maxScan', '$maxScan'],
['max', '$max'],
['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;
}

Expand Down Expand Up @@ -395,7 +336,7 @@ private function createQueryOptions(): array
}
}

foreach (['allowDiskUse', 'allowPartialResults', 'batchSize', 'comment', 'hint', 'limit', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'noCursorTimeout', 'oplogReplay', 'projection', 'readConcern', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'] as $option) {
foreach (['allowDiskUse', 'allowPartialResults', 'batchSize', 'comment', 'hint', 'limit', 'maxAwaitTimeMS', 'maxTimeMS', 'noCursorTimeout', 'projection', 'readConcern', 'returnKey', 'showRecordId', 'skip', 'sort'] as $option) {
if (isset($this->options[$option])) {
$options[$option] = $this->options[$option];
}
Expand All @@ -407,12 +348,6 @@ private function createQueryOptions(): array
}
}

if (! empty($this->options['modifiers'])) {
/** @psalm-var array|object */
$modifiers = $this->options['modifiers'];
$options['modifiers'] = is_object($modifiers) ? document_to_array($modifiers) : $modifiers;
}

return $options;
}
}
15 changes: 2 additions & 13 deletions src/Operation/FindOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,11 @@ final class FindOne implements Executable, Explainable
*
* * max (document): The exclusive upper bound for a specific index.
*
* * maxScan (integer): Maximum number of documents or index keys to scan
* when executing the query.
*
* This option has been deprecated since version 1.4.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run. If "$maxTimeMS" also exists in the modifiers document, this
* option will take precedence.
* run.
*
* * min (document): The inclusive upper bound for a specific index.
*
* * modifiers (document): Meta-operators modifying the output or behavior
* of a query.
*
* * projection (document): Limits the fields to return for the matching
* document.
*
Expand All @@ -87,9 +78,7 @@ final class FindOne implements Executable, Explainable
*
* * skip (integer): The number of documents to skip before returning.
*
* * sort (document): The order in which to return matching documents. If
* "$orderby" also exists in the modifiers document, this option will
* take precedence.
* * sort (document): The order in which to return matching documents.
*
* * let (document): Map of parameter names and values. Values must be
* constant or closed expressions that do not reference document fields.
Expand Down
24 changes: 0 additions & 24 deletions tests/Operation/ExplainFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,30 +157,6 @@ function (array $event): void {
);
}

public function testFindModifiers(): void
{
$this->createFixtures(3);

$operation = new Find(
$this->getDatabaseName(),
$this->getCollectionName(),
[],
['modifiers' => ['$orderby' => ['_id' => 1]]],
);

(new CommandObserver())->observe(
function () use ($operation): void {
$explainOperation = new Explain($this->getDatabaseName(), $operation, ['typeMap' => ['root' => 'array', 'document' => 'array']]);
$explainOperation->execute($this->getPrimaryServer());
},
function (array $event): void {
$command = $event['started']->getCommand();
$this->assertObjectHasProperty('sort', $command->explain);
$this->assertObjectNotHasProperty('modifiers', $command->explain);
},
);
}

/** @dataProvider provideVerbosityInformation */
public function testFindOne($verbosity, $executionStatsExpected, $allPlansExecutionExpected): void
{
Expand Down
36 changes: 0 additions & 36 deletions tests/Operation/FindFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace MongoDB\Tests\Operation;

use MongoDB\BSON\Document;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\ReadPreference;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\CreateIndexes;
use MongoDB\Operation\Find;
use MongoDB\Tests\CommandObserver;
Expand Down Expand Up @@ -36,40 +34,6 @@ function (array $event) use ($expectedQuery): void {
);
}

/** @dataProvider provideModifierDocuments */
public function testModifierDocuments($modifiers, stdClass $expectedSort): void
{
(new CommandObserver())->observe(
function () use ($modifiers): void {
$operation = new Find(
$this->getDatabaseName(),
$this->getCollectionName(),
[],
['modifiers' => $modifiers],
);

$this->assertDeprecated(
fn () => $operation->execute($this->getPrimaryServer()),
);
},
function (array $event) use ($expectedSort): void {
$this->assertEquals($expectedSort, $event['started']->getCommand()->sort ?? null);
},
);
}

public static function provideModifierDocuments(): array
{
$expectedSort = (object) ['x' => 1];

return [
'array' => [['$orderby' => ['x' => 1]], $expectedSort],
'object' => [(object) ['$orderby' => ['x' => 1]], $expectedSort],
'Serializable' => [new BSONDocument(['$orderby' => ['x' => 1]]), $expectedSort],
'Document' => [Document::fromPHP(['$orderby' => ['x' => 1]]), $expectedSort],
];
}

public function testDefaultReadConcernIsOmitted(): void
{
(new CommandObserver())->observe(
Expand Down
8 changes: 0 additions & 8 deletions tests/Operation/FindTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,15 @@ public static function provideInvalidConstructorOptions()
'limit' => self::getInvalidIntegerValues(),
'max' => self::getInvalidDocumentValues(),
'maxAwaitTimeMS' => self::getInvalidIntegerValues(),
'maxScan' => self::getInvalidIntegerValues(),
'maxTimeMS' => self::getInvalidIntegerValues(),
'min' => self::getInvalidDocumentValues(),
'modifiers' => self::getInvalidDocumentValues(),
'oplogReplay' => self::getInvalidBooleanValues(),
'projection' => self::getInvalidDocumentValues(),
'readConcern' => self::getInvalidReadConcernValues(),
'readPreference' => self::getInvalidReadPreferenceValues(),
'returnKey' => self::getInvalidBooleanValues(),
'session' => self::getInvalidSessionValues(),
'showRecordId' => self::getInvalidBooleanValues(),
'skip' => self::getInvalidIntegerValues(),
'snapshot' => self::getInvalidBooleanValues(),
'sort' => self::getInvalidDocumentValues(),
'typeMap' => self::getInvalidArrayValues(),
]);
Expand All @@ -69,7 +65,6 @@ public static function provideInvalidConstructorCursorTypeOptions()

public function testExplainableCommandDocument(): void
{
// all options except deprecated "snapshot" and "maxScan"
$options = [
'allowDiskUse' => true,
'allowPartialResults' => true,
Expand All @@ -82,7 +77,6 @@ public function testExplainableCommandDocument(): void
'maxTimeMS' => 100,
'min' => ['x' => 10],
'noCursorTimeout' => true,
'oplogReplay' => true,
'projection' => ['_id' => 0],
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
'returnKey' => true,
Expand All @@ -93,7 +87,6 @@ public function testExplainableCommandDocument(): void
// Intentionally omitted options
'cursorType' => Find::NON_TAILABLE,
'maxAwaitTimeMS' => 500,
'modifiers' => ['foo' => 'bar'],
'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED),
'typeMap' => ['root' => 'array'],
];
Expand All @@ -110,7 +103,6 @@ public function testExplainableCommandDocument(): void
'limit' => 15,
'maxTimeMS' => 100,
'noCursorTimeout' => true,
'oplogReplay' => true,
'projection' => ['_id' => 0],
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
'returnKey' => true,
Expand Down
6 changes: 3 additions & 3 deletions tests/UnifiedSpecTests/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ final class Util
'aggregate' => ['pipeline', 'session', 'allowDiskUse', 'batchSize', 'bypassDocumentValidation', 'collation', 'comment', 'explain', 'hint', 'let', 'maxAwaitTimeMS', 'maxTimeMS'],
'bulkWrite' => ['let', 'requests', 'session', 'ordered', 'bypassDocumentValidation', 'comment'],
'createChangeStream' => ['pipeline', 'session', 'fullDocument', 'fullDocumentBeforeChange', 'resumeAfter', 'startAfter', 'startAtOperationTime', 'batchSize', 'collation', 'maxAwaitTimeMS', 'comment', 'showExpandedEvents'],
'createFindCursor' => ['filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'limit', 'max', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'min', 'modifiers', 'noCursorTimeout', 'oplogReplay', 'projection', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'],
'createFindCursor' => ['filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'limit', 'max', 'maxAwaitTimeMS', 'maxTimeMS', 'min', 'noCursorTimeout', 'projection', 'returnKey', 'showRecordId', 'skip', 'sort'],
'createIndex' => ['keys', 'comment', 'commitQuorum', 'maxTimeMS', 'name', 'session', 'unique'],
'createSearchIndex' => ['model'],
'createSearchIndexes' => ['models'],
Expand All @@ -101,8 +101,8 @@ final class Util
'distinct' => ['fieldName', 'filter', 'session', 'collation', 'maxTimeMS', 'comment'],
'drop' => ['session', 'comment'],
'dropSearchIndex' => ['name'],
'find' => ['let', 'filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'limit', 'max', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'min', 'modifiers', 'noCursorTimeout', 'oplogReplay', 'projection', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'],
'findOne' => ['let', 'filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'max', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'min', 'modifiers', 'noCursorTimeout', 'oplogReplay', 'projection', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'],
'find' => ['let', 'filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'limit', 'max', 'maxAwaitTimeMS', 'maxTimeMS', 'min', 'noCursorTimeout', 'projection', 'returnKey', 'showRecordId', 'skip', 'sort'],
'findOne' => ['let', 'filter', 'session', 'allowDiskUse', 'allowPartialResults', 'batchSize', 'collation', 'comment', 'cursorType', 'hint', 'max', 'maxAwaitTimeMS', 'maxTimeMS', 'min', 'noCursorTimeout', 'projection', 'returnKey', 'showRecordId', 'skip', 'sort'],
'findOneAndReplace' => ['let', 'returnDocument', 'filter', 'replacement', 'session', 'projection', 'returnDocument', 'upsert', 'arrayFilters', 'bypassDocumentValidation', 'collation', 'hint', 'maxTimeMS', 'new', 'remove', 'sort', 'comment'],
'rename' => ['to', 'comment', 'dropTarget'],
'replaceOne' => ['let', 'filter', 'replacement', 'session', 'upsert', 'arrayFilters', 'bypassDocumentValidation', 'collation', 'hint', 'comment'],
Expand Down

0 comments on commit 7f67f26

Please sign in to comment.