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:
env:
global:
- DRIVER_VERSION=1.5.2
- DRIVER_VERSION=1.6.0alpha1
- SERVER_VERSION=4.0.1
- DEPLOYMENT=STANDALONE
......
This diff is collapsed.
......@@ -59,6 +59,16 @@ class UnsupportedException extends RuntimeException
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.
*
......@@ -68,4 +78,14 @@ class UnsupportedException extends RuntimeException
{
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
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']);
$hasOutStage = \MongoDB\is_last_pipeline_operator_out($this->pipeline);
......
......@@ -322,6 +322,11 @@ class BulkWrite implements Executable
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']];
if (
......
......@@ -151,6 +151,11 @@ class Count implements Executable, Explainable
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());
$result = current($cursor->toArray());
......
......@@ -151,6 +151,11 @@ class CountDocuments implements Executable
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());
$allResults = $cursor->toArray();
......
......@@ -139,6 +139,11 @@ class CreateIndexes implements Executable
throw UnsupportedException::writeConcernNotSupported();
}
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$this->executeCommand($server);
return array_map(function(IndexInput $index) { return (string) $index; }, $this->indexes);
......
......@@ -117,6 +117,11 @@ class Delete implements Executable, Explainable
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->delete($this->filter, $this->createDeleteOptions());
......
......@@ -133,6 +133,11 @@ class Distinct implements Executable, Explainable
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());
$result = current($cursor->toArray());
......
......@@ -102,6 +102,11 @@ class DropCollection implements Executable
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]);
try {
......
......@@ -116,6 +116,11 @@ class DropIndexes implements Executable
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());
if (isset($this->options['typeMap'])) {
......
......@@ -114,6 +114,11 @@ class EstimatedDocumentCount implements Executable, Explainable
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());
$result = current($cursor->toArray());
......
......@@ -296,6 +296,11 @@ class Find implements Executable, Explainable
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());
if (isset($this->options['typeMap'])) {
......
......@@ -210,6 +210,11 @@ class FindAndModify implements Executable, Explainable
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());
$result = current($cursor->toArray());
......
......@@ -24,6 +24,7 @@ use MongoDB\Driver\Session;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\UnsupportedException;
/**
* Operation for inserting multiple documents with the insert command.
......@@ -126,6 +127,11 @@ class InsertMany implements Executable
*/
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']];
if (
......
......@@ -24,6 +24,7 @@ use MongoDB\Driver\Session;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\UnsupportedException;
/**
* Operation for inserting a single document with the insert command.
......@@ -104,6 +105,11 @@ class InsertOne implements Executable
{
$options = [];
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if (isset($this->options['writeConcern']) && $inTransaction) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
if (
! empty($this->options['bypassDocumentValidation']) &&
\MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
......
......@@ -248,6 +248,16 @@ class MapReduce implements Executable
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);
$command = $this->createCommand($server);
......
......@@ -167,6 +167,11 @@ class Update implements Executable, Explainable
throw UnsupportedException::collationNotSupported();
}
$inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
if ($inTransaction && isset($this->options['writeConcern'])) {
throw UnsupportedException::writeConcernNotSupportedInTransaction();
}
$bulkOptions = [];
if (
......
......@@ -213,6 +213,11 @@ class Watch implements Executable, /* @internal */ CommandSubscriber
*/
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);
}
......
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