Commit 5b7bb9a4 authored by Jeremy Mikola's avatar Jeremy Mikola

Extract Collection::createIndexes() to an operation class

Additionally, this changes createIndexes() to no longer allow an empty array as input. The index management spec doesn't state that empty input must be accepted, so I'm not sure why we had that behavior.
parent 9746ccd2
......@@ -16,6 +16,7 @@ use MongoDB\Model\IndexInfoIterator;
use MongoDB\Model\IndexInfoIteratorIterator;
use MongoDB\Model\IndexInput;
use MongoDB\Operation\Aggregate;
use MongoDB\Operation\CreateIndexes;
use MongoDB\Operation\Distinct;
use Traversable;
......@@ -262,8 +263,6 @@ class Collection
/**
* Create a single index for the collection.
*
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
* @see Collection::createIndexes()
* @param array|object $key Document containing fields mapped to values,
* which denote order or an index type
......@@ -294,34 +293,16 @@ class Collection
*
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
* @param array $indexes List of index specifications
* @param array[] $indexes List of index specifications
* @return string[] The names of the created indexes
* @throws InvalidArgumentException if an index specification is invalid
*/
public function createIndexes(array $indexes)
{
if (empty($indexes)) {
return array();
}
foreach ($indexes as $i => $index) {
if ( ! is_array($index)) {
throw new UnexpectedTypeException($index, 'array');
}
if ( ! isset($index['ns'])) {
$index['ns'] = $this->ns;
}
$indexes[$i] = new IndexInput($index);
}
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
$server = $this->manager->selectServer($readPreference);
$operation = new CreateIndexes($this->dbname, $this->collname, $indexes);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return (FeatureDetection::isSupported($server, FeatureDetection::API_CREATEINDEXES_CMD))
? $this->createIndexesCommand($server, $indexes)
: $this->createIndexesLegacy($server, $indexes);
return $operation->execute($server);
}
/**
......@@ -1184,46 +1165,6 @@ class Collection
return $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc);
}
/**
* Create one or more indexes for the collection using the createIndexes
* command.
*
* @param Server $server
* @param IndexInput[] $indexes
* @return string[] The names of the created indexes
*/
private function createIndexesCommand(Server $server, array $indexes)
{
$command = new Command(array(
'createIndexes' => $this->collname,
'indexes' => $indexes,
));
$server->executeCommand($this->dbname, $command);
return array_map(function(IndexInput $index) { return (string) $index; }, $indexes);
}
/**
* Create one or more indexes for the collection by inserting into the
* "system.indexes" collection (MongoDB <2.6).
*
* @param Server $server
* @param IndexInput[] $indexes
* @return string[] The names of the created indexes
*/
private function createIndexesLegacy(Server $server, array $indexes)
{
$bulk = new BulkWrite(true);
foreach ($indexes as $index) {
$bulk->insert($index);
}
$server->executeBulkWrite($this->dbname . '.system.indexes', $bulk);
return array_map(function(IndexInput $index) { return (string) $index; }, $indexes);
}
/**
* Returns information for all indexes for this collection using the
* listIndexes command.
......
<?php
namespace MongoDB\Operation;
use MongoDB\Driver\Command;
use MongoDB\Driver\Server;
use MongoDB\Driver\BulkWrite;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedTypeException;
use MongoDB\Model\IndexInput;
/**
* Operation for the createIndexes command.
*
* @api
* @see MongoDB\Collection::createIndex()
* @see MongoDB\Collection::createIndexes()
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
*/
class CreateIndexes implements Executable
{
private static $wireVersionForCommand = 2;
private $databaseName;
private $collectionName;
private $indexes = array();
/**
* Constructs a createIndexes command.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array[] $indexes List of index specifications
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, array $indexes)
{
if (empty($indexes)) {
throw new InvalidArgumentException('$indexes is empty');
}
foreach ($indexes as $index) {
if ( ! is_array($index)) {
throw new UnexpectedTypeException($index, 'array');
}
if ( ! isset($index['ns'])) {
$index['ns'] = $databaseName . '.' . $collectionName;
}
$this->indexes[] = new IndexInput($index);
}
$this->databaseName = (string) $databaseName;
$this->collectionName = (string) $collectionName;
}
/**
* Execute the operation.
*
* For servers < 2.6, this will actually perform an insert operation on the
* database's "system.indexes" collection.
*
* @see Executable::execute()
* @param Server $server
* @return string[] The names of the created indexes
*/
public function execute(Server $server)
{
if (\MongoDB\server_supports_feature($server, self::$wireVersionForCommand)) {
$this->executeCommand($server);
} else {
$this->executeLegacy($server);
}
return array_map(function(IndexInput $index) { return (string) $index; }, $this->indexes);
}
/**
* Create one or more indexes for the collection using the createIndexes
* command.
*
* @param Server $server
*/
private function executeCommand(Server $server)
{
$command = new Command(array(
'createIndexes' => $this->collectionName,
'indexes' => $this->indexes,
));
$cursor = $server->executeCommand($this->databaseName, $command);
$result = current($cursor->toArray());
if (empty($result['ok'])) {
throw new RuntimeException(isset($result['errmsg']) ? $result['errmsg'] : 'Unknown error');
}
}
/**
* Create one or more indexes for the collection by inserting into the
* "system.indexes" collection (MongoDB <2.6).
*
* @param Server $server
* @param IndexInput[] $indexes
*/
private function executeLegacy(Server $server)
{
$bulk = new BulkWrite(true);
foreach ($this->indexes as $index) {
$bulk->insert($index);
}
$server->executeBulkWrite($this->databaseName . '.system.indexes', $bulk);
}
}
......@@ -85,7 +85,10 @@ class IndexManagementFunctionalTest extends FunctionalTestCase
});
}
public function testCreateIndexesWithEmptyInputIsNop()
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testCreateIndexesRequiresAtLeastOneIndex()
{
$this->assertSame(array(), $this->collection->createIndexes(array()));
}
......
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