Commit 9f36faf7 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-363: Remove support for server versions < 3.0

Since ext-mongodb 1.5.0 drops support for server 2.6, we can remove wire version checks and legacy code for servers before 3.0 (i.e. wire version 3).
parent aecfe92b
...@@ -6,10 +6,6 @@ description: | ...@@ -6,10 +6,6 @@ description: |
You can specify a query expression for collection fields (e.g. ``name``, You can specify a query expression for collection fields (e.g. ``name``,
``options``). ``options``).
For server versions < 3.0, the filter can only be used to match the ``name``
field with a string value. More complex filters will result in an exception at
execution time if used.
interface: phpmethod interface: phpmethod
operation: ~ operation: ~
optional: true optional: true
......
<?php
/*
* Copyright 2015-2017 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace MongoDB\Model;
use FilterIterator;
use Iterator;
use IteratorIterator;
use Traversable;
/**
* CollectionInfoIterator for legacy "system.namespaces" query results.
*
* This iterator may be used to wrap a Cursor returned for queries on the
* "system.namespaces" collection. It includes logic to filter out internal
* collections and modify the collection name to be consistent with results from
* the listCollections command.
*
* @internal
* @see \MongoDB\Database::listCollections()
* @see https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst
* @see http://docs.mongodb.org/manual/reference/command/listCollections/
* @see http://docs.mongodb.org/manual/reference/system-collections/
*/
class CollectionInfoLegacyIterator extends FilterIterator implements CollectionInfoIterator
{
/**
* Constructor.
*
* @param Traversable $iterator
*/
public function __construct(Traversable $iterator)
{
/* FilterIterator requires an Iterator, so wrap all other Traversables
* with an IteratorIterator as a convenience.
*/
if ( ! $iterator instanceof Iterator) {
$iterator = new IteratorIterator($iterator);
}
parent::__construct($iterator);
}
/**
* Filter out internal or invalid collections.
*
* @see http://php.net/filteriterator.accept
* @return boolean
*/
public function accept()
{
$info = parent::current();
if ( ! isset($info['name']) || ! is_string($info['name'])) {
return false;
}
// Reject names with "$" characters (e.g. indexes, oplog)
if (strpos($info['name'], '$') !== false) {
return false;
}
$firstDot = strpos($info['name'], '.');
/* Legacy collection names are a namespace and should be prefixed with
* the database name and a dot. Reject values that omit this prefix or
* are empty beyond it.
*/
if ($firstDot === false || $firstDot + 1 == strlen($info['name'])) {
return false;
}
return true;
}
/**
* Return the current element as a CollectionInfo instance.
*
* @see CollectionInfoIterator::current()
* @see http://php.net/iterator.current
* @return CollectionInfo
*/
public function current()
{
$info = parent::current();
// Trim the database prefix up to and including the first dot
$firstDot = strpos($info['name'], '.');
if ($firstDot !== false) {
$info['name'] = (string) substr($info['name'], $firstDot + 1);
}
return new CollectionInfo($info);
}
}
...@@ -38,7 +38,6 @@ class Explain implements Executable ...@@ -38,7 +38,6 @@ class Explain implements Executable
const VERBOSITY_EXEC_STATS = 'executionStats'; const VERBOSITY_EXEC_STATS = 'executionStats';
const VERBOSITY_QUERY = 'queryPlanner'; const VERBOSITY_QUERY = 'queryPlanner';
private static $wireVersionForExplain = 2;
private static $wireVersionForDistinct = 4; private static $wireVersionForDistinct = 4;
private static $wireVersionForFindAndModify = 4; private static $wireVersionForFindAndModify = 4;
...@@ -90,10 +89,6 @@ class Explain implements Executable ...@@ -90,10 +89,6 @@ class Explain implements Executable
public function execute(Server $server) public function execute(Server $server)
{ {
if (! \MongoDB\server_supports_feature($server, self::$wireVersionForExplain)) {
throw UnsupportedException::explainNotSupported();
}
if ($this->explainable instanceof Distinct && ! \MongoDB\server_supports_feature($server, self::$wireVersionForDistinct)) { if ($this->explainable instanceof Distinct && ! \MongoDB\server_supports_feature($server, self::$wireVersionForDistinct)) {
throw UnsupportedException::explainNotSupported(); throw UnsupportedException::explainNotSupported();
} }
......
...@@ -37,8 +37,6 @@ use MongoDB\Model\CollectionInfoLegacyIterator; ...@@ -37,8 +37,6 @@ use MongoDB\Model\CollectionInfoLegacyIterator;
*/ */
class ListCollections implements Executable class ListCollections implements Executable
{ {
private static $wireVersionForCommand = 3;
private $databaseName; private $databaseName;
private $options; private $options;
...@@ -49,10 +47,6 @@ class ListCollections implements Executable ...@@ -49,10 +47,6 @@ class ListCollections implements Executable
* *
* * filter (document): Query by which to filter collections. * * filter (document): Query by which to filter collections.
* *
* For server versions < 3.0, the filter can only be used to match the
* "name" field with a string value. More complex filters will result in
* an exception at execution time if used.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to * * maxTimeMS (integer): The maximum amount of time to allow the query to
* run. * run.
* *
...@@ -88,14 +82,11 @@ class ListCollections implements Executable ...@@ -88,14 +82,11 @@ class ListCollections implements Executable
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return CollectionInfoIterator * @return CollectionInfoIterator
* @throws InvalidArgumentException if filter.name is not a string for legacy execution
* @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/ */
public function execute(Server $server) public function execute(Server $server)
{ {
return \MongoDB\server_supports_feature($server, self::$wireVersionForCommand) return $this->executeCommand($server);
? $this->executeCommand($server)
: $this->executeLegacy($server);
} }
/** /**
...@@ -143,35 +134,4 @@ class ListCollections implements Executable ...@@ -143,35 +134,4 @@ class ListCollections implements Executable
return new CollectionInfoCommandIterator(new CachingIterator($cursor)); return new CollectionInfoCommandIterator(new CachingIterator($cursor));
} }
/**
* Returns information for all collections in this database by querying the
* "system.namespaces" collection (MongoDB <3.0).
*
* @param Server $server
* @return CollectionInfoLegacyIterator
* @throws InvalidArgumentException if filter.name is not a string
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/
private function executeLegacy(Server $server)
{
$filter = empty($this->options['filter']) ? [] : (array) $this->options['filter'];
if (array_key_exists('name', $filter)) {
if ( ! is_string($filter['name'])) {
throw InvalidArgumentException::invalidType('filter name for MongoDB <3.0', $filter['name'], 'string');
}
$filter['name'] = $this->databaseName . '.' . $filter['name'];
}
$options = isset($this->options['maxTimeMS'])
? ['modifiers' => ['$maxTimeMS' => $this->options['maxTimeMS']]]
: [];
$cursor = $server->executeQuery($this->databaseName . '.system.namespaces', new Query($filter, $options));
$cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
return new CollectionInfoLegacyIterator(new CachingIterator($cursor));
}
} }
...@@ -39,7 +39,6 @@ class ListIndexes implements Executable ...@@ -39,7 +39,6 @@ class ListIndexes implements Executable
{ {
private static $errorCodeDatabaseNotFound = 60; private static $errorCodeDatabaseNotFound = 60;
private static $errorCodeNamespaceNotFound = 26; private static $errorCodeNamespaceNotFound = 26;
private static $wireVersionForCommand = 3;
private $databaseName; private $databaseName;
private $collectionName; private $collectionName;
...@@ -87,9 +86,7 @@ class ListIndexes implements Executable ...@@ -87,9 +86,7 @@ class ListIndexes implements Executable
*/ */
public function execute(Server $server) public function execute(Server $server)
{ {
return \MongoDB\server_supports_feature($server, self::$wireVersionForCommand) return $this->executeCommand($server);
? $this->executeCommand($server)
: $this->executeLegacy($server);
} }
/** /**
...@@ -146,26 +143,4 @@ class ListIndexes implements Executable ...@@ -146,26 +143,4 @@ class ListIndexes implements Executable
return new IndexInfoIteratorIterator(new CachingIterator($cursor)); return new IndexInfoIteratorIterator(new CachingIterator($cursor));
} }
/**
* Returns information for all indexes for this collection by querying the
* "system.indexes" collection (MongoDB <3.0).
*
* @param Server $server
* @return IndexInfoIteratorIterator
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/
private function executeLegacy(Server $server)
{
$filter = ['ns' => $this->databaseName . '.' . $this->collectionName];
$options = isset($this->options['maxTimeMS'])
? ['modifiers' => ['$maxTimeMS' => $this->options['maxTimeMS']]]
: [];
$cursor = $server->executeQuery($this->databaseName . '.system.indexes', new Query($filter, $options));
$cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
return new IndexInfoIteratorIterator(new CachingIterator($cursor));
}
} }
...@@ -155,10 +155,6 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -155,10 +155,6 @@ class CollectionFunctionalTest extends FunctionalTestCase
public function testExplain() public function testExplain()
{ {
if (version_compare($this->getServerVersion(), '3.0.0', '<')) {
$this->markTestSkipped('Explain command is not supported');
}
$this->createFixtures(3); $this->createFixtures(3);
$operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []); $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []);
......
...@@ -25,14 +25,6 @@ use stdClass; ...@@ -25,14 +25,6 @@ use stdClass;
class ExplainFunctionalTest extends FunctionalTestCase class ExplainFunctionalTest extends FunctionalTestCase
{ {
public function setUp()
{
parent::setUp();
if (version_compare($this->getServerVersion(), '3.0.0', '<')) {
$this->markTestSkipped('Explain command is not supported');
}
}
/** /**
* @dataProvider provideVerbosityInformation * @dataProvider provideVerbosityInformation
*/ */
......
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