Differences Between: [Versions 310 and 400] [Versions 39 and 400] [Versions 400 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\Driver\Command; 21 use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; 22 use MongoDB\Driver\Server; 23 use MongoDB\Driver\Session; 24 use MongoDB\Driver\WriteConcern; 25 use MongoDB\Exception\InvalidArgumentException; 26 use MongoDB\Exception\UnsupportedException; 27 use MongoDB\Model\IndexInput; 28 use function array_map; 29 use function is_array; 30 use function is_integer; 31 use function is_string; 32 use function MongoDB\server_supports_feature; 33 use function sprintf; 34 35 /** 36 * Operation for the createIndexes command. 37 * 38 * @api 39 * @see \MongoDB\Collection::createIndex() 40 * @see \MongoDB\Collection::createIndexes() 41 * @see http://docs.mongodb.org/manual/reference/command/createIndexes/ 42 */ 43 class CreateIndexes implements Executable 44 { 45 /** @var integer */ 46 private static $wireVersionForCollation = 5; 47 48 /** @var integer */ 49 private static $wireVersionForWriteConcern = 5; 50 51 /** @var integer */ 52 private static $wireVersionForCommitQuorum = 9; 53 54 /** @var string */ 55 private $databaseName; 56 57 /** @var string */ 58 private $collectionName; 59 60 /** @var array */ 61 private $indexes = []; 62 63 /** @var boolean */ 64 private $isCollationUsed = false; 65 66 /** @var array */ 67 private $options = []; 68 69 /** 70 * Constructs a createIndexes command. 71 * 72 * Supported options: 73 * 74 * * commitQuorum (integer|string): Specifies how many data-bearing members 75 * of a replica set, including the primary, must complete the index 76 * builds successfully before the primary marks the indexes as ready. 77 * 78 * * maxTimeMS (integer): The maximum amount of time to allow the query to 79 * run. 80 * 81 * * session (MongoDB\Driver\Session): Client session. 82 * 83 * Sessions are not supported for server versions < 3.6. 84 * 85 * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. 86 * 87 * This is not supported for server versions < 3.4 and will result in an 88 * exception at execution time if used. 89 * 90 * @param string $databaseName Database name 91 * @param string $collectionName Collection name 92 * @param array[] $indexes List of index specifications 93 * @param array $options Command options 94 * @throws InvalidArgumentException for parameter/option parsing errors 95 */ 96 public function __construct($databaseName, $collectionName, array $indexes, array $options = []) 97 { 98 if (empty($indexes)) { 99 throw new InvalidArgumentException('$indexes is empty'); 100 } 101 102 $expectedIndex = 0; 103 104 foreach ($indexes as $i => $index) { 105 if ($i !== $expectedIndex) { 106 throw new InvalidArgumentException(sprintf('$indexes is not a list (unexpected index: "%s")', $i)); 107 } 108 109 if (! is_array($index)) { 110 throw InvalidArgumentException::invalidType(sprintf('$index[%d]', $i), $index, 'array'); 111 } 112 113 if (isset($index['collation'])) { 114 $this->isCollationUsed = true; 115 } 116 117 $this->indexes[] = new IndexInput($index); 118 119 $expectedIndex += 1; 120 } 121 122 if (isset($options['commitQuorum']) && ! is_string($options['commitQuorum']) && ! is_integer($options['commitQuorum'])) { 123 throw InvalidArgumentException::invalidType('"commitQuorum" option', $options['commitQuorum'], ['integer', 'string']); 124 } 125 126 if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) { 127 throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer'); 128 } 129 130 if (isset($options['session']) && ! $options['session'] instanceof Session) { 131 throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); 132 } 133 134 if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { 135 throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); 136 } 137 138 if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { 139 unset($options['writeConcern']); 140 } 141 142 $this->databaseName = (string) $databaseName; 143 $this->collectionName = (string) $collectionName; 144 $this->options = $options; 145 } 146 147 /** 148 * Execute the operation. 149 * 150 * @see Executable::execute() 151 * @param Server $server 152 * @return string[] The names of the created indexes 153 * @throws UnsupportedException if collation or write concern is used and unsupported 154 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 155 */ 156 public function execute(Server $server) 157 { 158 if ($this->isCollationUsed && ! server_supports_feature($server, self::$wireVersionForCollation)) { 159 throw UnsupportedException::collationNotSupported(); 160 } 161 162 if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) { 163 throw UnsupportedException::writeConcernNotSupported(); 164 } 165 166 $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); 167 if ($inTransaction && isset($this->options['writeConcern'])) { 168 throw UnsupportedException::writeConcernNotSupportedInTransaction(); 169 } 170 171 $this->executeCommand($server); 172 173 return array_map(function (IndexInput $index) { 174 return (string) $index; 175 }, $this->indexes); 176 } 177 178 /** 179 * Create options for executing the command. 180 * 181 * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php 182 * @return array 183 */ 184 private function createOptions() 185 { 186 $options = []; 187 188 if (isset($this->options['session'])) { 189 $options['session'] = $this->options['session']; 190 } 191 192 if (isset($this->options['writeConcern'])) { 193 $options['writeConcern'] = $this->options['writeConcern']; 194 } 195 196 return $options; 197 } 198 199 /** 200 * Create one or more indexes for the collection using the createIndexes 201 * command. 202 * 203 * @param Server $server 204 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 205 */ 206 private function executeCommand(Server $server) 207 { 208 $cmd = [ 209 'createIndexes' => $this->collectionName, 210 'indexes' => $this->indexes, 211 ]; 212 213 if (isset($this->options['commitQuorum'])) { 214 /* Drivers MUST manually raise an error if this option is specified 215 * when creating an index on a pre 4.4 server. */ 216 if (! server_supports_feature($server, self::$wireVersionForCommitQuorum)) { 217 throw UnsupportedException::commitQuorumNotSupported(); 218 } 219 220 $cmd['commitQuorum'] = $this->options['commitQuorum']; 221 } 222 223 if (isset($this->options['maxTimeMS'])) { 224 $cmd['maxTimeMS'] = $this->options['maxTimeMS']; 225 } 226 227 $server->executeWriteCommand($this->databaseName, new Command($cmd), $this->createOptions()); 228 } 229 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body