diff --git a/src/Schema/Table.php b/src/Schema/Table.php index da9e42b..88cf2f2 100644 --- a/src/Schema/Table.php +++ b/src/Schema/Table.php @@ -6,6 +6,7 @@ use Closure; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Table as Blueprint; use Doctrine\DBAL\Types\Type; @@ -56,6 +57,18 @@ public function primary(string $columns, $name = null): ?Blueprint return $this->table->setPrimaryKey($columns, $name); } + /** + * Dropping a defined primary index from the table + * + * @param string|array $name Name of the primary index or column names associated with the index + * + * @return void + */ + public function dropPrimary($name) + { + $this->dropIndex($name); + } + /** * Specify a unique index for the table. * @@ -72,6 +85,18 @@ public function unique($columns, $name = null, $options = []): ?Blueprint return $this->table->addUniqueIndex($columns, $name, $options); } + /** + * Dropping a defined unique index from the table + * + * @param string|array $name Name of the unique index or column names associated with the index + * + * @return void + */ + public function dropUnique($name) + { + $this->dropIndex($name); + } + /** * Specify an index for the table. * @@ -89,6 +114,35 @@ public function index($columns, $name = null, $flags = [], $options = []): ?Blue return $this->table->addIndex($columns, $name, $flags, $options); } + /** + * Dropping a basic index from the table + * + * @param string|array $name Name of the index or column names associated with the index + * + * @return void + */ + public function dropIndex($name) + { + if (is_string($name)) { + $this->table->dropIndex($name); + } else { + $indexes = $this->table->getIndexes(); + + $matched = []; + foreach ($indexes as $key => $index) { + $columns = $index->getColumns(); + + if (count(array_diff($columns, $name)) == 0 && count(array_diff($name, $columns)) == 0) { + array_push($matched, $key); + } + } + + foreach ($matched as $indexName) { + $this->table->dropIndex($indexName); + } + } + } + /** * Specify a foreign key for the table. * @@ -106,13 +160,27 @@ public function foreign( $foreignColumnNames = 'id', $options = [], $constraintName = null - ): ?Blueprint - { + ): ?Blueprint { $localColumnNames = is_array($localColumnNames) ? $localColumnNames : [$localColumnNames]; $foreignColumnNames = is_array($foreignColumnNames) ? $foreignColumnNames : [$foreignColumnNames]; - return $this->table->addForeignKeyConstraint($table, $localColumnNames, $foreignColumnNames, $options, - $constraintName); + return $this->table->addForeignKeyConstraint( + $table, + $localColumnNames, + $foreignColumnNames, + $options, + $constraintName + ); + } + + /** + * Dropping a foreign key from the table + * + * @param string|array $name Name of the foreign index or column names associated with the index + */ + public function dropForeign($name) + { + $this->dropIndex($name); } /** diff --git a/tests/Schema/SchemaTableTest.php b/tests/Schema/SchemaTableTest.php index 7f01fbf..93e6c1c 100644 --- a/tests/Schema/SchemaTableTest.php +++ b/tests/Schema/SchemaTableTest.php @@ -3,6 +3,8 @@ declare(strict_types=1); use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Index; +use Doctrine\DBAL\Types\Type; use LaravelDoctrine\Migrations\Schema\Table; use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; @@ -295,7 +297,7 @@ public function test_remember_token() { $column = m::mock(Column::class); $this->dbal->shouldReceive('addColumn')->with('remember_token', 'string', ['length' => 100]) - ->andReturn($column); + ->andReturn($column); $column->shouldReceive('setNotnull')->with(false)->once(); $this->table->rememberToken('column'); } @@ -311,4 +313,100 @@ public function test_drop_column() $this->table->dropColumn('column'); } + + public function test_drop_unique() + { + $this->dbal->shouldReceive('dropIndex')->with('unique'); + + $this->table->dropForeign('unique'); + } + + public function test_drop_unique_with_exact_column_names() + { + $this->dbal->shouldReceive('getIndexes')->andReturn([ + 'index1' => new Index('index1', ['column1', 'column2', 'column3'], true), + 'index2' => new Index('index2', ['column1', 'column2'], true), + 'index3' => new Index('index3', ['column1'], true), + 'index4' => new Index('index4', ['column1', 'column2', 'column3'], true), + 'index5' => new Index('index5', ['column1', 'column2'], true), + 'index6' => new Index('index6', ['column1'], true), + ]); + + $this->dbal->shouldReceive('dropIndex')->with('index2'); + $this->dbal->shouldReceive('dropIndex')->with('index5'); + + $this->table->dropUnique(['column1', 'column2']); + } + + public function test_drop_primary() + { + $this->dbal->shouldReceive('dropIndex')->with('primary'); + + $this->table->dropPrimary('primary'); + } + + public function test_drop_primary_with_exact_column_names() + { + $this->dbal->shouldReceive('getIndexes')->andReturn([ + 'index1' => new Index('index1', ['column1', 'column2', 'column3'], false, true), + 'index2' => new Index('index2', ['column1', 'column2'], false, true), + 'index3' => new Index('index3', ['column1'], false, true), + 'index4' => new Index('index4', ['column1', 'column2', 'column3'], false, true), + 'index5' => new Index('index5', ['column1', 'column2'], false, true), + 'index6' => new Index('index6', ['column1'], false, true), + ]); + + $this->dbal->shouldReceive('dropIndex')->with('index2'); + $this->dbal->shouldReceive('dropIndex')->with('index5'); + + $this->table->dropPrimary(['column1', 'column2']); + } + + public function test_drop_foreign() + { + $this->dbal->shouldReceive('dropIndex')->with('foreign'); + + $this->table->dropForeign('foreign'); + } + + public function test_drop_foreign_with_exact_column_names() + { + $this->dbal->shouldReceive('getIndexes')->andReturn([ + 'index1' => new Index('index1', ['column1', 'column2', 'column3']), + 'index2' => new Index('index2', ['column1', 'column2']), + 'index3' => new Index('index3', ['column1']), + ]); + + $this->dbal->shouldReceive('dropIndex')->with('index2'); + + $this->table->dropForeign(['column1', 'column2']); + } + + public function test_drop_index() + { + $this->dbal->shouldReceive('dropIndex')->with('index'); + + $this->table->dropIndex('index'); + } + + public function test_drop_index_with_exact_column_names() + { + $this->dbal->shouldReceive('getIndexes')->andReturn([ + 'index1' => new Index('index1', ['column1', 'column2', 'column3'], true), + 'index2' => new Index('index2', ['column1', 'column2'], true), + 'index3' => new Index('index3', ['column1'], true), + 'index4' => new Index('index4', ['column1', 'column2', 'column3'], false, true), + 'index5' => new Index('index5', ['column1', 'column2'], false, true), + 'index6' => new Index('index6', ['column1'], false, true), + 'index7' => new Index('index7', ['column1', 'column2', 'column3']), + 'index8' => new Index('index8', ['column1', 'column2']), + 'index9' => new Index('index9', ['column1']), + ]); + + $this->dbal->shouldReceive('dropIndex')->with('index2'); + $this->dbal->shouldReceive('dropIndex')->with('index5'); + $this->dbal->shouldReceive('dropIndex')->with('index8'); + + $this->table->dropIndex(['column1', 'column2']); + } }