Commit b1bc3c88 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-125: Support bypassDocumentValidation option on write commands

parent 4327715e
......@@ -22,6 +22,7 @@ use Traversable;
class Aggregate implements Executable
{
private static $wireVersionForCursor = 2;
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
......@@ -39,6 +40,13 @@ class Aggregate implements Executable
*
* * batchSize (integer): The number of documents to return per batch.
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation. This only applies when the $out
* stage is specified.
*
* For servers < 3.2, this option is ignored as document level validation
* is not available.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
......@@ -92,6 +100,10 @@ class Aggregate implements Executable
throw new InvalidArgumentTypeException('"batchSize" option', $options['batchSize'], 'integer');
}
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
throw new InvalidArgumentTypeException('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
}
......@@ -163,6 +175,10 @@ class Aggregate implements Executable
$cmd['allowDiskUse'] = $this->options['allowDiskUse'];
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
if (isset($this->options['maxTimeMS'])) {
$cmd['maxTimeMS'] = $this->options['maxTimeMS'];
}
......
......@@ -24,6 +24,8 @@ class BulkWrite implements Executable
const UPDATE_MANY = 'updateMany';
const UPDATE_ONE = 'updateOne';
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
private $operations;
......@@ -54,6 +56,9 @@ class BulkWrite implements Executable
*
* Supported options for the bulk write operation:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * 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.
......@@ -182,6 +187,10 @@ class BulkWrite implements Executable
$options += ['ordered' => true];
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if ( ! is_bool($options['ordered'])) {
throw new InvalidArgumentTypeException('"ordered" option', $options['ordered'], 'boolean');
}
......@@ -205,7 +214,13 @@ class BulkWrite implements Executable
*/
public function execute(Server $server)
{
$bulk = new Bulk(['ordered' => $this->options['ordered']]);
$options = ['ordered' => $this->options['ordered']];
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
$bulk = new Bulk($options);
$insertedIds = [];
foreach ($this->operations as $i => $operation) {
......
......@@ -19,6 +19,8 @@ use MongoDB\Exception\UnexpectedValueException;
*/
class FindAndModify implements Executable
{
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
private $options;
......@@ -28,6 +30,9 @@ class FindAndModify implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * fields (document): Limits the fields to return for the matching
* document.
*
......@@ -66,6 +71,10 @@ class FindAndModify implements Executable
'upsert' => false,
];
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if (isset($options['fields']) && ! is_array($options['fields']) && ! is_object($options['fields'])) {
throw new InvalidArgumentTypeException('"fields" option', $options['fields'], 'array or object');
}
......@@ -116,7 +125,7 @@ class FindAndModify implements Executable
*/
public function execute(Server $server)
{
$cursor = $server->executeCommand($this->databaseName, $this->createCommand());
$cursor = $server->executeCommand($this->databaseName, $this->createCommand($server));
$result = current($cursor->toArray());
if ( ! isset($result->value)) {
......@@ -144,9 +153,10 @@ class FindAndModify implements Executable
/**
* Create the findAndModify command.
*
* @param Server $server
* @return Command
*/
private function createCommand()
private function createCommand(Server $server)
{
$cmd = ['findAndModify' => $this->collectionName];
......@@ -167,6 +177,10 @@ class FindAndModify implements Executable
$cmd['maxTimeMS'] = $this->options['maxTimeMS'];
}
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
return new Command($cmd);
}
}
......@@ -26,6 +26,9 @@ class FindOneAndReplace implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
......
......@@ -26,6 +26,9 @@ class FindOneAndUpdate implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
......
......@@ -18,6 +18,8 @@ use MongoDB\Exception\InvalidArgumentTypeException;
*/
class InsertMany implements Executable
{
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
private $documents;
......@@ -28,6 +30,9 @@ class InsertMany implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * 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.
......@@ -62,6 +67,10 @@ class InsertMany implements Executable
$options += ['ordered' => true];
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if ( ! is_bool($options['ordered'])) {
throw new InvalidArgumentTypeException('"ordered" option', $options['ordered'], 'boolean');
}
......@@ -85,7 +94,13 @@ class InsertMany implements Executable
*/
public function execute(Server $server)
{
$bulk = new Bulk(['ordered' => $this->options['ordered']]);
$options = ['ordered' => $this->options['ordered']];
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
$bulk = new Bulk($options);
$insertedIds = [];
foreach ($this->documents as $i => $document) {
......
......@@ -17,6 +17,8 @@ use MongoDB\Exception\InvalidArgumentTypeException;
*/
class InsertOne implements Executable
{
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
private $document;
......@@ -27,6 +29,9 @@ class InsertOne implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
*
* @param string $databaseName Database name
......@@ -41,6 +46,10 @@ class InsertOne implements Executable
throw new InvalidArgumentTypeException('$document', $document, 'array or object');
}
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
}
......@@ -60,7 +69,13 @@ class InsertOne implements Executable
*/
public function execute(Server $server)
{
$bulk = new Bulk();
$options = [];
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
$bulk = new Bulk($options);
$insertedId = $bulk->insert($this->document);
if ($insertedId === null) {
......
......@@ -23,6 +23,9 @@ class ReplaceOne implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
......
......@@ -20,6 +20,8 @@ use MongoDB\Exception\InvalidArgumentTypeException;
*/
class Update implements Executable
{
private static $wireVersionForDocumentLevelValidation = 4;
private $databaseName;
private $collectionName;
private $filter;
......@@ -31,6 +33,9 @@ class Update implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * 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.
......@@ -63,6 +68,10 @@ class Update implements Executable
'upsert' => false,
];
if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
throw new InvalidArgumentTypeException('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
}
if ( ! is_bool($options['multi'])) {
throw new InvalidArgumentTypeException('"multi" option', $options['multi'], 'boolean');
}
......@@ -95,13 +104,19 @@ class Update implements Executable
*/
public function execute(Server $server)
{
$options = [
$updateOptions = [
'multi' => $this->options['multi'],
'upsert' => $this->options['upsert'],
];
$bulk = new Bulk();
$bulk->update($this->filter, $this->update, $options);
$bulkOptions = [];
if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) {
$bulkOptions['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
}
$bulk = new Bulk($bulkOptions);
$bulk->update($this->filter, $this->update, $updateOptions);
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
$writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern);
......
......@@ -23,6 +23,9 @@ class UpdateMany implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
......
......@@ -23,6 +23,9 @@ class UpdateOne implements Executable
*
* Supported options:
*
* * bypassDocumentValidation (boolean): If true, allows the write to opt
* out of document level validation.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
......
......@@ -45,6 +45,10 @@ class AggregateTest extends TestCase
$options[][] = ['batchSize' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidIntegerValues() as $value) {
$options[][] = ['maxTimeMS' => $value];
}
......
......@@ -350,6 +350,10 @@ class BulkWriteTest extends TestCase
{
$options = [];
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['ordered' => $value];
}
......
......@@ -19,6 +19,10 @@ class FindAndModifyTest extends TestCase
{
$options = [];
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['fields' => $value];
}
......
......@@ -47,6 +47,10 @@ class InsertManyTest extends TestCase
{
$options = [];
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['ordered' => $value];
}
......
......@@ -28,6 +28,10 @@ class InsertOneTest extends TestCase
{
$options = [];
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidWriteConcernValues() as $value) {
$options[][] = ['writeConcern' => $value];
}
......
......@@ -39,6 +39,10 @@ class UpdateTest extends TestCase
{
$options = [];
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['bypassDocumentValidation' => $value];
}
foreach ($this->getInvalidBooleanValues() as $value) {
$options[][] = ['multi' => $value];
}
......
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