status method

SqliteMigrationStatus status({
  1. required Database database,
  2. required String migrationsDirectory,
})

Compares database history with local migration artifacts.

Implementation

SqliteMigrationStatus status({
  required sqlite.Database database,
  required String migrationsDirectory,
}) {
  final activeHistory = runner.loadActiveHistory(database);
  final issues = <SqliteMigrationStatusIssue>[];
  List<LocalMigrationArtifact> localArtifacts;
  try {
    localArtifacts = loadLocalMigrationArtifacts(
      migrationsDirectory,
      provider: SqliteMigrationRunner.providerName,
    );
  } on StateError catch (error) {
    issues.add(
      SqliteMigrationStatusIssue(
        code: 'invalid-local-artifacts',
        message: error.message,
      ),
    );
    localArtifacts = const <LocalMigrationArtifact>[];
  } on UnsupportedError catch (error) {
    issues.add(
      SqliteMigrationStatusIssue(
        code: 'local-artifacts-unavailable',
        message: '$error',
      ),
    );
    return SqliteMigrationStatus(
      localMigrationCount: 0,
      activeMigrationCount: activeHistory.length,
      issues: List<SqliteMigrationStatusIssue>.unmodifiable(issues),
    );
  }

  final localByName = {
    for (final artifact in localArtifacts) artifact.name: artifact,
  };
  final activeNames = activeHistory.map((record) => record.name).toSet();

  for (final record in activeHistory) {
    final local = localByName[record.name];
    if (local == null) {
      issues.add(
        SqliteMigrationStatusIssue(
          code: 'applied-migration-missing-locally',
          message:
              'Migration ${record.name} is active in the database but missing from $migrationsDirectory.',
        ),
      );
      continue;
    }
    if (record.checksum != null && record.checksum != local.checksum) {
      issues.add(
        SqliteMigrationStatusIssue(
          code: 'checksum-mismatch',
          message:
              'Migration ${record.name} differs between database history and local artifacts.',
        ),
      );
    }
    if (record.beforeSchema == null || record.afterSchema == null) {
      issues.add(
        SqliteMigrationStatusIssue(
          code: 'missing-db-snapshot',
          message:
              'Migration ${record.name} was applied before database snapshots were recorded.',
        ),
      );
    }
  }

  for (final artifact in localArtifacts) {
    if (!activeNames.contains(artifact.name)) {
      issues.add(
        SqliteMigrationStatusIssue(
          code: 'local-migration-not-applied',
          message:
              'Local migration ${artifact.name} exists in $migrationsDirectory but is not currently active in the database.',
        ),
      );
    }
  }

  return SqliteMigrationStatus(
    localMigrationCount: localArtifacts.length,
    activeMigrationCount: activeHistory.length,
    issues: List<SqliteMigrationStatusIssue>.unmodifiable(issues),
  );
}