/** * Handle dynamic method calls. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { $start = microtime(true); $result = call_user_func_array([$this->collection, $method], $parameters); if ($this->connection->logging()) { // Once we have run the query we will calculate the time that it took to run and // then log the query, bindings, and execution time so we will report them on // the event that the developer needs them. We'll log time in milliseconds. $time = $this->connection->getElapsedTime($start); $query = []; // Convert the query parameters to a json string. array_walk_recursive($parameters, function (&$item, $key) { if ($item instanceof ObjectID) { $item = (string) $item; } }); // Convert the query parameters to a json string. foreach ($parameters as $parameter) { try { $query[] = json_encode($parameter); } catch (Exception $e) { $query[] = '{...}'; } } $queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')'; $this->connection->logQuery($queryString, [], $time); } return $result; }
/** * Updates a document and returns it. * @param array $condition query condition * @param array $update update criteria * @param array $fields fields to be returned * @param array $options list of options in format: optionName => optionValue. * @return array|null the original document, or the modified document when $options['new'] is set. * @throws Exception on failure. * @see http://www.php.net/manual/en/mongocollection.findandmodify.php */ public function findAndModify($condition, $update, $options = []) { $token = "mongoyii\\" . $this->collection->getCollectionName() . ".findAndModify({\$condition: " . json_encode($condition) . ", \$update: " . json_encode($update) . ", \$options: " . json_encode($options) . " })"; Yii::trace($token, "mongoyii\\Collection"); if ($this->client->enableProfiling) { Yii::beginProfile($token, 'mongoyii\\Collection.findAndModify'); } try { if (isset($options['remove']) && $options['remove']) { $result = $this->collection->findOneAndDelete($condition, $options); } elseif (isset($options['update']) && $options['update']) { if (isset($options['upsert']) && $options['upsert']) { $result = $this->collection->findOneAndReplace($condition, $update, $options); } else { $result = $this->collection->findOneAndUpdate($condition, $update, $options); } } else { throw new Exception('Must enter a operation type for findAndModify'); } if ($this->client->enableProfiling) { Yii::endProfile($token, 'mongoyii\\Collection.findAndModify'); } return $result; } catch (\Exception $e) { if ($this->client->enableProfiling) { Yii::endProfile($token, 'mongoyii\\Collection.findAndModify'); } throw new Exception($e->getMessage(), (int) $e->getCode(), $e); } }
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()); }
/** * Drop the collection if it exists. * * @param Collection $collection */ protected function dropCollectionIfItExists(Collection $collection) { $database = new Database($this->manager, $collection->getDatabaseName()); $collections = $database->listCollections(array('filter' => array('name' => $collection->getCollectionName()))); if (iterator_count($collections) > 0) { $this->assertCommandSucceeded($collection->drop()); } }
/** * Construct accepts actual objects rather than strings as this class is a delegate of * Tripod and should inherit connections set up there * @param string $storeName * @param Collection $collection * @param string $defaultContext * @param \Tripod\ITripodStat|null $stat * @param string $readPreference */ public function __construct($storeName, Collection $collection, $defaultContext, $stat = null, $readPreference = ReadPreference::RP_PRIMARY) { $this->labeller = new Labeller(); $this->storeName = $storeName; $this->collection = $collection; $this->podName = $collection->getCollectionName(); $this->defaultContext = $defaultContext; $this->stat = $stat; $this->readPreference = $readPreference; }
/** * Truncate any indexed fields in the generated rows which are too large to index * * @param Collection $collection * @param array $generatedRow - Pass by reference so that the contents is truncated */ protected function truncateFields(Collection $collection, array &$generatedRow) { // Find the name of any indexed fields $indexedFields = array(); $indexesGroupedByCollection = $this->config->getIndexesGroupedByCollection($this->storeName); if (isset($indexesGroupedByCollection) && isset($indexesGroupedByCollection[$collection->getCollectionName()])) { $indexes = $indexesGroupedByCollection[$collection->getCollectionName()]; if (isset($indexes)) { foreach ($indexes as $repset) { foreach ($repset as $index) { foreach ($index as $indexedFieldname => $v) { if (strpos($indexedFieldname, "value.") === 0) { $indexedFields[] = substr($indexedFieldname, strlen('value.')); } } } } } } if (count($indexedFields) > 0 && isset($generatedRow['value']) && is_array($generatedRow['value'])) { // Iterate over generated rows BY REFERENCE (&) - we are going to modify the contents of $field foreach ($generatedRow as &$field) { foreach ($indexedFields as $indexedFieldname) { // The key will have the index name in the following format added to it. // Adjust the max key size allowed to take it into account. $maxKeySize = 1020 - strlen("value_" . $indexedFieldname . "_1"); if (array_key_exists($indexedFieldname, $field)) { // It's important that we count the number of bytes // in the field - not just the number of characters. // UTF-8 characters can be between 1 and 4 bytes. // // From the strlen documentation: // Attention with utf8: // $foo = "bär"; // strlen($foo) will return 4 and not 3 as expected.. // // So strlen does count the bytes - not the characters. if (is_string($field[$indexedFieldname]) && strlen($field[$indexedFieldname]) > $maxKeySize) { $field[$indexedFieldname] = substr($field[$indexedFieldname], 0, $maxKeySize); } } } } } }
public function getCollectionName() { return $this->_collection->getCollectionName(); }
/** * Serializes this object storing the collection name instead of the actual * MongoDb\Collection (which is unserializable). * * @return string Serialized object. */ public function serialize() { $properties = get_object_vars($this); $properties['collection'] = $this->collection->getCollectionName(); return serialize($properties); }