Executes all document upserts for documents of the specified type.

@param ClassMetadata $class
@param array $options Array of options to be used with batchInsert()
166114
private function executeUpserts(ClassMetadata $class, array $options = array())
    {
        $className = $class->name;
        $persister = $this->getDocumentPersister($className);
        $collection = $this->dm->getDocumentCollection($className);

        $upsertedDocuments = array();

        foreach ($this->documentUpserts as $oid => $document) {
            if (get_class($document) === $className) {
                $persister->addUpsert($document);
                $upsertedDocuments[] = $document;
                unset($this->documentUpserts[$oid]);
            }
        }

        $persister->executeUpserts($options);

        $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]);
        $hasListeners = $this->evm->hasListeners(Events::postPersist);

        foreach ($upsertedDocuments as $document) {
            if ($hasLifecycleCallbacks) {
                $class->invokeLifecycleCallbacks(Events::postPersist, $document);
            }
            if ($hasListeners) {
                $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($document, $this->dm));
            }
            $this->cascadePostPersist($class, $document);
        }
    }
387586
public function loadMetadataForClass($className, ClassMetadata $class)
    {
        try {
            $xmlRoot = $this->getElement($className);
        } catch (DoctrineMappingException $e) {
            // Convert Exception type for consistency with other drivers
            throw new MappingException($e->getMessage(), $e->getCode(), $e);
        }

        if (!$xmlRoot) {
            return;
        }

        if (isset($xmlRoot['repository-class'])) {
            $class->setCustomRepositoryClassName((string) $xmlRoot['repository-class']);
        }

        if (isset($xmlRoot['translator'])) {
            $class->setTranslator((string) $xmlRoot['translator']);
        }

        if (isset($xmlRoot['versionable']) && $xmlRoot['versionable'] !== 'false') {
            $class->setVersioned(strtolower($xmlRoot['versionable']));
        }

        if (isset($xmlRoot['referenceable']) && $xmlRoot['referenceable'] !== 'false') {
            $class->setReferenceable((bool) $xmlRoot['referenceable']);
        }

        if (isset($xmlRoot['uniqueNodeType']) && $xmlRoot['uniqueNodeType'] !== 'false') {
            $class->setUniqueNodeType((bool) $xmlRoot['uniqueNodeType']);
        }

        if (isset($xmlRoot['is-leaf'])) {
            if (!in_array($value = $xmlRoot['is-leaf'], ['true', 'false'])) {
                throw new MappingException(sprintf(
                    'Value of is-leaf must be "true" or "false", got "%s" for class "%s"',
                    $value, $className
                ));
            }

            $class->setIsLeaf($value == 'true' ? true : false);
        }

        if (isset($xmlRoot->mixins)) {
            $mixins = [];
            foreach ($xmlRoot->mixins->mixin as $mixin) {
                $attributes = $mixin->attributes();
                if (!isset($attributes['type'])) {
                    throw new MappingException('<mixin> missing mandatory type attribute');
                }
                $mixins[] = (string) $attributes['type'];
            }
            $class->setMixins($mixins);
            $attributes = $xmlRoot->mixins->attributes();
            if (isset($attributes['inherit'])) {
                $class->setInheritMixins($attributes['inherit']);
            }
        }

        if (isset($xmlRoot['node-type'])) {
            $class->setNodeType((string) $xmlRoot['node-type']);
        }

        if ($xmlRoot->getName() === 'mapped-superclass') {
            $class->isMappedSuperclass = true;
        }

        if (isset($xmlRoot->field)) {
            foreach ($xmlRoot->field as $field) {
                $mapping = [];
                $attributes = $field->attributes();
                foreach ($attributes as $key => $value) {
                    $mapping[$key] = (string) $value;
                    // convert bool fields
                    if (in_array($key, ['id', 'multivalue', 'assoc', 'translated', 'nullable'])) {
                        $mapping[$key] = ('true' === $mapping[$key]) ? true : false;
                    }
                }
                if (!isset($mapping['name'])) {
                    throw new MappingException(sprintf('Missing name attribute for field of %s', $className));
                }
                $mapping['fieldName'] = $mapping['name'];
                unset($mapping['name']);
                $class->mapField($mapping);
            }
        }
        if (isset($xmlRoot->id)) {
            $mapping = [
                'fieldName' => (string) $xmlRoot->id->attributes()->name,
                'id'        => true,
            ];
            if (isset($xmlRoot->id->generator, $xmlRoot->id->generator->attributes()->strategy)) {
                $mapping['strategy'] = (string) $xmlRoot->id->generator->attributes()->strategy;
            }
            $class->mapId($mapping);
        }
        if (isset($xmlRoot->node)) {
            $class->mapNode(['fieldName' => (string) $xmlRoot->node->attributes()->name]);
        }
        if (isset($xmlRoot->nodename)) {
            $class->mapNodename(['fieldName' => (string) $xmlRoot->nodename->attributes()->name]);
        }
        if (isset($xmlRoot->{'parent-document'})) {
            $mapping = [
                'fieldName' => (string) $xmlRoot->{'parent-document'}->attributes()->name,
                'cascade'   => (isset($xmlRoot->{'parent-document'}->cascade)) ? $this->getCascadeMode($xmlRoot->{'parent-document'}->cascade) : 0,
            ];
            $class->mapParentDocument($mapping);
        }
        if (isset($xmlRoot->child)) {
            foreach ($xmlRoot->child as $child) {
                $attributes = $child->attributes();
                $mapping = [
                    'fieldName' => (string) $attributes->name,
                    'cascade'   => (isset($child->cascade)) ? $this->getCascadeMode($child->cascade) : 0,
                ];
                if (isset($attributes['node-name'])) {
                    $mapping['nodeName'] = (string) $attributes->{'node-name'};
                }
                $class->mapChild($mapping);
            }
        }
        if (isset($xmlRoot->children)) {
            foreach ($xmlRoot->children as $children) {
                $attributes = $children->attributes();
                $mapping = [
                    'fieldName'          => (string) $attributes->name,
                    'cascade'            => (isset($children->cascade)) ? $this->getCascadeMode($children->cascade) : 0,
                    'filter'             => isset($attributes['filter']) ? (array) $attributes->filter : null,
                    'fetchDepth'         => isset($attributes['fetch-depth']) ? (int) $attributes->{'fetch-depth'} : -1,
                    'ignoreUntranslated' => !empty($attributes['ignore-untranslated']),
            ];
                $class->mapChildren($mapping);
            }
        }
        if (isset($xmlRoot->{'reference-many'})) {
            foreach ($xmlRoot->{'reference-many'} as $reference) {
                $attributes = $reference->attributes();
                $reference['cascade'] = (isset($reference->cascade)) ? $this->getCascadeMode($reference->cascade) : 0;
                $reference['fieldName'] = (string) $attributes->name ?: null;
                $this->addReferenceMapping($class, $reference, 'many');
            }
        }
        if (isset($xmlRoot->{'reference-one'})) {
            foreach ($xmlRoot->{'reference-one'} as $reference) {
                $attributes = $reference->attributes();
                $reference['cascade'] = (isset($reference->cascade)) ? $this->getCascadeMode($reference->cascade) : 0;
                $reference['fieldName'] = (string) $attributes->name ?: null;
                $this->addReferenceMapping($class, $reference, 'one');
            }
        }

        if (isset($xmlRoot->locale)) {
            $class->mapLocale(['fieldName' => (string) $xmlRoot->locale->attributes()->name]);
        }

        if (isset($xmlRoot->depth)) {
            $class->mapDepth(['fieldName' => (string) $xmlRoot->depth->attributes()->name]);
        }

        if (isset($xmlRoot->{'mixed-referrers'})) {
            foreach ($xmlRoot->{'mixed-referrers'} as $mixedReferrers) {
                $attributes = $mixedReferrers->attributes();
                $mapping = [
                    'fieldName'     => (string) $attributes->name,
                    'referenceType' => isset($attributes['reference-type']) ? strtolower((string) $attributes->{'reference-type'}) : null,
                ];
                $class->mapMixedReferrers($mapping);
            }
        }
        if (isset($xmlRoot->referrers)) {
            foreach ($xmlRoot->referrers as $referrers) {
                $attributes = $referrers->attributes();
                if (!isset($attributes['referenced-by'])) {
                    throw new MappingException("$className is missing the referenced-by attribute for the referrer field ".$attributes->name);
                }
                if (!isset($attributes['referring-document'])) {
                    throw new MappingException("$className is missing the referring-document attribute for the referrer field ".$attributes->name);
                }
                // referenceType is determined from the referencedBy field of referringDocument
                $mapping = [
                    'fieldName'         => (string) $attributes->name,
                    'cascade'           => (isset($referrers->cascade)) ? $this->getCascadeMode($referrers->cascade) : 0,
                    'referencedBy'      => (string) $attributes->{'referenced-by'},
                    'referringDocument' => (string) $attributes->{'referring-document'},
                ];
                $class->mapReferrers($mapping);
            }
        }
        if (isset($xmlRoot->{'version-name'})) {
            $class->mapVersionName(['fieldName' => (string) $xmlRoot->{'version-name'}->attributes()->name]);
        }
        if (isset($xmlRoot->{'version-created'})) {
            $class->mapVersionCreated(['fieldName' => (string) $xmlRoot->{'version-created'}->attributes()->name]);
        }

        if (isset($xmlRoot->{'lifecycle-callbacks'})) {
            foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
                $class->addLifecycleCallback((string) $lifecycleCallback['method'], constant('Doctrine\ODM\PHPCR\Event::'.(string) $lifecycleCallback['type']));
            }
        }

        if (isset($xmlRoot->uuid)) {
            $mapping = [];
            $attributes = $xmlRoot->uuid->attributes();

            foreach ($attributes as $key => $value) {
                $mapping[$key] = (string) $value;
            }

            if (!array_key_exists('name', $mapping)) {
                throw new MappingException(sprintf('Missing name attribute for field of %s', $className));
            }

            $mapping['uuid'] = true;
            $mapping['fieldName'] = $mapping['name'];
            $class->mapField($mapping);
        }

        if (isset($xmlRoot->{'child-class'})) {
            $childClasses = [];
            foreach ($xmlRoot->{'child-class'} as $requiredClass) {
                $childClasses[] = (string) $requiredClass['name'];
            }
            $class->setChildClasses($childClasses);
        }

        $class->validateClassMapping();
    }
1307002
private function executeInserts($class, array $options = array())
    {
        $className = $class->name;
        $persister = $this->getXmlEntityPersister($className);

        $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]);
        $hasListeners = $this->evm->hasListeners(Events::postPersist);
        if ($hasLifecycleCallbacks || $hasListeners) {
            $documents = array();
        }

        $inserts = array();
        foreach ($this->entityInsertions as $oid => $xmlEntity) {
            if (get_class($xmlEntity) === $className) {
                $persister->insert($xmlEntity);
                unset($this->entityInsertions[$oid]);
            }
        }
    }
1116623
private function persistNew(ClassMetadata $class, $document)
    {
        $this->lifecycleEventManager->prePersist($class, $document);

        $oid    = spl_object_hash($document);
        $upsert = false;
        $index  = $class->getIndex();

        if ($index) {
            $identifier = $class->createIdentifier($document);
            $upsert     = !$class->isEmbeddedDocument && !$identifier->isNull();

            if ($identifier->isNull()) {
                foreach ($identifier->getKeys() as $key) {
                    $property = $key->getPropertyMetadata();

                    if ($property->generator === null) {
                        throw new \InvalidArgumentException(sprintf(
                            '%s.%s uses NONE identifier generation strategy but no identifier was provided when persisting.',
                            get_class($document),
                            $property->name
                        ));
                    } else {
                        $property->generate($this->dm, $document);
                    }
                }

                //rebuild identifier with the generated values
                $identifier = $class->createIdentifier($document);

                $this->documentIdentifiers[$oid] = $identifier;
            }
        } else {
            // this is for embedded documents without identifiers
            $this->documentIdentifiers[$oid] = $oid;
        }

        $this->documentStates[$oid] = self::STATE_MANAGED;

        if ($upsert) {
            $this->scheduleForUpsert($class, $document);
        } else {
            $this->scheduleForInsert($class, $document);
        }
    }
730908
public function setTypeMapping($type, $class = null)
    {
        if (is_string($type)) {
            if ($class === null) {
                throw new InvalidArgumentException(
                    'If $type is specified, $class is required'
                );
            }
            $type = array($type => (string) $class);
            $class = null;
        }

        if (!is_array($type)) {
            throw new InvalidArgumentException(
                'Type must either be an array or a string.'
            );
        }

        if ($class !== null) {
            throw new InvalidArgumentException(
                'If $type is an array, $class must not be specified.'
            );
        }

        $this->type_map = array_merge($this->type_map, $type);
    }
1259376
public function copyBulk($class, array $data, array $options = [])
    {
        $this->om->startFlushSuite();
        $copies = [];

        foreach ($data as $el) {
            //get the element
            $copies[] = $this->copy($el, $options);
        }

        $this->om->endFlushSuite();

        return $copies;
    }
795661
final public function addOverride($class, $type, array $options)
    {
        if (!isset($this->overrides[$class])) {
            $this->overrides[$class] = [];
        }

        if (!isset($this->overrides[$class][$type])) {
            $this->overrides[$class][$type] = [];
        }

        $this->overrides[$class][$type][] = $options;
    }
953984
private function executeUpserts(ClassMetadata $class, array $documents, array $options = []) : void
    {
        $persister = $this->getDocumentPersister($class->name);

        foreach ($documents as $oid => $document) {
            $persister->addUpsert($document);
            unset($this->documentUpserts[$oid]);
        }

        $persister->executeUpserts($options);

        foreach ($documents as $document) {
            $this->lifecycleEventManager->postPersist($class, $document);
        }
    }
455146
public function executeUpserts(array $options = []) : void
    {
        if (! $this->queuedUpserts) {
            return;
        }

        $options = $this->getWriteOptions($options);
        foreach ($this->queuedUpserts as $oid => $document) {
            try {
                $this->executeUpsert($document, $options);
                $this->handleCollections($document, $options);
                unset($this->queuedUpserts[$oid]);
            } catch (WriteException $e) {
                unset($this->queuedUpserts[$oid]);
                throw $e;
            }
        }
    }
1016071
private function cascadePostUpdate(ClassMetadata $class, $document)
    {
        foreach ($class->getEmbeddedAttributesMappings() as $mapping) {
            $value = $class->getPropertyMetadata($mapping->attributeName)->getValue($document);
            if ($value === null) {
                continue;
            }
            $values = $mapping->isOne() ? [$value] : $value;

            foreach ($values as $entry) {
                if (empty($this->uow->getDocumentChangeSet($entry)) && !$this->uow->hasScheduledCollections($entry)) {
                    continue;
                }
                $entryClass = $this->dm->getClassMetadata(get_class($entry));
                $event      = $this->uow->isScheduledForInsert($entry) ? Event::postPersist : Event::postUpdate;
                $entryClass->invokeLifecycleCallbacks($event, $entry, [new LifecycleEventArgs($entry, $this->dm)]);
                $this->evm->dispatchEvent($event, new LifecycleEventArgs($entry, $this->dm));

                $this->cascadePostUpdate($entryClass, $entry);
            }
        }
    }
609561
public function insertMany($documents, $options = [])
    {
        $insertQuery = [];
        foreach ($documents as $document) {
            $this->classMetadata->getEventManager()->execute(EventManager::EVENT_PRE_INSERT, $document);
            $query = $this->hydrator->unhydrate($document);

            $idGen = $this->classMetadata->getIdGenerator();
            if ($idGen !== null) {
                if (!class_exists($idGen) || !is_subclass_of($idGen, AbstractIdGenerator::class)) {
                    throw new \Exception('Bad ID generator : class \'' . $idGen . '\' not exists or not extends JPC\MongoDB\ODM\Id\AbstractIdGenerator');
                }
                $generator = new $idGen();
                $query['_id'] = $generator->generate($this->documentManager, $document);
            }

            $insertQuery[] = $query;
        }

        $result = $this->collection->insertMany($insertQuery, $options);

        if ($result->isAcknowledged()) {
            foreach ($result->getInsertedIds() as $key => $id) {
                if ($id instanceof \stdClass) {
                    $id = (array) $id;
                }
                $insertQuery[$key]["_id"] = $id;
                $this->hydrator->hydrate($documents[$key], $insertQuery[$key]);

                $this->classMetadata->getEventManager()->execute(EventManager::EVENT_POST_INSERT, $documents[$key]);

                $this->cacheObject($documents[$key]);
            }

            return true;
        } else {
            foreach ($documents as $document) {
                $this->cacheObject($document);
                // $this->documentManager->removeObject();
            }
            return false;
        }
    }
214497
public function update($class, $data, array $options = [])
    {
        // validates submitted data.
        if (!in_array(self::NO_VALIDATE, $options)) {
            $errors = $this->validate($class, $data, ValidatorProvider::UPDATE);

            if (count($errors) > 0) {
                return $errors;
            }
        }

        $oldObject = $this->om->getObject($data, $class) ?? new $class();
        $this->checkPermission('EDIT', $oldObject, [], true);
        $oldData = $this->serializer->serialize($oldObject);

        if (!$oldData) {
            $oldData = [];
        }

        $object = $this->serializer->deserialize($data, $oldObject, $options);

        if ($this->dispatch('update', 'pre', [$object, $options, $oldData])) {
            $this->om->save($object);
            $this->dispatch('update', 'post', [$object, $options, $oldData]);
        }

        return $object;
    }
1132428
private function implementJsonSerialize(Type $type, ClassGenerator $class)
    {
        $methodName = 'jsonSerialize';
        $class->removeMethod($methodName);
        $class->addMethodFromGenerator(
            MethodGenerator::fromArray([
                'name' => $methodName,
                'parameters' => [],
                'visibility' => MethodGenerator::VISIBILITY_PUBLIC,
                'body' => $this->generateJsonSerializeBody($type, $class),
                'docblock' => DocBlockGeneratorFactory::fromArray([
                    'tags' => [
                        [
                            'name' => 'return',
                            'description' => 'array'
                        ]
                    ]
                ])
            ])
        );
    }
322020
private function executeUpserts(ClassMetadata $class, array $documents)
    {
        $persister = $this->getDocumentPersister($class->name);

        foreach ($documents as $oid => $document) {
            try {
                $persister->upsert($document);
                $persister->handleCollections($document);

                unset($this->documentUpserts[$oid]);
            } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
                unset($this->documentUpserts[$oid]);

                throw $e;
            }

            $this->lifecycleEventManager->postPersist($class, $document);
        }
    }
256679
public function postPersist(ClassMetadata $class, $document)
    {
        $class->invokeLifecycleCallbacks(Event::postPersist, $document, [new LifecycleEventArgs($document, $this->dm)]);
        $this->evm->dispatchEvent(Event::postPersist, new LifecycleEventArgs($document, $this->dm));
        $this->cascadePostPersist($class, $document);
    }
849958
public function insertOne($document, $options = [])
    {
        $objectDatas = $this->hydrator->unhydrate($document);

        $stream = $objectDatas["stream"];
        unset($objectDatas["stream"]);

        if (!isset($objectDatas["filename"])) {
            $filename = stream_get_meta_data($stream)["uri"];
        } else {
            $filename = $objectDatas["filename"];
        }

        unset($objectDatas["filename"]);

        $id = $this->bucket->uploadFromStream($filename, $stream, $objectDatas);
        $data['_id'] = $id;

        $data["stream"] = $this->bucket->openDownloadStream($data['_id']);
        $this->hydrator->hydrate($document, $data, true);

        $this->documentManager->setObjectState($document, ObjectManager::OBJ_MANAGED);
        $this->cacheObject($document);

        return true;
    }
224362
private function executeUpdates(ClassMetadata $class, array $options = array())
    {
        $className = $class->name;
        $persister = $this->getDocumentPersister($className);

        $hasPreUpdateLifecycleCallbacks = ! empty($class->lifecycleCallbacks[Events::preUpdate]);
        $hasPreUpdateListeners = $this->evm->hasListeners(Events::preUpdate);
        $hasPostUpdateLifecycleCallbacks = ! empty($class->lifecycleCallbacks[Events::postUpdate]);
        $hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate);

        foreach ($this->documentUpdates as $oid => $document) {
            if (get_class($document) == $className || $document instanceof Proxy && $document instanceof $className) {
                if ( ! $class->isEmbeddedDocument) {
                    if ($hasPreUpdateLifecycleCallbacks) {
                        $class->invokeLifecycleCallbacks(Events::preUpdate, $document);
                        $this->recomputeSingleDocumentChangeSet($class, $document);
                    }

                    if ($hasPreUpdateListeners && isset($this->documentChangeSets[$oid])) {
                        $this->evm->dispatchEvent(Events::preUpdate, new Event\PreUpdateEventArgs(
                            $document, $this->dm, $this->documentChangeSets[$oid])
                        );
                    }
                    $this->cascadePreUpdate($class, $document);
                }

                if ( ! $class->isEmbeddedDocument && isset($this->documentChangeSets[$oid]) && $this->documentChangeSets[$oid]) {
                    $persister->update($document, $options);
                }
                unset($this->documentUpdates[$oid]);

                if ( ! $class->isEmbeddedDocument) {
                    if ($hasPostUpdateLifecycleCallbacks) {
                        $class->invokeLifecycleCallbacks(Events::postUpdate, $document);
                    }
                    if ($hasPostUpdateListeners) {
                        $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($document, $this->dm));
                    }
                    $this->cascadePostUpdateAndPostPersist($class, $document);
                }
            }
        }
    }