diff --git a/src/Illuminate/Database/Migrations/Migrator.php b/src/Illuminate/Database/Migrations/Migrator.php index 770ed87039a2..c043e6cd735f 100755 --- a/src/Illuminate/Database/Migrations/Migrator.php +++ b/src/Illuminate/Database/Migrations/Migrator.php @@ -387,11 +387,11 @@ protected function runMigration($migration, $method) $migration->getConnection() ); - $callback = function () use ($migration, $method) { + $callback = function () use ($connection, $migration, $method) { if (method_exists($migration, $method)) { $this->fireMigrationEvent(new MigrationStarted($migration, $method)); - $migration->{$method}(); + $this->runMethod($connection, $migration, $method); $this->fireMigrationEvent(new MigrationEnded($migration, $method)); } @@ -447,13 +447,34 @@ protected function getQueries($migration, $method) $migration->getConnection() ); - return $db->pretend(function () use ($migration, $method) { + return $db->pretend(function () use ($db, $migration, $method) { if (method_exists($migration, $method)) { - $migration->{$method}(); + $this->runMethod($db, $migration, $method); } }); } + /** + * Run a migration method on the given connection. + * + * @param \Illuminate\Database\Connection $connection + * @param object $migration + * @param string $method + * @return void + */ + protected function runMethod($connection, $migration, $method) + { + $previousConnection = $this->resolver->getDefaultConnection(); + + try { + $this->resolver->setDefaultConnection($connection->getName()); + + $migration->{$method}(); + } finally { + $this->resolver->setDefaultConnection($previousConnection); + } + } + /** * Resolve a migration instance from a file. * diff --git a/tests/Database/DatabaseMigratorIntegrationTest.php b/tests/Database/DatabaseMigratorIntegrationTest.php index 3ee9815cadcf..92528ed69cb2 100644 --- a/tests/Database/DatabaseMigratorIntegrationTest.php +++ b/tests/Database/DatabaseMigratorIntegrationTest.php @@ -37,6 +37,11 @@ protected function setUp(): void 'database' => ':memory:', ], 'sqlite2'); + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + ], 'sqlite3'); + $db->setAsGlobal(); $container = new Container; @@ -84,6 +89,55 @@ public function testBasicMigrationOfSingleFolder() $this->assertTrue(Str::contains($ran[1], 'password_resets')); } + public function testMigrationsDefaultConnectionCanBeChanged() + { + $ran = $this->migrator->usingConnection('sqlite2', function () { + return $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqllite3']); + }); + + $this->assertFalse($this->db->schema()->hasTable('users')); + $this->assertFalse($this->db->schema()->hasTable('password_resets')); + $this->assertTrue($this->db->schema('sqlite2')->hasTable('users')); + $this->assertTrue($this->db->schema('sqlite2')->hasTable('password_resets')); + $this->assertFalse($this->db->schema('sqlite3')->hasTable('users')); + $this->assertFalse($this->db->schema('sqlite3')->hasTable('password_resets')); + + $this->assertTrue(Str::contains($ran[0], 'users')); + $this->assertTrue(Str::contains($ran[1], 'password_resets')); + } + + public function testMigrationsCanEachDefineConnection() + { + $ran = $this->migrator->run([__DIR__.'/migrations/connection_configured']); + + $this->assertFalse($this->db->schema()->hasTable('failed_jobs')); + $this->assertFalse($this->db->schema()->hasTable('jobs')); + $this->assertFalse($this->db->schema('sqlite2')->hasTable('failed_jobs')); + $this->assertFalse($this->db->schema('sqlite2')->hasTable('jobs')); + $this->assertTrue($this->db->schema('sqlite3')->hasTable('failed_jobs')); + $this->assertTrue($this->db->schema('sqlite3')->hasTable('jobs')); + + $this->assertTrue(Str::contains($ran[0], 'failed_jobs')); + $this->assertTrue(Str::contains($ran[1], 'jobs')); + } + + public function testMigratorCannotChangeDefinedMigrationConnection() + { + $ran = $this->migrator->usingConnection('sqlite2', function () { + return $this->migrator->run([__DIR__.'/migrations/connection_configured']); + }); + + $this->assertFalse($this->db->schema()->hasTable('failed_jobs')); + $this->assertFalse($this->db->schema()->hasTable('jobs')); + $this->assertFalse($this->db->schema('sqlite2')->hasTable('failed_jobs')); + $this->assertFalse($this->db->schema('sqlite2')->hasTable('jobs')); + $this->assertTrue($this->db->schema('sqlite3')->hasTable('failed_jobs')); + $this->assertTrue($this->db->schema('sqlite3')->hasTable('jobs')); + + $this->assertTrue(Str::contains($ran[0], 'failed_jobs')); + $this->assertTrue(Str::contains($ran[1], 'jobs')); + } + public function testMigrationsCanBeRolledBack() { $this->migrator->run([__DIR__.'/migrations/one']); diff --git a/tests/Database/migrations/connection_configured/2022_02_21_000000_create_failed_jobs_table.php b/tests/Database/migrations/connection_configured/2022_02_21_000000_create_failed_jobs_table.php new file mode 100644 index 000000000000..c95b6f0e527d --- /dev/null +++ b/tests/Database/migrations/connection_configured/2022_02_21_000000_create_failed_jobs_table.php @@ -0,0 +1,42 @@ +id(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/tests/Database/migrations/connection_configured/2022_02_21_120000_create_jobs_table.php b/tests/Database/migrations/connection_configured/2022_02_21_120000_create_jobs_table.php new file mode 100644 index 000000000000..a4f3c54a59c1 --- /dev/null +++ b/tests/Database/migrations/connection_configured/2022_02_21_120000_create_jobs_table.php @@ -0,0 +1,36 @@ +create('jobs', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::connection('sqlite3')->dropIfExists('jobs'); + } +};