rollback method

Future<void> rollback()

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 (final 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();
  }
}