Commit ced71457 authored by Jeremy Mikola's avatar Jeremy Mikola

Merge pull request #26

parents 81477df2 c9ab86f9
......@@ -25,6 +25,7 @@ before_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
- sudo apt-get install ${SERVER_PACKAGE}
- sudo apt-get -y install gdb
before_script:
- 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:
- pecl install -f mongodb-${DRIVER_VERSION}
- php --ri mongodb
- 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;
This diff is collapsed.
<?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;
use MongoDB\Driver\Command;
use MongoDB\Driver\Server;
use MongoDB\Driver\BulkWrite;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedTypeException;
......@@ -96,9 +95,6 @@ class CreateCollection implements Executable
/**
* 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 object Command result document
......
......@@ -4,7 +4,7 @@ namespace MongoDB\Operation;
use MongoDB\Driver\Command;
use MongoDB\Driver\Server;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\RuntimeException;
use MongoDB\Exception\UnexpectedTypeException;
......@@ -108,7 +108,7 @@ class CreateIndexes implements Executable
*/
private function executeLegacy(Server $server)
{
$bulk = new BulkWrite(true);
$bulk = new Bulk(true);
foreach ($this->indexes as $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
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessage Unknown operation type called 'foo' (operation#0)
* @expectedExceptionMessage Unknown operation type "foo" in $operations[0]
*/
public function testUnknownOperation()
{
......@@ -139,7 +139,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @expectedExceptionMessageRegExp /Missing argument#\d+ for '\w+' \(operation#\d+\)/
* @expectedExceptionMessageRegExp /Missing (first|second) argument for \$operations\[\d+\]\["\w+\"]/
* @dataProvider provideOpsWithMissingArguments
*/
public function testMissingArguments(array $ops)
......@@ -164,7 +164,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/**
* @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()
{
......@@ -175,7 +175,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/**
* @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()
{
......@@ -186,7 +186,7 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
/**
* @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()
{
......
This diff is collapsed.
<?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