1
0
mirror of synced 2024-12-13 06:46:03 +03:00

[2.0] DDC-169 - Changed AbstractPlatform and AbstractSchemaManager Constraint API to accept Constraint interface, which is implemented by indexes and foreign keys.

This commit is contained in:
beberlei 2009-12-02 22:28:38 +00:00
parent 22375235db
commit 197224de2e
12 changed files with 160 additions and 121 deletions

View File

@ -454,8 +454,18 @@ abstract class AbstractPlatform
return 'DROP DATABASE ' . $database;
}
/**
* Drop a Table
*
* @param Table|string $table
* @return string
*/
public function getDropTableSql($table)
{
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
return 'DROP TABLE ' . $table;
}
@ -477,14 +487,42 @@ abstract class AbstractPlatform
return 'DROP INDEX ' . $index;
}
public function getDropConstraintSql($table, $name, $primary = false)
/**
* Get drop constraint sql
*
* @param \Doctrine\DBAL\Schema\Constraint $constraint
* @param string|Table $table
* @return string
*/
public function getDropConstraintSql($constraint, $table)
{
return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $name;
if ($constraint->getName()) {
$constraint = $constraint->getName();
}
if ($table->getName()) {
$table = $table->getName();
}
return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint;
}
public function getDropForeignKeySql($table, $name)
/**
* @param ForeignKeyConstraint|string $foreignKey
* @param Table|string $table
* @return string
*/
public function getDropForeignKeySql($foreignKey, $table)
{
return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $name;
if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
$foreignKey = $foreignKey->getName();
}
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey;
}
/**
@ -609,39 +647,46 @@ abstract class AbstractPlatform
/**
* Gets the SQL to create a constraint on a table on this platform.
*
* @param string $table name of the table on which the constraint is to be created
* @param string $name name of the constraint to be created
* @param array $definition associative array that defines properties of the constraint to be created.
* Currently, only one property named FIELDS is supported. This property
* is also an associative with the names of the constraint fields as array
* constraints. Each entry of this array is set to another type of associative
* array that specifies properties of the constraint that are specific to
* each field.
*
* Example
* array(
* 'columns' => array(
* 'user_name' => array(),
* 'last_login' => array()
* )
* )
* @param Constraint $constraint
* @param string|Table $table
* @return string
*/
public function getCreateConstraintSql($table, $name, $definition)
public function getCreateConstraintSql(\Doctrine\DBAL\Schema\Constraint $constraint, $table)
{
$query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $name;
if (isset($definition['primary']) && $definition['primary']) {
$query .= ' PRIMARY KEY';
} elseif (isset($definition['unique']) && $definition['unique']) {
$query .= ' UNIQUE';
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
$query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getName();
$columns = array();
foreach (array_keys($definition['columns']) as $column) {
foreach ($constraint->getColumns() as $column) {
$columns[] = $column;
}
$query .= ' ('. implode(', ', $columns) . ')';
$columnList = '('. implode(', ', $columns) . ')';
$referencesClause = '';
if ($constraint instanceof \Doctrine\DBAL\Schema\Index) {
if($constraint->isPrimary()) {
$query .= ' PRIMARY KEY';
} elseif ($constraint->isUnique()) {
$query .= ' UNIQUE';
} else {
throw new \InvalidArgumentException(
'Can only create primary or unique constraints, no common indexes with getCreateConstraintSql().'
);
}
} else if ($constraint instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
$query .= ' FOREIGN KEY';
$foreignColumns = array();
foreach ($constraint->getForeignColumns() AS $column) {
$foreignColumns[] = $column;
}
$referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')';
}
$query .= ' '.$columnList.$referencesClause;
return $query;
}
@ -1358,7 +1403,7 @@ abstract class AbstractPlatform
throw DBALException::notSupported(__METHOD__);
}
public function getDropSequenceSql($sequenceName)
public function getDropSequenceSql($sequence)
{
throw DBALException::notSupported(__METHOD__);
}

View File

@ -356,12 +356,14 @@ class OraclePlatform extends AbstractPlatform
'columns' => array($name => true),
);
$idx = new \Doctrine\DBAL\Schema\Index($indexName, array($name), true, true);
$sql[] = 'DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\';
IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSql($table, $indexName, $definition).'\';
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSql($idx, $table).'\';
END IF;
END;';
@ -440,9 +442,18 @@ END;';
return "SELECT * FROM all_tab_columns WHERE table_name = '" . $table . "' ORDER BY column_name";
}
public function getDropSequenceSql($sequenceName)
/**
*
* @param \Doctrine\DBAL\Schema\Sequence $sequence
* @return string
*/
public function getDropSequenceSql($sequence)
{
return 'DROP SEQUENCE ' . $sequenceName;
if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
$sequence = $sequence->getName();
}
return 'DROP SEQUENCE ' . $sequence;
}
public function getDropDatabaseSql($database)

View File

@ -572,14 +572,16 @@ class PostgreSqlPlatform extends AbstractPlatform
}
/**
* drop existing sequence
*
* @param string $sequenceName name of the sequence to be dropped
* @override
* Drop existing sequence
* @param \Doctrine\DBAL\Schema\Sequence $sequence
* @return string
*/
public function getDropSequenceSql($sequenceName)
public function getDropSequenceSql($sequence)
{
return 'DROP SEQUENCE ' . $sequenceName;
if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
$sequence = $sequence->getName();
}
return 'DROP SEQUENCE ' . $sequence;
}
/**

View File

@ -351,25 +351,24 @@ abstract class AbstractSchemaManager
/**
* Drop the constraint from the given table
*
* @param Constraint $constraint
* @param string $table The name of the table
* @param string $name The name of the constraint
* @param string $primary Whether or not it is a primary constraint
*/
public function dropConstraint($table, $name, $primary = false)
public function dropConstraint(Constraint $constraint, $table)
{
$this->_execSql($this->_platform->getDropConstraintSql($table, $name, $primary));
$this->_execSql($this->_platform->getDropConstraintSql($constraint, $table));
}
/**
* Drops a foreign key from a table.
*
* @param string $table The name of the table with the foreign key.
* @param string $name The name of the foreign key.
* @param ForeignKeyConstraint|string $table The name of the table with the foreign key.
* @param Table|string $name The name of the foreign key.
* @return boolean $result
*/
public function dropForeignKey($table, $name)
public function dropForeignKey($foreignKey, $table)
{
$this->_execSql($this->_platform->getDropForeignKeySql($table, $name));
$this->_execSql($this->_platform->getDropForeignKeySql($foreignKey, $table));
}
/**
@ -429,26 +428,12 @@ abstract class AbstractSchemaManager
/**
* Create a constraint on a table
*
* @param string $table name of the table on which the constraint is to be created
* @param string $name name of the constraint to be created
* @param array $definition associative array that defines properties of the constraint to be created.
* Currently, only one property named FIELDS is supported. This property
* is also an associative with the names of the constraint fields as array
* constraints. Each entry of this array is set to another type of associative
* array that specifies properties of the constraint that are specific to
* each field.
*
* Example
* array(
* 'columns' => array(
* 'user_name' => array(),
* 'last_login' => array()
* )
* )
* @param Constraint $constraint
* @param string|Table $table
*/
public function createConstraint($table, $name, $definition)
public function createConstraint(Constraint $constraint, $table)
{
$this->_execSql($this->_platform->getCreateConstraintSql($table, $name, $definition));
$this->_execSql($this->_platform->getCreateConstraintSql($constraint, $table));
}
/**
@ -489,30 +474,15 @@ abstract class AbstractSchemaManager
/**
* Drop and create a constraint
*
* @param string $table name of the table on which the constraint is to be created
* @param string $name name of the constraint to be created
* @param array $definition associative array that defines properties of the constraint to be created.
* Currently, only one property named FIELDS is supported. This property
* is also an associative with the names of the constraint fields as array
* constraints. Each entry of this array is set to another type of associative
* array that specifies properties of the constraint that are specific to
* each field.
*
* Example
* array(
* 'columns' => array(
* 'user_name' => array(),
* 'last_login' => array()
* )
* )
* @param boolean $primary Whether or not it is a primary constraint
* @param Constraint $constraint
* @param string $table
* @see dropConstraint()
* @see createConstraint()
*/
public function dropAndCreateConstraint($table, $name, $definition, $primary = false)
public function dropAndCreateConstraint(Constraint $constraint, $table)
{
$this->tryMethod('dropConstraint', $table, $name, $primary);
$this->createConstraint($table, $name, $definition);
$this->tryMethod('dropConstraint', $constraint, $table);
$this->createConstraint($constraint, $table);
}
/**
@ -530,24 +500,22 @@ abstract class AbstractSchemaManager
/**
* Drop and create a new foreign key
*
* @param string $table name of the table on which the foreign key is to be created
* @param array $definition associative array that defines properties of the foreign key to be created.
* @param ForeignKeyConstraint $foreignKey associative array that defines properties of the foreign key to be created.
* @param string|Table $table name of the table on which the foreign key is to be created
*/
public function dropAndCreateForeignKey($table, $definition)
public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
{
$this->tryMethod('dropForeignKey', $table, $definition['name']);
$this->createForeignKey($table, $definition);
$this->tryMethod('dropForeignKey', $foreignKey, $table);
$this->createForeignKey($foreignKey, $table);
}
/**
* Drop and create a new sequence
*
* @param string $seqName name of the sequence to be created
* @param string $start start value of the sequence; default is 1
* @param array $allocationSize The size to allocate for sequence
* @param Sequence $sequence
* @throws Doctrine\DBAL\ConnectionException if something fails at database level
*/
public function dropAndCreateSequence($seqName, $start = 1, $allocationSize = 1)
public function dropAndCreateSequence(Sequence $sequence)
{
$this->tryMethod('createSequence', $seqName, $start, $allocationSize);
$this->createSequence($seqName, $start, $allocationSize);

View File

@ -32,5 +32,7 @@ namespace Doctrine\DBAL\Schema;
*/
interface Constraint
{
public function getName();
public function getColumns();
}

View File

@ -75,6 +75,11 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
return $this->_localColumnNames;
}
public function getColumns()
{
return $this->_localColumnNames;
}
/**
* @return string
*/

View File

@ -23,7 +23,7 @@ namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Schema\Visitor\Visitor;
class Index extends AbstractAsset
class Index extends AbstractAsset implements Constraint
{
/**
* @var array

View File

@ -58,4 +58,34 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
}
abstract public function getGenerateForeignKeySql();
public function testGeneratesConstraintCreationSql()
{
$idx = new \Doctrine\DBAL\Schema\Index('constraint_name', array('test'), true, false);
$sql = $this->_platform->getCreateConstraintSql($idx, 'test');
$this->assertEquals($this->getGenerateConstraintUniqueIndexSql(), $sql);
$pk = new \Doctrine\DBAL\Schema\Index('constraint_name', array('test'), true, true);
$sql = $this->_platform->getCreateConstraintSql($pk, 'test');
$this->assertEquals($this->getGenerateConstraintPrimaryIndexSql(), $sql);
$fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('fk_name'), 'foreign', array('id'), 'constraint_fk');
$sql = $this->_platform->getCreateConstraintSql($fk, 'test');
$this->assertEquals($this->getGenerateConstraintForeignKeySql(), $sql);
}
public function getGenerateConstraintUniqueIndexSql()
{
return 'ALTER TABLE test ADD CONSTRAINT constraint_name UNIQUE (test)';
}
public function getGenerateConstraintPrimaryIndexSql()
{
return 'ALTER TABLE test ADD CONSTRAINT constraint_name PRIMARY KEY (test)';
}
public function getGenerateConstraintForeignKeySql()
{
return 'ALTER TABLE test ADD CONSTRAINT constraint_fk FOREIGN KEY (fk_name) REFERENCES foreign (id)';
}
}

View File

@ -125,12 +125,6 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase
$this->assertFalse($this->_platform->supportsSavepoints());
}
public function testGeneratesConstraintCreationSql()
{
$sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('columns' => array('test' => array())));
$this->assertEquals($sql, 'ALTER TABLE test ADD CONSTRAINT constraint_name (test)');
}
public function getGenerateIndexSql()
{
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';

View File

@ -127,12 +127,6 @@ class MySqlPlatformTest extends AbstractPlatformTestCase
$this->assertFalse($this->_platform->supportsSavepoints());
}
public function testGeneratesConstraintCreationSql()
{
$sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('columns' => array('test' => array())));
$this->assertEquals($sql, 'ALTER TABLE test ADD CONSTRAINT constraint_name (test)');
}
public function getGenerateIndexSql()
{
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';

View File

@ -162,13 +162,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
{
$this->assertTrue($this->_platform->supportsSavepoints());
}
public function testGeneratesConstraintCreationSql()
{
$sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('columns' => array('test' => array())));
$this->assertEquals($sql, 'ALTER TABLE test ADD CONSTRAINT constraint_name (test)');
}
public function getGenerateIndexSql()
{
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';

View File

@ -75,12 +75,6 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
);
}
public function testGeneratesConstraintCreationSql()
{
$sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('columns' => array('test' => array())));
$this->assertEquals('ALTER TABLE test ADD CONSTRAINT constraint_name (test)', $sql);
}
public function getGenerateIndexSql()
{
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';