/** * {@inheritdoc} */ public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) { // The table may already be deleted in a previous // RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that // point to nowhere. if (!$this->schema->hasTable($fkConstraint->getForeignTableName())) { $localTable->removeForeignKey($fkConstraint->getName()); return; } $foreignTable = $this->schema->getTable($fkConstraint->getForeignTableName()); if (!$foreignTable->isInDefaultNamespace($this->schema->getName())) { $localTable->removeForeignKey($fkConstraint->getName()); } }
/** * @param Schema $schema * @param Table $table * @param string $keyName */ protected function setOwnerCascadeDelete(Schema $schema, Table $table, $keyName) { foreach ($table->getForeignKeys() as $foreignKey) { if ($foreignKey->getLocalColumns() == ['owner_id']) { $table->removeForeignKey($foreignKey->getName()); $table->addForeignKeyConstraint($schema->getTable('orocrm_contact'), ['owner_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => null], $keyName); break; } } }
/** * Gathers columns and fk constraints that are required for one part of relationship. * * @param array $joinColumns * @param Table $theJoinTable * @param ClassMetadata $class * @param array $mapping * @param array $primaryKeyColumns * @param array $addedFks * @param array $blacklistedFks * * @return void * * @throws \Doctrine\ORM\ORMException */ private function gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$addedFks, &$blacklistedFks) { $localColumns = array(); $foreignColumns = array(); $fkOptions = array(); $foreignTableName = $this->quoteStrategy->getTableName($class, $this->platform); $uniqueConstraints = array(); foreach ($joinColumns as $joinColumn) { list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']); if (!$definingClass) { throw new \Doctrine\ORM\ORMException("Column name `" . $joinColumn['referencedColumnName'] . "` referenced for relation from " . $mapping['sourceEntity'] . " towards " . $mapping['targetEntity'] . " does not exist."); } $quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); $quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $class, $this->platform); $primaryKeyColumns[] = $quotedColumnName; $localColumns[] = $quotedColumnName; $foreignColumns[] = $quotedRefColumnName; if (!$theJoinTable->hasColumn($quotedColumnName)) { // Only add the column to the table if it does not exist already. // It might exist already if the foreign key is mapped into a regular // property as well. $fieldMapping = $definingClass->getFieldMapping($referencedFieldName); $columnDef = null; if (isset($joinColumn['columnDefinition'])) { $columnDef = $joinColumn['columnDefinition']; } elseif (isset($fieldMapping['columnDefinition'])) { $columnDef = $fieldMapping['columnDefinition']; } $columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef); if (isset($joinColumn['nullable'])) { $columnOptions['notnull'] = !$joinColumn['nullable']; } if (isset($fieldMapping['options'])) { $columnOptions['options'] = $fieldMapping['options']; } if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) { $columnOptions['length'] = $fieldMapping['length']; } elseif ($fieldMapping['type'] == "decimal") { $columnOptions['scale'] = $fieldMapping['scale']; $columnOptions['precision'] = $fieldMapping['precision']; } $theJoinTable->addColumn($quotedColumnName, $fieldMapping['type'], $columnOptions); } if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) { $uniqueConstraints[] = array('columns' => array($quotedColumnName)); } if (isset($joinColumn['onDelete'])) { $fkOptions['onDelete'] = $joinColumn['onDelete']; } } // Prefer unique constraints over implicit simple indexes created for foreign keys. // Also avoids index duplication. foreach ($uniqueConstraints as $indexName => $unique) { $theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName); } $compositeName = $theJoinTable->getName() . '.' . implode('', $localColumns); if (isset($addedFks[$compositeName]) && ($foreignTableName != $addedFks[$compositeName]['foreignTableName'] || 0 < count(array_diff($foreignColumns, $addedFks[$compositeName]['foreignColumns'])))) { foreach ($theJoinTable->getForeignKeys() as $fkName => $key) { if (0 === count(array_diff($key->getLocalColumns(), $localColumns)) && ($key->getForeignTableName() != $foreignTableName || 0 < count(array_diff($key->getForeignColumns(), $foreignColumns)))) { $theJoinTable->removeForeignKey($fkName); break; } } $blacklistedFks[$compositeName] = true; } elseif (!isset($blacklistedFks[$compositeName])) { $addedFks[$compositeName] = array('foreignTableName' => $foreignTableName, 'foreignColumns' => $foreignColumns); $theJoinTable->addUnnamedForeignKeyConstraint($foreignTableName, $localColumns, $foreignColumns, $fkOptions); } }
/** * @dataProvider getNormalizesAssetNames * @group DBAL-831 */ public function testNormalizesColumnNames($assetName) { $table = new Table('test'); $table->addColumn($assetName, 'integer'); $table->addIndex(array($assetName), $assetName); $table->addForeignKeyConstraint('test', array($assetName), array($assetName), array(), $assetName); $this->assertTrue($table->hasColumn($assetName)); $this->assertTrue($table->hasColumn('foo')); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\Column', $table->getColumn($assetName)); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\Column', $table->getColumn('foo')); $this->assertTrue($table->hasIndex($assetName)); $this->assertTrue($table->hasIndex('foo')); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\Index', $table->getIndex($assetName)); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\Index', $table->getIndex('foo')); $this->assertTrue($table->hasForeignKey($assetName)); $this->assertTrue($table->hasForeignKey('foo')); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\ForeignKeyConstraint', $table->getForeignKey($assetName)); $this->assertInstanceOf('Doctrine\\DBAL\\Schema\\ForeignKeyConstraint', $table->getForeignKey('foo')); $table->renameIndex($assetName, $assetName); $this->assertTrue($table->hasIndex($assetName)); $this->assertTrue($table->hasIndex('foo')); $table->renameIndex($assetName, 'foo'); $this->assertTrue($table->hasIndex($assetName)); $this->assertTrue($table->hasIndex('foo')); $table->renameIndex('foo', $assetName); $this->assertTrue($table->hasIndex($assetName)); $this->assertTrue($table->hasIndex('foo')); $table->renameIndex($assetName, 'bar'); $this->assertFalse($table->hasIndex($assetName)); $this->assertFalse($table->hasIndex('foo')); $this->assertTrue($table->hasIndex('bar')); $table->renameIndex('bar', $assetName); $table->dropColumn($assetName); $table->dropIndex($assetName); $table->removeForeignKey($assetName); $this->assertFalse($table->hasColumn($assetName)); $this->assertFalse($table->hasColumn('foo')); $this->assertFalse($table->hasIndex($assetName)); $this->assertFalse($table->hasIndex('foo')); $this->assertFalse($table->hasForeignKey($assetName)); $this->assertFalse($table->hasForeignKey('foo')); }
/** * @param \Doctrine\DBAL\Schema\Table $table * @param string $name */ private function removeForeignKeyAndIndex(\Doctrine\DBAL\Schema\Table $table, $name) { $table->removeForeignKey($name); $table->dropIndex(str_replace('FK', 'IDX', $name)); }