Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401]

   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  
  18  namespace MongoDB\Operation;
  19  
  20  use MongoDB\DeleteResult;
  21  use MongoDB\Driver\BulkWrite as Bulk;
  22  use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
  23  use MongoDB\Driver\Server;
  24  use MongoDB\Driver\Session;
  25  use MongoDB\Driver\WriteConcern;
  26  use MongoDB\Exception\InvalidArgumentException;
  27  use MongoDB\Exception\UnsupportedException;
  28  use function is_array;
  29  use function is_object;
  30  use function MongoDB\server_supports_feature;
  31  
  32  /**
  33   * Operation for the delete command.
  34   *
  35   * This class is used internally by the DeleteMany and DeleteOne operation
  36   * classes.
  37   *
  38   * @internal
  39   * @see http://docs.mongodb.org/manual/reference/command/delete/
  40   */
  41  class Delete implements Executable, Explainable
  42  {
  43      /** @var integer */
  44      private static $wireVersionForCollation = 5;
  45  
  46      /** @var string */
  47      private $databaseName;
  48  
  49      /** @var string */
  50      private $collectionName;
  51  
  52      /** @var array|object */
  53      private $filter;
  54  
  55      /** @var integer */
  56      private $limit;
  57  
  58      /** @var array */
  59      private $options;
  60  
  61      /**
  62       * Constructs a delete command.
  63       *
  64       * Supported options:
  65       *
  66       *  * collation (document): Collation specification.
  67       *
  68       *    This is not supported for server versions < 3.4 and will result in an
  69       *    exception at execution time if used.
  70       *
  71       *  * session (MongoDB\Driver\Session): Client session.
  72       *
  73       *    Sessions are not supported for server versions < 3.6.
  74       *
  75       *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
  76       *
  77       * @param string       $databaseName   Database name
  78       * @param string       $collectionName Collection name
  79       * @param array|object $filter         Query by which to delete documents
  80       * @param integer      $limit          The number of matching documents to
  81       *                                     delete. Must be 0 or 1, for all or a
  82       *                                     single document, respectively.
  83       * @param array        $options        Command options
  84       * @throws InvalidArgumentException for parameter/option parsing errors
  85       */
  86      public function __construct($databaseName, $collectionName, $filter, $limit, array $options = [])
  87      {
  88          if (! is_array($filter) && ! is_object($filter)) {
  89              throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
  90          }
  91  
  92          if ($limit !== 0 && $limit !== 1) {
  93              throw new InvalidArgumentException('$limit must be 0 or 1');
  94          }
  95  
  96          if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
  97              throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
  98          }
  99  
 100          if (isset($options['session']) && ! $options['session'] instanceof Session) {
 101              throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
 102          }
 103  
 104          if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
 105              throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
 106          }
 107  
 108          if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
 109              unset($options['writeConcern']);
 110          }
 111  
 112          $this->databaseName = (string) $databaseName;
 113          $this->collectionName = (string) $collectionName;
 114          $this->filter = $filter;
 115          $this->limit = $limit;
 116          $this->options = $options;
 117      }
 118  
 119      /**
 120       * Execute the operation.
 121       *
 122       * @see Executable::execute()
 123       * @param Server $server
 124       * @return DeleteResult
 125       * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
 126       */
 127      public function execute(Server $server)
 128      {
 129          if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
 130              throw UnsupportedException::collationNotSupported();
 131          }
 132  
 133          $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
 134          if ($inTransaction && isset($this->options['writeConcern'])) {
 135              throw UnsupportedException::writeConcernNotSupportedInTransaction();
 136          }
 137  
 138          $bulk = new Bulk();
 139          $bulk->delete($this->filter, $this->createDeleteOptions());
 140  
 141          $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions());
 142  
 143          return new DeleteResult($writeResult);
 144      }
 145  
 146      public function getCommandDocument(Server $server)
 147      {
 148          $cmd = ['delete' => $this->collectionName, 'deletes' => [['q' => $this->filter] + $this->createDeleteOptions()]];
 149  
 150          if (isset($this->options['writeConcern'])) {
 151              $cmd['writeConcern'] = $this->options['writeConcern'];
 152          }
 153  
 154          return $cmd;
 155      }
 156  
 157      /**
 158       * Create options for the delete command.
 159       *
 160       * Note that these options are different from the bulk write options, which
 161       * are created in createExecuteOptions().
 162       *
 163       * @return array
 164       */
 165      private function createDeleteOptions()
 166      {
 167          $deleteOptions = ['limit' => $this->limit];
 168  
 169          if (isset($this->options['collation'])) {
 170              $deleteOptions['collation'] = (object) $this->options['collation'];
 171          }
 172  
 173          return $deleteOptions;
 174      }
 175  
 176      /**
 177       * Create options for executing the bulk write.
 178       *
 179       * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
 180       * @return array
 181       */
 182      private function createExecuteOptions()
 183      {
 184          $options = [];
 185  
 186          if (isset($this->options['session'])) {
 187              $options['session'] = $this->options['session'];
 188          }
 189  
 190          if (isset($this->options['writeConcern'])) {
 191              $options['writeConcern'] = $this->options['writeConcern'];
 192          }
 193  
 194          return $options;
 195      }
 196  }