in registry/datastore/migrations/migrator.go [352:444]
func (m *MigratorImpl) migrateUpWithCheck(maximum int, extraCheck ...MigrationDependencyResolver) (MigrationResult, error) {
var mr MigrationResult
// Initialize a new store to manage background migrations
bbmStore := datastore.NewBackgroundMigrationStore(m.db)
// Retrieve the source of eligible migrations
src, err := m.EligibleMigrationSource()
if err != nil {
return mr, fmt.Errorf("getting eligible migration source: %w", err)
}
// Fetch the migration records that have already been applied
migrationRecords, err := m.ms.GetMigrationRecords(m.db.DB, dialect)
if err != nil {
return mr, fmt.Errorf("retrieving migration records: %w", err)
}
// no migrations have been applied means this is an new install
newInstall := len(migrationRecords) == 0
// Create a map to store applied migrations for quick lookup
migrationRecordsMap := make(map[string]struct{}, len(migrationRecords))
for _, record := range migrationRecords {
migrationRecordsMap[record.Id] = struct{}{}
}
// Retrieve and sort all available migrations by ID
sortedMigrations, err := src.FindMigrations()
if err != nil {
return mr, fmt.Errorf("finding migrations: %w", err)
}
// Map to hold all local migrations for reference during the process
localMigrationsMap := make(map[string]*Migration, len(m.migrations))
for _, migration := range m.migrations {
localMigrationsMap[migration.Id] = migration
}
ctx := context.Background()
// Iterate through each migration, applying them if necessary
for _, migration := range sortedMigrations {
// Stop if we reach the specified 'max' number of migrations
if maximum != 0 && mr.AppliedCount == maximum {
break
}
// Skip migrations that have already been applied
if _, applied := migrationRecordsMap[migration.Id]; applied {
continue
}
// Ensure all Batched Background Migrations (BBMs) are completed before applying migration
if err := m.ensureBBMsComplete(ctx, bbmStore, localMigrationsMap[migration.Id]); err != nil {
// Apply incomplete BBMs during new installations
if !errors.Is(err, ErrBBMNotComplete) || !newInstall {
// Return the error if it's not a new installation and there are incomplete BBMs
return mr, err
}
// Run the BBM worker
if err := m.bbmWorker.Run(ctx); err != nil {
return mr, err
}
// Increment the count of finished BBMs
mr.AppliedBBMCount += m.bbmWorker.FinishedMigrationCount()
}
// runs custom checks per migration
for _, check := range extraCheck {
var appliedDependentMigration int
if appliedDependentMigration, err = check(ctx, localMigrationsMap[migration.Id]); err != nil {
return mr, err
}
// Increment the count of applied migrations
mr.AppliedDependencyCount += appliedDependentMigration
}
// Apply the migration
var appliedCount int
if appliedCount, err = m.ApplyMigration(src, migration); err != nil {
return mr, err
}
// Increment the count of applied migrations
mr.AppliedCount += appliedCount
}
// Return the number of applied migrations
return mr, nil
}