TableDiff.of constructor

TableDiff.of(
  1. AlterTable operation
)

Computes the diff carried by operation.

Renamed columns are matched old-name to new-name and never appear in addedColumns or droppedColumns. The differ only detects a rename between columns that are otherwise identical, so a renamed pair cannot appear in alteredColumns either.

Implementation

factory TableDiff.of(AlterTable operation) {
  final old = operation.oldTable;
  final new_ = operation.newTable;
  final renames = operation.renamedColumns;

  final added = <ColumnInfo>[];
  final dropped = <ColumnInfo>[];
  final altered = <(ColumnInfo, ColumnInfo)>[];

  for (final oldColumn in old.columns) {
    final newName = renames[oldColumn.name] ?? oldColumn.name;
    final newColumn = new_.column(newName);
    if (newColumn == null) {
      dropped.add(oldColumn);
    } else if (renames[oldColumn.name] == null && oldColumn != newColumn) {
      altered.add((oldColumn, newColumn));
    }
  }
  final consumed = {
    for (final oldColumn in old.columns)
      renames[oldColumn.name] ?? oldColumn.name,
  };
  for (final newColumn in new_.columns) {
    if (!consumed.contains(newColumn.name)) added.add(newColumn);
  }

  final addedChecks = <String, String>{};
  final droppedChecks = <String, String>{};
  final changedChecks = <String, (String, String)>{};
  for (final entry in old.checks.entries) {
    final replacement = new_.checks[entry.key];
    if (replacement == null) {
      droppedChecks[entry.key] = entry.value;
    } else if (replacement != entry.value) {
      changedChecks[entry.key] = (entry.value, replacement);
    }
  }
  for (final entry in new_.checks.entries) {
    if (!old.checks.containsKey(entry.key)) {
      addedChecks[entry.key] = entry.value;
    }
  }

  // A changed index is a drop plus a create, matched by name.
  final oldIndexes = {for (final i in operation.oldIndexes) i.name: i};
  final newIndexes = {for (final i in operation.newIndexes) i.name: i};
  final addedIndexes = <IndexInfo>[];
  final droppedIndexes = <IndexInfo>[];
  for (final index in operation.oldIndexes) {
    final replacement = newIndexes[index.name];
    if (replacement == null || replacement != index) {
      droppedIndexes.add(index);
    }
  }
  for (final index in operation.newIndexes) {
    final previous = oldIndexes[index.name];
    if (previous == null || previous != index) addedIndexes.add(index);
  }

  return TableDiff._(
    addedColumns: added,
    droppedColumns: dropped,
    alteredColumns: altered,
    addedChecks: addedChecks,
    droppedChecks: droppedChecks,
    changedChecks: changedChecks,
    addedIndexes: addedIndexes,
    droppedIndexes: droppedIndexes,
  );
}