Ejemplo n.º 1
2
 public function insert(array $data)
 {
     $result = $this->collection->insertOne($data);
     $id = (string) $result->getInsertedId();
     $data['id'] = $id;
     return $data;
 }
Ejemplo n.º 2
0
 /**
  * @param QueryInterface $query
  * @param ModelInterface $model
  * @return ModelListInterface
  * @throws NotSupportedFilterException
  */
 public function find(QueryInterface $query, ModelInterface $model)
 {
     $queryArray = array();
     foreach ($query->getFilters() as $filter) {
         if (!in_array(get_class($filter), self::$supportedFilters)) {
             throw new NotSupportedFilterException(sprintf('%s filter is not supported or unknown.', get_class($filter)));
         }
         $queryArray[$filter->getFieldName()] = $filter->getValue();
     }
     $options = array();
     if ($query->getLimit() !== null) {
         $options['limit'] = $query->getLimit();
     }
     if ($query->getOffset() !== null) {
         $options['skip'] = $query->getOffset();
     }
     $list = new ModelList();
     $cursor = $this->collection->find($queryArray, $options);
     /** @var \MongoDB\Model\BSONDocument $doc */
     foreach ($cursor as $doc) {
         $docArray = (array) $doc;
         unset($docArray['_id']);
         /** @var ModelInterface $item */
         $item = new $model();
         $item->loadData($docArray);
         if ($item instanceof SavableModelInterface) {
             $item->markAsStored();
         }
         $list->addListItem($item);
     }
     return $list;
 }
Ejemplo n.º 3
0
 /**
  * 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;
 }
 /**
  * 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());
     }
 }
Ejemplo n.º 5
0
 /**
  * @param string $sagaType
  * @param array $associationValue
  * @return string[]
  */
 public function find(string $sagaType, array $associationValue) : array
 {
     $sagas = $this->collection->find(['type' => $sagaType, 'associations' => $associationValue]);
     return array_map(function (BSONDocument $sagaData) : string {
         $sagaDataArray = $sagaData->getArrayCopy();
         return $sagaDataArray['identity'];
     }, $sagas->toArray());
 }
Ejemplo n.º 6
0
 public function createIndexes()
 {
     try {
         $this->collection->dropIndexes();
     } catch (RuntimeException $e) {
     }
     $this->collection->createIndex(['timestamp' => 1], ['expireAfterSeconds' => 302]);
     $this->collection->createIndex(['sessionId' => 1], ['unique' => false]);
 }
Ejemplo n.º 7
0
 /**
  * {@inheritdoc}
  */
 public function purge()
 {
     if ($this->collection instanceof \MongoDB\Collection) {
         $this->collection->deleteMany(['expiration' => ['$lte' => time()]]);
     } else {
         $this->collection->remove(['expiration' => ['$lte' => time()]], ['multiple' => true]);
     }
     return true;
 }
 public function tearDown()
 {
     foreach (['fs.files', 'fs.chunks'] as $collection) {
         $col = new Collection($this->manager, $this->getDatabaseName(), $collection);
         $col->drop();
     }
     if ($this->hasFailed()) {
         return;
     }
 }
Ejemplo n.º 9
0
 /**
  * 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;
 }
Ejemplo n.º 10
0
 /**
  * Persists participation in MongoDB
  *
  * @param string $userIdentifier Web user unique identification
  * @param string $scenarioIdentifier Scenario where tests has been executed (ie. url)
  *
  * @return boolean
  */
 public function store($userIdentifier, $scenarioIdentifier)
 {
     if (empty($this->participations)) {
         return false;
     }
     $documents = [];
     $uniqueRunIdentifier = uniqid('', true);
     foreach ($this->participations as $testIdentifier => $variantIdentifier) {
         $document = ['testIdentifier' => $testIdentifier, 'variantIdentifier' => $variantIdentifier, 'userIdentifier' => $userIdentifier, 'scenarioIdentifier' => $scenarioIdentifier, 'runIdentifier' => $uniqueRunIdentifier, 'createdAt' => new \MongoDB\BSON\UTCDatetime(time() * 1000)];
         $documents[] = ['insertOne' => [$document]];
     }
     $result = $this->collection->bulkWrite($documents);
     return $result->getInsertedCount();
 }
Ejemplo n.º 11
0
 /**
  * Ensure index of correct specification and a unique name whether the specification or name already exist or not.
  * Will not create index if $index is a prefix of an existing index
  *
  * @param array $index index to create in same format as \MongoDB\Collection::createIndex()
  *
  * @return void
  *
  * @throws \Exception couldnt create index after 5 attempts
  */
 private function ensureIndex(array $index)
 {
     //if $index is a prefix of any existing index we are good
     foreach ($this->collection->listIndexes() as $existingIndex) {
         $slice = array_slice($existingIndex['key'], 0, count($index), true);
         if ($slice === $index) {
             return;
         }
     }
     for ($i = 0; $i < 5; ++$i) {
         for ($name = uniqid(); strlen($name) > 0; $name = substr($name, 0, -1)) {
             //creating an index with same name and different spec does nothing.
             //creating an index with same spec and different name does nothing.
             //so we use any generated name, and then find the right spec after we have called,
             //and just go with that name.
             try {
                 $this->collection->createIndex($index, ['name' => $name, 'background' => true]);
             } catch (\MongoDB\Exception\Exception $e) {
                 //this happens when the name was too long, let continue
             }
             foreach ($this->collection->listIndexes() as $existingIndex) {
                 if ($existingIndex['key'] === $index) {
                     return;
                 }
             }
         }
     }
     throw new \Exception('couldnt create index after 5 attempts');
     //@codeCoverageIgnoreEnd
 }
Ejemplo n.º 12
0
 /**
  * Retrieve the cached results of the api $request.
  *
  * @param RequestInterface $request A request for which the response may be cached.
  *
  * @return ResponseInterface|null
  */
 public function get(RequestInterface $request)
 {
     $cached = $this->collection->findOne(['_id' => $request->getUrl()]);
     if ($cached === null) {
         return null;
     }
     $headers = $cached['headers'];
     if ($headers instanceof BSONArray) {
         $headers = $headers->getArrayCopy();
     }
     $body = $cached['body'];
     if ($body instanceof BSONArray) {
         $body = $body->getArrayCopy();
     }
     return new Response($cached['httpCode'], $headers, $body);
 }
 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());
 }
Ejemplo n.º 14
0
 /**
  * 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);
     }
 }
Ejemplo n.º 15
0
 public function fetch(CriteriaManager $criteriaManager, Collection $collection) : array
 {
     $order = 1;
     $filter = [];
     $options = ['limit' => self::DEFAULT_LIMIT];
     $criteriaManager->doWith(SortCriteria::class, function (SortCriteria $criteria) use(&$options, &$order) {
         $order = strtolower($criteria->getOrder()) === 'asc' ? 1 : -1;
         $options['sort'] = [];
         $options['sort'][$criteria->getField()] = $order;
     });
     $criteriaManager->doWith(SeekCriteria::class, function (SeekCriteria $criteria) use(&$options, &$filter, $order) {
         $options['limit'] = $criteria->getLimit();
         $options['skip'] = 0;
         if ($criteria->getLastId()) {
             $lastId = new ObjectID($criteria->getLastId());
             if ($order === 1) {
                 $filter['_id'] = ['$gt' => $lastId];
             } else {
                 $filter['_id'] = ['$lt' => $lastId];
             }
         }
     });
     $criteriaManager->doWith(ThemeIdCriteria::class, function (ThemeIdCriteria $criteria) use(&$filter) {
         $filter[sprintf('theme_ids.%s', (string) $criteria->getThemeId())] = ['$exists' => true];
     });
     $criteriaManager->doWith(QueryStringCriteria::class, function (QueryStringCriteria $criteria) use(&$filter) {
         if ($criteria->isAvailable()) {
             $filter['$text'] = ['$search' => $criteria->getQuery()];
         }
     });
     $cursor = $collection->find($filter, $options)->toArray();
     if (count($cursor)) {
         $this->profileService->loadProfilesByIds(array_map(function (BSONDocument $document) {
             return (int) $document['id'];
         }, $cursor));
         return $this->cleanResults(array_map(function (BSONDocument $document) {
             try {
                 $profile = $this->profileService->getProfileById((int) $document['id']);
                 return array_merge(['_id' => (string) $document['_id']], $profile->toJSON());
             } catch (ProfileNotFoundException $e) {
                 return null;
             }
         }, $cursor));
     } else {
         return [];
     }
 }
Ejemplo n.º 16
0
 /**
  * @param array $filter
  * @param array $options
  *
  * @return \Traversable
  */
 public function find(array $filter = [], array $options = [])
 {
     $cursor = $this->collection->find($filter, $options);
     $cursor->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
     foreach ($cursor as $values) {
         (yield $this->hydrator->hydrate($values));
     }
 }
Ejemplo n.º 17
0
 /**
  * @param array $criteria
  * @param int $offset
  * @param int $limit
  * @return Document[]
  */
 public function findBy(array $criteria, int $offset = 0, int $limit = 500) : array
 {
     $cursor = $this->collection->find($criteria, ['skip' => $offset, 'limit' => $limit]);
     return array_map(function (BSONDocument $document) : Document {
         $data = $document->getArrayCopy();
         unset($data['_id']);
         return $this->converter->arrayToObject($data, $this->documentClass);
     }, $cursor->toArray());
 }
Ejemplo n.º 18
0
 /**
  * @return \MongoDB\Collection
  */
 private function createCollectionObject()
 {
     $options = ['readPreference' => $this->readPreference, 'writeConcern' => $this->writeConcern];
     if ($this->collection === null) {
         $this->collection = $this->db->getDb()->selectCollection($this->name, $options);
     } else {
         $this->collection = $this->collection->withOptions($options);
     }
 }
Ejemplo n.º 19
0
 /**
  * Garbage collection
  *
  * Note: MongoDB 2.2+ supports TTL collections, which may be used in place
  * of this method by indexing the "modified" field with an
  * "expireAfterSeconds" option. Regardless of whether TTL collections are
  * used, consider indexing this field to make the remove query more
  * efficient.
  *
  * @see http://docs.mongodb.org/manual/tutorial/expire-data/
  * @param int $maxlifetime
  * @return bool
  */
 public function gc($maxlifetime)
 {
     /* Note: unlike DbTableGateway, we do not use the lifetime field in
      * each document. Doing so would require a $where query to work with the
      * computed value (modified + lifetime) and be very inefficient.
      */
     $microseconds = floor(microtime(true) * 1000) - $maxlifetime;
     $result = $this->mongoCollection->deleteMany([$this->options->getModifiedField() => ['$lt' => new UTCDateTime($microseconds)]], $this->options->getSaveOptions());
     return $result->isAcknowledged();
 }
Ejemplo n.º 20
0
 public function testSeeElementIsObjectThrowsError()
 {
     $trumpet = new \StdClass();
     $trumpet->name = 'Trumpet 1';
     $trumpet->pitch = 'B♭';
     $trumpet->price = array('min' => 458, 'max' => 891);
     $this->setExpectedException('PHPUnit_Framework_ExpectationFailedException');
     $this->userCollection->insertOne(array('id' => 5, 'trumpet' => $trumpet));
     $this->userCollection->insertOne(array('id' => 6, 'trumpet' => $trumpet));
     $this->module->seeElementIsObject('users', array(), 'trumpet');
 }
Ejemplo n.º 21
0
 /**
  * {@inheritdoc}
  */
 public function keys()
 {
     try {
         $cursor = $this->collection->find(array(), array('projection' => array('_id' => 1)));
         $keys = array();
         foreach ($cursor as $document) {
             $keys[] = $document['_id'];
         }
     } catch (Exception $e) {
         throw ReadException::forException($e);
     }
     return $keys;
 }
Ejemplo n.º 22
0
 /**
  * 
  * @return array
  */
 public function getDatasetRaces()
 {
     return $this->cacheGet('pie/races/', function () {
         $data = [Character::RACE_ASURA => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_ASURA)], Character::RACE_CHARR => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_CHARR)], Character::RACE_HUMAN => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_HUMAN)], Character::RACE_NORN => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_NORN)], Character::RACE_SYLVARI => ['y' => 0, 'name' => $this->trans('race.' . Character::RACE_SYLVARI)]];
         foreach ($this->collection->find() as $row) {
             if (isset($row['race'])) {
                 foreach ($row['race'] as $key => $value) {
                     $data[$key]['y'] += $value;
                 }
             }
         }
         return array_values($data);
     }, 4 * 3600);
 }
 /**
  * Assert that the collections contain equivalent documents.
  *
  * This method will resolve references within the expected collection's
  * documents before comparing documents. Occurrences of "*result" in the
  * expected collection's documents will be replaced with the actual result.
  * Occurrences of "*actual" in the expected collection's documents will be
  * replaced with the corresponding value in the actual collection's document
  * being compared.
  *
  * @param Collection $expectedCollection
  * @param Collection $actualCollection
  * @param mixed      $actualResult
  */
 private function assertEquivalentCollections($expectedCollection, $actualCollection, $actualResult)
 {
     $mi = new MultipleIterator();
     $mi->attachIterator(new IteratorIterator($expectedCollection->find()));
     $mi->attachIterator(new IteratorIterator($actualCollection->find()));
     foreach ($mi as $documents) {
         list($expectedDocument, $actualDocument) = $documents;
         array_walk($expectedDocument, function (&$value) use($actualResult) {
             if ($value === '*result') {
                 $value = $actualResult;
             }
         });
         array_walk($expectedDocument, function (&$value, $key) use($actualDocument) {
             if (!is_string($value)) {
                 return;
             }
             if (!strncmp($value, '*actual_', 8)) {
                 $value = $actualDocument[$key];
             }
         });
         $this->assertSameDocument($expectedDocument, $actualDocument);
     }
 }
Ejemplo n.º 24
0
 /**
  * Returns the array containing all cities in a country.
  *
  * @author Shivam Mathur <*****@*****.**>
  *
  * @param $countryName
  * @param bool $test
  * @return array
  * @throws \Exception
  */
 private function cities($countryName, $test = false)
 {
     if ($countryName == '_id') {
         throw new \Exception('Could not found the country - ' . $countryName);
     }
     $locationData = [];
     if (!$test) {
         $locationData = $this->database->findOne([], ['projection' => ['_id' => false, $countryName => true], 'typeMap' => ['root' => 'array', 'document' => 'array']]);
     }
     if (!$locationData) {
         throw new \Exception('Could not found the country - ' . $countryName);
     }
     // Getting names of cities from $locationData
     $cities = $locationData[$countryName];
     sort($cities);
     return $cities;
 }
Ejemplo n.º 25
0
 public function ensureIndexes(Database $database, Collection $collection)
 {
     $collection->createIndex(['title' => 'text']);
 }
Ejemplo n.º 26
0
 /**
  * Ensure $indexToEnsure on the given mongo $collection
  * @param Collection $collection
  * @param array $indexToEnsure
  */
 protected function ensureIndex(Collection $collection, array $indexToEnsure)
 {
     $collection->createIndex($indexToEnsure, array('background' => 1));
 }
Ejemplo n.º 27
0
 public static function createCollection(Manager $manager, $namespace)
 {
     $collection = new Collection($manager, $namespace);
     $collection->createIndex(['expireAt' => 1], ['expireAfterSeconds' => 0]);
     return $collection;
 }
Ejemplo n.º 28
0
 /**
  * @param Result $result
  * @return \MongoDB\InsertOneResult
  */
 public function save(Result $result)
 {
     $document = ['url' => $result->getUrl(), 'modifiedSince' => $result->getModifiedSince(), 'feed' => $result->getFeed()->toArray()];
     return $this->collection->insertOne($document);
 }
 /**
  * @param array $data
  * @param string $id
  * @param int $keyType
  * @param string $rootId
  * @param string $property
  * @return string
  */
 protected function update($data, $id, $keyType, $rootId, $property)
 {
     CodeGuard::checkTypeAndThrow($rootId, 'string');
     CodeGuard::checkTypeAndThrow($id, 'string');
     if ($keyType == self::ID_IN_KEY) {
         if (empty($rootId)) {
             $mongoid = self::mongoID($id);
             $filter = array('_id' => $mongoid);
             $updateCommand = array('$set' => $data);
             $options = array('upsert' => true);
             $this->_collection->updateOne($filter, $updateCommand, $options);
             $id = $mongoid->__toString();
         } else {
             CodeGuard::checkNullAndThrow($id, 'id');
             CodeGuard::checkNullAndThrow($property, 'property');
             $subKey = $property . '.' . $id;
             $filter = array('_id' => self::mongoID($rootId));
             $updateCommand = array('$set' => array($subKey => $data));
             $this->_collection->updateOne($filter, $updateCommand);
         }
     } else {
         CodeGuard::checkNullAndThrow($id, 'id');
         $filter = array('_id' => self::mongoID($rootId));
         $updateCommand = array('$set' => array($property . '$' . $id => $data));
         $this->_collection->updateOne($filter, $updateCommand);
     }
     return $id;
 }
Ejemplo n.º 30
-1
 /**
  * @param string $cbdSubject
  * @param MongoGraph $cbdGraph
  * @param Collection $collection
  * @param string $context
  * @throws \Exception
  */
 protected function saveCBD($cbdSubject, MongoGraph $cbdGraph, Collection $collection, $context)
 {
     $cbdSubject = $this->labeller->uri_to_alias($cbdSubject);
     if ($cbdGraph == null || $cbdGraph->is_empty()) {
         throw new \Exception("graph for {$cbdSubject} was null");
     }
     try {
         $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1));
         print ".";
     } catch (\Exception $e) {
         if (preg_match('/E11000/', $e->getMessage())) {
             print "M";
             // key already exists, merge it
             $criteria = array("_id" => array("r" => $cbdSubject, "c" => $context));
             $existingGraph = new MongoGraph();
             $existingGraph->add_tripod_array($collection->findOne($criteria));
             $existingGraph->add_graph($cbdGraph);
             try {
                 $collection->updateOne($criteria, ['$set' => $existingGraph->to_tripod_array($cbdSubject, $context)], array("w" => 1));
             } catch (\Exception $e2) {
                 throw new \Exception($e2->getMessage());
                 // todo: would be good to have typed exception
             }
         } else {
             // retry
             print "CursorException on update: " . $e->getMessage() . ", retrying\n";
             try {
                 $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1));
             } catch (\Exception $e2) {
                 throw new \Exception($e2->getMessage());
                 // todo: would be good to have typed exception
             }
         }
     }
 }