diff --git a/internal/migrations/migration20220101.go b/internal/migrations/migration20220101.go index ad2e191a53fe4555c7fb60ddb0c214aed62491d5..aefa4e1f349457f9c0081997474f9a50a1aaff82 100644 --- a/internal/migrations/migration20220101.go +++ b/internal/migrations/migration20220101.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/astaxie/beego/orm" "github.com/go-atomci/atomci/internal/middleware/log" - "os" "time" ) @@ -15,7 +14,7 @@ func (m Migration20220101) GetCreateAt() time.Time { return time.Date(2022, 1, 1, 0, 0, 0, 0, time.Local) } -func (m Migration20220101) Upgrade(ormer orm.Ormer) { +func (m Migration20220101) Upgrade(ormer orm.Ormer) error { tables := []string{ "sys_resource_type", "sys_resource_operation", @@ -33,12 +32,13 @@ func (m Migration20220101) Upgrade(ormer orm.Ormer) { if err := setCreateAt(ormer, tables); err != nil { log.Log.Error(err.Error()) - os.Exit(2) + return err } if err := setUpdateAt(ormer, tables); err != nil { log.Log.Error(err.Error()) - os.Exit(2) + return err } + return nil } func setCreateAt(ormer orm.Ormer, tables []string) error { diff --git a/internal/migrations/migration20220309.go b/internal/migrations/migration20220309.go index 58e02db538d8e7879862884df8964d4f5121fed2..22ea2490c2976d9f150f12a28db7a3d05c072b0f 100644 --- a/internal/migrations/migration20220309.go +++ b/internal/migrations/migration20220309.go @@ -13,29 +13,34 @@ func (m Migration20220309) GetCreateAt() time.Time { return time.Date(2022, 3, 9, 0, 0, 0, 0, time.Local) } -func (m Migration20220309) Upgrade(ormer orm.Ormer) { - ormer.Raw("UPDATE `sys_integrate_setting` SET `type`='registry' WHERE `type`='harbor';").Exec() +func (m Migration20220309) Upgrade(ormer orm.Ormer) error { + _, err := ormer.Raw("UPDATE `sys_integrate_setting` SET `type`='registry' WHERE `type`='harbor';").Exec() + if err != nil { + return err + } - ormer.Raw(strings.ReplaceAll(`DROP PROCEDURE IF EXISTS <|SPIT|>ModifyHarborToRegistry<|SPIT|>; -delimiter $$ -CREATE PROCEDURE <|SPIT|>ModifyHarborToRegistry<|SPIT|>() + _, err = ormer.Raw("DROP PROCEDURE IF EXISTS `ModifyHarborToRegistry`;").Exec() + _, err = ormer.Raw(strings.ReplaceAll(`CREATE PROCEDURE <|SPIT|>ModifyHarborToRegistry<|SPIT|>() BEGIN DECLARE HARBOREXISTS int DEFAULT 0; DECLARE REGISTRYEXISTS int DEFAULT 0; SELECT count(1) INTO @HARBOREXISTS FROM information_schema.COLUMNS WHERE TABLE_NAME='project_env' AND COLUMN_NAME='harbor'; SELECT count(1) INTO @REGISTRYEXISTS FROM information_schema.COLUMNS WHERE TABLE_NAME='project_env' AND COLUMN_NAME='registry'; - IF @HARBOREXISTS>0 AND @REGISTRYEXISTS=0 #存在harbor列 不存在registry列时 直接修改列名 + IF @HARBOREXISTS>0 AND @REGISTRYEXISTS=0 THEN ALTER TABLE <|SPIT|>project_env<|SPIT|> CHANGE COLUMN <|SPIT|>harbor<|SPIT|> <|SPIT|>registry<|SPIT|> bigint(20) NOT NULL DEFAULT 0; - ELSEIF @HARBOREXISTS>0 AND @REGISTRYEXISTS>0 #harbor列和registry都存在时迁移数据并删除harbor列 + ELSEIF @HARBOREXISTS>0 AND @REGISTRYEXISTS>0 THEN UPDATE <|SPIT|>project_env<|SPIT|> SET <|SPIT|>registry<|SPIT|>=<|SPIT|>harbor<|SPIT|>; ALTER TABLE <|SPIT|>project_env<|SPIT|> DROP COLUMN <|SPIT|>harbor<|SPIT|>; END IF; -END; -$$ -delimiter ; -CALL <|SPIT|>ModifyHarborToRegistry<|SPIT|>; -DROP PROCEDURE IF EXISTS <|SPIT|>ModifyHarborToRegistry<|SPIT|>;`, "<|SPIT|>", "`")).Exec() +END;`, "<|SPIT|>", "`")).Exec() + _, err = ormer.Raw("CALL `ModifyHarborToRegistry`;").Exec() + _, err = ormer.Raw("DROP PROCEDURE IF EXISTS `ModifyHarborToRegistry`;").Exec() + + if err != nil { + return err + } + return nil } diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 4c62689bace4e071b3157926f0527087ee757277..85ca69f9b6fbf6687b8598704173db97607c8518 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -2,24 +2,96 @@ package migrations import ( "github.com/astaxie/beego/orm" + "sort" "time" ) +type MigrationTypes []Migration + // Migration db migration base interface type Migration interface { GetCreateAt() time.Time - Upgrade(ormer orm.Ormer) + Upgrade(ormer orm.Ormer) error +} + +// Len 排序三人组 +func (t MigrationTypes) Len() int { + return len(t) +} + +// Less 排序三人组 +func (t MigrationTypes) Less(i, j int) bool { + return t[i].GetCreateAt().Before(t[j].GetCreateAt()) +} + +// Swap 排序三人组 +func (t MigrationTypes) Swap(i, j int) { + t[i], t[j] = t[j], t[i] } // InitMigration db migration register func InitMigration() { - migrationTypes := []Migration{ + migrationTypes := MigrationTypes{ new(Migration20220101), new(Migration20220309), } - //数据迁移 + migrateInTx(migrationTypes) +} + +func migrateInTx(migrationTypes MigrationTypes) { + //升序 + sort.Sort(migrationTypes) + + //数据迁移(事务) + ormClient := orm.NewOrm() + last := getNewestData(ormClient) + tempLast := last + errRet := ormClient.Begin() for _, m := range migrationTypes { - m.Upgrade(orm.NewOrm()) + if m.GetCreateAt().After(last) { + errRet = m.Upgrade(ormClient) + if errRet != nil { + break + } + } + tempLast = m.GetCreateAt() } + errRet = updateNewestData(ormClient, tempLast) + if errRet != nil { + ormClient.Rollback() + } else { + ormClient.Commit() + } +} + +func getNewestData(ormer orm.Ormer) time.Time { + sureCreateTable(ormer) + sql := `Select * From __dbmigration Limit 1` + var lastMigrationDate time.Time + ormer.Raw(sql).QueryRow(&lastMigrationDate) + if lastMigrationDate.IsZero() { + lastMigrationDate = time.Now() + } + return lastMigrationDate +} + +func updateNewestData(ormer orm.Ormer, lastTime time.Time) error { + countSql := "Select count(*) from __dbmigration" + var count int + ormer.Raw(countSql).QueryRow(&count) + + sql := "Update __dbmigration set last_migration_date=?" + if count == 0 { + sql = "Insert into __dbmigration(last_migration_date) values (?)" + } + _, err := ormer.Raw(sql, lastTime).Exec() + return err +} + +func sureCreateTable(ormer orm.Ormer) { + ddl := `CREATE TABLE IF NOT EXISTS __dbmigration ( + last_migration_date datetime DEFAULT CURRENT_TIMESTAMP + )` + ormer.Raw(ddl).Exec() }