/** * Store the api $response as the cached result of the api $request. * * @param RequestInterface $request The request for which the response will be cached. * @param ResponseInterface $response The reponse to cache. * @param integer $timeToLive The time in seconds that the cache should live. * * @return void * * @throws \InvalidArgumentException Throw if $timeToLive is not an integer between 0 and 86400. */ public function set(RequestInterface $request, ResponseInterface $response, $timeToLive = null) { $timeToLive = self::ensureTTL($timeToLive ?: $this->getDefaultTTL()); $id = $request->getUrl(); $cache = ['httpCode' => $response->getHttpCode(), 'body' => $response->getBody(), 'headers' => $response->getHeaders(), 'expires' => new UTCDateTime(time() + $timeToLive)]; $this->collection->updateOne(['_id' => $id], ['$set' => $cache], ['upsert' => true]); }
/** * Write session data * * @param string $id * @param string $data * @return bool */ public function write($id, $data) { $saveOptions = array_replace($this->options->getSaveOptions(), ['upsert' => true, 'multiple' => false]); $criteria = ['_id' => $id, $this->options->getNameField() => $this->sessionName]; $newObj = ['$set' => [$this->options->getDataField() => new Binary((string) $data, Binary::TYPE_GENERIC), $this->options->getLifetimeField() => $this->lifetime, $this->options->getModifiedField() => new UTCDatetime(floor(microtime(true) * 1000))]]; /* Note: a MongoCursorException will be thrown if a record with this ID * already exists with a different session name, since the upsert query * cannot insert a new document with the same ID and new session name. * This should only happen if ID's are not unique or if the session name * is altered mid-process. */ $result = $this->mongoCollection->updateOne($criteria, $newObj, $saveOptions); return $result->isAcknowledged(); }
/** * @param Persistable $model * @param array $options * * @return \MongoDB\UpdateResult */ public function update(Persistable $model, array $options = []) { $bson = $model->bsonSerialize(); $modelId = $bson['_id']; unset($bson['_id']); $result = $this->collection->updateOne(['_id' => new ObjectID($modelId)], ['$set' => $bson], $options); if (false == $result->isAcknowledged()) { throw new \LogicException('Operation is not acknowledged'); } return $result; }
/** * @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; }
/** * Atomically acknowledge and send a message to the queue. * * @param array $message the message to ack received from get() * @param array $payload the data to store in the message to send. Data is handled same way * as \MongoDB\Collection::insertOne() * @param int $earliestGet earliest unix timestamp the message can be retreived. * @param float $priority priority for order out of get(). 0 is higher priority than 1 * @param bool $newTimestamp true to give the payload a new timestamp or false to use given message timestamp * * @return void * * @throws \InvalidArgumentException $message does not have a field "id" that is a ObjectID * @throws \InvalidArgumentException $earliestGet was not an int * @throws \InvalidArgumentException $priority was not a float * @throws \InvalidArgumentException $priority is NaN * @throws \InvalidArgumentException $newTimestamp was not a bool */ public function ackSend(array $message, array $payload, $earliestGet = 0, $priority = 0.0, $newTimestamp = true) { $id = null; if (array_key_exists('id', $message)) { $id = $message['id']; } if (!is_a($id, 'MongoDB\\BSON\\ObjectID')) { throw new \InvalidArgumentException('$message does not have a field "id" that is a ObjectID'); } if (!is_int($earliestGet)) { throw new \InvalidArgumentException('$earliestGet was not an int'); } if (!is_float($priority)) { throw new \InvalidArgumentException('$priority was not a float'); } if (is_nan($priority)) { throw new \InvalidArgumentException('$priority was NaN'); } if ($newTimestamp !== true && $newTimestamp !== false) { throw new \InvalidArgumentException('$newTimestamp was not a bool'); } //Ensure $earliestGet is between 0 and MONGO_INT32_MAX $earliestGet = min(max(0, $earliestGet * 1000), self::MONGO_INT32_MAX); $toSet = ['payload' => $payload, 'running' => false, 'resetTimestamp' => new \MongoDB\BSON\UTCDateTime(self::MONGO_INT32_MAX), 'earliestGet' => new \MongoDB\BSON\UTCDateTime($earliestGet), 'priority' => $priority]; if ($newTimestamp) { $toSet['created'] = new \MongoDB\BSON\UTCDateTime((int) (microtime(true) * 1000)); } //using upsert because if no documents found then the doc was removed (SHOULD ONLY HAPPEN BY SOMEONE MANUALLY) //so we can just send $this->collection->updateOne(['_id' => $id], ['$set' => $toSet], ['upsert' => true]); }
/** * @param object $model * @param null|array $filter * @param array $options * * @return \MongoDB\UpdateResult */ public function update($model, $filter = null, array $options = []) { if (null === $filter) { $filter = ['_id' => new ObjectID(get_object_id($model))]; } $values = get_object_values($model); unset($values['_id']); $result = $this->collection->updateOne($filter, ['$set' => $values], $options); if (false == $result->isAcknowledged()) { throw new \LogicException('Operation is not acknowledged'); } return $result; }
public function updateMany($filter, $update, array $options = []) { $collectionName = $this->collection->getCollectionName(); $textFilter = json_encode($filter); $textUpdate = json_encode($update); $textOptions = json_encode($options); Yii::trace("Executing updateAll: {\$query: {$textFilter}, \$document: {$textUpdate}, \$options: {$textOptions} }", "mongoyii\\Collection"); if ($this->client->enableProfiling) { $token = "mongoyii\\{$collectionName}.updateMany({\$query: {$textFilter}, \$document: {$textUpdate}, \$options: {$textOptions} })"; Yii::beginProfile($token, 'mongoyii\\Collection.updateMany'); } $res = $this->collection->updateOne($filter, $update, $options); if ($this->client->enableProfiling) { Yii::endProfile($token, 'mongoyii\\Collection.updateMany'); } return $res; }
/** * Save the generated rows to the given collection. * * If an exception in thrown because a field is too large to index, the field is * truncated and the save is retried. * * @param Collection $collection * @param array $generatedRow The rows to save. * @throws \Exception */ protected function truncatingSave(Collection $collection, array $generatedRow) { try { $collection->updateOne($generatedRow['_id'], array('$set' => $generatedRow), array('upsert' => true)); } catch (\Exception $e) { // We only truncate and retry the save if the \Exception contains this text. if (strpos($e->getMessage(), "Btree::insert: key too large to index") !== FALSE) { $this->truncateFields($collection, $generatedRow); $collection->updateOne($generatedRow['_id'], array('$set' => $generatedRow), array('upsert' => true)); } else { throw $e; } } }
/** * @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 } } } }
/** * * @param MongoCollection $collection */ public function calculateStatistics(MongoCollection $collection, $quiet = true) { try { $data = $collection->findOne(['account' => $this->getName()]); if (!empty($data) && time() - $data['last_update'] < 86400) { return; } $data = ['account' => $this->getName(), 'last_update' => time(), 'wallet' => $this->getStatsWallet(), 'unlocks' => $this->getStatsUnlocks(), 'pvp' => $this->getStatsPvp(), 'race' => $this->getRaceCount(), 'gender' => $this->getGenderCount(), 'profession' => $this->getProfessionCount(), 'generic' => ['characters' => $this->getCharactersCount(), 'age' => $this->getTotalAge(), 'deaths' => $this->getTotalDeaths(), 'level80' => $this->getCharactersLevel80Count()], Item::RARITY_ASCENDED => $this->getAscendedCount(), Item::RARITY_LEGENDARY => $this->getLegendariesCount()]; $collection->updateOne(['account' => $this->getName()], $data, ['upsert' => true]); } catch (\Exception $ex) { if (!$quiet) { throw $ex; } } }
/** * Reset a process expire time in the registry. * * @param \MongoDB\Collection $collection the collection * @param string $id a unique id * @param int $minsBeforeExpire number of minutes before a process is considered expired. * * @return void * * @throws \InvalidArgumentException if $id was not a string * @throws \InvalidArgumentException if $minsBeforeExpire was not an int */ public static function reset(\MongoDB\Collection $collection, $id, $minsBeforeExpire) { if (!is_string($id)) { throw new \InvalidArgumentException('$id was not a string'); } if (!is_int($minsBeforeExpire)) { throw new \InvalidArgumentException('$minsBeforeExpire was not an int'); } $expireSecs = time() + $minsBeforeExpire * 60; if (!is_int($expireSecs)) { if ($minsBeforeExpire > 0) { $expireSecs = self::MONGO_INT32_MAX; } else { $expireSecs = 0; } } $thisHostName = self::_getEncodedHostname(); $thisPid = getmypid(); $collection->updateOne(['_id' => $id], ['$set' => ["hosts.{$thisHostName}.{$thisPid}" => new \MongoDB\BSON\UTCDateTime($expireSecs * 1000), 'version' => new \MongoDB\BSON\ObjectID()]]); }
/** * {@inheritdoc} */ public function updateOne($filter, $update, array $options = []) { $event = $this->startQueryLogging(__FUNCTION__, $filter, $update, $options); $result = parent::updateOne($filter, $update, $options); $this->logger->logQuery($event); return $result; }