/** * @return MapperMatrix */ public function create() { $matrix = new MapperMatrix(); foreach ($this->container->findByTag('echo511.leanmapper.mapper') as $serviceName => $tagAttributes) { $matrix->addMapper($this->container->getService($serviceName)); } return $matrix; }
/** * * @param EntityReflection[] $reflections * @return Schema * @throws Exception * @throws InvalidAnnotationException */ public function createSchema(array $reflections) { $schema = new Schema(); foreach ($reflections as $reflection) { $properties = $reflection->getEntityProperties(); $onEnd = array(); if (count($properties) === 0) { continue; } $table = $schema->createTable($this->mapperMatrix->getTable($reflection->getName())); foreach ($properties as $property) { if (!$property->hasRelationship()) { $type = $this->getType($property); if ($type === NULL) { throw new Exception('Unknown type'); } $column = $table->addColumn($property->getColumn(), $type); if ($property->getColumn() == $this->mapperMatrix->getPrimaryKey($table->getName())) { $table->setPrimaryKey([$property->getColumn()]); if ($property->hasCustomFlag('unique')) { throw new InvalidAnnotationException("Entity {$reflection->name}:{$property->getName()} - m:unique can not be used together with primary key."); } } if ($property->hasCustomFlag('autoincrement')) { $column->setAutoincrement(true); } /* if ($property->containsEnumeration()) { $column->getType()->setEnumeration($property->getEnumValues()); } */ if ($property->hasCustomFlag('size')) { $column->setLength($property->getCustomFlagValue('size')); } } else { $relationship = $property->getRelationship(); // primary keys types $sourcePrimaryKey = $this->mapperMatrix->getPrimaryKey($this->mapperMatrix->getTable($reflection->getName())); $sourcePrimaryKeyType = $reflection->getEntityProperty($sourcePrimaryKey)->getType(); $targetPrimaryKey = $this->mapperMatrix->getPrimaryKey($relationship->getTargetTable()); $targetPrimaryKeyType = (new EntityReflection($this->mapperMatrix->getEntityClass($relationship->getTargetTable()), $this->mapperMatrix))->getEntityProperty($targetPrimaryKey)->getType(); if ($relationship instanceof HasMany) { $relationshipTable = $schema->createTable($relationship->getRelationshipTable()); $relationshipTable->addColumn($relationship->getColumnReferencingSourceTable(), $sourcePrimaryKeyType); $relationshipTable->addColumn($relationship->getColumnReferencingTargetTable(), $targetPrimaryKeyType); $relationshipTable->addForeignKeyConstraint($table, [$relationship->getColumnReferencingSourceTable()], [$sourcePrimaryKey], array('onDelete' => 'CASCADE')); $relationshipTable->addForeignKeyConstraint($relationship->getTargetTable(), [$relationship->getColumnReferencingTargetTable()], [$targetPrimaryKey], array('onDelete' => 'CASCADE')); } elseif ($relationship instanceof HasOne) { $column = $table->addColumn($relationship->getColumnReferencingTargetTable(), $targetPrimaryKeyType); if (!$property->hasCustomFlag('nofk')) { $cascade = $property->isNullable() ? 'SET NULL' : 'CASCADE'; $table->addForeignKeyConstraint($relationship->getTargetTable(), [$column->getName()], [$this->mapperMatrix->getPrimaryKey($relationship->getTargetTable())], array('onDelete' => $cascade)); } } } if ($property->hasCustomFlag('unique')) { $indexColumns = $this->parseColumns($property->getCustomFlagValue('unique'), array($column->getName())); $onEnd[] = $this->createIndexClosure($table, $indexColumns, TRUE); } if ($property->hasCustomFlag('index')) { $indexColumns = $this->parseColumns($property->getCustomFlagValue('index'), array($column->getName())); $onEnd[] = $this->createIndexClosure($table, $indexColumns, FALSE); } if ($property->hasCustomFlag('comment')) { $column->setComment($property->getCustomFlagValue('comment')); } if (isset($column)) { if ($property->isNullable()) { $column->setNotnull(false); } if ($property->hasDefaultValue()) { $column->setDefault($property->getDefaultValue()); } } } foreach ($onEnd as $cb) { $cb(); } } return $schema; }
/** @inheritdoc */ public function getRelationshipColumn($sourceTable, $targetTable) { return $targetTable . '_' . $this->matrix->getPrimaryKey($targetTable); }
/** * Get schema the database should be in based on entities. * @return Schema */ public function getDesiredSchema() { return $this->schemaGenerator->createSchema($this->mapperMatrix->getAllReflections()); }