rollback method
Rolls back the most recent batch of migrations.
Each rollback is wrapped in its own transaction.
Implementation
Future<void> rollback() async {
await _ensureMigrationsTable();
final locked = await _acquireLock();
if (!locked) {
Logger.staticWarning('⚠️ Another migration process is running. Skipping rollback.');
return;
}
try {
final last = await _getLastBatch();
if (last.isEmpty) {
Logger.staticInfo('ℹ️ Nothing to rollback.');
return;
}
for (var name in last.reversed) {
final entry = _registry.cast<MigrationEntry?>().firstWhere(
(e) => e!.name == name,
orElse: () => null,
);
if (entry == null) {
Logger.staticWarning('⚠️ Migration "$name" not found in registry. Skipping.');
continue;
}
Logger.staticInfo('⏪ Rolling back: $name');
try {
await _db.transaction((tx) async {
await entry.migration.down(tx);
await tx.query('DELETE FROM migrations WHERE name = @name', {'name': name});
});
} catch (e) {
Logger.staticWarning('❌ Rollback of "$name" failed: $e. Stopping.');
return;
}
}
Logger.staticInfo('✅ Rollback complete.');
} finally {
await _releaseLock();
}
}