Commit 15af4606 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-109: Extract InsertOne and InsertMany operation classes

parent 70fc9535
...@@ -24,6 +24,8 @@ use MongoDB\Operation\FindOne; ...@@ -24,6 +24,8 @@ use MongoDB\Operation\FindOne;
use MongoDB\Operation\FindOneAndDelete; use MongoDB\Operation\FindOneAndDelete;
use MongoDB\Operation\FindOneAndReplace; use MongoDB\Operation\FindOneAndReplace;
use MongoDB\Operation\FindOneAndUpdate; use MongoDB\Operation\FindOneAndUpdate;
use MongoDB\Operation\InsertMany;
use MongoDB\Operation\InsertOne;
use MongoDB\Operation\ListIndexes; use MongoDB\Operation\ListIndexes;
use Traversable; use Traversable;
...@@ -539,56 +541,45 @@ class Collection ...@@ -539,56 +541,45 @@ class Collection
} }
/** /**
* Inserts the provided documents * Inserts multiple documents.
* *
* @see InsertMany::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/insert/ * @see http://docs.mongodb.org/manual/reference/command/insert/
*
* @param array[]|object[] $documents The documents to insert * @param array[]|object[] $documents The documents to insert
* @param array $options Command options
* @return InsertManyResult * @return InsertManyResult
*/ */
public function insertMany(array $documents) public function insertMany(array $documents, array $options = array())
{ {
$options = array_merge($this->getWriteOptions()); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
$bulk = new BulkWrite($options["ordered"]);
$insertedIds = array();
foreach ($documents as $i => $document) {
$insertedId = $bulk->insert($document);
if ($insertedId !== null) {
$insertedIds[$i] = $insertedId;
} else {
$insertedIds[$i] = is_array($document) ? $document['_id'] : $document->_id;
}
} }
$writeResult = $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc); $operation = new InsertMany($this->dbname, $this->collname, $documents, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return new InsertManyResult($writeResult, $insertedIds); return $operation->execute($server);
} }
/** /**
* Inserts the provided document * Inserts one document.
* *
* @see InsertOne::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/insert/ * @see http://docs.mongodb.org/manual/reference/command/insert/
*
* @param array|object $document The document to insert * @param array|object $document The document to insert
* @param array $options Command options
* @return InsertOneResult * @return InsertOneResult
*/ */
public function insertOne($document) public function insertOne($document, array $options = array())
{ {
$options = array_merge($this->getWriteOptions()); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
$bulk = new BulkWrite($options["ordered"]);
$id = $bulk->insert($document);
$wr = $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc);
if ($id === null) {
$id = is_array($document) ? $document['_id'] : $document->_id;
} }
return new InsertOneResult($wr, $id); $operation = new InsertOne($this->dbname, $this->collname, $document, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return $operation->execute($server);
} }
/** /**
......
<?php
namespace MongoDB\Operation;
use MongoDB\InsertManyResult;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for inserting multiple documents with the insert command.
*
* @api
* @see MongoDB\Collection::insertMany()
* @see http://docs.mongodb.org/manual/reference/command/insert/
*/
class InsertMany implements Executable
{
private $databaseName;
private $collectionName;
private $documents;
private $options;
/**
* Constructs an insert command.
*
* Supported options:
*
* * ordered (boolean): If true, when an insert fails, return without
* performing the remaining writes. If false, when a write fails,
* continue with the remaining writes, if any. The default is true.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array[]|object[] $documents List of documents to insert
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, array $documents, array $options = array())
{
if (empty($documents)) {
throw new InvalidArgumentException('$documents is empty');
}
$expectedIndex = 0;
foreach ($documents as $i => $document) {
if ($i !== $expectedIndex) {
throw new InvalidArgumentException(sprintf('$documents is not a list (unexpected index: "%s")', $i));
}
if ( ! is_array($document) && ! is_object($document)) {
throw new InvalidArgumentTypeException(sprintf('$documents[%d]', $i), $document, 'array or object');
}
$expectedIndex += 1;
}
$options += array(
'ordered' => true,
);
if ( ! is_bool($options['ordered'])) {
throw new InvalidArgumentTypeException('"ordered" option', $options['ordered'], 'boolean');
}
if (array_key_exists('writeConcern', $options) && ! $options['writeConcern'] instanceof WriteConcern) {
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
}
$this->databaseName = (string) $databaseName;
$this->collectionName = (string) $collectionName;
$this->documents = $documents;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return InsertManyResult
*/
public function execute(Server $server)
{
$bulk = new BulkWrite($this->options['ordered']);
$insertedIds = array();
foreach ($this->documents as $i => $document) {
$insertedId = $bulk->insert($document);
if ($insertedId !== null) {
$insertedIds[$i] = $insertedId;
} else {
// TODO: This may be removed if PHPC-382 is implemented
$insertedIds[$i] = is_array($document) ? $document['_id'] : $document->_id;
}
}
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
return new InsertManyResult($writeResult, $insertedIds);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\InsertOneResult;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for inserting a single document with the insert command.
*
* @api
* @see MongoDB\Collection::insertOne()
* @see http://docs.mongodb.org/manual/reference/command/insert/
*/
class InsertOne implements Executable
{
private $databaseName;
private $collectionName;
private $document;
private $options;
/**
* Constructs an insert command.
*
* Supported options:
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $document Document to insert
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $document, array $options = array())
{
if ( ! is_array($document) && ! is_object($document)) {
throw new InvalidArgumentTypeException('$document', $document, 'array or object');
}
if (array_key_exists('writeConcern', $options) && ! $options['writeConcern'] instanceof WriteConcern) {
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
}
$this->databaseName = (string) $databaseName;
$this->collectionName = (string) $collectionName;
$this->document = $document;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return InsertOneResult
*/
public function execute(Server $server)
{
$bulk = new BulkWrite();
$insertedId = $bulk->insert($this->document);
if ($insertedId === null) {
// TODO: This may be removed if PHPC-382 is implemented
$insertedId = is_array($this->document) ? $this->document['_id'] : $this->document->_id;
}
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
return new InsertOneResult($writeResult, $insertedId);
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\InsertMany;
class InsertManyTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testConstructorDocumentsMustNotBeEmpty()
{
new InsertMany($this->getDatabaseName(), $this->getCollectionName(), array());
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testConstructorDocumentsMustBeAList()
{
new InsertMany($this->getDatabaseName(), $this->getCollectionName(), array(1 => array('x' => 1)));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorDocumentsElementType($document)
{
new InsertMany($this->getDatabaseName(), $this->getCollectionName(), array($document));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidBooleanArguments
*/
public function testConstructorOrderedOptionType($ordered)
{
new InsertMany($this->getDatabaseName(), $this->getCollectionName(), array(array('x' => 1)), array('ordered' => $ordered));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
*/
public function testConstructorWriteConcernOptionType()
{
new InsertMany($this->getDatabaseName(), $this->getCollectionName(), array(array('x' => 1)), array('writeConcern' => null));
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\InsertOne;
class InsertOneTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorDocumentArgumentType($document)
{
new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
*/
public function testConstructorWriteConcernOptionType()
{
new InsertOne($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('writeConcern' => null));
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Tests\TestCase as BaseTestCase;
use stdClass;
/**
* Base class for Operation unit tests.
*/
abstract class TestCase extends BaseTestCase
{
public function provideInvalidDocumentArguments()
{
return array(
array(null),
array(123),
array('foo'),
array(true),
);
}
public function provideInvalidBooleanArguments()
{
return array(
array(null),
array(123),
array('foo'),
array(array()),
array(new stdClass()),
);
}
}
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