/cache/stores/mongodb/MongoDB/Operation/FindOneAndReplace.php

https://github.com/markn86/moodle · PHP · 168 lines · 60 code · 17 blank · 91 comment · 11 complexity · 75fd52eaa291ba103052f2ec8b13ce52 MD5 · raw file

  1. <?php
  2. /*
  3. * Copyright 2015-2017 MongoDB, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace MongoDB\Operation;
  18. use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
  19. use MongoDB\Driver\Server;
  20. use MongoDB\Exception\InvalidArgumentException;
  21. use MongoDB\Exception\UnsupportedException;
  22. use function is_array;
  23. use function is_integer;
  24. use function is_object;
  25. use function MongoDB\is_first_key_operator;
  26. /**
  27. * Operation for replacing a document with the findAndModify command.
  28. *
  29. * @api
  30. * @see \MongoDB\Collection::findOneAndReplace()
  31. * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
  32. */
  33. class FindOneAndReplace implements Executable, Explainable
  34. {
  35. const RETURN_DOCUMENT_BEFORE = 1;
  36. const RETURN_DOCUMENT_AFTER = 2;
  37. /** @var FindAndModify */
  38. private $findAndModify;
  39. /**
  40. * Constructs a findAndModify command for replacing a document.
  41. *
  42. * Supported options:
  43. *
  44. * * bypassDocumentValidation (boolean): If true, allows the write to
  45. * circumvent document level validation.
  46. *
  47. * For servers < 3.2, this option is ignored as document level validation
  48. * is not available.
  49. *
  50. * * collation (document): Collation specification.
  51. *
  52. * This is not supported for server versions < 3.4 and will result in an
  53. * exception at execution time if used.
  54. *
  55. * * hint (string|document): The index to use. Specify either the index
  56. * name as a string or the index key pattern as a document. If specified,
  57. * then the query system will only consider plans using the hinted index.
  58. *
  59. * This is not supported for server versions < 4.4 and will result in an
  60. * exception at execution time if used.
  61. *
  62. * * maxTimeMS (integer): The maximum amount of time to allow the query to
  63. * run.
  64. *
  65. * * projection (document): Limits the fields to return for the matching
  66. * document.
  67. *
  68. * * returnDocument (enum): Whether to return the document before or after
  69. * the update is applied. Must be either
  70. * FindOneAndReplace::RETURN_DOCUMENT_BEFORE or
  71. * FindOneAndReplace::RETURN_DOCUMENT_AFTER. The default is
  72. * FindOneAndReplace::RETURN_DOCUMENT_BEFORE.
  73. *
  74. * * session (MongoDB\Driver\Session): Client session.
  75. *
  76. * Sessions are not supported for server versions < 3.6.
  77. *
  78. * * sort (document): Determines which document the operation modifies if
  79. * the query selects multiple documents.
  80. *
  81. * * typeMap (array): Type map for BSON deserialization.
  82. *
  83. * * upsert (boolean): When true, a new document is created if no document
  84. * matches the query. The default is false.
  85. *
  86. * * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
  87. *
  88. * This is not supported for server versions < 3.2 and will result in an
  89. * exception at execution time if used.
  90. *
  91. * @param string $databaseName Database name
  92. * @param string $collectionName Collection name
  93. * @param array|object $filter Query by which to filter documents
  94. * @param array|object $replacement Replacement document
  95. * @param array $options Command options
  96. * @throws InvalidArgumentException for parameter/option parsing errors
  97. */
  98. public function __construct($databaseName, $collectionName, $filter, $replacement, array $options = [])
  99. {
  100. if (! is_array($filter) && ! is_object($filter)) {
  101. throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
  102. }
  103. if (! is_array($replacement) && ! is_object($replacement)) {
  104. throw InvalidArgumentException::invalidType('$replacement', $replacement, 'array or object');
  105. }
  106. if (is_first_key_operator($replacement)) {
  107. throw new InvalidArgumentException('First key in $replacement argument is an update operator');
  108. }
  109. $options += [
  110. 'returnDocument' => self::RETURN_DOCUMENT_BEFORE,
  111. 'upsert' => false,
  112. ];
  113. if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
  114. throw InvalidArgumentException::invalidType('"projection" option', $options['projection'], 'array or object');
  115. }
  116. if (! is_integer($options['returnDocument'])) {
  117. throw InvalidArgumentException::invalidType('"returnDocument" option', $options['returnDocument'], 'integer');
  118. }
  119. if ($options['returnDocument'] !== self::RETURN_DOCUMENT_AFTER &&
  120. $options['returnDocument'] !== self::RETURN_DOCUMENT_BEFORE) {
  121. throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
  122. }
  123. if (isset($options['projection'])) {
  124. $options['fields'] = $options['projection'];
  125. }
  126. $options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;
  127. unset($options['projection'], $options['returnDocument']);
  128. $this->findAndModify = new FindAndModify(
  129. $databaseName,
  130. $collectionName,
  131. ['query' => $filter, 'update' => $replacement] + $options
  132. );
  133. }
  134. /**
  135. * Execute the operation.
  136. *
  137. * @see Executable::execute()
  138. * @param Server $server
  139. * @return array|object|null
  140. * @throws UnsupportedException if collation or write concern is used and unsupported
  141. * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
  142. */
  143. public function execute(Server $server)
  144. {
  145. return $this->findAndModify->execute($server);
  146. }
  147. public function getCommandDocument(Server $server)
  148. {
  149. return $this->findAndModify->getCommandDocument($server);
  150. }
  151. }