/** * Finds objects by a set of criteria. * * Optionally sorting and limiting details can be passed. An implementation may throw * an UnexpectedValueException if certain values of the sorting or limiting details are * not supported. * * @param array $criteria * @param array|null $orderBy * @param int|null $limit * @param int|null $offset * @param string $fetchPlan * * @return ArrayCollection The objects. * @throws OrientDBException */ public function findBy(array $criteria, array $orderBy = [], $limit = null, $offset = null, $fetchPlan = '*:0') { $parts[] = sprintf('SELECT FROM %s', $this->metadata->getOrientClass()); if ($criteria) { $where = []; foreach ($criteria as $key => $value) { $value = json_encode($value); $where[] = "{$key} = {$value}"; } $parts[] = sprintf('WHERE %s', implode(' AND ', $where)); } if ($orderBy) { $orders = []; foreach ($orderBy as $key => $order) { $orders[] = "{$key} {$order}"; } $parts[] = sprintf('ORDER BY %s', implode(', ', $orders)); } if ($limit) { $parts[] = "LIMIT " . $limit; } $select = implode(' ', $parts); $collection = $this->dm->query($select, $fetchPlan); if (!$collection instanceof ArrayCollection) { throw new OrientDBException("Problems executing the query \"{$select}\". " . "The server returned {$collection} instead of ArrayCollection."); } return $collection; }
/** * Prepares the array that is ready to be inserted to mongodb for a given object document. * * @param ClassMetadata $class * @param UnitOfWork $uow * @param object $document * * @return \stdClass $insertData * @throws ODMOrientDbException */ public function prepareData(ClassMetadata $class, UnitOfWork $uow, $document) { $insertData = new \stdClass(); if ($class->isEmbeddedDocument()) { $insertData->{'@type'} = 'd'; $insertData->{'@class'} = $class->getOrientClass(); $cs = $uow->getDocumentActualData($document); } else { $cs = $uow->getDocumentChangeSet($document); array_Walk($cs, function (&$val) { $val = $val[1]; }); } $mappings =& $class->fieldMappings; foreach ($cs as $name => $new) { $mapping = isset($mappings[$name]) ? $mappings[$name] : null; if ($mapping === null) { // don't store arbitrary values for now continue; } // Don't store null values unless nullable === true if ($new === null && $mapping['nullable'] === false) { continue; } $value = null; if ($new !== null) { switch (true) { // @Property case !isset($mapping['association']): $value = Type::getType($mapping['type'])->convertToDatabaseValue($new); break; case $mapping['association'] & ClassMetadata::LINK: $value = $this->getDocReference($new); break; case $mapping['association'] & ClassMetadata::LINK_MANY: // initialize the link collection if ($mapping['association'] & ClassMetadata::LINK_MAP) { $value = new \stdClass(); } else { $value = []; } break; case $mapping['association'] & ClassMetadata::EMBED: /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($new)); $value = $this->prepareData($rmd, $uow, $new); break; case $mapping['association'] & ClassMetadata::EMBED_MANY: $value = []; if ($mapping['association'] & ClassMetadata::EMBED_MAP) { foreach ($new as $k => $item) { /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($item)); $value[$k] = $this->prepareData($rmd, $uow, $item); } } else { foreach ($new as $k => $item) { /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($item)); $value[] = $this->prepareData($rmd, $uow, $item); } } break; } } $insertData->{$mapping['name']} = $value; } return $insertData; }