Commit 197224de authored by beberlei's avatar beberlei

[2.0] DDC-169 - Changed AbstractPlatform and AbstractSchemaManager Constraint...

[2.0] DDC-169 - Changed AbstractPlatform and AbstractSchemaManager Constraint API to accept Constraint interface, which is implemented by indexes and foreign keys.
parent 22375235
...@@ -454,8 +454,18 @@ abstract class AbstractPlatform ...@@ -454,8 +454,18 @@ abstract class AbstractPlatform
return 'DROP DATABASE ' . $database; return 'DROP DATABASE ' . $database;
} }
/**
* Drop a Table
*
* @param Table|string $table
* @return string
*/
public function getDropTableSql($table) public function getDropTableSql($table)
{ {
if ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
return 'DROP TABLE ' . $table; return 'DROP TABLE ' . $table;
} }
...@@ -477,14 +487,42 @@ abstract class AbstractPlatform ...@@ -477,14 +487,42 @@ abstract class AbstractPlatform
return 'DROP INDEX ' . $index; 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();
} }
public function getDropForeignKeySql($table, $name) return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint;
}
/**
* @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 ...@@ -609,39 +647,46 @@ abstract class AbstractPlatform
/** /**
* Gets the SQL to create a constraint on a table on this platform. * 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 Constraint $constraint
* @param string $name name of the constraint to be created * @param string|Table $table
* @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()
* )
* )
* @return string * @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 ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
if (isset($definition['primary']) && $definition['primary']) { $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getName();
$columns = array();
foreach ($constraint->getColumns() as $column) {
$columns[] = $column;
}
$columnList = '('. implode(', ', $columns) . ')';
$referencesClause = '';
if ($constraint instanceof \Doctrine\DBAL\Schema\Index) {
if($constraint->isPrimary()) {
$query .= ' PRIMARY KEY'; $query .= ' PRIMARY KEY';
} elseif (isset($definition['unique']) && $definition['unique']) { } elseif ($constraint->isUnique()) {
$query .= ' UNIQUE'; $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';
$columns = array(); $foreignColumns = array();
foreach (array_keys($definition['columns']) as $column) { foreach ($constraint->getForeignColumns() AS $column) {
$columns[] = $column; $foreignColumns[] = $column;
}
$referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')';
} }
$query .= ' ('. implode(', ', $columns) . ')'; $query .= ' '.$columnList.$referencesClause;
return $query; return $query;
} }
...@@ -1358,7 +1403,7 @@ abstract class AbstractPlatform ...@@ -1358,7 +1403,7 @@ abstract class AbstractPlatform
throw DBALException::notSupported(__METHOD__); throw DBALException::notSupported(__METHOD__);
} }
public function getDropSequenceSql($sequenceName) public function getDropSequenceSql($sequence)
{ {
throw DBALException::notSupported(__METHOD__); throw DBALException::notSupported(__METHOD__);
} }
......
...@@ -356,12 +356,14 @@ class OraclePlatform extends AbstractPlatform ...@@ -356,12 +356,14 @@ class OraclePlatform extends AbstractPlatform
'columns' => array($name => true), 'columns' => array($name => true),
); );
$idx = new \Doctrine\DBAL\Schema\Index($indexName, array($name), true, true);
$sql[] = 'DECLARE $sql[] = 'DECLARE
constraints_Count NUMBER; constraints_Count NUMBER;
BEGIN BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\'; 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 IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSql($table, $indexName, $definition).'\'; EXECUTE IMMEDIATE \''.$this->getCreateConstraintSql($idx, $table).'\';
END IF; END IF;
END;'; END;';
...@@ -440,9 +442,18 @@ END;'; ...@@ -440,9 +442,18 @@ END;';
return "SELECT * FROM all_tab_columns WHERE table_name = '" . $table . "' ORDER BY column_name"; 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) public function getDropDatabaseSql($database)
......
...@@ -572,14 +572,16 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -572,14 +572,16 @@ class PostgreSqlPlatform extends AbstractPlatform
} }
/** /**
* drop existing sequence * Drop existing sequence
* * @param \Doctrine\DBAL\Schema\Sequence $sequence
* @param string $sequenceName name of the sequence to be dropped * @return string
* @override
*/ */
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;
} }
/** /**
......
...@@ -351,25 +351,24 @@ abstract class AbstractSchemaManager ...@@ -351,25 +351,24 @@ abstract class AbstractSchemaManager
/** /**
* Drop the constraint from the given table * Drop the constraint from the given table
* *
* @param Constraint $constraint
* @param string $table The name of the table * @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. * Drops a foreign key from a table.
* *
* @param string $table The name of the table with the foreign key. * @param ForeignKeyConstraint|string $table The name of the table with the foreign key.
* @param string $name The name of the foreign key. * @param Table|string $name The name of the foreign key.
* @return boolean $result * @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 ...@@ -429,26 +428,12 @@ abstract class AbstractSchemaManager
/** /**
* Create a constraint on a table * Create a constraint on a table
* *
* @param string $table name of the table on which the constraint is to be created * @param Constraint $constraint
* @param string $name name of the constraint to be created * @param string|Table $table
* @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()
* )
* )
*/ */
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 ...@@ -489,30 +474,15 @@ abstract class AbstractSchemaManager
/** /**
* Drop and create a constraint * Drop and create a constraint
* *
* @param string $table name of the table on which the constraint is to be created * @param Constraint $constraint
* @param string $name name of the constraint to be created * @param string $table
* @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
* @see dropConstraint() * @see dropConstraint()
* @see createConstraint() * @see createConstraint()
*/ */
public function dropAndCreateConstraint($table, $name, $definition, $primary = false) public function dropAndCreateConstraint(Constraint $constraint, $table)
{ {
$this->tryMethod('dropConstraint', $table, $name, $primary); $this->tryMethod('dropConstraint', $constraint, $table);
$this->createConstraint($table, $name, $definition); $this->createConstraint($constraint, $table);
} }
/** /**
...@@ -530,24 +500,22 @@ abstract class AbstractSchemaManager ...@@ -530,24 +500,22 @@ abstract class AbstractSchemaManager
/** /**
* Drop and create a new foreign key * Drop and create a new foreign key
* *
* @param string $table name of the table on which the foreign key is to be created * @param ForeignKeyConstraint $foreignKey associative array that defines properties of the foreign key to be created.
* @param array $definition 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->tryMethod('dropForeignKey', $foreignKey, $table);
$this->createForeignKey($table, $definition); $this->createForeignKey($foreignKey, $table);
} }
/** /**
* Drop and create a new sequence * Drop and create a new sequence
* *
* @param string $seqName name of the sequence to be created * @param Sequence $sequence
* @param string $start start value of the sequence; default is 1
* @param array $allocationSize The size to allocate for sequence
* @throws Doctrine\DBAL\ConnectionException if something fails at database level * @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->tryMethod('createSequence', $seqName, $start, $allocationSize);
$this->createSequence($seqName, $start, $allocationSize); $this->createSequence($seqName, $start, $allocationSize);
......
...@@ -32,5 +32,7 @@ namespace Doctrine\DBAL\Schema; ...@@ -32,5 +32,7 @@ namespace Doctrine\DBAL\Schema;
*/ */
interface Constraint interface Constraint
{ {
public function getName();
public function getColumns();
} }
\ No newline at end of file
...@@ -75,6 +75,11 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -75,6 +75,11 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
return $this->_localColumnNames; return $this->_localColumnNames;
} }
public function getColumns()
{
return $this->_localColumnNames;
}
/** /**
* @return string * @return string
*/ */
......
...@@ -23,7 +23,7 @@ namespace Doctrine\DBAL\Schema; ...@@ -23,7 +23,7 @@ namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Schema\Visitor\Visitor; use Doctrine\DBAL\Schema\Visitor\Visitor;
class Index extends AbstractAsset class Index extends AbstractAsset implements Constraint
{ {
/** /**
* @var array * @var array
......
...@@ -58,4 +58,34 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase ...@@ -58,4 +58,34 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
} }
abstract public function getGenerateForeignKeySql(); 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)';
}
} }
...@@ -125,12 +125,6 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase ...@@ -125,12 +125,6 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase
$this->assertFalse($this->_platform->supportsSavepoints()); $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() public function getGenerateIndexSql()
{ {
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
......
...@@ -127,12 +127,6 @@ class MySqlPlatformTest extends AbstractPlatformTestCase ...@@ -127,12 +127,6 @@ class MySqlPlatformTest extends AbstractPlatformTestCase
$this->assertFalse($this->_platform->supportsSavepoints()); $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() public function getGenerateIndexSql()
{ {
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
......
...@@ -163,12 +163,6 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -163,12 +163,6 @@ class OraclePlatformTest extends AbstractPlatformTestCase
$this->assertTrue($this->_platform->supportsSavepoints()); $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() public function getGenerateIndexSql()
{ {
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
......
...@@ -75,12 +75,6 @@ class SqlitePlatformTest extends AbstractPlatformTestCase ...@@ -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() public function getGenerateIndexSql()
{ {
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment