Exemplo n.º 1
0
 /**
  * Executes all queued document upserts.
  *
  * Queued documents with an ID are upserted individually.
  *
  * If no upserts are queued, invoking this method is a NOOP.
  *
  * @param array $options Options for batchInsert() and update() driver methods
  */
 public function executeUpserts(array $options = array())
 {
     if (!$this->queuedUpserts) {
         return;
     }
     foreach ($this->queuedUpserts as $oid => $document) {
         $data = $this->pb->prepareUpsertData($document);
         // Set the initial version for each upsert
         if ($this->class->isVersioned) {
             $versionMapping = $this->class->fieldMappings[$this->class->versionField];
             if ($versionMapping['type'] === 'int') {
                 $nextVersion = max(1, (int) $this->class->reflFields[$this->class->versionField]->getValue($document));
                 $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion);
             } elseif ($versionMapping['type'] === 'date') {
                 $nextVersionDateTime = new \DateTime();
                 $nextVersion = new \MongoDate($nextVersionDateTime->getTimestamp());
                 $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersionDateTime);
             }
             $data['$set'][$versionMapping['name']] = $nextVersion;
         }
         try {
             $this->executeUpsert($data, $options);
             $this->handleCollections($document, $options);
             unset($this->queuedUpserts[$oid]);
         } catch (\MongoException $e) {
             unset($this->queuedUpserts[$oid]);
             throw $e;
         }
     }
 }
Exemplo n.º 2
0
 /**
  * Executes a single upsert in {@link executeUpserts}
  *
  * @param object $document
  * @param array  $options
  */
 private function executeUpsert($document, array $options)
 {
     $options['upsert'] = true;
     $criteria = $this->getQueryForDocument($document);
     $data = $this->pb->prepareUpsertData($document);
     // Set the initial version for each upsert
     if ($this->class->isVersioned) {
         $versionMapping = $this->class->fieldMappings[$this->class->versionField];
         if ($versionMapping['type'] === 'int') {
             $nextVersion = max(1, (int) $this->class->reflFields[$this->class->versionField]->getValue($document));
             $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion);
         } elseif ($versionMapping['type'] === 'date') {
             $nextVersionDateTime = new \DateTime();
             $nextVersion = new \MongoDate($nextVersionDateTime->getTimestamp());
             $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersionDateTime);
         }
         $data['$set'][$versionMapping['name']] = $nextVersion;
     }
     foreach (array_keys($criteria) as $field) {
         unset($data['$set'][$field]);
     }
     // Do not send an empty $set modifier
     if (empty($data['$set'])) {
         unset($data['$set']);
     }
     /* If there are no modifiers remaining, we're upserting a document with
      * an identifier as its only field. Since a document with the identifier
      * may already exist, the desired behavior is "insert if not exists" and
      * NOOP otherwise. MongoDB 2.6+ does not allow empty modifiers, so $set
      * the identifier to the same value in our criteria.
      *
      * This will fail for versions before MongoDB 2.6, which require an
      * empty $set modifier. The best we can do (without attempting to check
      * server versions in advance) is attempt the 2.6+ behavior and retry
      * after the relevant exception.
      *
      * See: https://jira.mongodb.org/browse/SERVER-12266
      */
     if (empty($data)) {
         $retry = true;
         $data = array('$set' => array('_id' => $criteria['_id']));
     }
     try {
         $this->collection->update($criteria, $data, $options);
         return;
     } catch (\MongoCursorException $e) {
         if (empty($retry) || strpos($e->getMessage(), 'Mod on _id not allowed') === false) {
             throw $e;
         }
     }
     $this->collection->update($criteria, array('$set' => new \stdClass()), $options);
 }
Exemplo n.º 3
0
 /**
  * Executes all queued document upserts.
  *
  * Queued documents with an ID are upserted individually.
  *
  * If no upserts are queued, invoking this method is a NOOP.
  *
  * @param array $options Options for batchInsert() and update() driver methods
  */
 public function executeUpserts(array $options = array())
 {
     if (!$this->queuedUpserts) {
         return;
     }
     foreach ($this->queuedUpserts as $oid => $document) {
         $data = $this->pb->prepareUpsertData($document);
         try {
             $this->executeUpsert($data, $options);
             unset($this->queuedUpserts[$oid]);
         } catch (\MongoException $e) {
             unset($this->queuedUpserts[$oid]);
             throw $e;
         }
     }
 }