diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index fe477e0f78f228b0f45bbac0581430657359e6e8..a58c747e92973470935800a0c59c128506b5d458 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -674,6 +674,44 @@ LEFT JOIN user_cons_columns r_cols return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; } + /** + * {@inheritdoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $referentialAction = null; + + if ($foreignKey->hasOption('onDelete')) { + $referentialAction = $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + + return $referentialAction ? ' ON DELETE ' . $referentialAction : ''; + } + + /** + * {@inheritdoc} + */ + public function getForeignKeyReferentialActionSQL($action) + { + $action = strtoupper($action); + + switch ($action) { + case 'RESTRICT': // RESTRICT is not supported, therefore falling back to NO ACTION. + case 'NO ACTION': + // NO ACTION cannot be declared explicitly, + // therefore returning empty string to indicate to OMIT the referential clause. + return ''; + + case 'CASCADE': + case 'SET NULL': + return $action; + + default: + // SET DEFAULT is not supported, throw exception instead. + throw new \InvalidArgumentException('Invalid foreign key action: ' . $action); + } + } + /** * {@inheritDoc} */ diff --git a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php index 53493b97fe84240d95d8886f9cc05be4f78d502a..ab99a90c7e4e0a85fbeb2fad47481c052c4b0ee6 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php @@ -5,6 +5,7 @@ namespace Doctrine\Tests\DBAL\Platforms; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; @@ -203,6 +204,47 @@ class OraclePlatformTest extends AbstractPlatformTestCase return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)'; } + /** + * @group DBAL-1097 + * + * @dataProvider getGeneratesAdvancedForeignKeyOptionsSQLData + */ + public function testGeneratesAdvancedForeignKeyOptionsSQL(array $options, $expectedSql) + { + $foreignKey = new ForeignKeyConstraint(array('foo'), 'foreign_table', array('bar'), null, $options); + + $this->assertSame($expectedSql, $this->_platform->getAdvancedForeignKeyOptionsSQL($foreignKey)); + } + + /** + * @return array + */ + public function getGeneratesAdvancedForeignKeyOptionsSQLData() + { + return array( + array(array(), ''), + array(array('onUpdate' => 'CASCADE'), ''), + array(array('onDelete' => 'CASCADE'), ' ON DELETE CASCADE'), + array(array('onDelete' => 'NO ACTION'), ''), + array(array('onDelete' => 'RESTRICT'), ''), + array(array('onUpdate' => 'SET NULL', 'onDelete' => 'SET NULL'), ' ON DELETE SET NULL'), + ); + } + + /** + * {@inheritdoc} + */ + public function getReturnsForeignKeyReferentialActionSQL() + { + return array( + array('CASCADE', 'CASCADE'), + array('SET NULL', 'SET NULL'), + array('NO ACTION', ''), + array('RESTRICT', ''), + array('CaScAdE', 'CASCADE'), + ); + } + public function testModifyLimitQuery() { $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0);