Commit 39f59b20 authored by Derick Rethans's avatar Derick Rethans

PHPLIB-368: Operations executed within transaction should not inherit read/write concern

parent 6ecf84a8
...@@ -15,7 +15,7 @@ cache: ...@@ -15,7 +15,7 @@ cache:
env: env:
global: global:
- DRIVER_VERSION=1.5.2 - DRIVER_VERSION=1.6.0alpha1
- SERVER_VERSION=4.0.1 - SERVER_VERSION=4.0.1
- DEPLOYMENT=STANDALONE - DEPLOYMENT=STANDALONE
......
This diff is collapsed.
...@@ -59,6 +59,16 @@ class UnsupportedException extends RuntimeException ...@@ -59,6 +59,16 @@ class UnsupportedException extends RuntimeException
return new static('Read concern is not supported by the server executing this command'); return new static('Read concern is not supported by the server executing this command');
} }
/**
* Thrown when a readConcern is used with a read operation in a transaction.
*
* @return self
*/
public static function readConcernNotSupportedInTransaction()
{
return new static('The "readConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.');
}
/** /**
* Thrown when a command's writeConcern option is not supported by a server. * Thrown when a command's writeConcern option is not supported by a server.
* *
...@@ -68,4 +78,14 @@ class UnsupportedException extends RuntimeException ...@@ -68,4 +78,14 @@ class UnsupportedException extends RuntimeException
{ {
return new static('Write concern is not supported by the server executing this command'); return new static('Write concern is not supported by the server executing this command');
} }
/**
* Thrown when a writeConcern is used with a write operation in a transaction.
*
* @return self
*/
public static function writeConcernNotSupportedInTransaction()
{
return new static('The "writeConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.');
}
} }
...@@ -252,6 +252,17 @@ class Aggregate implements Executable ...@@ -252,6 +252,17 @@ class Aggregate implements Executable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction) {
if (isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
if (isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
}
$hasExplain = ! empty($this->options['explain']); $hasExplain = ! empty($this->options['explain']);
$hasOutStage = \MongoDB\is_last_pipeline_operator_out($this->pipeline); $hasOutStage = \MongoDB\is_last_pipeline_operator_out($this->pipeline);
......
...@@ -322,6 +322,11 @@ class BulkWrite implements Executable ...@@ -322,6 +322,11 @@ class BulkWrite implements Executable
throw UnsupportedException::collationNotSupported(); throw UnsupportedException::collationNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$options = ['ordered' => $this->options['ordered']]; $options = ['ordered' => $this->options['ordered']];
if ( if (
......
...@@ -151,6 +151,11 @@ class Count implements Executable, Explainable ...@@ -151,6 +151,11 @@ class Count implements Executable, Explainable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
$cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
$result = current($cursor->toArray()); $result = current($cursor->toArray());
......
...@@ -151,6 +151,11 @@ class CountDocuments implements Executable ...@@ -151,6 +151,11 @@ class CountDocuments implements Executable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
$cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
$allResults = $cursor->toArray(); $allResults = $cursor->toArray();
......
...@@ -139,6 +139,11 @@ class CreateIndexes implements Executable ...@@ -139,6 +139,11 @@ class CreateIndexes implements Executable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$this->executeCommand($server); $this->executeCommand($server);
return array_map(function(IndexInput $index) { return (string) $index; }, $this->indexes); return array_map(function(IndexInput $index) { return (string) $index; }, $this->indexes);
......
...@@ -117,6 +117,11 @@ class Delete implements Executable, Explainable ...@@ -117,6 +117,11 @@ class Delete implements Executable, Explainable
throw UnsupportedException::collationNotSupported(); throw UnsupportedException::collationNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$bulk = new Bulk(); $bulk = new Bulk();
$bulk->delete($this->filter, $this->createDeleteOptions()); $bulk->delete($this->filter, $this->createDeleteOptions());
......
...@@ -133,6 +133,11 @@ class Distinct implements Executable, Explainable ...@@ -133,6 +133,11 @@ class Distinct implements Executable, Explainable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
$cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
$result = current($cursor->toArray()); $result = current($cursor->toArray());
......
...@@ -102,6 +102,11 @@ class DropCollection implements Executable ...@@ -102,6 +102,11 @@ class DropCollection implements Executable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$command = new Command(['drop' => $this->collectionName]); $command = new Command(['drop' => $this->collectionName]);
try { try {
......
...@@ -116,6 +116,11 @@ class DropIndexes implements Executable ...@@ -116,6 +116,11 @@ class DropIndexes implements Executable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions());
if (isset($this->options['typeMap'])) { if (isset($this->options['typeMap'])) {
......
...@@ -114,6 +114,11 @@ class EstimatedDocumentCount implements Executable, Explainable ...@@ -114,6 +114,11 @@ class EstimatedDocumentCount implements Executable, Explainable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
$cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
$result = current($cursor->toArray()); $result = current($cursor->toArray());
......
...@@ -296,6 +296,11 @@ class Find implements Executable, Explainable ...@@ -296,6 +296,11 @@ class Find implements Executable, Explainable
throw UnsupportedException::readConcernNotSupported(); throw UnsupportedException::readConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
$cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createQueryOptions()), $this->createExecuteOptions()); $cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createQueryOptions()), $this->createExecuteOptions());
if (isset($this->options['typeMap'])) { if (isset($this->options['typeMap'])) {
......
...@@ -210,6 +210,11 @@ class FindAndModify implements Executable, Explainable ...@@ -210,6 +210,11 @@ class FindAndModify implements Executable, Explainable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$cursor = $server->executeWriteCommand($this->databaseName, new Command($this->createCommandDocument($server)), $this->createOptions()); $cursor = $server->executeWriteCommand($this->databaseName, new Command($this->createCommandDocument($server)), $this->createOptions());
$result = current($cursor->toArray()); $result = current($cursor->toArray());
......
...@@ -24,6 +24,7 @@ use MongoDB\Driver\Session; ...@@ -24,6 +24,7 @@ use MongoDB\Driver\Session;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\UnsupportedException;
/** /**
* Operation for inserting multiple documents with the insert command. * Operation for inserting multiple documents with the insert command.
...@@ -126,6 +127,11 @@ class InsertMany implements Executable ...@@ -126,6 +127,11 @@ class InsertMany implements Executable
*/ */
public function execute(Server $server) public function execute(Server $server)
{ {
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$options = ['ordered' => $this->options['ordered']]; $options = ['ordered' => $this->options['ordered']];
if ( if (
......
...@@ -24,6 +24,7 @@ use MongoDB\Driver\Session; ...@@ -24,6 +24,7 @@ use MongoDB\Driver\Session;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\UnsupportedException;
/** /**
* Operation for inserting a single document with the insert command. * Operation for inserting a single document with the insert command.
...@@ -104,6 +105,11 @@ class InsertOne implements Executable ...@@ -104,6 +105,11 @@ class InsertOne implements Executable
{ {
$options = []; $options = [];
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if (isset($this->options['writeConcern']) && $inTransaction) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
if ( if (
! empty($this->options['bypassDocumentValidation']) && ! empty($this->options['bypassDocumentValidation']) &&
\MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation) \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
......
...@@ -248,6 +248,16 @@ class MapReduce implements Executable ...@@ -248,6 +248,16 @@ class MapReduce implements Executable
throw UnsupportedException::writeConcernNotSupported(); throw UnsupportedException::writeConcernNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction) {
if (isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
if (isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
}
$hasOutputCollection = ! \MongoDB\is_mapreduce_output_inline($this->out); $hasOutputCollection = ! \MongoDB\is_mapreduce_output_inline($this->out);
$command = $this->createCommand($server); $command = $this->createCommand($server);
......
...@@ -167,6 +167,11 @@ class Update implements Executable, Explainable ...@@ -167,6 +167,11 @@ class Update implements Executable, Explainable
throw UnsupportedException::collationNotSupported(); throw UnsupportedException::collationNotSupported();
} }
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$bulkOptions = []; $bulkOptions = [];
if ( if (
......
...@@ -213,6 +213,11 @@ class Watch implements Executable, /* @internal */ CommandSubscriber ...@@ -213,6 +213,11 @@ class Watch implements Executable, /* @internal */ CommandSubscriber
*/ */
public function execute(Server $server) public function execute(Server $server)
{ {
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['readConcern'])) {
throw UnsupportedException::readConcernNotSupportedInTransaction();
}
return new ChangeStream($this->executeAggregate($server), $this->resumeCallable); return new ChangeStream($this->executeAggregate($server), $this->resumeCallable);
} }
......
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