/** * Prepares the update query to upsert a given document object in riak. * * @param object $document * @return array $updateData */ public function prepareUpsertData($document) { $class = $this->dm->getClassMetadata(get_class($document)); $changeset = $this->uow->getDocumentChangeSet($document); $updateData = array(); foreach ($changeset as $fieldName => $change) { $mapping = $class->fieldMappings[$fieldName]; list($old, $new) = $change; // @Inc if ($mapping['type'] === 'increment') { if ($new >= $old) { $updateData['$inc'][$mapping['name']] = $new - $old; } else { $updateData['$inc'][$mapping['name']] = ($old - $new) * -1; } // @Field, @String, @Date, etc. } elseif (!isset($mapping['association'])) { if (isset($new) || $mapping['nullable'] === true) { $updateData['$set'][$mapping['name']] = is_null($new) ? null : Type::getType($mapping['type'])->convertToDatabaseValue($new); } // @EmbedOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_ONE) { // If we have a new embedded document then lets set the whole thing if ($new && $this->uow->isScheduledForInsert($new)) { $updateData['$set'][$mapping['name']] = $this->prepareEmbeddedDocumentValue($mapping, $new); // If we don't have a new value then do nothing on upsert } elseif (!$new) { // Update existing embedded document } else { $update = $this->prepareUpsertData($new); foreach ($update as $cmd => $values) { foreach ($values as $key => $value) { $updateData[$cmd][$mapping['name'] . '.' . $key] = $value; } } } // @ReferenceOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isOwningSide']) { if (isset($new) || $mapping['nullable'] === true) { $updateData['$set'][$mapping['name']] = is_null($new) ? null : $this->prepareReferencedDocumentValue($mapping, $new); } // @ReferenceMany, @EmbedMany } elseif ($mapping['type'] === ClassMetadata::MANY && !$mapping['isInverseSide'] && $new instanceof PersistentCollection && $new->isDirty() && CollectionHelper::isAtomic($mapping['strategy'])) { $updateData['$set'][$mapping['name']] = $this->prepareAssociatedCollectionValue($new, true); } // @EmbedMany and @ReferenceMany are handled by CollectionPersister } // add discriminator if the class has one if (isset($class->discriminatorField)) { $updateData['$set'][$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name; } return $updateData; }