computeDiff method

Future<DatabaseSchemaDiff> computeDiff(
  1. Session db
)

Computes the difference between the live database schema from db and this schema.

The returned DatabaseSchemaDiff contains all changes needed to migrate the database schema to match this schema.

Implementation

Future<DatabaseSchemaDiff> computeDiff(Session db) async {
  var existingSchema = await inspectDatabaseSchema(db);
  var newSchema = copy();

  var diff = DatabaseSchemaDiff(existingSchema, this);

  for (var extTable in existingSchema.tables.values) {
    if (newSchema.tables.containsKey(extTable.name)) {
      var newTable = newSchema.tables.remove(extTable.name)!;
      var tableDiff = TableSchemaDiff(newTable.name);

      for (var extColumn in extTable.columns.values) {
        var newColumn =
            newTable.columns.values.where((c) => c.name == extColumn.name).firstOrNull;
        if (newColumn != null) {
          newTable.columns.removeWhere((_, c) => c == newColumn);
          if (newColumn.type != extColumn.type ||
              newColumn.isNullable != extColumn.isNullable ||
              newColumn.defaultValue != extColumn.defaultValue) {
            tableDiff.columns.modified.add(Change(extColumn, newColumn));
          }
        } else {
          tableDiff.columns.removed.add(extColumn);
        }
      }

      for (var newColumn in newTable.columns.values) {
        tableDiff.columns.added.add(newColumn);
      }

      for (var extConstraint in extTable.constraints) {
        var newConstraint = newTable.constraints.where((c) => c == extConstraint).firstOrNull;

        if (newConstraint != null) {
          newTable.constraints.remove(newConstraint);
        } else {
          tableDiff.constraints.removed.add(extConstraint);
        }
      }

      for (var newConstraint in newTable.constraints) {
        tableDiff.constraints.added.add(newConstraint);
      }

      for (var extIndex in extTable.indexes) {
        var newIndex = newTable.indexes.where((t) => t == extIndex).firstOrNull;

        if (newIndex != null) {
          newTable.indexes.remove(newIndex);
        } else {
          tableDiff.indexes.removed.add(extIndex);
        }
      }

      for (var newIndex in newTable.indexes) {
        tableDiff.indexes.added.add(newIndex);
      }

      if (tableDiff.hasChanges) {
        diff.tables.modified.add(tableDiff);
      }
    } else {
      diff.tables.removed.add(extTable);
    }
  }

  for (var newTable in newSchema.tables.values) {
    diff.tables.added.add(newTable);
  }

  return diff;
}