generateDatabaseMigration function
DatabaseMigration
generateDatabaseMigration({
- required DatabaseDefinition databaseSource,
- required DatabaseDefinition databaseTarget,
Implementation
DatabaseMigration generateDatabaseMigration({
required DatabaseDefinition databaseSource,
required DatabaseDefinition databaseTarget,
}) {
var warnings = <DatabaseMigrationWarning>[];
var actions = <DatabaseMigrationAction>[];
var sourceTables =
databaseSource.tables.where((table) => table.isManaged).toList();
var targetTables =
databaseTarget.tables.where((table) => table.isManaged).toList();
var deleteTables = <String>{};
// Mark tables which do not exist in the target schema anymore for deletion
for (var srcTable in sourceTables) {
if (!databaseTarget.containsTableNamed(srcTable.name)) {
deleteTables.addAll([
srcTable.name,
// For any table we delete, we also need to delete any other existing table that has and retains a foreign key pointing into this table
..._findDependentTables(srcTable.name,
sourceTables: sourceTables, targetTables: targetTables),
]);
}
}
for (var tableName in deleteTables.toList().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 ||
deleteTables.contains(srcTable.name)) {
// Added table
actions.add(
DatabaseMigrationAction(
type: srcTable == null || deleteTables.contains(srcTable.name)
? 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,
);
}