fix(models): isolate versioned migration sessions
This commit is contained in:
@@ -33,14 +33,18 @@ func runVersionedMigrations(database *gorm.DB) error {
|
|||||||
{version: 2, name: "deduplicate_project_tags", run: deduplicateLegacyProjectTags},
|
{version: 2, name: "deduplicate_project_tags", run: deduplicateLegacyProjectTags},
|
||||||
}
|
}
|
||||||
for _, migration := range migrations {
|
for _, migration := range migrations {
|
||||||
|
// Connection callbacks can provide an initialized Gorm session. Start each
|
||||||
|
// migration from a clean statement so Model/Where clauses used to check the
|
||||||
|
// version table are not inherited by the data-repair transaction.
|
||||||
|
migrationDatabase := database.Session(&gorm.Session{NewDB: true})
|
||||||
var applied int64
|
var applied int64
|
||||||
if err := database.Model(&SenlinAgentSchemaMigration{}).Where("version = ?", migration.version).Count(&applied).Error; err != nil {
|
if err := migrationDatabase.Model(&SenlinAgentSchemaMigration{}).Where("version = ?", migration.version).Count(&applied).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if applied > 0 {
|
if applied > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := database.Transaction(func(tx *gorm.DB) error {
|
if err := migrationDatabase.Session(&gorm.Session{NewDB: true}).Transaction(func(tx *gorm.DB) error {
|
||||||
details, err := migration.run(tx)
|
details, err := migration.run(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -61,7 +65,7 @@ func runVersionedMigrations(database *gorm.DB) error {
|
|||||||
|
|
||||||
func normalizeLegacyProjectIdentifiers(tx *gorm.DB) (map[string]int, error) {
|
func normalizeLegacyProjectIdentifiers(tx *gorm.DB) (map[string]int, error) {
|
||||||
var projects []SenlinAgentProject
|
var projects []SenlinAgentProject
|
||||||
if err := tx.Select("id", "owner_id", "identifier").Order("owner_id asc, id asc").Find(&projects).Error; err != nil {
|
if err := tx.Model(&SenlinAgentProject{}).Select("id", "owner_id", "identifier").Order("owner_id asc, id asc").Find(&projects).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +125,7 @@ func uniqueIdentifier(base string, reserved map[string]struct{}) string {
|
|||||||
|
|
||||||
func deduplicateLegacyProjectTags(tx *gorm.DB) (map[string]int, error) {
|
func deduplicateLegacyProjectTags(tx *gorm.DB) (map[string]int, error) {
|
||||||
var tags []SenlinAgentTag
|
var tags []SenlinAgentTag
|
||||||
if err := tx.Select("id", "identity", "project_id", "name").Order("project_id asc, name asc, id asc").Find(&tags).Error; err != nil {
|
if err := tx.Model(&SenlinAgentTag{}).Select("id", "identity", "project_id", "name").Order("project_id asc, name asc, id asc").Find(&tags).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
keepers := make(map[string]SenlinAgentTag)
|
keepers := make(map[string]SenlinAgentTag)
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ func TestAutoMigrateUpgradesLegacyProjectsAndTagsWithoutLosingAssociations(t *te
|
|||||||
require.NoError(t, database.Exec(statement).Error)
|
require.NoError(t, database.Exec(statement).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, AutoMigrate(database))
|
// PostgreSQL migrations run through database.Connection, whose callback DB can
|
||||||
|
// carry an initialized Gorm statement. Exercise that mode so model state from
|
||||||
|
// the migration-version lookup cannot leak into the data-repair transaction.
|
||||||
|
require.NoError(t, AutoMigrate(database.Session(&gorm.Session{Initialized: true})))
|
||||||
|
|
||||||
var projects []SenlinAgentProject
|
var projects []SenlinAgentProject
|
||||||
require.NoError(t, database.Order("id asc").Find(&projects).Error)
|
require.NoError(t, database.Order("id asc").Find(&projects).Error)
|
||||||
|
|||||||
Reference in New Issue
Block a user