From 7a35d728582bdf33a335f82a37cb4bf52cb598d2 Mon Sep 17 00:00:00 2001 From: Amelia Ikeda Date: Wed, 5 Oct 2016 21:52:32 +0100 Subject: [PATCH 1/2] Allow wrapping schema changes in a transaction if the database supports it. --- .../Database/Migrations/Migrator.php | 29 +++++++++++++++++-- .../Database/Schema/Grammars/Grammar.php | 17 +++++++++++ .../Schema/Grammars/PostgresGrammar.php | 7 +++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Migrations/Migrator.php b/src/Illuminate/Database/Migrations/Migrator.php index d9c707583445..9fde41931ef3 100755 --- a/src/Illuminate/Database/Migrations/Migrator.php +++ b/src/Illuminate/Database/Migrations/Migrator.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Migrations; +use Closure; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Collection; @@ -159,7 +160,9 @@ protected function runUp($file, $batch, $pretend) return $this->pretendToRun($migration, 'up'); } - $migration->up(); + $this->runMigration(function () use ($migration) { + $migration->up(); + }); // Once we have run a migrations class, we will log that it was run in this // repository so that we don't try to run it next time we do a migration @@ -279,7 +282,9 @@ protected function runDown($file, $migration, $pretend) return $this->pretendToRun($instance, 'down'); } - $instance->down(); + $this->runMigration(function () use ($instance) { + $instance->down(); + }); // Once we have successfully run the migration "down" we will remove it from // the migration repository so it will be considered to have not been run @@ -356,6 +361,26 @@ protected function getQueries($migration, $method) }); } + /** + * Run a migration, inside a transaction if the database supports it. + * + * @param \Closure $callback + * @retrun void + */ + protected function runMigration(Closure $callback) + { + // To deal with potential errors during migrations that may leave a database + // in an invalid state, we wrap everything in a transaction so all changes + // are rolled back, and the developer need not manually repair errors. + $connection = $this->resolveConnection($this->connection); + + $grammar = $connection->getSchemaGrammar(); + + $grammar->supportsSchemaTransactions() + ? $connection->transaction($callback) + : $callback(); + } + /** * Resolve a migration instance from a file. * diff --git a/src/Illuminate/Database/Schema/Grammars/Grammar.php b/src/Illuminate/Database/Schema/Grammars/Grammar.php index ddf918f2aec9..6c32ee909c49 100755 --- a/src/Illuminate/Database/Schema/Grammars/Grammar.php +++ b/src/Illuminate/Database/Schema/Grammars/Grammar.php @@ -17,6 +17,13 @@ abstract class Grammar extends BaseGrammar { + /** + * If this Grammar supports schema changes wrapped in a transaction. + * + * @var bool + */ + protected $transactions = false; + /** * Compile a rename column command. * @@ -456,4 +463,14 @@ protected function mapFluentValueToDoctrine($option, $value) { return $option == 'notnull' ? ! $value : $value; } + + /** + * Check if this Grammar supports schema changes wrapped in a transaction. + * + * @return bool + */ + public function supportsSchemaTransactions() + { + return $this->transactions; + } } diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 7929abde9e30..0595c7357d06 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -7,6 +7,13 @@ class PostgresGrammar extends Grammar { + /** + * If this Grammar supports schema changes wrapped in a transaction. + * + * @var bool + */ + protected $transactions = true; + /** * The possible column modifiers. * From 4ef6fd76d5bcf3590f930ec262f1f0756eeaed3b Mon Sep 17 00:00:00 2001 From: Amelia Ikeda Date: Wed, 5 Oct 2016 21:56:33 +0100 Subject: [PATCH 2/2] Fix a typo --- src/Illuminate/Database/Migrations/Migrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Migrations/Migrator.php b/src/Illuminate/Database/Migrations/Migrator.php index 9fde41931ef3..da926dbf7655 100755 --- a/src/Illuminate/Database/Migrations/Migrator.php +++ b/src/Illuminate/Database/Migrations/Migrator.php @@ -365,7 +365,7 @@ protected function getQueries($migration, $method) * Run a migration, inside a transaction if the database supports it. * * @param \Closure $callback - * @retrun void + * @return void */ protected function runMigration(Closure $callback) {