From bfb73c8bf4be5d98207a9911eca14aabdadd79c8 Mon Sep 17 00:00:00 2001 From: nanawel Date: Mon, 22 May 2017 18:40:37 +0200 Subject: [PATCH 1/8] Fix AlterTable::dropConstraint() by allowing the use of decorator (broken implementation under MySQL) --- src/Sql/Ddl/AlterTable.php | 18 +++++++++++------- .../Platform/Mysql/Ddl/AlterTableDecorator.php | 13 +++++++++++++ test/Sql/Ddl/AlterTableTest.php | 8 +++++--- .../Mysql/Ddl/AlterTableDecoratorTest.php | 8 +++++++- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/Sql/Ddl/AlterTable.php b/src/Sql/Ddl/AlterTable.php index ff46b9172c..b4784ec8dc 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; class AlterTable extends AbstractSql implements SqlInterface @@ -27,7 +28,7 @@ class AlterTable extends AbstractSql implements SqlInterface protected $addColumns = []; /** - * @var array + * @var Constraint\ConstraintInterface[] */ protected $addConstraints = []; @@ -42,7 +43,7 @@ class AlterTable extends AbstractSql implements SqlInterface protected $dropColumns = []; /** - * @var array + * @var ConstraintObject[] */ protected $dropConstraints = []; @@ -74,7 +75,7 @@ class AlterTable extends AbstractSql implements SqlInterface ], self::DROP_CONSTRAINTS => [ "%1\$s" => [ - [1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => ""], + [2 => "DROP %1\$s %2\$s,\n", 'combinedby' => ""], ] ] ]; @@ -138,12 +139,12 @@ public function dropColumn($name) } /** - * @param string $name + * @param ConstraintObject $constraint * @return self Provides a fluent interface */ - public function dropConstraint($name) + public function dropConstraint(ConstraintObject $constraint) { - $this->dropConstraints[] = $name; + $this->dropConstraints[] = $constraint; return $this; } @@ -229,7 +230,10 @@ protected function processDropConstraints(PlatformInterface $adapterPlatform = n { $sqls = []; foreach ($this->dropConstraints as $constraint) { - $sqls[] = $adapterPlatform->quoteIdentifier($constraint); + $sqls[] = [ + 'CONSTRAINT', + $adapterPlatform->quoteIdentifier($constraint->getName()) + ]; } return [$sqls]; diff --git a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php index faca880798..e3cbca679c 100644 --- a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php @@ -248,4 +248,17 @@ private function compareColumnOptions($columnA, $columnB) return $columnA - $columnB; } + + protected function processDropConstraints(PlatformInterface $adapterPlatform = null) + { + $sqls = []; + foreach ($this->dropConstraints as $constraint) { + $sqls[] = [ + $constraint->getType(), + $adapterPlatform->quoteIdentifier($constraint->getName()) + ]; + } + + return [$sqls]; + } } diff --git a/test/Sql/Ddl/AlterTableTest.php b/test/Sql/Ddl/AlterTableTest.php index 563b1972d9..4aeb30379b 100644 --- a/test/Sql/Ddl/AlterTableTest.php +++ b/test/Sql/Ddl/AlterTableTest.php @@ -9,6 +9,7 @@ namespace ZendTest\Db\Sql\Ddl; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; use Zend\Db\Sql\Ddl\Column; use Zend\Db\Sql\Ddl\Constraint; @@ -66,8 +67,9 @@ public function testDropColumn() public function testDropConstraint() { $at = new AlterTable(); - $this->assertSame($at, $at->dropConstraint('foo')); - $this->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)); } /** @@ -93,7 +95,7 @@ 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)); $expected =<<addConstraint(new PrimaryKey()); $ct->addColumn($col); + $fk = new ConstraintObject('my_fk', null); + $fk->setType('FOREIGN KEY'); + $ct->dropConstraint($fk); + $this->assertEquals( - "ALTER TABLE `foo`\n ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'baz' AFTER `bar`", + "ALTER TABLE `foo`\n ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'baz' AFTER `bar`,\n" + ." DROP FOREIGN KEY `my_fk`", @$ctd->getSqlString(new Mysql()) ); } From e692ebcece47a4b0162ce2937fd3c4692f0d717d Mon Sep 17 00:00:00 2001 From: nanawel Date: Mon, 22 May 2017 18:59:47 +0200 Subject: [PATCH 2/8] Update doc --- doc/book/sql-ddl.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/book/sql-ddl.md b/doc/book/sql-ddl.md index 8dd4467ab2..d1363832ed 100644 --- a/doc/book/sql-ddl.md +++ b/doc/book/sql-ddl.md @@ -87,8 +87,21 @@ $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: +```php +use \Zend\Db\Metadata\Object\ConstraintObject; + +$fkConstraint = new ConstraintObject('my_fk', null); +$fkConstraint->setType('FOREIGN KEY'); +$table->dropConstraint($fkConstraint); ``` ## Dropping Tables From 529293a954e27fa224c14c8c1c9042c72d167cff Mon Sep 17 00:00:00 2001 From: nanawel Date: Mon, 22 May 2017 21:13:20 +0200 Subject: [PATCH 3/8] Adaptation to support both \Zend\Db\Sql\Ddl\Constraint\ConstraintInterface and \Zend\Db\Metadata\Object\ConstraintObject when dropping a constraint (thanks @alextech) --- doc/book/sql-ddl.md | 13 ++++++- src/Sql/Ddl/AlterTable.php | 13 +++---- .../Ddl/Constraint/ConstraintInterface.php | 2 ++ .../Mysql/Ddl/AlterTableDecorator.php | 34 ++++++++++++++++++- test/Sql/Ddl/AlterTableTest.php | 4 ++- .../Mysql/Ddl/AlterTableDecoratorTest.php | 6 +++- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/doc/book/sql-ddl.md b/doc/book/sql-ddl.md index d1363832ed..f687a228cf 100644 --- a/doc/book/sql-ddl.md +++ b/doc/book/sql-ddl.md @@ -95,7 +95,10 @@ $constraint = new ConstraintObject('my_index', null); $table->dropConstraint($constraint); ``` -Notice: On MySQL, you need to specify the type of constraint you want to drop: +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; @@ -104,6 +107,14 @@ $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 To drop a table, create a `DropTable` instance: diff --git a/src/Sql/Ddl/AlterTable.php b/src/Sql/Ddl/AlterTable.php index b4784ec8dc..4da19363d2 100644 --- a/src/Sql/Ddl/AlterTable.php +++ b/src/Sql/Ddl/AlterTable.php @@ -43,7 +43,7 @@ class AlterTable extends AbstractSql implements SqlInterface protected $dropColumns = []; /** - * @var ConstraintObject[] + * @var Constraint\ConstraintInterface[]|ConstraintObject[] */ protected $dropConstraints = []; @@ -75,7 +75,7 @@ class AlterTable extends AbstractSql implements SqlInterface ], self::DROP_CONSTRAINTS => [ "%1\$s" => [ - [2 => "DROP %1\$s %2\$s,\n", 'combinedby' => ""], + [1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => " "], ] ] ]; @@ -139,10 +139,10 @@ public function dropColumn($name) } /** - * @param ConstraintObject $constraint + * @param Constraint\ConstraintInterface|ConstraintObject $constraint * @return self Provides a fluent interface */ - public function dropConstraint(ConstraintObject $constraint) + public function dropConstraint($constraint) { $this->dropConstraints[] = $constraint; @@ -230,10 +230,7 @@ protected function processDropConstraints(PlatformInterface $adapterPlatform = n { $sqls = []; foreach ($this->dropConstraints as $constraint) { - $sqls[] = [ - 'CONSTRAINT', - $adapterPlatform->quoteIdentifier($constraint->getName()) - ]; + $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 e3cbca679c..8acb3c9657 100644 --- a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php @@ -10,7 +10,14 @@ namespace Zend\Db\Sql\Platform\Mysql\Ddl; use Zend\Db\Adapter\Platform\PlatformInterface; +use Zend\Db\Exception\InvalidArgumentException; +use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; +use Zend\Db\Sql\Ddl\Constraint\ConstraintInterface; +use Zend\Db\Sql\Ddl\Constraint\ForeignKey; +use Zend\Db\Sql\Ddl\Constraint\PrimaryKey; +use Zend\Db\Sql\Ddl\Constraint\UniqueKey; +use Zend\Db\Sql\Ddl\Index\AbstractIndex; use Zend\Db\Sql\Platform\PlatformDecoratorInterface; class AlterTableDecorator extends AlterTable implements PlatformDecoratorInterface @@ -43,6 +50,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; } @@ -254,11 +266,31 @@ protected function processDropConstraints(PlatformInterface $adapterPlatform = n $sqls = []; foreach ($this->dropConstraints as $constraint) { $sqls[] = [ - $constraint->getType(), + $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/Sql/Ddl/AlterTableTest.php b/test/Sql/Ddl/AlterTableTest.php index 4aeb30379b..5b8cad769e 100644 --- a/test/Sql/Ddl/AlterTableTest.php +++ b/test/Sql/Ddl/AlterTableTest.php @@ -96,13 +96,15 @@ public function testGetSqlString() $at->dropColumn('foo'); $at->addConstraint(new Constraint\ForeignKey('my_fk', 'other_id', 'other_table', 'id', 'CASCADE', 'CASCADE')); $at->dropConstraint(new ConstraintObject('my_index', null)); + $at->dropConstraint(new Constraint\UniqueKey(null, 'my_unique_index')); $expected =<<getSqlString(); diff --git a/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php b/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php index f73b0758dd..0e9bf297b9 100644 --- a/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php +++ b/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php @@ -14,6 +14,7 @@ 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 \PHPUnit_Framework_TestCase @@ -50,9 +51,12 @@ public function testGetSqlString() $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`,\n" - ." DROP FOREIGN KEY `my_fk`", + ." DROP FOREIGN KEY `my_fk`,\n" + ." DROP KEY `my_unique_index`", @$ctd->getSqlString(new Mysql()) ); } From cd5a0610950472bd23995d172369a5eb7fec0128 Mon Sep 17 00:00:00 2001 From: nanawel Date: Mon, 22 May 2017 21:20:56 +0200 Subject: [PATCH 4/8] Remove unused use --- src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php index 8acb3c9657..011bb2d2c9 100644 --- a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php @@ -10,7 +10,6 @@ namespace Zend\Db\Sql\Platform\Mysql\Ddl; use Zend\Db\Adapter\Platform\PlatformInterface; -use Zend\Db\Exception\InvalidArgumentException; use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; use Zend\Db\Sql\Ddl\Constraint\ConstraintInterface; From f287cf28422c0f93ad66bfe0ec882ae2aea88148 Mon Sep 17 00:00:00 2001 From: nanawel Date: Mon, 22 May 2017 21:26:21 +0200 Subject: [PATCH 5/8] Remove unused use --- src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php index 011bb2d2c9..83ec4d2e43 100644 --- a/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php @@ -12,10 +12,8 @@ use Zend\Db\Adapter\Platform\PlatformInterface; use Zend\Db\Metadata\Object\ConstraintObject; use Zend\Db\Sql\Ddl\AlterTable; -use Zend\Db\Sql\Ddl\Constraint\ConstraintInterface; use Zend\Db\Sql\Ddl\Constraint\ForeignKey; use Zend\Db\Sql\Ddl\Constraint\PrimaryKey; -use Zend\Db\Sql\Ddl\Constraint\UniqueKey; use Zend\Db\Sql\Ddl\Index\AbstractIndex; use Zend\Db\Sql\Platform\PlatformDecoratorInterface; From 308ac7b10d06c72b26c231fbb2e159e141df9ac7 Mon Sep 17 00:00:00 2001 From: nanawel Date: Wed, 27 Dec 2017 12:53:10 +0100 Subject: [PATCH 6/8] Fix PHPCS error --- test/Sql/Ddl/AlterTableTest.php | 2 +- test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/Sql/Ddl/AlterTableTest.php b/test/Sql/Ddl/AlterTableTest.php index 947eb55ef2..c80088e9ff 100644 --- a/test/Sql/Ddl/AlterTableTest.php +++ b/test/Sql/Ddl/AlterTableTest.php @@ -98,7 +98,7 @@ public function testGetSqlString() $at->addConstraint(new Constraint\ForeignKey('my_fk', 'other_id', 'other_table', 'id', 'CASCADE', 'CASCADE')); $at->dropConstraint(new ConstraintObject('my_index', null)); $at->dropConstraint(new Constraint\UniqueKey(null, 'my_unique_index')); - $expected =<<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`,\n" + "ALTER TABLE `foo`\n" + ." ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL 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()) From 9ae551608c2db722a50f9419f69c1d23f8e79833 Mon Sep 17 00:00:00 2001 From: nanawel Date: Wed, 27 Dec 2017 14:55:46 +0100 Subject: [PATCH 7/8] Fix PHPCS warning --- test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php b/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php index dc1cc3bee9..98cea28175 100644 --- a/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php +++ b/test/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php @@ -56,7 +56,8 @@ public function testGetSqlString() $this->assertEquals( "ALTER TABLE `foo`\n" - ." ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'baz' AFTER `bar`,\n" + ." ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL 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()) From 07419e86371d88e1b26e65e4391f339152f49d21 Mon Sep 17 00:00:00 2001 From: nanawel Date: Sun, 12 Aug 2018 11:48:03 +0200 Subject: [PATCH 8/8] Merge to match code style --- .../Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php b/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php index 98cea28175..0f844ea1fd 100644 --- a/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php +++ b/test/unit/Sql/Platform/Mysql/Ddl/AlterTableDecoratorTest.php @@ -55,11 +55,10 @@ public function testGetSqlString() $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`,\n" - ." DROP FOREIGN KEY `my_fk`,\n" - ." DROP KEY `my_unique_index`", + "ALTER TABLE `foo`\n ADD COLUMN `bar` INTEGER UNSIGNED ZEROFILL " . + "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()) ); }