提交 c4332339 编写于 作者: S SampsonYe

优化Migration策略,在数据库中记录最新的Migration历史,确保每个Migration有且执行一次

上级 e8e4f7ce
......@@ -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 {
......
......@@ -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
}
......@@ -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()
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册