func()

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
}