/** * @dataProvider provideTypeMapOptionsAndExpectedDocument */ public function testTypeMapOption(array $typeMap, array $expectedDocuments) { if (!\MongoDB\server_supports_feature($this->getPrimaryServer(), self::$wireVersionForCursor)) { $this->markTestSkipped('Command cursor is not supported'); } $this->createFixtures(3); $pipeline = [['$match' => ['_id' => ['$ne' => 2]]]]; $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, ['typeMap' => $typeMap]); $cursor = $operation->execute($this->getPrimaryServer()); $this->assertEquals($expectedDocuments, $cursor->toArray()); }
/** * Execute the operation. * * For servers < 2.6, this will actually perform an insert operation on the * database's "system.indexes" collection. * * @see Executable::execute() * @param Server $server * @return string[] The names of the created indexes */ public function execute(Server $server) { if (\MongoDB\server_supports_feature($server, self::$wireVersionForCommand)) { $this->executeCommand($server); } else { $this->executeLegacy($server); } return array_map(function (IndexInput $index) { return (string) $index; }, $this->indexes); }
public function testAggregateWithOut() { $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY)); if (!\MongoDB\server_supports_feature($server, self::$wireVersionForOutOperator)) { $this->markTestSkipped('$out aggregation pipeline operator is not supported'); } $outputCollection = new Collection($this->manager, $this->getNamespace() . '_output'); $this->dropCollectionIfItExists($outputCollection); $this->collection->aggregate(array(array('$sort' => array('x' => 1)), array('$match' => array('_id' => array('$gt' => 1))), array('$out' => $outputCollection->getCollectionName()))); $expected = array(array('_id' => 2, 'x' => 22), array('_id' => 3, 'x' => 33)); $this->assertSameDocuments($expected, $outputCollection->find()); // Manually clean up our output collection $this->dropCollectionIfItExists($outputCollection); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return InsertOneResult */ public function execute(Server $server) { $options = []; if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } $bulk = new Bulk($options); $insertedId = $bulk->insert($this->document); if ($insertedId === null) { $insertedId = \MongoDB\extract_id_from_inserted_document($this->document); } $writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null; $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern); return new InsertOneResult($writeResult, $insertedId); }
public function testAggregateWithOut() { $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY)); if (!\MongoDB\server_supports_feature($server, self::$wireVersionForOutOperator)) { $this->markTestSkipped('$out aggregation pipeline operator is not supported'); } $outputCollection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName() . '_output'); $operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName()); $operation->execute($this->getPrimaryServer()); $this->collection->aggregate([['$sort' => ['x' => 1]], ['$match' => ['_id' => ['$gt' => 1]]], ['$out' => $outputCollection->getCollectionName()]]); $expected = [['_id' => 2, 'x' => 22], ['_id' => 3, 'x' => 33]]; $this->assertSameDocuments($expected, $outputCollection->find()); // Manually clean up our output collection $operation = new DropCollection($this->getDatabaseName(), $outputCollection->getCollectionName()); $operation->execute($this->getPrimaryServer()); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return InsertOneResult */ public function execute(Server $server) { $options = []; if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } $bulk = new Bulk($options); $insertedId = $bulk->insert($this->document); if ($insertedId === null) { // TODO: This may be removed if PHPC-382 is implemented $insertedId = is_array($this->document) ? $this->document['_id'] : $this->document->_id; } $writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null; $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern); return new InsertOneResult($writeResult, $insertedId); }
/** * Finds a single document and updates it, returning either the original or * the updated document. * * The document to return may be null. By default, the original document is * returned. Specify FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the * "returnDocument" option to return the updated document. * * Note: BSON deserialization of the returned document does not yet support * a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314). * * @see FindOneAndReplace::__construct() for supported options * @see http://docs.mongodb.org/manual/reference/command/findAndModify/ * @param array|object $filter Query by which to filter documents * @param array|object $update Update to apply to the matched document * @param array $options Command options * @return object|null */ public function findOneAndUpdate($filter, $update, array $options = []) { $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY)); if (!isset($options['writeConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForFindAndModifyWriteConcern)) { $options['writeConcern'] = $this->writeConcern; } $operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options); return $operation->execute($server); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return CollectionInfoIterator */ public function execute(Server $server) { return \MongoDB\server_supports_feature($server, self::$wireVersionForCommand) ? $this->executeCommand($server) : $this->executeLegacy($server); }
public function testCreateConflictingIndexesWithLegacyInsert() { if (\MongoDB\server_supports_feature($this->getPrimaryServer(), self::$wireVersionForCommand)) { $this->markTestSkipped('Index creation does not use legacy insertion'); } $indexes = [['key' => ['x' => 1], 'sparse' => true, 'unique' => false], ['key' => ['x' => 1], 'sparse' => false, 'unique' => true]]; $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes); $createdIndexNames = $operation->execute($this->getPrimaryServer()); /* When creating indexes with legacy insert operations, the server * ignores conflicting index specifications and leaves the original * index in place. */ $this->assertSame('x_1', $createdIndexNames[0]); $this->assertIndexExists('x_1', function (IndexInfo $info) { $this->assertTrue($info->isSparse()); $this->assertFalse($info->isUnique()); $this->assertFalse($info->isTtl()); }); }
/** * Create the aggregate command. * * @param Server $server * @param boolean $isCursorSupported * @return Command */ private function createCommand(Server $server, $isCursorSupported) { $cmd = ['aggregate' => $this->collectionName, 'pipeline' => $this->pipeline]; // Servers < 2.6 do not support any command options if (!$isCursorSupported) { return new Command($cmd); } $cmd['allowDiskUse'] = $this->options['allowDiskUse']; if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } if (isset($this->options['maxTimeMS'])) { $cmd['maxTimeMS'] = $this->options['maxTimeMS']; } if ($this->options['useCursor']) { $cmd['cursor'] = isset($this->options["batchSize"]) ? ['batchSize' => $this->options["batchSize"]] : new stdClass(); } return new Command($cmd); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return BulkWriteResult */ public function execute(Server $server) { $options = ['ordered' => $this->options['ordered']]; if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } $bulk = new Bulk($options); $insertedIds = []; foreach ($this->operations as $i => $operation) { $type = key($operation); $args = current($operation); switch ($type) { case self::DELETE_MANY: case self::DELETE_ONE: $bulk->delete($args[0], $args[1]); break; case self::INSERT_ONE: $insertedId = $bulk->insert($args[0]); if ($insertedId !== null) { $insertedIds[$i] = $insertedId; } else { $insertedIds[$i] = \MongoDB\extract_id_from_inserted_document($args[0]); } break; case self::REPLACE_ONE: case self::UPDATE_MANY: case self::UPDATE_ONE: $bulk->update($args[0], $args[1], $args[2]); } } $writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null; $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern); return new BulkWriteResult($writeResult, $insertedIds); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return Traversable */ public function execute(Server $server) { $isCursorSupported = \MongoDB\server_supports_feature($server, self::$wireVersionForCursor); $command = $this->createCommand($server, $isCursorSupported); $cursor = $server->executeCommand($this->databaseName, $command); if ($isCursorSupported && $this->options['useCursor']) { return $cursor; } $result = current($cursor->toArray()); if (empty($result->ok)) { throw new RuntimeException(isset($result->errmsg) ? $result->errmsg : 'Unknown error'); } if (!isset($result->result) || !is_array($result->result)) { throw new UnexpectedValueException('aggregate command did not return a "result" array'); } return new ArrayIterator($result->result); }
/** * Execute the operation. * * @see Executable::execute() * @param Server $server * @return UpdateResult */ public function execute(Server $server) { $updateOptions = ['multi' => $this->options['multi'], 'upsert' => $this->options['upsert']]; $bulkOptions = []; if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $bulkOptions['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } $bulk = new Bulk($bulkOptions); $bulk->update($this->filter, $this->update, $updateOptions); $writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null; $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $writeConcern); return new UpdateResult($writeResult); }
/** * Create the findAndModify command. * * @param Server $server * @return Command */ private function createCommand(Server $server) { $cmd = ['findAndModify' => $this->collectionName]; if ($this->options['remove']) { $cmd['remove'] = true; } else { $cmd['new'] = $this->options['new']; $cmd['upsert'] = $this->options['upsert']; } foreach (['fields', 'query', 'sort', 'update'] as $option) { if (isset($this->options[$option])) { $cmd[$option] = (object) $this->options[$option]; } } if (isset($this->options['maxTimeMS'])) { $cmd['maxTimeMS'] = $this->options['maxTimeMS']; } if (isset($this->options['bypassDocumentValidation']) && \MongoDB\server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)) { $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; } if (isset($this->options['writeConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForWriteConcern)) { $cmd['writeConcern'] = $this->options['writeConcern']; } return new Command($cmd); }
/** * Create the count command. * * @param Server $server * @return Command */ private function createCommand(Server $server) { $cmd = ['count' => $this->collectionName]; if (!empty($this->filter)) { $cmd['query'] = (object) $this->filter; } foreach (['hint', 'limit', 'maxTimeMS', 'skip'] as $option) { if (isset($this->options[$option])) { $cmd[$option] = $this->options[$option]; } } if (isset($this->options['readConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForReadConcern)) { $cmd['readConcern'] = \MongoDB\read_concern_as_document($this->options['readConcern']); } return new Command($cmd); }
/** * Create the distinct command. * * @param Server $server * @return Command */ private function createCommand(Server $server) { $cmd = ['distinct' => $this->collectionName, 'key' => $this->fieldName]; if (!empty($this->filter)) { $cmd['query'] = (object) $this->filter; } if (isset($this->options['maxTimeMS'])) { $cmd['maxTimeMS'] = $this->options['maxTimeMS']; } if (isset($this->options['readConcern']) && \MongoDB\server_supports_feature($server, self::$wireVersionForReadConcern)) { $cmd['readConcern'] = \MongoDB\read_concern_as_document($this->options['readConcern']); } return new Command($cmd); }