generateDatabaseMigration function

DatabaseMigration generateDatabaseMigration({
  1. required DatabaseDefinition databaseSource,
  2. required DatabaseDefinition databaseTarget,
})

Implementation

DatabaseMigration generateDatabaseMigration({
  required DatabaseDefinition databaseSource,
  required DatabaseDefinition databaseTarget,
}) {
  var warnings = <DatabaseMigrationWarning>[];
  var actions = <DatabaseMigrationAction>[];

  // Find deleted tables
  var deleteTables = <String>[];
  var sourceTables = databaseSource.tables.where((table) => table.isManaged);
  var targetTables = databaseTarget.tables.where((table) => table.isManaged);

  for (var srcTable in sourceTables) {
    if (!databaseTarget.containsTableNamed(srcTable.name)) {
      deleteTables.add(srcTable.name);
    }
  }
  for (var tableName in deleteTables.reversed) {
    actions.add(
      DatabaseMigrationAction(
        type: DatabaseMigrationActionType.deleteTable,
        deleteTable: tableName,
      ),
    );
    warnings.add(
      DatabaseMigrationWarning(
        type: DatabaseMigrationWarningType.tableDropped,
        message: 'Table "$tableName" will be dropped.',
        table: tableName,
        destrucive: true,
        columns: [],
      ),
    );
  }

  // Find added or modified tables
  for (var dstTable in targetTables) {
    var srcTable = databaseSource.tables.cast<TableDefinition?>().firstWhere(
        (table) => table?.name == dstTable.name,
        orElse: () => null);

    if (srcTable == null || srcTable.managed == false) {
      // Added table

      actions.add(
        DatabaseMigrationAction(
          type: srcTable == null
              ? DatabaseMigrationActionType.createTable
              : DatabaseMigrationActionType.createTableIfNotExists,
          createTable: dstTable,
        ),
      );
    } else {
      // Table exists in src and dst
      var diff = generateTableMigration(srcTable, dstTable, warnings);
      if (diff == null) {
        // Table was modified, but cannot be migrated. Recreate the table.
        actions.add(
          DatabaseMigrationAction(
            type: DatabaseMigrationActionType.deleteTable,
            deleteTable: dstTable.name,
          ),
        );
        actions.add(
          DatabaseMigrationAction(
            type: DatabaseMigrationActionType.createTable,
            createTable: dstTable,
          ),
        );
      } else if (!diff.isEmpty) {
        // Table was modified
        // TODO: Check if table can be modified

        actions.add(
          DatabaseMigrationAction(
            type: DatabaseMigrationActionType.alterTable,
            alterTable: diff,
          ),
        );
      }
    }
  }

  return DatabaseMigration(
    actions: actions,
    warnings: warnings,
    migrationApiVersion: DatabaseConstants.migrationApiVersion,
  );
}