Skip to content

Commit 2d4b791

Browse files
committed
Rollback a specific batch of migrations
- Add a new option `batch` to the RollbackCommand. - Add a new function `getMigrationsByBatch` to the MigrationRepositoryInterface. - Implement `getMigrationsByBatch` in DatabaseMigrationRepository. This new option allows the developer to rollback a specific batch of migrations. This can be helpful in situations where a production bugfix introduced database changes after the current feature branch introduced database changes. The develop may not be able to rollback the production bugfix batch, but still wants to revert the batch from the current feature branch to make slight changes to the database migrations introduced in the current feature branch. A PR to laravel/docs will also be submitted.
1 parent 18a996f commit 2d4b791

File tree

5 files changed

+33
-3
lines changed

5 files changed

+33
-3
lines changed

src/Illuminate/Database/Console/Migrations/RollbackCommand.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public function handle()
6060
$this->getMigrationPaths(), [
6161
'pretend' => $this->option('pretend'),
6262
'step' => (int) $this->option('step'),
63+
'batch' => (int) $this->option('batch'),
6364
]
6465
);
6566
});
@@ -86,6 +87,8 @@ protected function getOptions()
8687
['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'],
8788

8889
['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted'],
90+
91+
['batch', null, InputOption::VALUE_REQUIRED, 'The batch of migrations (identified by their batch number) to be reverted'],
8992
];
9093
}
9194
}

src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ public function getMigrations($steps)
6868
->take($steps)->get()->all();
6969
}
7070

71+
/**
72+
* Get the list of the migrations by batch number.
73+
*
74+
* @param int $batchNumber
75+
* @return array
76+
*/
77+
public function getMigrationsByBatch($batch): array
78+
{
79+
return $this->table()
80+
->where('batch', $batch)
81+
->orderBy('migration', 'desc')
82+
->get()
83+
->all();
84+
}
85+
7186
/**
7287
* Get the last migration batch.
7388
*

src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ public function getRan();
1919
*/
2020
public function getMigrations($steps);
2121

22+
/**
23+
* Get the list of the migrations by batch.
24+
*
25+
* @param int $batch
26+
* @return array
27+
*/
28+
public function getMigrationsByBatch($batch): array;
29+
2230
/**
2331
* Get the last migration batch.
2432
*

src/Illuminate/Database/Migrations/Migrator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ protected function getMigrationsForRollback(array $options)
248248
return $this->repository->getMigrations($steps);
249249
}
250250

251+
if (($batch = $options['batch'] ?? 0) > 0) {
252+
return $this->repository->getMigrationsByBatch($batch);
253+
}
254+
251255
return $this->repository->getLast();
252256
}
253257

tests/Database/DatabaseMigrationRollbackCommandTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function testRollbackCommandCallsMigratorWithProperArguments()
2828
return $callback();
2929
});
3030
$migrator->shouldReceive('setOutput')->once()->andReturn($migrator);
31-
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 0]);
31+
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 0, 'batch' => 0]);
3232

3333
$this->runCommand($command);
3434
}
@@ -44,7 +44,7 @@ public function testRollbackCommandCallsMigratorWithStepOption()
4444
return $callback();
4545
});
4646
$migrator->shouldReceive('setOutput')->once()->andReturn($migrator);
47-
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 2]);
47+
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 2, 'batch' => 0]);
4848

4949
$this->runCommand($command, ['--step' => 2]);
5050
}
@@ -76,7 +76,7 @@ public function testRollbackCommandCanBePretendedWithStepOption()
7676
return $callback();
7777
});
7878
$migrator->shouldReceive('setOutput')->once()->andReturn($migrator);
79-
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => true, 'step' => 2]);
79+
$migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => true, 'step' => 2, 'batch' => 0]);
8080

8181
$this->runCommand($command, ['--pretend' => true, '--database' => 'foo', '--step' => 2]);
8282
}

0 commit comments

Comments
 (0)