[2.0] - DDC-169 - Completed refactoring of SchemaTool::getCreateSql() to use new DBAL Schema API, several internal optimizations in SchemaTool are now possible. Stripped out shared functionality with getUpdateSql() so that this part of SchemaTool is still completly working with the old API.
This commit is contained in:
parent
ba01175700
commit
2c27435bb2
@ -97,7 +97,6 @@ class SchemaTool
|
|||||||
{
|
{
|
||||||
$sql = array(); // All SQL statements
|
$sql = array(); // All SQL statements
|
||||||
$processedClasses = array(); // Reminder for processed classes, used for hierarchies
|
$processedClasses = array(); // Reminder for processed classes, used for hierarchies
|
||||||
$foreignKeyConstraints = array(); // FK SQL statements. Appended to $sql at the end.
|
|
||||||
$sequences = array(); // Sequence SQL statements. Appended to $sql at the end.
|
$sequences = array(); // Sequence SQL statements. Appended to $sql at the end.
|
||||||
|
|
||||||
$schema = new \Doctrine\DBAL\Schema\Schema();
|
$schema = new \Doctrine\DBAL\Schema\Schema();
|
||||||
@ -115,16 +114,14 @@ class SchemaTool
|
|||||||
$table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_SEQUENCE);
|
$table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_SEQUENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = array(); // table options
|
|
||||||
$columns = array(); // table columns
|
$columns = array(); // table columns
|
||||||
|
|
||||||
if ($class->isInheritanceTypeSingleTable()) {
|
if ($class->isInheritanceTypeSingleTable()) {
|
||||||
$columns = $this->_gatherColumns($class, $options, $table);
|
$columns = $this->_gatherColumns($class, $table);
|
||||||
$this->_gatherRelationsSql($class, $sql, $columns, $foreignKeyConstraints, $table, $schema);
|
$this->_gatherRelationsSql($class, $sql, $columns, $table, $schema);
|
||||||
|
|
||||||
// Add the discriminator column
|
// Add the discriminator column
|
||||||
$discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
|
$discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
|
||||||
$columns[$discrColumnDef['name']] = $discrColumnDef;
|
|
||||||
|
|
||||||
// Aggregate all the information from all classes in the hierarchy
|
// Aggregate all the information from all classes in the hierarchy
|
||||||
foreach ($class->parentClasses as $parentClassName) {
|
foreach ($class->parentClasses as $parentClassName) {
|
||||||
@ -134,8 +131,8 @@ class SchemaTool
|
|||||||
|
|
||||||
foreach ($class->subClasses as $subClassName) {
|
foreach ($class->subClasses as $subClassName) {
|
||||||
$subClass = $this->_em->getClassMetadata($subClassName);
|
$subClass = $this->_em->getClassMetadata($subClassName);
|
||||||
$columns = array_merge($columns, $this->_gatherColumns($subClass, $options, $table));
|
$this->_gatherColumns($subClass, $table);
|
||||||
$this->_gatherRelationsSql($subClass, $sql, $columns, $foreignKeyConstraints, $table, $schema);
|
$this->_gatherRelationsSql($subClass, $table, $schema);
|
||||||
$processedClasses[$subClassName] = true;
|
$processedClasses[$subClassName] = true;
|
||||||
}
|
}
|
||||||
} else if ($class->isInheritanceTypeJoined()) {
|
} else if ($class->isInheritanceTypeJoined()) {
|
||||||
@ -144,7 +141,7 @@ class SchemaTool
|
|||||||
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
||||||
if ( ! isset($mapping['inherited'])) {
|
if ( ! isset($mapping['inherited'])) {
|
||||||
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
||||||
$columns[$columnName] = $this->_gatherColumn($class, $mapping, $options, $table);
|
$this->_gatherColumn($class, $mapping, $table);
|
||||||
|
|
||||||
if ($class->isIdentifier($fieldName)) {
|
if ($class->isIdentifier($fieldName)) {
|
||||||
$pkColumns[] = $columnName;
|
$pkColumns[] = $columnName;
|
||||||
@ -152,38 +149,28 @@ class SchemaTool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_gatherRelationsSql($class, $sql, $columns, $foreignKeyConstraints, $table, $schema);
|
$this->_gatherRelationsSql($class, $table, $schema);
|
||||||
|
|
||||||
// Add the discriminator column only to the root table
|
// Add the discriminator column only to the root table
|
||||||
if ($class->name == $class->rootEntityName) {
|
if ($class->name == $class->rootEntityName) {
|
||||||
$discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
|
$discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
|
||||||
$columns[$discrColumnDef['name']] = $discrColumnDef;
|
|
||||||
} else {
|
} else {
|
||||||
// Add an ID FK column to child tables
|
// Add an ID FK column to child tables
|
||||||
|
/* @var Doctrine\ORM\Mapping\ClassMetadata $class */
|
||||||
$idMapping = $class->fieldMappings[$class->identifier[0]];
|
$idMapping = $class->fieldMappings[$class->identifier[0]];
|
||||||
$idColumn = $this->_gatherColumn($class, $idMapping, $options, $table);
|
$this->_gatherColumn($class, $idMapping, $table);
|
||||||
|
$columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
|
||||||
|
|
||||||
unset($idColumn['autoincrement']);
|
$pkColumns[] = $columnName;
|
||||||
$pkColumns[] = $idColumn['name'];
|
|
||||||
if ($table->isIdGeneratorIdentity()) {
|
if ($table->isIdGeneratorIdentity()) {
|
||||||
$table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_NONE);
|
$table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
$columns[$idColumn['name']] = $idColumn;
|
|
||||||
|
|
||||||
// Add a FK constraint on the ID column
|
// Add a FK constraint on the ID column
|
||||||
$constraint = array();
|
|
||||||
$constraint['tableName'] = $class->getQuotedTableName($this->_platform);
|
|
||||||
$constraint['foreignTable'] = $this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform);
|
|
||||||
$constraint['local'] = array($idColumn['name']);
|
|
||||||
$constraint['foreign'] = array($idColumn['name']);
|
|
||||||
$constraint['onDelete'] = 'CASCADE';
|
|
||||||
$foreignKeyConstraints[] = $constraint;
|
|
||||||
|
|
||||||
$table->addForeignKeyConstraint(
|
$table->addForeignKeyConstraint(
|
||||||
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
|
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
|
||||||
$constraint['local'], $constraint['foreign'], null,
|
array($columnName), array($columnName), null,
|
||||||
$constraint
|
array('onDelete' => 'CASCADE')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,34 +179,24 @@ class SchemaTool
|
|||||||
} else if ($class->isInheritanceTypeTablePerClass()) {
|
} else if ($class->isInheritanceTypeTablePerClass()) {
|
||||||
throw DoctrineException::notSupported();
|
throw DoctrineException::notSupported();
|
||||||
} else {
|
} else {
|
||||||
$columns = $this->_gatherColumns($class, $options, $table);
|
$this->_gatherColumns($class, $table);
|
||||||
$this->_gatherRelationsSql($class, $sql, $columns, $foreignKeyConstraints, $table, $schema);
|
$this->_gatherRelationsSql($class, $table, $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($class->primaryTable['indexes'])) {
|
if (isset($class->primaryTable['indexes'])) {
|
||||||
$options['indexes'] = $class->primaryTable['indexes'];
|
|
||||||
|
|
||||||
foreach ($class->primaryTable['indexes'] AS $indexName => $indexData) {
|
foreach ($class->primaryTable['indexes'] AS $indexName => $indexData) {
|
||||||
$table->addIndex($indexData, $indexName);
|
$table->addIndex($indexData, $indexName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($class->primaryTable['uniqueConstraints'])) {
|
if (isset($class->primaryTable['uniqueConstraints'])) {
|
||||||
$options['uniqueConstraints'] = $class->primaryTable['uniqueConstraints'];
|
|
||||||
|
|
||||||
foreach ($class->primaryTable['uniqueConstraints'] AS $indexName => $indexData) {
|
foreach ($class->primaryTable['uniqueConstraints'] AS $indexName => $indexData) {
|
||||||
$table->addUniqueIndex($indexData, $indexName);
|
$table->addUniqueIndex($indexData, $indexName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = array_merge($sql, $this->_platform->getCreateTableSql(
|
|
||||||
$class->getQuotedTableName($this->_platform), $columns, $options)
|
|
||||||
);
|
|
||||||
|
|
||||||
$processedClasses[$class->name] = true;
|
$processedClasses[$class->name] = true;
|
||||||
|
|
||||||
// TODO if we're reusing the sequence previously defined (in another model),
|
|
||||||
// it should not attempt to create a new sequence.
|
|
||||||
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
|
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
|
||||||
$seqDef = $class->getSequenceGeneratorDefinition();
|
$seqDef = $class->getSequenceGeneratorDefinition();
|
||||||
|
|
||||||
@ -230,42 +207,10 @@ class SchemaTool
|
|||||||
$seqDef['initialValue']
|
$seqDef['initialValue']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sequences[] = $this->_platform->getCreateSequenceSql(
|
|
||||||
$seqDef['sequenceName'],
|
|
||||||
$seqDef['initialValue'],
|
|
||||||
$seqDef['allocationSize']
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the foreign key constraints SQL
|
return $schema->toSql($this->_platform);
|
||||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
|
||||||
foreach ($foreignKeyConstraints as $fkConstraint) {
|
|
||||||
$sql = array_merge($sql, (array) $this->_platform->getCreateForeignKeySql($fkConstraint['tableName'], $fkConstraint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*try {
|
|
||||||
$newSql = $schema->toSql($this->_platform);
|
|
||||||
#return $newSql;
|
|
||||||
} catch(\Exception $e) {
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Append the sequence SQL
|
|
||||||
$sql = array_merge($sql, $sequences);
|
|
||||||
/*$sql2 = $sql;
|
|
||||||
sort($sql2);
|
|
||||||
sort($newSql);
|
|
||||||
|
|
||||||
if($newSql !== $sql2) {
|
|
||||||
var_dump($newSql);
|
|
||||||
var_dump($sql2);
|
|
||||||
die();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return $sql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,13 +230,6 @@ class SchemaTool
|
|||||||
$discrColumn['type'],
|
$discrColumn['type'],
|
||||||
array('length' => $discrColumn['length'], 'notnull' => true)
|
array('length' => $discrColumn['length'], 'notnull' => true)
|
||||||
);
|
);
|
||||||
|
|
||||||
return array(
|
|
||||||
'name' => $class->getQuotedDiscriminatorColumnName($this->_platform),
|
|
||||||
'type' => Type::getType($discrColumn['type']),
|
|
||||||
'length' => $discrColumn['length'],
|
|
||||||
'notnull' => true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -299,22 +237,19 @@ class SchemaTool
|
|||||||
* found in the given class.
|
* found in the given class.
|
||||||
*
|
*
|
||||||
* @param ClassMetadata $class
|
* @param ClassMetadata $class
|
||||||
* @param array $options The table options/constraints where any additional options/constraints
|
|
||||||
* that are required by columns should be appended.
|
|
||||||
* @param Table $table
|
* @param Table $table
|
||||||
* @return array The list of portable column definitions as required by the DBAL.
|
* @return array The list of portable column definitions as required by the DBAL.
|
||||||
*/
|
*/
|
||||||
private function _gatherColumns($class, array &$options, $table)
|
private function _gatherColumns($class, $table)
|
||||||
{
|
{
|
||||||
$columns = array();
|
$columns = array();
|
||||||
$pkColumns = array();
|
$pkColumns = array();
|
||||||
|
|
||||||
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
||||||
$column = $this->_gatherColumn($class, $mapping, $options, $table);
|
$column = $this->_gatherColumn($class, $mapping, $table);
|
||||||
$columns[$column['name']] = $column;
|
|
||||||
|
|
||||||
if ($class->isIdentifier($mapping['fieldName'])) {
|
if ($class->isIdentifier($mapping['fieldName'])) {
|
||||||
$pkColumns[] = $column['name'];
|
$pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For now, this is a hack required for single table inheritence, since this method is called
|
// For now, this is a hack required for single table inheritence, since this method is called
|
||||||
@ -323,7 +258,6 @@ class SchemaTool
|
|||||||
$table->setPrimaryKey($pkColumns);
|
$table->setPrimaryKey($pkColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $columns;
|
return $columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,55 +266,44 @@ class SchemaTool
|
|||||||
*
|
*
|
||||||
* @param ClassMetadata $class The class that owns the field mapping.
|
* @param ClassMetadata $class The class that owns the field mapping.
|
||||||
* @param array $mapping The field mapping.
|
* @param array $mapping The field mapping.
|
||||||
* @param array $options The table options/constraints where any additional options/constraints
|
|
||||||
* required by the column should be appended.
|
|
||||||
* @param Table $table
|
* @param Table $table
|
||||||
* @return array The portable column definition as required by the DBAL.
|
* @return array The portable column definition as required by the DBAL.
|
||||||
*/
|
*/
|
||||||
private function _gatherColumn($class, array $mapping, array &$options, $table)
|
private function _gatherColumn($class, array $mapping, $table)
|
||||||
{
|
{
|
||||||
$column = array();
|
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
||||||
$column['name'] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
$columnType = $mapping['type'];
|
||||||
$column['type'] = Type::getType($mapping['type']);
|
|
||||||
$column['length'] = isset($mapping['length']) ? $mapping['length'] : null;
|
|
||||||
$column['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
|
|
||||||
$column['unique'] = isset($mapping['unique']) ? $mapping['unique'] : false;
|
|
||||||
$column['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
|
|
||||||
|
|
||||||
if(strtolower($column['type']) == 'string' && $column['length'] === null) {
|
$options = array();
|
||||||
$column['length'] = 255;
|
$options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
|
||||||
|
$options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
|
||||||
|
|
||||||
|
$options['platformOptions'] = array();
|
||||||
|
$options['platformOptions']['unique'] = isset($mapping['unique']) ? $mapping['unique'] : false;
|
||||||
|
$options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
|
||||||
|
|
||||||
|
if(strtolower($columnType) == 'string' && $options['length'] === null) {
|
||||||
|
$options['length'] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($mapping['precision'])) {
|
if (isset($mapping['precision'])) {
|
||||||
$column['precision'] = $mapping['precision'];
|
$options['precision'] = $mapping['precision'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($mapping['scale'])) {
|
if (isset($mapping['scale'])) {
|
||||||
$column['scale'] = $mapping['scale'];
|
$options['scale'] = $mapping['scale'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($mapping['default'])) {
|
if (isset($mapping['default'])) {
|
||||||
$column['default'] = $mapping['default'];
|
$options['default'] = $mapping['default'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$column['platformOptions']['unique'] = $column['unique'];
|
if ($table->hasColumn($columnName)) {
|
||||||
$column['platformOptions']['version'] = $column['version'];
|
// required in some inheritence scenarios
|
||||||
if ($table->hasColumn($column['name'])) {
|
$table->changeColumn($columnName, $options);
|
||||||
$table->changeColumn($column['name'], $column);
|
|
||||||
} else {
|
} else {
|
||||||
$table->createColumn($column['name'], $mapping['type'], $column);
|
$table->createColumn($columnName, $columnType, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($class->isIdentifier($mapping['fieldName'])) {
|
|
||||||
$column['primary'] = true;
|
|
||||||
$options['primary'][] = $mapping['columnName'];
|
|
||||||
|
|
||||||
if ($class->isIdGeneratorIdentity()) {
|
|
||||||
$column['autoincrement'] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -395,7 +318,7 @@ class SchemaTool
|
|||||||
* required by relations should be appended.
|
* required by relations should be appended.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function _gatherRelationsSql($class, array &$sql, array &$columns, array &$constraints, $table, $schema)
|
private function _gatherRelationsSql($class, $table, $schema)
|
||||||
{
|
{
|
||||||
foreach ($class->associationMappings as $fieldName => $mapping) {
|
foreach ($class->associationMappings as $fieldName => $mapping) {
|
||||||
if (isset($class->inheritedAssociationFields[$fieldName])) {
|
if (isset($class->inheritedAssociationFields[$fieldName])) {
|
||||||
@ -405,15 +328,12 @@ class SchemaTool
|
|||||||
$foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
$foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
||||||
|
|
||||||
if ($mapping->isOneToOne() && $mapping->isOwningSide) {
|
if ($mapping->isOneToOne() && $mapping->isOwningSide) {
|
||||||
$constraint = array();
|
$options = array();
|
||||||
$constraint['tableName'] = $class->getQuotedTableName($this->_platform);
|
$localColumns = array();
|
||||||
$constraint['foreignTable'] = $foreignClass->getQuotedTableName($this->_platform);
|
$foreignColumns = array();
|
||||||
$constraint['local'] = array();
|
|
||||||
$constraint['foreign'] = array();
|
|
||||||
|
|
||||||
foreach ($mapping->getJoinColumns() as $joinColumn) {
|
foreach ($mapping->getJoinColumns() as $joinColumn) {
|
||||||
$column = array();
|
$columnName = $mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform);
|
||||||
$column['name'] = $mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform);
|
|
||||||
$referencedColumnName = $joinColumn['referencedColumnName'];
|
$referencedColumnName = $joinColumn['referencedColumnName'];
|
||||||
$referencedFieldName = $foreignClass->getFieldName($referencedColumnName);
|
$referencedFieldName = $foreignClass->getFieldName($referencedColumnName);
|
||||||
if (!$foreignClass->hasField($referencedFieldName)) {
|
if (!$foreignClass->hasField($referencedFieldName)) {
|
||||||
@ -422,107 +342,82 @@ class SchemaTool
|
|||||||
"$mapping->sourceEntityName towards $mapping->targetEntityName does not exist."
|
"$mapping->sourceEntityName towards $mapping->targetEntityName does not exist."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$column['type'] = Type::getType($foreignClass->getTypeOfField($referencedFieldName));
|
|
||||||
|
|
||||||
$table->createColumn($column['name'], $foreignClass->getTypeOfField($referencedFieldName), array('notnull' => false));
|
$table->createColumn(
|
||||||
|
$columnName, $foreignClass->getTypeOfField($referencedFieldName), array('notnull' => false)
|
||||||
|
);
|
||||||
|
|
||||||
$columns[$column['name']] = $column;
|
$localColumns[] = $columnName;
|
||||||
$constraint['local'][] = $column['name'];
|
$foreignColumns[] = $joinColumn['referencedColumnName'];
|
||||||
$constraint['foreign'][] = $joinColumn['referencedColumnName'];
|
|
||||||
|
|
||||||
if (isset($joinColumn['onUpdate'])) {
|
if (isset($joinColumn['onUpdate'])) {
|
||||||
$constraint['onUpdate'] = $joinColumn['onUpdate'];
|
$options['onUpdate'] = $joinColumn['onUpdate'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($joinColumn['onDelete'])) {
|
if (isset($joinColumn['onDelete'])) {
|
||||||
$constraint['onDelete'] = $joinColumn['onDelete'];
|
$options['onDelete'] = $joinColumn['onDelete'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$table->addForeignKeyConstraint(
|
$table->addForeignKeyConstraint(
|
||||||
$foreignClass->getQuotedTableName($this->_platform),
|
$foreignClass->getQuotedTableName($this->_platform),
|
||||||
$constraint['local'], $constraint['foreign'], null,
|
$localColumns, $foreignColumns, null, $options
|
||||||
$constraint
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$constraints[] = $constraint;
|
|
||||||
} else if ($mapping->isOneToMany() && $mapping->isOwningSide) {
|
} else if ($mapping->isOneToMany() && $mapping->isOwningSide) {
|
||||||
//... create join table, one-many through join table supported later
|
//... create join table, one-many through join table supported later
|
||||||
throw DoctrineException::notSupported();
|
throw DoctrineException::notSupported();
|
||||||
} else if ($mapping->isManyToMany() && $mapping->isOwningSide) {
|
} else if ($mapping->isManyToMany() && $mapping->isOwningSide) {
|
||||||
// create join table
|
// create join table
|
||||||
$joinTableColumns = array();
|
|
||||||
$joinTableOptions = array('primary' => array(), 'uniqueConstraints' => array());
|
|
||||||
$joinTable = $mapping->getJoinTable();
|
$joinTable = $mapping->getJoinTable();
|
||||||
|
|
||||||
// Build first FK constraint (relation table => source table)
|
$localColumns = array();
|
||||||
$constraint1 = array(
|
$foreignColumns = array();
|
||||||
'tableName' => $mapping->getQuotedJoinTableName($this->_platform),
|
$fkOptions = array();
|
||||||
'foreignTable' => $class->getQuotedTableName($this->_platform),
|
|
||||||
'local' => array(),
|
|
||||||
'foreign' => array()
|
|
||||||
);
|
|
||||||
|
|
||||||
$theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform));
|
$theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform));
|
||||||
|
|
||||||
$primaryKeyColumns = array();
|
$primaryKeyColumns = array();
|
||||||
|
$uniqueConstraints = array();
|
||||||
foreach ($joinTable['joinColumns'] as $joinColumn) {
|
foreach ($joinTable['joinColumns'] as $joinColumn) {
|
||||||
$column = array();
|
$columnName = $mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform);
|
||||||
$column['primary'] = true;
|
|
||||||
$joinTableOptions['primary'][] = $joinColumn['name'];
|
|
||||||
$primaryKeyColumns[] = $joinColumn['name'];
|
|
||||||
$column['name'] = $mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform);
|
|
||||||
$column['type'] = Type::getType($class->getTypeOfColumn($joinColumn['referencedColumnName']));
|
|
||||||
$joinTableColumns[$column['name']] = $column;
|
|
||||||
|
|
||||||
$theJoinTable->createColumn(
|
$theJoinTable->createColumn(
|
||||||
$mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform),
|
$columnName,
|
||||||
$class->getTypeOfColumn($joinColumn['referencedColumnName']),
|
$class->getTypeOfColumn($joinColumn['referencedColumnName']),
|
||||||
array('notnull' => false)
|
array('notnull' => false)
|
||||||
);
|
);
|
||||||
|
|
||||||
$constraint1['local'][] = $column['name'];
|
$primaryKeyColumns[] = $columnName;
|
||||||
$constraint1['foreign'][] = $joinColumn['referencedColumnName'];
|
|
||||||
|
$localColumns[] = $columnName;
|
||||||
|
$foreignColumns[] = $joinColumn['referencedColumnName'];
|
||||||
|
|
||||||
if(isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
|
if(isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
|
||||||
$joinTableOptions['uniqueConstraints'][] = array($joinColumn['name']);
|
$uniqueConstraints[] = array($joinColumn['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($joinColumn['onUpdate'])) {
|
if (isset($joinColumn['onUpdate'])) {
|
||||||
$constraint1['onUpdate'] = $joinColumn['onUpdate'];
|
$fkOptions['onUpdate'] = $joinColumn['onUpdate'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($joinColumn['onDelete'])) {
|
if (isset($joinColumn['onDelete'])) {
|
||||||
$constraint1['onDelete'] = $joinColumn['onDelete'];
|
$fkOptions['onDelete'] = $joinColumn['onDelete'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build first FK constraint (relation table => source table)
|
||||||
$theJoinTable->addForeignKeyConstraint(
|
$theJoinTable->addForeignKeyConstraint(
|
||||||
$class->getQuotedTableName($this->_platform),
|
$class->getQuotedTableName($this->_platform), $localColumns, $foreignColumns, null, $fkOptions
|
||||||
$constraint1['local'], $constraint1['foreign'], null,
|
|
||||||
$constraint1
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$constraints[] = $constraint1;
|
$localColumns = array();
|
||||||
|
$foreignColumns = array();
|
||||||
// Build second FK constraint (relation table => target table)
|
$fkOptions = array();
|
||||||
$constraint2 = array();
|
|
||||||
$constraint2['tableName'] = $mapping->getQuotedJoinTableName($this->_platform);
|
|
||||||
$constraint2['foreignTable'] = $foreignClass->getQuotedTableName($this->_platform);
|
|
||||||
$constraint2['local'] = array();
|
|
||||||
$constraint2['foreign'] = array();
|
|
||||||
|
|
||||||
foreach ($joinTable['inverseJoinColumns'] as $inverseJoinColumn) {
|
foreach ($joinTable['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||||
$column = array();
|
|
||||||
$column['primary'] = true;
|
|
||||||
$joinTableOptions['primary'][] = $inverseJoinColumn['name'];
|
|
||||||
$primaryKeyColumns[] = $inverseJoinColumn['name'];
|
$primaryKeyColumns[] = $inverseJoinColumn['name'];
|
||||||
$column['name'] = $inverseJoinColumn['name'];
|
$localColumns[] = $inverseJoinColumn['name'];
|
||||||
$column['type'] = Type::getType($this->_em->getClassMetadata($mapping->getTargetEntityName())
|
$foreignColumns[] = $inverseJoinColumn['referencedColumnName'];
|
||||||
->getTypeOfColumn($inverseJoinColumn['referencedColumnName']));
|
|
||||||
$joinTableColumns[$inverseJoinColumn['name']] = $column;
|
|
||||||
$constraint2['local'][] = $inverseJoinColumn['name'];
|
|
||||||
$constraint2['foreign'][] = $inverseJoinColumn['referencedColumnName'];
|
|
||||||
|
|
||||||
$theJoinTable->createColumn(
|
$theJoinTable->createColumn(
|
||||||
$inverseJoinColumn['name'],
|
$inverseJoinColumn['name'],
|
||||||
@ -532,36 +427,28 @@ class SchemaTool
|
|||||||
);
|
);
|
||||||
|
|
||||||
if(isset($inverseJoinColumn['unique']) && $inverseJoinColumn['unique'] == true) {
|
if(isset($inverseJoinColumn['unique']) && $inverseJoinColumn['unique'] == true) {
|
||||||
$joinTableOptions['uniqueConstraints'][] = array($inverseJoinColumn['name']);
|
$uniqueConstraints[] = array($inverseJoinColumn['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($inverseJoinColumn['onUpdate'])) {
|
if (isset($inverseJoinColumn['onUpdate'])) {
|
||||||
$constraint2['onUpdate'] = $inverseJoinColumn['onUpdate'];
|
$fkOptions['onUpdate'] = $inverseJoinColumn['onUpdate'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($joinColumn['onDelete'])) {
|
if (isset($joinColumn['onDelete'])) {
|
||||||
$constraint2['onDelete'] = $inverseJoinColumn['onDelete'];
|
$fkOptions['onDelete'] = $inverseJoinColumn['onDelete'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($joinTableOptions['uniqueConstraints'] AS $unique) {
|
foreach($uniqueConstraints AS $unique) {
|
||||||
$theJoinTable->addUniqueIndex($unique);
|
$theJoinTable->addUniqueIndex($unique);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build second FK constraint (relation table => target table)
|
||||||
$theJoinTable->addForeignKeyConstraint(
|
$theJoinTable->addForeignKeyConstraint(
|
||||||
$foreignClass->getQuotedTableName($this->_platform),
|
$foreignClass->getQuotedTableName($this->_platform), $localColumns, $foreignColumns, null, $fkOptions
|
||||||
$constraint2['local'], $constraint2['foreign'], null,
|
|
||||||
$constraint2
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$theJoinTable->setPrimaryKey($primaryKeyColumns);
|
$theJoinTable->setPrimaryKey($primaryKeyColumns);
|
||||||
|
|
||||||
$constraints[] = $constraint2;
|
|
||||||
|
|
||||||
// Get the SQL for creating the join table and merge it with the others
|
|
||||||
$sql = array_merge($sql, $this->_platform->getCreateTableSql(
|
|
||||||
$mapping->getQuotedJoinTableName($this->_platform), $joinTableColumns, $joinTableOptions)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,7 +749,7 @@ class SchemaTool
|
|||||||
foreach ($newFields as $newField) {
|
foreach ($newFields as $newField) {
|
||||||
$options = array();
|
$options = array();
|
||||||
$table = new \Doctrine\DBAL\Schema\Table("foo");
|
$table = new \Doctrine\DBAL\Schema\Table("foo");
|
||||||
$changes['add'][$newField['columnName']] = $this->_gatherColumn($class, $newField, $options, $table);
|
$changes['add'][$newField['columnName']] = $this->_gatherUpdateColumn($class, $newField, $options, $table);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($newJoinColumns as $name => $joinColumn) {
|
foreach ($newJoinColumns as $name => $joinColumn) {
|
||||||
@ -915,6 +802,53 @@ class SchemaTool
|
|||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary method, required because schema update is not on par with schema create refactorings.
|
||||||
|
*
|
||||||
|
* @param <type> $class
|
||||||
|
* @param array $mapping
|
||||||
|
* @param array $options
|
||||||
|
* @param <type> $table
|
||||||
|
* @return <type>
|
||||||
|
*/
|
||||||
|
private function _gatherUpdateColumn($class, array $mapping, array &$options, $table)
|
||||||
|
{
|
||||||
|
$column = array();
|
||||||
|
$column['name'] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
|
||||||
|
$column['type'] = Type::getType($mapping['type']);
|
||||||
|
$column['length'] = isset($mapping['length']) ? $mapping['length'] : null;
|
||||||
|
$column['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
|
||||||
|
$column['unique'] = isset($mapping['unique']) ? $mapping['unique'] : false;
|
||||||
|
$column['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
|
||||||
|
|
||||||
|
if(strtolower($column['type']) == 'string' && $column['length'] === null) {
|
||||||
|
$column['length'] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mapping['precision'])) {
|
||||||
|
$column['precision'] = $mapping['precision'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mapping['scale'])) {
|
||||||
|
$column['scale'] = $mapping['scale'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($mapping['default'])) {
|
||||||
|
$column['default'] = $mapping['default'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($class->isIdentifier($mapping['fieldName'])) {
|
||||||
|
$column['primary'] = true;
|
||||||
|
$options['primary'][] = $mapping['columnName'];
|
||||||
|
|
||||||
|
if ($class->isIdGeneratorIdentity()) {
|
||||||
|
$column['autoincrement'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $column;
|
||||||
|
}
|
||||||
|
|
||||||
private function _getCommitOrder(array $classes)
|
private function _getCommitOrder(array $classes)
|
||||||
{
|
{
|
||||||
$calc = new CommitOrderCalculator;
|
$calc = new CommitOrderCalculator;
|
||||||
|
@ -28,8 +28,8 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$sql = $tool->getCreateSchemaSql($classes);
|
$sql = $tool->getCreateSchemaSql($classes);
|
||||||
$this->assertEquals(count($sql), 8);
|
$this->assertEquals(count($sql), 8);
|
||||||
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(id)) ENGINE = InnoDB", $sql[0]);
|
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(id)) ENGINE = InnoDB", $sql[0]);
|
||||||
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT DEFAULT NULL, group_id INT DEFAULT NULL, PRIMARY KEY(user_id, group_id)) ENGINE = InnoDB", $sql[1]);
|
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(50) NOT NULL, username VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB", $sql[1]);
|
||||||
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(50) NOT NULL, username VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB", $sql[2]);
|
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT DEFAULT NULL, group_id INT DEFAULT NULL, PRIMARY KEY(user_id, group_id)) ENGINE = InnoDB", $sql[2]);
|
||||||
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber)) ENGINE = InnoDB", $sql[3]);
|
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber)) ENGINE = InnoDB", $sql[3]);
|
||||||
$this->assertEquals("ALTER TABLE cms_addresses ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[4]);
|
$this->assertEquals("ALTER TABLE cms_addresses ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[4]);
|
||||||
$this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[5]);
|
$this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[5]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user