See Release Notes
Long Term Support Release
<?php /*< * Copyright 2015-2017 MongoDB, Inc.> * Copyright 2015-present MongoDB, Inc.* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *< * http://www.apache.org/licenses/LICENSE-2.0> * https://www.apache.org/licenses/LICENSE-2.0* * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace MongoDB\Operation; use MongoDB\Driver\Command; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Server; use MongoDB\Driver\Session; use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException;< use MongoDB\Exception\UnsupportedException;>use function current; use function is_array; use function is_bool; use function is_integer; use function is_object; use function is_string;< use function MongoDB\server_supports_feature;> use function sprintf;use function trigger_error;>use const E_USER_DEPRECATED; /** * Operation for the create command. * * @api * @see \MongoDB\Database::createCollection()< * @see http://docs.mongodb.org/manual/reference/command/create/> * @see https://mongodb.com/docs/manual/reference/command/create/*/ class CreateCollection implements Executable {< const USE_POWER_OF_2_SIZES = 1; < const NO_PADDING = 2; < < /** @var integer */ < private static $wireVersionForCollation = 5; < < /** @var integer */ < private static $wireVersionForWriteConcern = 5;> public const USE_POWER_OF_2_SIZES = 1; > public const NO_PADDING = 2;/** @var string */ private $databaseName; /** @var string */ private $collectionName; /** @var array */ private $options = []; /** * Constructs a create command. * * Supported options: * * * autoIndexId (boolean): Specify false to disable the automatic creation * of an index on the _id field. For replica sets, this option cannot be * false. The default is true. * * This option has been deprecated since MongoDB 3.2. As of MongoDB 4.0, * this option cannot be false when creating a replicated collection * (i.e. a collection outside of the local database in any mongod mode). * * * capped (boolean): Specify true to create a capped collection. If set, * the size option must also be specified. The default is false. *> * * comment (mixed): BSON value to attach as a comment to this command. * * collation (document): Collation specification. > * * > * This is not supported for servers versions < 4.4. * This is not supported for server versions < 3.4 and will result in an > * * exception at execution time if used. > * * changeStreamPreAndPostImages (document): Used to configure support for * > * pre- and post-images in change streams. * * flags (integer): Options for the MMAPv1 storage engine only. Must be a > * * bitwise combination CreateCollection::USE_POWER_OF_2_SIZES and > * This is not supported for server versions < 6.0. * CreateCollection::NO_PADDING. The default is > * * CreateCollection::USE_POWER_OF_2_SIZES. > * * clusteredIndex (document): A clustered index specification. * > * * * indexOptionDefaults (document): Default configuration for indexes when > * This is not supported for server versions < 5.3. * creating the collection. > *< * This is not supported for server versions < 3.4 and will result in an < * exception at execution time if used.> * * encryptedFields (document): CSFLE specification. > * > * * expireAfterSeconds: The TTL for documents in time series collections. > * > * This is not supported for servers versions < 5.0.* collection. The size option takes precedence over this limit. * * * maxTimeMS (integer): The maximum amount of time to allow the query to * run. *< * * session (MongoDB\Driver\Session): Client session.> * * pipeline (array): An array that consists of the aggregation pipeline > * stage(s), which will be applied to the collection or view specified by > * viewOn.*< * Sessions are not supported for server versions < 3.6.> * * session (MongoDB\Driver\Session): Client session.* * * size (integer): The maximum number of bytes for a capped collection. * * * storageEngine (document): Storage engine options. *> * * timeseries (document): Options for time series collections. * * typeMap (array): Type map for BSON deserialization. This will only be > * * used for the returned command result document. > * This is not supported for servers versions < 5.0. * > ** * validationAction (string): Validation action. * * * validationLevel (string): Validation level. * * * validator (document): Validation rules or expressions. *< * * writeConcern (MongoDB\Driver\WriteConcern): Write concern.> * * viewOn (string): The name of the source collection or view from which > * to create the view.*< * This is not supported for server versions < 3.4 and will result in an < * exception at execution time if used.> * * writeConcern (MongoDB\Driver\WriteConcern): Write concern.*< * @see http://source.wiredtiger.com/2.4.1/struct_w_t___s_e_s_s_i_o_n.html#a358ca4141d59c345f401c58501276bbb < * @see https://docs.mongodb.org/manual/core/document-validation/> * @see https://source.wiredtiger.com/2.4.1/struct_w_t___s_e_s_s_i_o_n.html#a358ca4141d59c345f401c58501276bbb > * @see https://mongodb.com/docs/manual/core/schema-validation/* @param string $databaseName Database name * @param string $collectionName Collection name * @param array $options Command options * @throws InvalidArgumentException for parameter/option parsing errors */< public function __construct($databaseName, $collectionName, array $options = [])> public function __construct(string $databaseName, string $collectionName, array $options = []){ if (isset($options['autoIndexId']) && ! is_bool($options['autoIndexId'])) { throw InvalidArgumentException::invalidType('"autoIndexId" option', $options['autoIndexId'], 'boolean'); } if (isset($options['capped']) && ! is_bool($options['capped'])) { throw InvalidArgumentException::invalidType('"capped" option', $options['capped'], 'boolean'); }> if (isset($options['changeStreamPreAndPostImages']) && ! is_array($options['changeStreamPreAndPostImages']) && ! is_object($options['changeStreamPreAndPostImages'])) { if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) { > throw InvalidArgumentException::invalidType('"changeStreamPreAndPostImages" option', $options['changeStreamPreAndPostImages'], 'array or object'); throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object'); > } } > > if (isset($options['clusteredIndex']) && ! is_array($options['clusteredIndex']) && ! is_object($options['clusteredIndex'])) { if (isset($options['flags']) && ! is_integer($options['flags'])) { > throw InvalidArgumentException::invalidType('"clusteredIndex" option', $options['clusteredIndex'], 'array or object'); throw InvalidArgumentException::invalidType('"flags" option', $options['flags'], 'integer'); > } } >> if (isset($options['encryptedFields']) && ! is_array($options['encryptedFields']) && ! is_object($options['encryptedFields'])) { if (isset($options['indexOptionDefaults']) && ! is_array($options['indexOptionDefaults']) && ! is_object($options['indexOptionDefaults'])) { > throw InvalidArgumentException::invalidType('"encryptedFields" option', $options['encryptedFields'], 'array or object'); throw InvalidArgumentException::invalidType('"indexOptionDefaults" option', $options['indexOptionDefaults'], 'array or object'); > } } > > if (isset($options['expireAfterSeconds']) && ! is_integer($options['expireAfterSeconds'])) { if (isset($options['max']) && ! is_integer($options['max'])) { > throw InvalidArgumentException::invalidType('"expireAfterSeconds" option', $options['expireAfterSeconds'], 'integer'); throw InvalidArgumentException::invalidType('"max" option', $options['max'], 'integer'); > } } >if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) { throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer'); }> if (isset($options['pipeline']) && ! is_array($options['pipeline'])) { if (isset($options['session']) && ! $options['session'] instanceof Session) { > throw InvalidArgumentException::invalidType('"pipeline" option', $options['pipeline'], 'array'); throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); > } } >if (isset($options['size']) && ! is_integer($options['size'])) { throw InvalidArgumentException::invalidType('"size" option', $options['size'], 'integer'); } if (isset($options['storageEngine']) && ! is_array($options['storageEngine']) && ! is_object($options['storageEngine'])) { throw InvalidArgumentException::invalidType('"storageEngine" option', $options['storageEngine'], 'array or object'); }> if (isset($options['timeseries']) && ! is_array($options['timeseries']) && ! is_object($options['timeseries'])) { if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { > throw InvalidArgumentException::invalidType('"timeseries" option', $options['timeseries'], ['array', 'object']); throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); > } } >if (isset($options['validationAction']) && ! is_string($options['validationAction'])) { throw InvalidArgumentException::invalidType('"validationAction" option', $options['validationAction'], 'string'); } if (isset($options['validationLevel']) && ! is_string($options['validationLevel'])) { throw InvalidArgumentException::invalidType('"validationLevel" option', $options['validationLevel'], 'string'); } if (isset($options['validator']) && ! is_array($options['validator']) && ! is_object($options['validator'])) { throw InvalidArgumentException::invalidType('"validator" option', $options['validator'], 'array or object'); }> if (isset($options['viewOn']) && ! is_string($options['viewOn'])) { if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { > throw InvalidArgumentException::invalidType('"viewOn" option', $options['viewOn'], 'string'); throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); > } } >if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { unset($options['writeConcern']); } if (isset($options['autoIndexId'])) { trigger_error('The "autoIndexId" option is deprecated and will be removed in a future release', E_USER_DEPRECATED); }< $this->databaseName = (string) $databaseName; < $this->collectionName = (string) $collectionName;> if (isset($options['pipeline'])) { > $expectedIndex = 0; > > foreach ($options['pipeline'] as $i => $operation) { > if ($i !== $expectedIndex) { > throw new InvalidArgumentException(sprintf('The "pipeline" option is not a list (unexpected index: "%s")', $i)); > } > > if (! is_array($operation) && ! is_object($operation)) { > throw InvalidArgumentException::invalidType(sprintf('$options["pipeline"][%d]', $i), $operation, 'array or object'); > } > > $expectedIndex += 1; > } > } > > $this->databaseName = $databaseName; > $this->collectionName = $collectionName;$this->options = $options; } /** * Execute the operation. * * @see Executable::execute()< * @param Server $server* @return array|object Command result document< * @throws UnsupportedException if collation or write concern is used and unsupported* @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ public function execute(Server $server) {< if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) { < throw UnsupportedException::collationNotSupported(); < } < < if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) { < throw UnsupportedException::writeConcernNotSupported(); < } <$cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); if (isset($this->options['typeMap'])) { $cursor->setTypeMap($this->options['typeMap']); } return current($cursor->toArray()); } /** * Create the create command.< * < * @return Command*/< private function createCommand()> private function createCommand(): Command{ $cmd = ['create' => $this->collectionName];< foreach (['autoIndexId', 'capped', 'flags', 'max', 'maxTimeMS', 'size', 'validationAction', 'validationLevel'] as $option) {> foreach (['autoIndexId', 'capped', 'comment', 'expireAfterSeconds', 'flags', 'max', 'maxTimeMS', 'pipeline', 'size', 'validationAction', 'validationLevel', 'viewOn'] as $option) {if (isset($this->options[$option])) { $cmd[$option] = $this->options[$option]; } }< foreach (['collation', 'indexOptionDefaults', 'storageEngine', 'validator'] as $option) {> foreach (['changeStreamPreAndPostImages', 'clusteredIndex', 'collation', 'encryptedFields', 'indexOptionDefaults', 'storageEngine', 'timeseries', 'validator'] as $option) {if (isset($this->options[$option])) { $cmd[$option] = (object) $this->options[$option]; } } return new Command($cmd); } /** * Create options for executing the command. *< * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php < * @return array> * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php*/< private function createOptions()> private function createOptions(): array{ $options = []; if (isset($this->options['session'])) { $options['session'] = $this->options['session']; } if (isset($this->options['writeConcern'])) { $options['writeConcern'] = $this->options['writeConcern']; } return $options; } }