Beispiel #1
0
 /**
  * Checks that the current field includes a reference to the supplied document.
  */
 public function includesReferenceTo($document)
 {
     if ($this->currentField) {
         $mapping = $this->class->getFieldMapping($this->currentField);
         $dbRef = $this->dm->createDBRef($document, $mapping);
         if (isset($mapping['simple']) && $mapping['simple']) {
             $this->query[$mapping['name']]['$elemMatch'] = $dbRef;
         } else {
             $keys = array('ref' => true, 'id' => true, 'db' => true);
             if (isset($mapping['targetDocument'])) {
                 unset($keys['ref'], $keys['db']);
             }
             foreach ($keys as $key => $value) {
                 $this->query[$this->currentField]['$elemMatch']['$' . $key] = $dbRef['$' . $key];
             }
         }
     } else {
         $dbRef = $this->dm->createDBRef($document);
         $this->query['$elemMatch'] = $dbRef;
     }
     return $this;
 }
 /**
  * @param ClassMetadata $classMetadata
  * @param array $mapping
  */
 private function remapAssociation(ClassMetadata $classMetadata, array $mapping)
 {
     $newMapping = $this->resolveTargetDocuments[$mapping['targetDocument']];
     $newMapping = array_replace_recursive($mapping, $newMapping);
     $newMapping['fieldName'] = $mapping['fieldName'];
     // clear reference case of duplicate exception
     unset($classMetadata->fieldMappings[$mapping['fieldName']]);
     unset($classMetadata->associationMappings[$mapping['fieldName']]);
     switch ($mapping['association']) {
         case ClassMetadata::REFERENCE_ONE:
             $classMetadata->mapOneReference($newMapping);
             break;
         case ClassMetadata::REFERENCE_MANY:
             $classMetadata->mapManyReference($newMapping);
             break;
         case ClassMetadata::EMBED_ONE:
             $classMetadata->mapOneEmbedded($newMapping);
             break;
         case ClassMetadata::EMBED_MANY:
             $classMetadata->mapManyEmbedded($newMapping);
             break;
     }
 }
Beispiel #3
0
 /**
  * Adds support for magic finders.
  *
  * @param string $method
  * @param array $arguments
  * @throws RiakException
  * @throws \BadMethodCallException If the method called is an invalid find* method
  *                                 or no find* method at all and therefore an invalid
  *                                 method call.
  * @return array|object The found document/documents.
  */
 public function __call($method, $arguments)
 {
     if (substr($method, 0, 6) == 'findBy') {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } elseif (substr($method, 0, 9) == 'findOneBy') {
         $by = substr($method, 9, strlen($method));
         $method = 'findOneBy';
     } else {
         throw new \BadMethodCallException("Undefined method '{$method}'. The method name must start with " . "either findBy or findOneBy!");
     }
     if (!isset($arguments[0])) {
         throw RiakException::findByRequiresParameter($method . $by);
     }
     $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
     if ($this->class->hasField($fieldName)) {
         return $this->{$method}(array($fieldName => $arguments[0]));
     } else {
         throw RiakException::invalidFindByCall($this->documentName, $fieldName, $method . $by);
     }
 }
Beispiel #4
0
 /**
  * @param ClassMetadata $class
  * @return array
  */
 private function prepareIndexes(ClassMetadata $class)
 {
     $persister = $this->dm->getUnitOfWork()->getDocumentPersister($class->name);
     $indexes = $class->getIndexes();
     $newIndexes = array();
     foreach ($indexes as $index) {
         $newIndex = array('keys' => array(), 'options' => $index['options']);
         foreach ($index['keys'] as $key => $value) {
             $key = $persister->prepareFieldName($key);
             if ($class->hasField($key)) {
                 $mapping = $class->getFieldMapping($key);
                 $newIndex['keys'][$mapping['name']] = $value;
             } else {
                 $newIndex['keys'][$key] = $value;
             }
         }
         $newIndexes[] = $newIndex;
     }
     return $newIndexes;
 }
Beispiel #5
0
 /**
  * Prepares a query expression.
  *
  * @param array|object  $expression
  * @param ClassMetadata $class
  * @return array
  */
 private function prepareQueryExpression($expression, $class)
 {
     foreach ($expression as $k => $v) {
         // Ignore query operators whose arguments need no type conversion
         if (in_array($k, array('$exists', '$type', '$mod', '$size'))) {
             continue;
         }
         // Process query operators whose argument arrays need type conversion
         if (in_array($k, array('$in', '$nin', '$all')) && is_array($v)) {
             foreach ($v as $k2 => $v2) {
                 $expression[$k][$k2] = $class->getDatabaseIdentifierValue($v2);
             }
             continue;
         }
         // Recursively process expressions within a $not operator
         if ($k === '$not' && is_array($v)) {
             $expression[$k] = $this->prepareQueryExpression($v, $class);
             continue;
         }
         $expression[$k] = $class->getDatabaseIdentifierValue($v);
     }
     return $expression;
 }
Beispiel #6
0
 /**
  * INTERNAL:
  * Tries to get a document by its identifier hash. If no document is found
  * for the given hash, FALSE is returned.
  *
  * @ignore
  * @param mixed         $id    Document identifier
  * @param ClassMetadata $class Document class
  * @return mixed The found document or FALSE.
  * @throws InvalidArgumentException if the class does not have an identifier
  */
 public function tryGetById($id, ClassMetadata $class)
 {
     if (!$class->identifier) {
         throw new \InvalidArgumentException(sprintf('Class "%s" does not have an identifier', $class->name));
     }
     $serializedId = serialize($class->getDatabaseIdentifierValue($id));
     return isset($this->identityMap[$class->name][$serializedId]) ? $this->identityMap[$class->name][$serializedId] : false;
 }
 /**
  * Adds inherited indexes to the subclass mapping.
  *
  * @param ClassMetadata $subClass
  * @param ClassMetadata $parentClass
  */
 private function addInheritedIndexes(ClassMetadata $subClass, ClassMetadata $parentClass)
 {
     foreach ($parentClass->indexes as $index) {
         $subClass->addIndex($index['keys'], $index['options']);
     }
 }
Beispiel #8
0
 /**
  * If you are priming references inside an embedded document you'll need to parse the dot syntax.
  * This method will traverse through embedded documents to find the reference to prime.
  * However this method will not traverse through multiple layers of references.
  * I.e. you can prime this: myDocument.embeddedDocument.embeddedDocuments.embeddedDocuments.referencedDocument(s)
  * ... but you cannot prime this: myDocument.embeddedDocument.referencedDocuments.referencedDocument(s)
  * This addresses Issue #624.
  *
  * @param string             $fieldName
  * @param ClassMetadata      $class
  * @param array|\Traversable $documents
  * @param array              $mapping
  * @return array
  */
 private function parseDotSyntaxForPrimer($fieldName, $class, $documents, $mapping = null)
 {
     // Recursion passthrough:
     if ($mapping != null) {
         return array('fieldName' => $fieldName, 'class' => $class, 'documents' => $documents, 'mapping' => $mapping);
     }
     // Gather mapping data:
     $e = explode('.', $fieldName);
     if (!isset($class->fieldMappings[$e[0]])) {
         throw new \InvalidArgumentException(sprintf('Field %s cannot be further parsed for priming because it is unmapped.', $fieldName));
     }
     $mapping = $class->fieldMappings[$e[0]];
     $e[0] = $mapping['name'];
     // Case of embedded document(s) to recurse through:
     if (!isset($mapping['reference'])) {
         if (empty($mapping['embedded'])) {
             throw new \InvalidArgumentException(sprintf('Field "%s" of fieldName "%s" is not an embedded document, therefore no children can be primed. Aborting. This feature does not support traversing nested referenced documents at this time.', $e[0], $fieldName));
         }
         if (!isset($mapping['targetDocument'])) {
             throw new \InvalidArgumentException(sprintf('No target document class has been specified for this embedded document. However, targetDocument mapping must be specified in order for prime to work on fieldName "%s" for mapping of field "%s".', $fieldName, $mapping['fieldName']));
         }
         $childDocuments = array();
         foreach ($documents as $document) {
             $fieldValue = $class->getFieldValue($document, $e[0]);
             if ($fieldValue instanceof PersistentCollection) {
                 foreach ($fieldValue as $elemDocument) {
                     array_push($childDocuments, $elemDocument);
                 }
             } else {
                 array_push($childDocuments, $fieldValue);
             }
         }
         array_shift($e);
         $childClass = $this->dm->getClassMetadata($mapping['targetDocument']);
         if (!$childClass->hasField($e[0])) {
             throw new \InvalidArgumentException(sprintf('Field to prime must exist in embedded target document. Reference fieldName "%s" for mapping of target document class "%s".', $fieldName, $mapping['targetDocument']));
         }
         $childFieldName = implode('.', $e);
         return $this->parseDotSyntaxForPrimer($childFieldName, $childClass, $childDocuments);
     }
     // Case of reference(s) to prime:
     if ($mapping['reference']) {
         if (count($e) > 1) {
             throw new \InvalidArgumentException(sprintf('Cannot prime more than one layer deep but field "%s" is a reference and has children in fieldName "%s".', $e[0], $fieldName));
         }
         return array('fieldName' => $fieldName, 'class' => $class, 'documents' => $documents, 'mapping' => $mapping);
     }
 }