rollbackToSchema method

SqliteRollbackResult rollbackToSchema({
  1. required Database database,
  2. required SchemaDocument target,
  3. required String targetMigrationName,
  4. String? rollbackName,
  5. bool allowWarnings = false,
})

Rolls migration history back to targetMigrationName.

Implementation

SqliteRollbackResult rollbackToSchema({
  required sqlite.Database database,
  required SchemaDocument target,
  required String targetMigrationName,
  String? rollbackName,
  bool allowWarnings = false,
}) {
  ensureHistoryTable(database);
  final history = loadHistory(database);
  final activeNames = _activeMigrationNames(history);
  if (!activeNames.contains(targetMigrationName)) {
    return SqliteRollbackResult(
      targetMigrationName: targetMigrationName,
      rolledBack: false,
      statementCount: 0,
      warnings: const <String>[],
    );
  }

  final source = _currentSourceSchema(database);
  final plan = _mergeRiskWarnings(
    planner.plan(from: source, to: target),
    detectPotentialDataLossWarnings(from: source, to: target),
  );
  if (plan.warnings.isNotEmpty && !allowWarnings) {
    throw StateError(
      'Rollback plan contains warnings: ${plan.warnings.join(' | ')}',
    );
  }
  final effectiveRollbackName =
      rollbackName ??
      '${targetMigrationName}_rollback_${DateTime.now().toUtc().millisecondsSinceEpoch}';
  final beforeSchema = schemaToSource(source);
  final afterSchema = schemaToSource(target);
  final migrationSql = buildMigrationSqlScript(plan);
  final checksum = computeMigrationChecksum(
    provider: providerName,
    beforeSchema: beforeSchema,
    afterSchema: afterSchema,
    migrationSql: migrationSql,
    warnings: plan.warnings,
    requiresRebuild: true,
  );
  final statementCount = _rebuildDatabase(
    database: database,
    source: source,
    target: target,
  );

  _recordHistory(
    database: database,
    migrationName: effectiveRollbackName,
    statementCount: statementCount,
    kind: SqliteMigrationRecordKind.rollback,
    provider: providerName,
    checksum: checksum,
    beforeSchema: beforeSchema,
    afterSchema: afterSchema,
    warnings: plan.warnings,
    rebuildRequired: true,
    targetName: targetMigrationName,
  );

  return SqliteRollbackResult(
    targetMigrationName: targetMigrationName,
    rolledBack: true,
    statementCount: statementCount,
    warnings: List<String>.unmodifiable(plan.warnings),
  );
}