repairMigration method
Creates a repair migration that will bring the database up to date with the targeted migration version.
If targetMigrationVersion is not specified, the latest migration version
will be used.
Returns the repair migration file, or null if no migration was created.
Implementation
Future<File?> repairMigration({
String? tag,
required bool force,
required String runMode,
required DatabaseDialect dialect,
String? targetMigrationVersion,
}) async {
var migrationVersion =
targetMigrationVersion ??
(await _artifactStore.listVersions()).lastOrNull;
await _validateRepairMigrationVersion(migrationVersion);
DatabaseDefinition dstDatabase = await _getSourceDatabaseDefinition(
projectName,
migrationVersion,
);
// Stored artifacts use the full merged definition (same as create-migration
// before SQL is generated). The live database only contains objects that
// exist for this dialect, so we must compare against the dialect-filtered
// target-otherwise unsupported indexes (etc.) appear as spurious drift.
var dstDatabaseForDialect = dstDatabase.forDialect(
dialect,
logWarnings: log.warning,
);
var client = ConfigInfo(runMode).createServiceClient();
DatabaseDefinition liveDatabase;
try {
liveDatabase = normalizeDefinitionToV2(
await client.insights.getLiveDatabaseDefinition(),
);
} catch (e) {
throw MigrationLiveDatabaseDefinitionException(
exception: e.toString(),
);
} finally {
client.close();
}
var migration = generateDatabaseMigration(
databaseSource: liveDatabase,
databaseTarget: dstDatabaseForDialect,
);
var warnings = migration.warnings;
_logWarnings(warnings);
if (warnings.isNotEmpty && !force) {
log.info('Migration aborted. Use --force to ignore warnings.');
return null;
}
bool versionsMismatch = _moduleVersionMismatch(liveDatabase, dstDatabase);
if (migration.isEmpty && !versionsMismatch && !force) {
log.info(
'No changes detected. Use --force to create an empty repair migration.',
);
return null;
}
var repairMigrationName = createVersionName(tag);
var installedModules = [
...dstDatabase.installedModules,
DatabaseMigrationVersionModel(
module: MigrationConstants.repairMigrationModuleName,
version: repairMigrationName,
),
];
List<DatabaseMigrationVersionModel> removedModules = _removedModulesDiff(
liveDatabase.installedModules,
installedModules,
);
return await _writeRepairMigration(
repairMigrationName,
migration,
dstDatabaseForDialect,
installedModules,
removedModules,
dialect,
);
}