diff --git a/docs/book/sql-ddl.md b/docs/book/sql-ddl.md index 0daac436c9..cf20d9ad48 100644 --- a/docs/book/sql-ddl.md +++ b/docs/book/sql-ddl.md @@ -102,8 +102,32 @@ $table->changeColumn('name', Column\Varchar('new_name', 50)); You may also *drop* existing columns or constraints: ```php +use \Zend\Db\Metadata\Object\ConstraintObject; + $table->dropColumn('foo'); -$table->dropConstraint('my_index'); + +$constraint = new ConstraintObject('my_index', null); +$table->dropConstraint($constraint); +``` + +Notice: On MySQL, you need to specify the type of constraint you want to drop. +To do so you may use a `\Zend\Db\Metadata\Object\ConstraintObject` and set its +type accordingly or directly a subclass of +`\Zend\Db\Sql\Ddl\Constraint\ConstraintInterface`. +```php +use \Zend\Db\Metadata\Object\ConstraintObject; + +$fkConstraint = new ConstraintObject('my_fk', null); +$fkConstraint->setType('FOREIGN KEY'); +$table->dropConstraint($fkConstraint); +``` + +```php +use \Zend\Db\Sql\Ddl\Constraint\UniqueKey; +$idxConstraint = new \Zend\Db\Sql\Ddl\Constraint\UniqueKey( + null, 'my_unique_index' +); +$table->dropConstraint($idxConstraint); ``` ## Dropping Tables diff --git a/src/Sql/Ddl/AlterTable.php b/src/Sql/Ddl/AlterTable.php index bee08f9996..9fef7facd7 100644 --- a/src/Sql/Ddl/AlterTable.php +++ b/src/Sql/Ddl/AlterTable.php @@ -10,6 +10,7 @@ namespace Zend\Db\Sql\Ddl; use Zend\Db\Adapter\Platform\PlatformInterface; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\AbstractSql; use Zend\Db\Sql\TableIdentifier; @@ -28,7 +29,7 @@ class AlterTable extends AbstractSql implements SqlInterface protected $addColumns = []; /** - * @var array + * @var Constraint\ConstraintInterface[] */ protected $addConstraints = []; @@ -43,7 +44,7 @@ class AlterTable extends AbstractSql implements SqlInterface protected $dropColumns = []; /** - * @var array + * @var Constraint\ConstraintInterface[]|ConstraintObject[] */ protected $dropConstraints = []; @@ -75,7 +76,7 @@ class AlterTable extends AbstractSql implements SqlInterface ], self::DROP_CONSTRAINTS => [ "%1\$s" => [ - [1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => ""], + [1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => " "], ] ] ]; @@ -139,12 +140,12 @@ public function dropColumn($name) } /** - * @param string $name + * @param Constraint\ConstraintInterface|ConstraintObject $constraint * @return self Provides a fluent interface */ - public function dropConstraint($name) + public function dropConstraint($constraint) { - $this->dropConstraints[] = $name; + $this->dropConstraints[] = $constraint; return $this; } @@ -230,7 +231,7 @@ protected function processDropConstraints(PlatformInterface $adapterPlatform = n { $sqls = []; foreach ($this->dropConstraints as $constraint) { - $sqls[] = $adapterPlatform->quoteIdentifier($constraint); + $sqls[] = $adapterPlatform->quoteIdentifier($constraint->getName()); } return [$sqls]; diff --git a/src/Sql/Ddl/Constraint/ConstraintInterface.php b/src/Sql/Ddl/Constraint/ConstraintInterface.php index aaa092022a..adb6f9e9a6 100644 --- a/src/Sql/Ddl/Constraint/ConstraintInterface.php +++ b/src/Sql/Ddl/Constraint/ConstraintInterface.php @@ -14,4 +14,6 @@ interface ConstraintInterface extends ExpressionInterface { public function getColumns(); + + public function getName(); } diff --git a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php index ea3176532d..15c844702c 100644 --- a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php @@ -10,7 +10,11 @@ namespace Zend\Db\Sql\Platform\Mysql\Ddl; use Zend\Db\Adapter\Platform\PlatformInterface; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; +use Zend\Db\Sql\Ddl\Constraint\ForeignKey; +use Zend\Db\Sql\Ddl\Constraint\PrimaryKey; +use Zend\Db\Sql\Ddl\Index\AbstractIndex; use Zend\Db\Sql\Platform\PlatformDecoratorInterface; class AlterTableDecorator extends AlterTable implements PlatformDecoratorInterface @@ -43,6 +47,11 @@ class AlterTableDecorator extends AlterTable implements PlatformDecoratorInterfa public function setSubject($subject) { $this->subject = $subject; + $this->subject->specifications[self::DROP_CONSTRAINTS] = [ + "%1\$s" => [ + [2 => "DROP %1\$s %2\$s,\n", 'combinedby' => " "], + ] + ]; return $this; } @@ -248,4 +257,37 @@ private function compareColumnOptions($columnA, $columnB) return $columnA - $columnB; } + + protected function processDropConstraints(PlatformInterface $adapterPlatform = null) + { + $sqls = []; + foreach ($this->dropConstraints as $constraint) { + $sqls[] = [ + $this->getConstraintType($constraint), + $adapterPlatform->quoteIdentifier($constraint->getName()) + ]; + } + + return [$sqls]; + } + + /** + * @param $constraint + * @return string + */ + protected function getConstraintType($constraint) + { + if ($constraint instanceof ConstraintObject) { + return $constraint->getType(); + } + if ($constraint instanceof PrimaryKey) { + return 'PRIMARY KEY'; + } elseif ($constraint instanceof ForeignKey) { + return 'FOREIGN KEY'; + } elseif ($constraint instanceof AbstractIndex) { + return 'INDEX'; + } else { + return 'KEY'; + } + } } diff --git a/test/unit/Sql/Ddl/AlterTableTest.php b/test/unit/Sql/Ddl/AlterTableTest.php index 1bd618b647..e5e31ed692 100644 --- a/test/unit/Sql/Ddl/AlterTableTest.php +++ b/test/unit/Sql/Ddl/AlterTableTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Db\Sql\Ddl; use PHPUnit\Framework\TestCase; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; use Zend\Db\Sql\Ddl\Column; use Zend\Db\Sql\Ddl\Constraint; @@ -68,8 +69,9 @@ public function testDropColumn() public function testDropConstraint() { $at = new AlterTable(); - self::assertSame($at, $at->dropConstraint('foo')); - self::assertEquals(['foo'], $at->getRawState($at::DROP_CONSTRAINTS)); + $constraint = new ConstraintObject('foo', null); + $this->assertSame($at, $at->dropConstraint($constraint)); + $this->assertEquals([$constraint], $at->getRawState($at::DROP_CONSTRAINTS)); } /** @@ -95,14 +97,16 @@ public function testGetSqlString() $at->changeColumn('name', new Column\Varchar('new_name', 50)); $at->dropColumn('foo'); $at->addConstraint(new Constraint\ForeignKey('my_fk', 'other_id', 'other_table', 'id', 'CASCADE', 'CASCADE')); - $at->dropConstraint('my_index'); + $at->dropConstraint(new ConstraintObject('my_index', null)); + $at->dropConstraint(new Constraint\UniqueKey(null, 'my_unique_index')); $expected = <<getSqlString(); diff --git a/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php b/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php index 5be80ff688..0f844ea1fd 100644 --- a/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php +++ b/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php @@ -11,9 +11,11 @@ use PHPUnit\Framework\TestCase; use Zend\Db\Adapter\Platform\Mysql; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; use Zend\Db\Sql\Ddl\Column\Column; use Zend\Db\Sql\Ddl\Constraint\PrimaryKey; +use Zend\Db\Sql\Ddl\Constraint\UniqueKey; use Zend\Db\Sql\Platform\Mysql\Ddl\AlterTableDecorator; class AlterTableDecoratorTest extends TestCase @@ -46,9 +48,17 @@ public function testGetSqlString() $col->addConstraint(new PrimaryKey()); $ct->addColumn($col); - self::assertEquals( + $fk = new ConstraintObject('my_fk', null); + $fk->setType('FOREIGN KEY'); + $ct->dropConstraint($fk); + + $ct->dropConstraint(new UniqueKey(null, 'my_unique_index')); + + $this->assertEquals( "ALTER TABLE `foo`\n ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL " . - "NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'baz' AFTER `bar`", + "NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'baz' AFTER `bar`,\n" . + " DROP FOREIGN KEY `my_fk`,\n" . + " DROP KEY `my_unique_index`", @$ctd->getSqlString(new Mysql()) ); }