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 when no schema drift is
detected between the live database and the target version (callers can
override with force).
Throws MigrationAbortedException when warnings are present and force
is false. Other typed exceptions surface specific failure modes; see the
MigrationRepair*Exception types.
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) {
throw const MigrationAbortedException();
}
bool versionsMismatch = _moduleVersionMismatch(liveDatabase, dstDatabase);
if (migration.isEmpty && !versionsMismatch && !force) {
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,
);
}