diff --git a/src/Illuminate/Database/Schema/Blueprint.php b/src/Illuminate/Database/Schema/Blueprint.php index 20d014894ab4..b5c003c9e620 100755 --- a/src/Illuminate/Database/Schema/Blueprint.php +++ b/src/Illuminate/Database/Schema/Blueprint.php @@ -302,6 +302,18 @@ public function renameColumn($from, $to) return $this->addCommand('renameColumn', compact('from', 'to')); } + /** + * Indicate that the given indexes should be renamed. + * + * @param string $from + * @param string $to + * @return \Illuminate\Support\Fluent + */ + public function renameIndex($from, $to) + { + return $this->addCommand('renameIndex', compact('from', 'to')); + } + /** * Indicate that the given primary key should be dropped. * diff --git a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php index d445f39b6b95..14576e0e9aad 100755 --- a/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php @@ -342,6 +342,22 @@ public function compileRename(Blueprint $blueprint, Fluent $command) return "rename table {$from} to ".$this->wrapTable($command->to); } + /** + * Compile a rename index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRenameIndex(Blueprint $blueprint, Fluent $command) + { + return sprintf('alter table %s rename index %s to %s', + $this->wrapTable($blueprint), + $this->wrap($command->from), + $this->wrap($command->to) + ); + } + /** * Compile the SQL needed to drop all tables. * diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 3c8637d42e9c..a0bd6bd44fad 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -310,6 +310,21 @@ public function compileRename(Blueprint $blueprint, Fluent $command) return "alter table {$from} rename to ".$this->wrapTable($command->to); } + /** + * Compile a rename index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRenameIndex(Blueprint $blueprint, Fluent $command) + { + return sprintf('alter index %s rename to %s', + $this->wrap($command->from), + $this->wrap($command->to) + ); + } + /** * Compile the command to enable foreign key constraints. * diff --git a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php index 9744915ed489..adce734ae53c 100755 --- a/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php @@ -4,6 +4,7 @@ use RuntimeException; use Illuminate\Support\Fluent; +use Doctrine\DBAL\Schema\Index; use Illuminate\Database\Connection; use Illuminate\Database\Schema\Blueprint; @@ -307,6 +308,36 @@ public function compileRename(Blueprint $blueprint, Fluent $command) return "alter table {$from} rename to ".$this->wrapTable($command->to); } + /** + * Compile a rename index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array + */ + public function compileRenameIndex(Blueprint $blueprint, Fluent $command, Connection $connection) + { + $schemaManager = $connection->getDoctrineSchemaManager(); + $indexes = $schemaManager->listTableIndexes($this->getTablePrefix().$blueprint->getTable()); + $index = array_get($indexes, $command->from); + + if (! $index) { + throw new RuntimeException("Index '{$command->from}' doesn't seem to exist"); + } + + /** @var \Doctrine\DBAL\Schema\Index $index */ + $newIndex = new Index($command->to, $index->getColumns(), $index->isUnique(), $index->isPrimary(), + $index->getFlags(), $index->getOptions()); + + $platform = $schemaManager->getDatabasePlatform(); + + return [ + $platform->getDropIndexSQL($command->from, $this->getTablePrefix().$blueprint->getTable()), + $platform->getCreateIndexSQL($newIndex, $this->getTablePrefix().$blueprint->getTable()), + ]; + } + /** * Compile the command to enable foreign key constraints. * diff --git a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php index e9b8043b8f0c..38f55fcf55ad 100755 --- a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php @@ -277,6 +277,21 @@ public function compileRename(Blueprint $blueprint, Fluent $command) return "sp_rename {$from}, ".$this->wrapTable($command->to); } + /** + * Compile a rename index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRenameIndex(Blueprint $blueprint, Fluent $command) + { + return sprintf("sp_rename N'%s', %s, N'INDEX'", + $this->wrap($blueprint->getTable().'.'.$command->from), + $this->wrap($command->to) + ); + } + /** * Compile the command to enable foreign key constraints. * diff --git a/tests/Database/DatabaseMySqlSchemaGrammarTest.php b/tests/Database/DatabaseMySqlSchemaGrammarTest.php index 86235bf88527..c949fb442201 100755 --- a/tests/Database/DatabaseMySqlSchemaGrammarTest.php +++ b/tests/Database/DatabaseMySqlSchemaGrammarTest.php @@ -279,6 +279,16 @@ public function testRenameTable() $this->assertEquals('rename table `users` to `foo`', $statements[0]); } + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertEquals('alter table `users` rename index `foo` to `bar`', $statements[0]); + } + public function testAddingPrimaryKey() { $blueprint = new Blueprint('users'); diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index 568b5d52b235..e0bd2bf65ce2 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -194,6 +194,16 @@ public function testRenameTable() $this->assertEquals('alter table "users" rename to "foo"', $statements[0]); } + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertEquals('alter index "foo" rename to "bar"', $statements[0]); + } + public function testAddingPrimaryKey() { $blueprint = new Blueprint('users'); diff --git a/tests/Database/DatabaseSQLiteSchemaGrammarTest.php b/tests/Database/DatabaseSQLiteSchemaGrammarTest.php index 633e991cce29..f9cb93e9ce01 100755 --- a/tests/Database/DatabaseSQLiteSchemaGrammarTest.php +++ b/tests/Database/DatabaseSQLiteSchemaGrammarTest.php @@ -142,6 +142,47 @@ public function testRenameTable() $this->assertEquals('alter table "users" rename to "foo"', $statements[0]); } + public function testRenameIndex() + { + if (! class_exists('Doctrine\DBAL\Schema\SqliteSchemaManager')) { + $this->markTestSkipped('Doctrine should be installed to run renameIndex tests'); + } + + $db = new \Illuminate\Database\Capsule\Manager; + + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => 'prefix_', + ]); + + $schema = $db->getConnection()->getSchemaBuilder(); + + $schema->create('users', function (Blueprint $table) { + $table->string('name'); + $table->string('email'); + }); + + $schema->table('users', function (Blueprint $table) { + $table->index(['name', 'email'], 'index1'); + }); + + $manager = $db->getConnection()->getDoctrineSchemaManager(); + $details = $manager->listTableDetails('prefix_users'); + $this->assertTrue($details->hasIndex('index1')); + $this->assertFalse($details->hasIndex('index2')); + + $schema->table('users', function (Blueprint $table) { + $table->renameIndex('index1', 'index2'); + }); + + $details = $manager->listTableDetails('prefix_users'); + $this->assertFalse($details->hasIndex('index1')); + $this->assertTrue($details->hasIndex('index2')); + + $this->assertEquals(['name', 'email'], $details->getIndex('index2')->getUnquotedColumns()); + } + public function testAddingPrimaryKey() { $blueprint = new Blueprint('users'); diff --git a/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php b/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php index 1c9a80163e89..80fb1b620776 100644 --- a/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php +++ b/tests/Database/DatabaseSchemaBlueprintIntegrationTest.php @@ -68,4 +68,53 @@ public function testRenamingAndChangingColumnsWork() $this->assertEquals($expected, $queries); } + + public function testRenameIndexWorks() + { + $this->db->connection()->getSchemaBuilder()->create('users', function ($table) { + $table->string('name'); + $table->string('age'); + }); + + $this->db->connection()->getSchemaBuilder()->table('users', function ($table) { + $table->index(['name'], 'index1'); + }); + + $blueprint = new Blueprint('users', function ($table) { + $table->renameIndex('index1', 'index2'); + }); + + $queries = $blueprint->toSql($this->db->connection(), new \Illuminate\Database\Schema\Grammars\SQLiteGrammar); + + $expected = [ + 'DROP INDEX index1', + 'CREATE INDEX index2 ON users (name)', + ]; + + $this->assertEquals($expected, $queries); + + $queries = $blueprint->toSql($this->db->connection(), new \Illuminate\Database\Schema\Grammars\SqlServerGrammar()); + + $expected = [ + 'sp_rename N\'"users"."index1"\', "index2", N\'INDEX\'', + ]; + + $this->assertEquals($expected, $queries); + + $queries = $blueprint->toSql($this->db->connection(), new \Illuminate\Database\Schema\Grammars\MySqlGrammar()); + + $expected = [ + 'alter table `users` rename index `index1` to `index2`', + ]; + + $this->assertEquals($expected, $queries); + + $queries = $blueprint->toSql($this->db->connection(), new \Illuminate\Database\Schema\Grammars\PostgresGrammar()); + + $expected = [ + 'alter index "index1" rename to "index2"', + ]; + + $this->assertEquals($expected, $queries); + } } diff --git a/tests/Database/DatabaseSqlServerSchemaGrammarTest.php b/tests/Database/DatabaseSqlServerSchemaGrammarTest.php index 35e8729074e7..38410a354ade 100755 --- a/tests/Database/DatabaseSqlServerSchemaGrammarTest.php +++ b/tests/Database/DatabaseSqlServerSchemaGrammarTest.php @@ -204,6 +204,16 @@ public function testRenameTable() $this->assertEquals('sp_rename "users", "foo"', $statements[0]); } + public function testRenameIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->renameIndex('foo', 'bar'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertEquals('sp_rename N\'"users"."foo"\', "bar", N\'INDEX\'', $statements[0]); + } + public function testAddingPrimaryKey() { $blueprint = new Blueprint('users');