Commit ced71457 authored by Jeremy Mikola's avatar Jeremy Mikola

Merge pull request #26

parents 81477df2 c9ab86f9
...@@ -25,6 +25,7 @@ before_install: ...@@ -25,6 +25,7 @@ before_install:
install: install:
- if dpkg --compare-versions ${SERVER_VERSION} le "2.4"; then export SERVER_PACKAGE=mongodb-10gen-enterprise; else export SERVER_PACKAGE=mongodb-enterprise; fi - if dpkg --compare-versions ${SERVER_VERSION} le "2.4"; then export SERVER_PACKAGE=mongodb-10gen-enterprise; else export SERVER_PACKAGE=mongodb-enterprise; fi
- sudo apt-get install ${SERVER_PACKAGE} - sudo apt-get install ${SERVER_PACKAGE}
- sudo apt-get -y install gdb
before_script: before_script:
- if dpkg --compare-versions ${SERVER_VERSION} le "2.4"; then export SERVER_SERVICE=mongodb; else export SERVER_SERVICE=mongod; fi - if dpkg --compare-versions ${SERVER_VERSION} le "2.4"; then export SERVER_SERVICE=mongodb; else export SERVER_SERVICE=mongod; fi
...@@ -33,3 +34,10 @@ before_script: ...@@ -33,3 +34,10 @@ before_script:
- pecl install -f mongodb-${DRIVER_VERSION} - pecl install -f mongodb-${DRIVER_VERSION}
- php --ri mongodb - php --ri mongodb
- composer install --dev --no-interaction --prefer-source - composer install --dev --no-interaction --prefer-source
- ulimit -c
- ulimit -c unlimited -S
script:
- phpunit --debug || RESULT=$?
- for i in $(find ./ -maxdepth 1 -name 'core*' -print); do gdb `php -r 'echo PHP_BINARY;'` core* -ex "thread apply all bt" -ex "set pagination 0" -batch; done;
- if [[ ${RESULT} != 0 ]]; then exit $RESULT ; fi;
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
namespace MongoDB; namespace MongoDB;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Command; use MongoDB\Driver\Command;
use MongoDB\Driver\Cursor; use MongoDB\Driver\Cursor;
use MongoDB\Driver\Manager; use MongoDB\Driver\Manager;
...@@ -14,8 +13,11 @@ use MongoDB\Exception\UnexpectedTypeException; ...@@ -14,8 +13,11 @@ use MongoDB\Exception\UnexpectedTypeException;
use MongoDB\Model\IndexInfoIterator; use MongoDB\Model\IndexInfoIterator;
use MongoDB\Model\IndexInput; use MongoDB\Model\IndexInput;
use MongoDB\Operation\Aggregate; use MongoDB\Operation\Aggregate;
use MongoDB\Operation\BulkWrite;
use MongoDB\Operation\CreateIndexes; use MongoDB\Operation\CreateIndexes;
use MongoDB\Operation\Count; use MongoDB\Operation\Count;
use MongoDB\Operation\DeleteMany;
use MongoDB\Operation\DeleteOne;
use MongoDB\Operation\Distinct; use MongoDB\Operation\Distinct;
use MongoDB\Operation\DropCollection; use MongoDB\Operation\DropCollection;
use MongoDB\Operation\DropIndexes; use MongoDB\Operation\DropIndexes;
...@@ -24,7 +26,12 @@ use MongoDB\Operation\FindOne; ...@@ -24,7 +26,12 @@ 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 MongoDB\Operation\ReplaceOne;
use MongoDB\Operation\UpdateMany;
use MongoDB\Operation\UpdateOne;
use Traversable; use Traversable;
class Collection class Collection
...@@ -94,135 +101,23 @@ class Collection ...@@ -94,135 +101,23 @@ class Collection
} }
/** /**
* Adds a full set of write operations into a bulk and executes it * Executes multiple write operations.
* *
* The syntax of the $bulk array is: * @see BulkWrite::__construct() for supported options
* $bulk = [ * @param array[] $operations List of write operations
* [ * @param array $options Command options
* 'METHOD' => [ * @return BulkWriteResult
* $document,
* $extraArgument1,
* $extraArgument2,
* ],
* ],
* [
* 'METHOD' => [
* $document,
* $extraArgument1,
* $extraArgument2,
* ],
* ],
* ]
*
*
* Where METHOD is one of
* - 'insertOne'
* Supports no $extraArgument
* - 'updateMany'
* Requires $extraArgument1, same as $update for Collection::updateMany()
* Optional $extraArgument2, same as $options for Collection::updateMany()
* - 'updateOne'
* Requires $extraArgument1, same as $update for Collection::updateOne()
* Optional $extraArgument2, same as $options for Collection::updateOne()
* - 'replaceOne'
* Requires $extraArgument1, same as $update for Collection::replaceOne()
* Optional $extraArgument2, same as $options for Collection::replaceOne()
* - 'deleteOne'
* Supports no $extraArgument
* - 'deleteMany'
* Supports no $extraArgument
*
* @example Collection-bulkWrite.php Using Collection::bulkWrite()
*
* @see Collection::getBulkOptions() for supported $options
*
* @param array $ops Array of operations
* @param array $options Additional options
* @return WriteResult
*/ */
public function bulkWrite(array $ops, array $options = array()) public function bulkWrite(array $operations, array $options = array())
{ {
$options = array_merge($this->getBulkOptions(), $options); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
$bulk = new BulkWrite($options["ordered"]);
$insertedIds = array();
foreach ($ops as $n => $op) {
foreach ($op as $opname => $args) {
if (!isset($args[0])) {
throw new InvalidArgumentException(sprintf("Missing argument#1 for '%s' (operation#%d)", $opname, $n));
}
switch ($opname) {
case "insertOne":
$insertedId = $bulk->insert($args[0]);
if ($insertedId !== null) {
$insertedIds[$n] = $insertedId;
} else {
$insertedIds[$n] = is_array($args[0]) ? $args[0]['_id'] : $args[0]->_id;
}
break;
case "updateMany":
if (!isset($args[1])) {
throw new InvalidArgumentException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
}
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("multi" => true));
$firstKey = key($args[1]);
if (!isset($firstKey[0]) || $firstKey[0] != '$') {
throw new InvalidArgumentException("First key in \$update must be a \$operator");
}
$bulk->update($args[0], $args[1], $options);
break;
case "updateOne":
if (!isset($args[1])) {
throw new InvalidArgumentException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
}
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("multi" => false));
$firstKey = key($args[1]);
if (!isset($firstKey[0]) || $firstKey[0] != '$') {
throw new InvalidArgumentException("First key in \$update must be a \$operator");
}
$bulk->update($args[0], $args[1], $options);
break;
case "replaceOne":
if (!isset($args[1])) {
throw new InvalidArgumentException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
}
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("multi" => false));
$firstKey = key($args[1]);
if (isset($firstKey[0]) && $firstKey[0] == '$') {
throw new InvalidArgumentException("First key in \$update must NOT be a \$operator");
}
$bulk->update($args[0], $args[1], $options);
break;
case "deleteOne":
$options = array_merge($this->getWriteOptions(), isset($args[1]) ? $args[1] : array(), array("limit" => 1));
$bulk->delete($args[0], $options);
break;
case "deleteMany":
$options = array_merge($this->getWriteOptions(), isset($args[1]) ? $args[1] : array(), array("limit" => 0));
$bulk->delete($args[0], $options);
break;
default:
throw new InvalidArgumentException(sprintf("Unknown operation type called '%s' (operation#%d)", $opname, $n));
}
}
} }
$writeResult = $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc); $operation = new BulkWrite($this->dbname, $this->collname, $operations, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return new BulkWriteResult($writeResult, $insertedIds); return $operation->execute($server);
} }
/** /**
...@@ -287,35 +182,45 @@ class Collection ...@@ -287,35 +182,45 @@ class Collection
} }
/** /**
* Deletes a document matching the $filter criteria. * Deletes all documents matching the filter.
* NOTE: Will delete ALL documents matching $filter
* *
* @see DeleteMany::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/delete/ * @see http://docs.mongodb.org/manual/reference/command/delete/
* * @param array|object $filter Query by which to delete documents
* @param array $filter The $filter criteria to delete * @param array $options Command options
* @return DeleteResult * @return DeleteResult
*/ */
public function deleteMany(array $filter) public function deleteMany($filter, array $options = array())
{ {
$wr = $this->_delete($filter, 0); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
}
$operation = new DeleteMany($this->dbname, $this->collname, $filter, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return new DeleteResult($wr); return $operation->execute($server);
} }
/** /**
* Deletes a document matching the $filter criteria. * Deletes at most one document matching the filter.
* NOTE: Will delete at most ONE document matching $filter
* *
* @see DeleteOne::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/delete/ * @see http://docs.mongodb.org/manual/reference/command/delete/
* * @param array|object $filter Query by which to delete documents
* @param array $filter The $filter criteria to delete * @param array $options Command options
* @return DeleteResult * @return DeleteResult
*/ */
public function deleteOne(array $filter) public function deleteOne($filter, array $options = array())
{ {
$wr = $this->_delete($filter); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
}
return new DeleteResult($wr); $operation = new DeleteOne($this->dbname, $this->collname, $filter, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return $operation->execute($server);
} }
/** /**
...@@ -422,6 +327,7 @@ class Collection ...@@ -422,6 +327,7 @@ class Collection
* The document to return may be null. * The document to return may be null.
* *
* @see FindOneAndDelete::__construct() for supported options * @see FindOneAndDelete::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array $options Command options * @param array $options Command options
* @return object|null * @return object|null
...@@ -443,6 +349,7 @@ class Collection ...@@ -443,6 +349,7 @@ class Collection
* "returnDocument" option to return the updated document. * "returnDocument" option to return the updated document.
* *
* @see FindOneAndReplace::__construct() for supported options * @see FindOneAndReplace::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array|object $replacement Replacement document * @param array|object $replacement Replacement document
* @param array $options Command options * @param array $options Command options
...@@ -465,6 +372,7 @@ class Collection ...@@ -465,6 +372,7 @@ class Collection
* "returnDocument" option to return the updated document. * "returnDocument" option to return the updated document.
* *
* @see FindOneAndReplace::__construct() for supported options * @see FindOneAndReplace::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document * @param array|object $update Update to apply to the matched document
* @param array $options Command options * @param array $options Command options
...@@ -478,18 +386,6 @@ class Collection ...@@ -478,18 +386,6 @@ class Collection
return $operation->execute($server); return $operation->execute($server);
} }
/**
* Retrieves all Bulk Write options with their default values.
*
* @return array of available Bulk Write options
*/
public function getBulkOptions()
{
return array(
"ordered" => false,
);
}
/** /**
* Return the collection name. * Return the collection name.
* *
...@@ -522,70 +418,45 @@ class Collection ...@@ -522,70 +418,45 @@ class Collection
} }
/** /**
* Retrieves all Write options with their default values. * Inserts multiple documents.
*
* @return array of available Write options
*/
public function getWriteOptions()
{
return array(
"ordered" => false,
"upsert" => false,
"limit" => 1,
);
}
/**
* Inserts the provided 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);
} }
/** /**
...@@ -603,92 +474,68 @@ class Collection ...@@ -603,92 +474,68 @@ class Collection
} }
/** /**
* Replace one document * Replaces at most one document matching the filter.
* *
* @see ReplaceOne::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/update/ * @see http://docs.mongodb.org/manual/reference/command/update/
* @see Collection::getWriteOptions() for supported $options * @param array|object $filter Query by which to filter documents
* * @param array|object $replacement Replacement document
* @param array $filter The document to be replaced * @param array $options Command options
* @param array $update The document to replace with
* @param array $options Additional options
* @return UpdateResult * @return UpdateResult
*/ */
public function replaceOne(array $filter, array $update, array $options = array()) public function replaceOne($filter, $replacement, array $options = array())
{ {
$firstKey = key($update); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
if (isset($firstKey[0]) && $firstKey[0] == '$') { $options['writeConcern'] = $this->wc;
throw new InvalidArgumentException("First key in \$update must NOT be a \$operator");
} }
$wr = $this->_update($filter, $update, $options + array("multi" => false));
return new UpdateResult($wr); $operation = new ReplaceOne($this->dbname, $this->collname, $filter, $replacement, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return $operation->execute($server);
} }
/** /**
* Update one document * Updates all documents matching the filter.
* NOTE: Will update ALL documents matching $filter
* *
* @see UpdateMany::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/update/ * @see http://docs.mongodb.org/manual/reference/command/update/
* @see Collection::getWriteOptions() for supported $options * @param array|object $filter Query by which to filter documents
* * @param array|object $replacement Update to apply to the matched documents
* @param array $filter The document to be replaced * @param array $options Command options
* @param array $update An array of update operators to apply to the document
* @param array $options Additional options
* @return UpdateResult * @return UpdateResult
*/ */
public function updateMany(array $filter, $update, array $options = array()) public function updateMany($filter, $update, array $options = array())
{ {
$wr = $this->_update($filter, $update, $options + array("multi" => true)); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
$options['writeConcern'] = $this->wc;
}
$operation = new UpdateMany($this->dbname, $this->collname, $filter, $update, $options);
$server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
return new UpdateResult($wr); return $operation->execute($server);
} }
/** /**
* Update one document * Updates at most one document matching the filter.
* NOTE: Will update at most ONE document matching $filter
* *
* @see ReplaceOne::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/update/ * @see http://docs.mongodb.org/manual/reference/command/update/
* @see Collection::getWriteOptions() for supported $options * @param array|object $filter Query by which to filter documents
* * @param array|object $replacement Update to apply to the matched document
* @param array $filter The document to be replaced * @param array $options Command options
* @param array $update An array of update operators to apply to the document
* @param array $options Additional options
* @return UpdateResult * @return UpdateResult
*/ */
public function updateOne(array $filter, array $update, array $options = array()) public function updateOne($filter, $update, array $options = array())
{ {
$firstKey = key($update); if ( ! isset($options['writeConcern']) && isset($this->wc)) {
if (!isset($firstKey[0]) || $firstKey[0] != '$') { $options['writeConcern'] = $this->wc;
throw new InvalidArgumentException("First key in \$update must be a \$operator");
} }
$wr = $this->_update($filter, $update, $options + array("multi" => false));
return new UpdateResult($wr); $operation = new UpdateOne($this->dbname, $this->collname, $filter, $update, $options);
} $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
/**
* Internal helper for delete one/many documents
* @internal
*/
final protected function _delete($filter, $limit = 1)
{
$options = array_merge($this->getWriteOptions(), array("limit" => $limit));
$bulk = new BulkWrite($options["ordered"]);
$bulk->delete($filter, $options);
return $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc);
}
/**
* Internal helper for replacing/updating one/many documents
* @internal
*/
protected function _update($filter, $update, $options)
{
$options = array_merge($this->getWriteOptions(), $options);
$bulk = new BulkWrite($options["ordered"]); return $operation->execute($server);
$bulk->update($filter, $update, $options);
return $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc);
} }
} }
<?php
namespace MongoDB\Operation;
use MongoDB\BulkWriteResult;
use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for executing multiple write operations.
*
* @api
* @see MongoDB\Collection::bulkWrite()
*/
class BulkWrite implements Executable
{
const DELETE_MANY = 'deleteMany';
const DELETE_ONE = 'deleteOne';
const INSERT_ONE = 'insertOne';
const REPLACE_ONE = 'replaceOne';
const UPDATE_MANY = 'updateMany';
const UPDATE_ONE = 'updateOne';
private $databaseName;
private $collectionName;
private $operations;
private $options;
/**
* Constructs a bulk write operation.
*
* Example array structure for all supported operation types:
*
* [
* [ 'deleteOne' => [ $filter ] ],
* [ 'deleteMany' => [ $filter ] ],
* [ 'insertOne' => [ $document ] ],
* [ 'replaceOne' => [ $filter, $replacement, $options ] ],
* [ 'updateMany' => [ $filter, $update, $options ] ],
* [ 'updateOne' => [ $filter, $update, $options ] ],
* ]
*
* Arguments correspond to the respective Operation classes; however, the
* writeConcern option is specified for the top-level bulk write operation
* instead of each individual operations.
*
* Supported options for replaceOne, updateMany, and updateOne operations:
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* Supported options for the bulk write operation:
*
* * 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[] $operations List of write operations
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, array $operations, array $options = array())
{
if (empty($operations)) {
throw new InvalidArgumentException('$operations is empty');
}
$expectedIndex = 0;
foreach ($operations as $i => $operation) {
if ($i !== $expectedIndex) {
throw new InvalidArgumentException(sprintf('$operations is not a list (unexpected index: "%s")', $i));
}
if ( ! is_array($operation)) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]', $i), $operation, 'array');
}
if (count($operation) !== 1) {
throw new InvalidArgumentException(sprintf('Expected one element in $operation[%d], actually: %d', $i, count($operation)));
}
$type = key($operation);
$args = current($operation);
if ( ! isset($args[0]) && ! array_key_exists(0, $args)) {
throw new InvalidArgumentException(sprintf('Missing first argument for $operations[%d]["%s"]', $i, $type));
}
if ( ! is_array($args[0]) && ! is_object($args[0])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][0]', $i, $type), $args[0], 'array or object');
}
switch ($type) {
case self::INSERT_ONE:
break;
case self::DELETE_MANY:
case self::DELETE_ONE:
$operations[$i][$type][1] = array('limit' => ($type === self::DELETE_ONE ? 1 : 0));
break;
case self::REPLACE_ONE:
if ( ! isset($args[1]) && ! array_key_exists(1, $args)) {
throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type));
}
if ( ! is_array($args[1]) && ! is_object($args[1])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array or object');
}
if (\MongoDB\is_first_key_operator($args[1])) {
throw new InvalidArgumentException(sprintf('First key in $operations[%d]["%s"][1] is an update operator', $i, $type));
}
if ( ! isset($args[2])) {
$args[2] = array();
}
if ( ! is_array($args[2])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array');
}
$args[2]['multi'] = false;
$args[2] += array('upsert' => false);
if ( ! is_bool($args[2]['upsert'])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
}
$operations[$i][$type][2] = $args[2];
break;
case self::UPDATE_MANY:
case self::UPDATE_ONE:
if ( ! isset($args[1]) && ! array_key_exists(1, $args)) {
throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type));
}
if ( ! is_array($args[1]) && ! is_object($args[1])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array or object');
}
if ( ! \MongoDB\is_first_key_operator($args[1])) {
throw new InvalidArgumentException(sprintf('First key in $operations[%d]["%s"][1] is not an update operator', $i, $type));
}
if ( ! isset($args[2])) {
$args[2] = array();
}
if ( ! is_array($args[2])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array');
}
$args[2]['multi'] = ($type === self::UPDATE_MANY);
$args[2] += array('upsert' => false);
if ( ! is_bool($args[2]['upsert'])) {
throw new InvalidArgumentTypeException(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
}
$operations[$i][$type][2] = $args[2];
break;
default:
throw new InvalidArgumentException(sprintf('Unknown operation type "%s" in $operations[%d]', $type, $i));
}
$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->operations = $operations;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return BulkWriteResult
*/
public function execute(Server $server)
{
$bulk = new Bulk($this->options['ordered']);
$insertedIds = array();
foreach ($this->operations as $i => $operation) {
$type = key($operation);
$args = current($operation);
switch ($type) {
case self::DELETE_MANY:
case self::DELETE_ONE:
$bulk->delete($args[0], $args[1]);
break;
case self::INSERT_ONE:
$insertedId = $bulk->insert($args[0]);
if ($insertedId !== null) {
$insertedIds[$i] = $insertedId;
} else {
// TODO: This may be removed if PHPC-382 is implemented
$insertedIds[$i] = is_array($args[0]) ? $args[0]['_id'] : $args[0]->_id;
}
break;
case self::REPLACE_ONE:
case self::UPDATE_MANY:
case self::UPDATE_ONE:
$bulk->update($args[0], $args[1], $args[2]);
}
}
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
return new BulkWriteResult($writeResult, $insertedIds);
}
}
...@@ -4,7 +4,6 @@ namespace MongoDB\Operation; ...@@ -4,7 +4,6 @@ namespace MongoDB\Operation;
use MongoDB\Driver\Command; use MongoDB\Driver\Command;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\BulkWrite;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\RuntimeException; use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedTypeException; use MongoDB\Exception\UnexpectedTypeException;
...@@ -96,9 +95,6 @@ class CreateCollection implements Executable ...@@ -96,9 +95,6 @@ class CreateCollection implements Executable
/** /**
* Execute the operation. * Execute the operation.
* *
* For servers < 2.6, this will actually perform an insert operation on the
* database's "system.indexes" collection.
*
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return object Command result document * @return object Command result document
......
...@@ -4,7 +4,7 @@ namespace MongoDB\Operation; ...@@ -4,7 +4,7 @@ namespace MongoDB\Operation;
use MongoDB\Driver\Command; use MongoDB\Driver\Command;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\BulkWrite; use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\RuntimeException; use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedTypeException; use MongoDB\Exception\UnexpectedTypeException;
...@@ -108,7 +108,7 @@ class CreateIndexes implements Executable ...@@ -108,7 +108,7 @@ class CreateIndexes implements Executable
*/ */
private function executeLegacy(Server $server) private function executeLegacy(Server $server)
{ {
$bulk = new BulkWrite(true); $bulk = new Bulk(true);
foreach ($this->indexes as $index) { foreach ($this->indexes as $index) {
$bulk->insert($index); $bulk->insert($index);
......
<?php
namespace MongoDB\Operation;
use MongoDB\DeleteResult;
use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for the delete command.
*
* This class is used internally by the DeleteMany and DeleteOne operation
* classes.
*
* @internal
* @see http://docs.mongodb.org/manual/reference/command/delete/
*/
class Delete implements Executable
{
private $databaseName;
private $collectionName;
private $filter;
private $limit;
private $options;
/**
* Constructs a delete command.
*
* Supported options:
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to delete documents
* @param integer $limit The number of matching documents to
* delete. Must be 0 or 1, for all or a
* single document, respectively.
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, $limit, array $options = array())
{
if ( ! is_array($filter) && ! is_object($filter)) {
throw new InvalidArgumentTypeException('$filter', $filter, 'array or object');
}
if ($limit !== 0 && $limit !== 1) {
throw new InvalidArgumentException('$limit must be 0 or 1');
}
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->filter = $filter;
$this->limit = $limit;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return DeleteResult
*/
public function execute(Server $server)
{
$bulk = new Bulk();
$bulk->delete($this->filter, array('limit' => $this->limit));
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
return new DeleteResult($writeResult);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\DeleteResult;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
/**
* Operation for deleting multiple document with the delete command.
*
* @api
* @see MongoDB\Collection::deleteOne()
* @see http://docs.mongodb.org/manual/reference/command/delete/
*/
class DeleteMany implements Executable
{
private $delete;
/**
* Constructs a delete command.
*
* Supported options:
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to delete documents
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, array $options = array())
{
$this->delete = new Delete($databaseName, $collectionName, $filter, 0, $options);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return DeleteResult
*/
public function execute(Server $server)
{
return $this->delete->execute($server);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\DeleteResult;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
/**
* Operation for deleting a single document with the delete command.
*
* @api
* @see MongoDB\Collection::deleteOne()
* @see http://docs.mongodb.org/manual/reference/command/delete/
*/
class DeleteOne implements Executable
{
private $delete;
/**
* Constructs a delete command.
*
* Supported options:
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to delete documents
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, array $options = array())
{
$this->delete = new Delete($databaseName, $collectionName, $filter, 1, $options);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return DeleteResult
*/
public function execute(Server $server)
{
return $this->delete->execute($server);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\InsertManyResult;
use MongoDB\Driver\BulkWrite as Bulk;
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 Bulk($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 as Bulk;
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 Bulk();
$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\Operation;
use MongoDB\UpdateResult;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for replacing a single document with the update command.
*
* @api
* @see MongoDB\Collection::replaceOne()
* @see http://docs.mongodb.org/manual/reference/command/update/
*/
class ReplaceOne implements Executable
{
private $update;
/**
* Constructs an update command.
*
* Supported options:
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array|object $replacement Replacement document
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, $replacement, array $options = array())
{
if ( ! is_array($replacement) && ! is_object($replacement)) {
throw new InvalidArgumentTypeException('$replacement', $replacement, 'array or object');
}
if (\MongoDB\is_first_key_operator($replacement)) {
throw new InvalidArgumentException('First key in $replacement argument is an update operator');
}
$this->update = new Update(
$databaseName,
$collectionName,
$filter,
$replacement,
array('multi' => false) + $options
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return UpdateResult
*/
public function execute(Server $server)
{
return $this->update->execute($server);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\UpdateResult;
use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for the update command.
*
* This class is used internally by the ReplaceOne, UpdateMany, and UpdateOne
* operation classes.
*
* @internal
* @see http://docs.mongodb.org/manual/reference/command/update/
*/
class Update implements Executable
{
private $databaseName;
private $collectionName;
private $filter;
private $update;
private $options;
/**
* Constructs a update command.
*
* Supported options:
*
* * multi (boolean): When true, updates all documents matching the query.
* This option cannot be true if the $update argument is a replacement
* document (i.e. contains no update operators). The default is false.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to delete documents
* @param array|object $update Update to apply to the matched
* document(s) or a replacement document
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, $update, array $options = array())
{
if ( ! is_array($filter) && ! is_object($filter)) {
throw new InvalidArgumentTypeException('$filter', $filter, 'array or object');
}
if ( ! is_array($update) && ! is_object($update)) {
throw new InvalidArgumentTypeException('$update', $filter, 'array or object');
}
$options += array(
'multi' => false,
'upsert' => false,
);
if ( ! is_bool($options['multi'])) {
throw new InvalidArgumentTypeException('"multi" option', $options['multi'], 'boolean');
}
if ($options['multi'] && ! \MongoDB\is_first_key_operator($update)) {
throw new InvalidArgumentException('"multi" option cannot be true if $update is a replacement document');
}
if ( ! is_bool($options['upsert'])) {
throw new InvalidArgumentTypeException('"upsert" option', $options['upsert'], '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->filter = $filter;
$this->update = $update;
$this->options = $options;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return UpdateResult
*/
public function execute(Server $server)
{
$options = array(
'multi' => $this->options['multi'],
'upsert' => $this->options['upsert'],
);
$bulk = new Bulk();
$bulk->update($this->filter, $this->update, $options);
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
return new UpdateResult($writeResult);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\UpdateResult;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for updating multiple documents with the update command.
*
* @api
* @see MongoDB\Collection::updateMany()
* @see http://docs.mongodb.org/manual/reference/command/update/
*/
class UpdateMany implements Executable
{
private $update;
/**
* Constructs an update command.
*
* Supported options:
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched documents
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, $update, array $options = array())
{
if ( ! is_array($update) && ! is_object($update)) {
throw new InvalidArgumentTypeException('$update', $update, 'array or object');
}
if ( ! \MongoDB\is_first_key_operator($update)) {
throw new InvalidArgumentException('First key in $update argument is not an update operator');
}
$this->update = new Update(
$databaseName,
$collectionName,
$filter,
$update,
array('multi' => true) + $options
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return UpdateResult
*/
public function execute(Server $server)
{
return $this->update->execute($server);
}
}
<?php
namespace MongoDB\Operation;
use MongoDB\UpdateResult;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
/**
* Operation for updating a single document with the update command.
*
* @api
* @see MongoDB\Collection::updateOne()
* @see http://docs.mongodb.org/manual/reference/command/update/
*/
class UpdateOne implements Executable
{
private $update;
/**
* Constructs an update command.
*
* Supported options:
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document
* @param array $options Command options
* @throws InvalidArgumentException
*/
public function __construct($databaseName, $collectionName, $filter, $update, array $options = array())
{
if ( ! is_array($update) && ! is_object($update)) {
throw new InvalidArgumentTypeException('$update', $update, 'array or object');
}
if ( ! \MongoDB\is_first_key_operator($update)) {
throw new InvalidArgumentException('First key in $update argument is not an update operator');
}
$this->update = new Update(
$databaseName,
$collectionName,
$filter,
$update,
array('multi' => false) + $options
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return UpdateResult
*/
public function execute(Server $server)
{
return $this->update->execute($server);
}
}
...@@ -128,7 +128,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -128,7 +128,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/** /**
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Unknown operation type called 'foo' (operation#0) * @expectedExceptionMessage Unknown operation type "foo" in $operations[0]
*/ */
public function testUnknownOperation() public function testUnknownOperation()
{ {
...@@ -139,7 +139,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -139,7 +139,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/** /**
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessageRegExp /Missing argument#\d+ for '\w+' \(operation#\d+\)/ * @expectedExceptionMessageRegExp /Missing (first|second) argument for \$operations\[\d+\]\["\w+\"]/
* @dataProvider provideOpsWithMissingArguments * @dataProvider provideOpsWithMissingArguments
*/ */
public function testMissingArguments(array $ops) public function testMissingArguments(array $ops)
...@@ -164,7 +164,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -164,7 +164,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/** /**
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $update must be a $operator * @expectedExceptionMessage First key in $operations[0]["updateOne"][1] is not an update operator
*/ */
public function testUpdateOneRequiresUpdateOperators() public function testUpdateOneRequiresUpdateOperators()
{ {
...@@ -175,7 +175,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -175,7 +175,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/** /**
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $update must be a $operator * @expectedExceptionMessage First key in $operations[0]["updateMany"][1] is not an update operator
*/ */
public function testUpdateManyRequiresUpdateOperators() public function testUpdateManyRequiresUpdateOperators()
{ {
...@@ -186,7 +186,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -186,7 +186,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/** /**
* @expectedException MongoDB\Exception\InvalidArgumentException * @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $update must NOT be a $operator * @expectedExceptionMessage First key in $operations[0]["replaceOne"][1] is an update operator
*/ */
public function testReplaceOneRequiresReplacementDocument() public function testReplaceOneRequiresReplacementDocument()
{ {
......
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\BulkWrite;
class BulkWriteTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage $operations is empty
*/
public function testOperationsMustNotBeEmpty()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array());
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage $operations is not a list (unexpected index: "1")
*/
public function testOperationsMustBeAList()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
1 => array(BulkWrite::INSERT_ONE => array(array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Expected one element in $operation[0], actually: 2
*/
public function testMultipleOperationsInOneElement()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(
BulkWrite::INSERT_ONE => array(array('x' => 1)),
BulkWrite::DELETE_ONE => array(array('x' => 1)),
),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Unknown operation type "foo" in $operations[0]
*/
public function testUnknownOperation()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array('foo' => array(array('_id' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["insertOne"]
*/
public function testInsertOneDocumentArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::INSERT_ONE => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["insertOne"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testInsertOneDocumentArgumentType($document)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::INSERT_ONE => array($document)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["deleteMany"]
*/
public function testDeleteManyFilterArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::DELETE_MANY => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["deleteMany"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testDeleteManyFilterArgumentType($document)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::DELETE_MANY => array($document)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["deleteOne"]
*/
public function testDeleteOneFilterArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::DELETE_ONE => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["deleteOne"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testDeleteOneFilterArgumentType($document)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::DELETE_ONE => array($document)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["replaceOne"]
*/
public function testReplaceOneFilterArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["replaceOne"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testReplaceOneFilterArgumentType($filter)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array($filter, array('y' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing second argument for $operations[0]["replaceOne"]
*/
public function testReplaceOneReplacementArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array(array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["replaceOne"\]\[1\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testReplaceOneReplacementArgumentType($replacement)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array(array('x' => 1), $replacement)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $operations[0]["replaceOne"][1] is an update operator
*/
public function testReplaceOneReplacementArgumentRequiresNoOperators()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array(array('_id' => 1), array('$inc' => array('x' => 1)))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["replaceOne"\]\[2\]\["upsert"\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidBooleanArguments
*/
public function testReplaceOneUpsertOptionType($upsert)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::REPLACE_ONE => array(array('x' => 1), array('y' => 1), array('upsert' => $upsert))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["updateMany"]
*/
public function testUpdateManyFilterArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateMany"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testUpdateManyFilterArgumentType($filter)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array($filter, array('$set' => array('x' => 1)))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing second argument for $operations[0]["updateMany"]
*/
public function testUpdateManyUpdateArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array(array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateMany"\]\[1\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testUpdateManyUpdateArgumentType($update)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array(array('x' => 1), $update)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $operations[0]["updateMany"][1] is not an update operator
*/
public function testUpdateManyUpdateArgumentRequiresOperators()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array(array('_id' => array('$gt' => 1)), array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateMany"\]\[2\]\["upsert"\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidBooleanArguments
*/
public function testUpdateManyUpsertOptionType($upsert)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_MANY => array(array('x' => 1), array('$set' => array('x' => 1)), array('upsert' => $upsert))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing first argument for $operations[0]["updateOne"]
*/
public function testUpdateOneFilterArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array()),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateOne"\]\[0\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testUpdateOneFilterArgumentType($filter)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array($filter, array('$set' => array('x' => 1)))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Missing second argument for $operations[0]["updateOne"]
*/
public function testUpdateOneUpdateArgumentMissing()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array(array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateOne"\]\[1\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidDocumentArguments
*/
public function testUpdateOneUpdateArgumentType($update)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array(array('x' => 1), $update)),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage First key in $operations[0]["updateOne"][1] is not an update operator
*/
public function testUpdateOneUpdateArgumentRequiresOperators()
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array(array('_id' => 1), array('x' => 1))),
));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @expectedExceptionMessageRegExp /Expected \$operations\[0\]\["updateOne"\]\[2\]\["upsert"\] to have type "[\w ]+" but found "[\w ]+"/
* @dataProvider provideInvalidBooleanArguments
*/
public function testUpdateOneUpsertOptionType($upsert)
{
new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), array(
array(BulkWrite::UPDATE_ONE => array(array('x' => 1), array('$set' => array('x' => 1)), array('upsert' => $upsert))),
));
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\Delete;
class DeleteTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorFilterArgumentType($filter)
{
new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 0);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorLimitArgumentMustBeOneOrZero()
{
new Delete($this->getDatabaseName(), $this->getCollectionName(), array(), 2);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
*/
public function testConstructorWriteConcernOptionType()
{
new Delete($this->getDatabaseName(), $this->getCollectionName(), array(), 1, array('writeConcern' => null));
}
}
<?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\Operation\ReplaceOne;
class ReplaceOneTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorFilterArgumentType($filter)
{
new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), $filter, array('y' => 1));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorReplacementArgumentType($replacement)
{
new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), $replacement);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testConstructorReplacementArgumentRequiresNoOperators()
{
new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('$set' => array('x' => 1)));
}
}
<?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()),
);
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\UpdateMany;
class UpdateManyTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorFilterArgumentType($filter)
{
new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), $filter, array('$set' => array('x' => 1)));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorUpdateArgumentType($update)
{
new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), $update);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testConstructorUpdateArgumentRequiresOperators()
{
new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('y' => 1));
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\UpdateOne;
class UpdateOneTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorFilterArgumentType($filter)
{
new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), $filter, array('$set' => array('x' => 1)));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorUpdateArgumentType($update)
{
new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), $update);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public function testConstructorUpdateArgumentRequiresOperators()
{
new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('y' => 1));
}
}
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Operation\Update;
class UpdateTest extends TestCase
{
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorFilterArgumentType($filter)
{
new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, array('$set' => array('x' => 1)));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDocumentArguments
*/
public function testConstructorUpdateArgumentType($update)
{
new Update($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), $update);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidBooleanArguments
*/
public function testConstructorMultiOptionType($multi)
{
new Update($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('y' => 1), array('multi' => $multi));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidBooleanArguments
*/
public function testConstructorUpsertOptionType($upsert)
{
new Update($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('y' => 1), array('upsert' => $upsert));
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
*/
public function testConstructorWriteConcernOptionType()
{
new Update($this->getDatabaseName(), $this->getCollectionName(), array('x' => 1), array('y' => 1), array('writeConcern' => null));
}
}
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