예제 #1
0
파일: Reader.php 프로젝트: andreyors/orm
 /**
  * Get an ID for the given data
  *
  * @return string
  */
 public function getId()
 {
     $values = [];
     foreach ($this->metadata->getIdColumns() as $column) {
         $values[] = $this->getPropertyValue($column->getProperty());
     }
     if (!count($values)) {
         throw new InvalidEntityException('Entity "' . $this->metadata->getClassName() . '" has no ID column');
     }
     return implode(self::ID_DELIMITER, $values);
 }
예제 #2
0
파일: Writer.php 프로젝트: bravo3/orm
 /**
  * Hydrate a relationship
  *
  * @param Relationship $relative
  * @return $this
  */
 public function hydrateRelative(Relationship $relative)
 {
     $this->entity_manager->getDriver()->debugLog("Hydrating relative for " . $this->metadata->getTableName() . "[" . $this->getReader()->getId() . "]::" . $relative->getName());
     $setter = $relative->getSetter();
     $key = $this->entity_manager->getKeyScheme()->getRelationshipKey($relative, $this->entity_manager->getMapper()->getEntityMetadata($relative->getSource())->getTableName(), $this->entity_manager->getMapper()->getEntityMetadata($relative->getTarget())->getTableName(), $this->getReader()->getId());
     if (RelationshipType::isMultiIndex($relative->getRelationshipType())) {
         $items = [];
         $ids = $this->entity_manager->getDriver()->getMultiValueIndex($key);
         foreach ($ids as $id) {
             $items[] = $this->entity_manager->retrieveEntityOrNew($relative->getTarget(), $id);
         }
         $this->proxy->{$setter}($items);
     } else {
         $id = $this->entity_manager->getDriver()->getSingleValueIndex($key);
         if ($id) {
             $this->proxy->{$setter}($this->entity_manager->retrieve($relative->getTarget(), $id));
         }
     }
     return $this;
 }
예제 #3
0
 /**
  * Traverse an array of relationships and persist them
  *
  * @param Entity $metadata
  * @param object $entity
  * @param Reader $reader
  * @param string $local_id
  */
 private function persistRelationshipsTraversal(Entity $metadata, $entity, Reader $reader, $local_id)
 {
     $relationships = $metadata->getRelationships();
     $is_proxy = $entity instanceof OrmProxyInterface;
     foreach ($relationships as $relationship) {
         $key = $this->getRelationshipKey($relationship, $local_id);
         $value = $reader->getPropertyValue($relationship->getName());
         // Skip relationship rules:
         // If the entity is not a proxy (i.e. a new entity) we still must allow for the scenario in which a new
         // entity is created over the top of an existing entity (same ID), as such, we still need to check every
         // relationship attached to the entity
         if (!$this->entity_manager->getMaintenanceMode() && $is_proxy) {
             /** @var OrmProxyInterface $entity */
             // Check if we can skip the update
             if (!$entity->isRelativeModified($relationship->getName())) {
                 // Looks like we can skip, but check inverted sort indices first -
                 if ($relationship->getInversedBy()) {
                     $inverse_relationship = $this->invertRelationship($relationship);
                     if ($inverse_relationship->getSortableBy()) {
                         // The inverse relationship has sortable columns, we need to check for local property
                         // changes that might have impacted this -
                         list(, , $maintain) = $this->getRelationshipDeltas($key, $relationship, $value);
                         $this->updateMaintainedRelationshipSortIndices($inverse_relationship, $maintain, $reader, $local_id);
                     }
                 }
                 // Nothing else to update on this relationship
                 continue;
             }
         }
         // This condition allows NEW (not a proxy) entities that have NOT set a relationship to inherit existing
         // relationships which could be useful if the relationship was set by a foreign entity
         // See: docs/RaceConditions.md
         if ($is_proxy || $value || $this->entity_manager->getMaintenanceMode()) {
             $this->persistForwardRelationship($relationship, $key, $value);
             if (count($relationship->getSortableBy())) {
                 $this->persistForwardSortIndices($relationship, $local_id, $value);
             }
             // Modify the inversed relationships
             if ($relationship->getInversedBy()) {
                 $this->persistInversedRelationship($relationship, $key, $value, $local_id, $reader);
             } else {
                 $this->persistRefs($relationship, $key, $value, $local_id);
             }
         }
     }
 }
예제 #4
0
 /**
  * Get the Entity metadata object
  *
  * @return Entity
  */
 public function getEntityMetadata()
 {
     $entity = new Entity($this->reflection_obj->name, $this->getTableName());
     $entity->setColumns($this->getColumns());
     $entity->setRelationships($this->getRelationships());
     $entity->setIndices($this->getIndices());
     $entity->setSortables($this->getSortables());
     return $entity;
 }
예제 #5
0
 /**
  * Deserialise the entity
  *
  * @param Entity         $metadata Metadata object to match the entity
  * @param SerialisedData $data     Data to deserialise
  * @param object         $entity   Entity to hydrate
  */
 public function deserialise(Entity $metadata, SerialisedData $data, $entity)
 {
     // Using $assoc = true is ~ 10-20% quicker on PHP 5.3
     // Source: http://stackoverflow.com/questions/8498114/should-i-use-an-associative-array-or-an-object
     $raw = json_decode($data->getData(), true, self::ENCODE_DEPTH);
     foreach ($metadata->getColumns() as $column) {
         $setter = $column->getSetter();
         $field = $column->getName();
         $value = isset($raw[$field]) ? $raw[$field] : null;
         switch ($column->getType()) {
             default:
                 break;
             case FieldType::DATETIME():
                 $entity->{$setter}($this->deserialiseDateTime($value));
                 break;
             case FieldType::INT():
                 $entity->{$setter}((int) $value);
                 break;
             case FieldType::STRING():
                 $entity->{$setter}((string) $value);
                 break;
             case FieldType::DECIMAL():
                 $entity->{$setter}((double) $value);
                 break;
             case FieldType::BOOL():
                 $entity->{$setter}((bool) $value);
                 break;
             case FieldType::SET():
                 $entity->{$setter}(json_decode($value, true));
                 break;
             case FieldType::OBJECT():
                 $entity->{$setter}($this->deserialiseObject($value, $column->getClassName()));
                 break;
         }
     }
 }
예제 #6
0
 /**
  * Compiles all columns for an entity
  *
  * @param Entity $md
  * @return array
  */
 private function compileColumns(Entity $md)
 {
     $out = [];
     $columns = $md->getColumns();
     foreach ($columns as $column) {
         $data = [Schema::COLUMN_TYPE => $column->getType()->value()];
         if ($column->isId()) {
             $data[Schema::COLUMN_ID] = true;
         }
         $default_getter = 'get' . Inflector::classify($column->getProperty());
         if ($column->getGetter() && $column->getGetter() != $default_getter) {
             $data[Schema::GETTER] = $column->getGetter();
         }
         $default_setter = 'set' . Inflector::classify($column->getProperty());
         if ($column->getSetter() && $column->getSetter() != $default_setter) {
             $data[Schema::SETTER] = $column->getSetter();
         }
         if ($column->getClassName()) {
             $data[Schema::COLUMN_CLASS] = $column->getClassName();
         }
         $out[$column->getName()] = $data;
     }
     $relationships = $md->getRelationships();
     foreach ($relationships as $relationship) {
         $data = [Schema::REL_ASSOCIATION => $relationship->getRelationshipType()->value(), Schema::REL_TARGET => $relationship->getTarget()];
         $default_getter = 'get' . Inflector::classify($relationship->getName());
         if ($relationship->getGetter() && $relationship->getGetter() != $default_getter) {
             $data[Schema::GETTER] = $relationship->getGetter();
         }
         $default_setter = 'set' . Inflector::classify($relationship->getName());
         if ($relationship->getSetter() && $relationship->getSetter() != $default_setter) {
             $data[Schema::SETTER] = $relationship->getSetter();
         }
         if ($relationship->getInversedBy()) {
             $data[Schema::REL_INVERSED_BY] = $relationship->getInversedBy();
         }
         if ($relationship->getSortableBy()) {
             $data[Schema::SORT_INDICES] = $this->compileSortables($relationship->getSortableBy());
         }
         $out[$relationship->getName()] = $data;
     }
     return $out;
 }
예제 #7
0
파일: YamlMapper.php 프로젝트: bravo3/orm
 /**
  * Parse a map file, loading metadata from YAML
  *
  * @param string $fn
  * @return $this
  */
 protected function loadMap($fn)
 {
     $map = $this->getParser()->parse(file_get_contents($fn));
     foreach ($map as $class => $schema) {
         $table = $this->getNode($schema, Schema::TABLE_NAME);
         $entity = new Entity($class, $table);
         // Columns
         $columns = $this->getNode($schema, Schema::COLUMNS);
         foreach ($columns as $property => $column_schema) {
             if ($this->getNode($column_schema, Schema::REL_ASSOCIATION, false)) {
                 $rel = $this->createRelationship($property, $column_schema);
                 $rel->setSource($class);
                 $entity->addRelationship($rel);
             } else {
                 $entity->addColumn($this->createColumn($property, $column_schema));
             }
         }
         // Table sortables
         $entity->setSortables($this->createSortables($schema));
         // Table indices
         $indices = $this->getNode($schema, Schema::STD_INDICES, false, []);
         foreach ($indices as $name => $index_schema) {
             $index = new Index($table, $name);
             $index->setColumns($this->getNode($index_schema, Schema::INDEX_COLUMNS, false, []));
             $index->setMethods($this->getNode($index_schema, Schema::INDEX_METHODS, false, []));
             $entity->addIndex($index);
         }
         // Add to map
         $this->entities[$class] = $entity;
     }
     return $this;
 }