优化
This commit is contained in:
+32
-20
@@ -38,7 +38,7 @@ func migrateAll(db *gorm.DB) error {
|
||||
// Older builds used a status label outside the administration page's supported
|
||||
// state set, so normalize existing rows during migration.
|
||||
func normalizeErrorRecordStatuses(db *gorm.DB) error {
|
||||
return db.Model(&errorRecordPO{}).Where("status = ?", "未解决").Update("status", "未处理").Error
|
||||
return db.Session(&gorm.Session{NewDB: true}).Model(&errorRecordPO{}).Where("status = ?", "未解决").Update("status", "未处理").Error
|
||||
}
|
||||
|
||||
// migrateLegacyAuthorityAPIsToCasbinRules upgrades the early Kra join-table
|
||||
@@ -46,7 +46,8 @@ func normalizeErrorRecordStatuses(db *gorm.DB) error {
|
||||
// table in place for backwards compatibility, but make casbin_rule the sole
|
||||
// live policy source. Existing policy rows are not duplicated.
|
||||
func migrateLegacyAuthorityAPIsToCasbinRules(db *gorm.DB) error {
|
||||
if !db.Migrator().HasTable(&authorityAPIPO{}) || !db.Migrator().HasTable(&casbinRulePO{}) {
|
||||
clean := db.Session(&gorm.Session{NewDB: true})
|
||||
if !clean.Migrator().HasTable(&authorityAPIPO{}) || !clean.Migrator().HasTable(&casbinRulePO{}) {
|
||||
return nil
|
||||
}
|
||||
type legacyPolicy struct {
|
||||
@@ -54,22 +55,28 @@ func migrateLegacyAuthorityAPIsToCasbinRules(db *gorm.DB) error {
|
||||
Path string
|
||||
Method string
|
||||
}
|
||||
var rows []legacyPolicy
|
||||
if err := db.Table("sys_authority_apis sa").
|
||||
query := clean.Table("sys_authority_apis sa").
|
||||
Select("sa.authority_id, a.path, a.method").
|
||||
Joins("JOIN sys_apis a ON a.id = sa.api_id").
|
||||
Where("a.deleted_at IS NULL").Find(&rows).Error; err != nil {
|
||||
Joins("JOIN sys_apis a ON a.id = sa.api_id")
|
||||
// Early Kra schemas stored sys_apis without soft-delete timestamps. The
|
||||
// legacy-policy migration must run before assuming that column exists;
|
||||
// otherwise an upgrade from those schemas cannot start on MySQL.
|
||||
if clean.Migrator().HasColumn(&apiPO{}, "deleted_at") {
|
||||
query = query.Where("a.deleted_at IS NULL")
|
||||
}
|
||||
var rows []legacyPolicy
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, row := range rows {
|
||||
exists, err := policyExists(db, row.AuthorityID, row.Path, row.Method)
|
||||
exists, err := policyExists(clean, row.AuthorityID, row.Path, row.Method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
continue
|
||||
}
|
||||
if err := db.Create(&casbinRulePO{Ptype: "p", V0: fmt.Sprint(row.AuthorityID), V1: row.Path, V2: row.Method}).Error; err != nil {
|
||||
if err := clean.Create(&casbinRulePO{Ptype: "p", V0: fmt.Sprint(row.AuthorityID), V1: row.Path, V2: row.Method}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -82,7 +89,8 @@ func migrateLegacyAuthorityAPIsToCasbinRules(db *gorm.DB) error {
|
||||
// composite primary key portably, so rebuild the small table once while
|
||||
// preserving every existing ignore rule.
|
||||
func migrateLegacyIgnoreAPITable(db *gorm.DB) error {
|
||||
if !db.Migrator().HasTable(&ignoredAPIPO{}) || db.Migrator().HasColumn(&ignoredAPIPO{}, "id") {
|
||||
clean := db.Session(&gorm.Session{NewDB: true})
|
||||
if !clean.Migrator().HasTable(&ignoredAPIPO{}) || clean.Migrator().HasColumn(&ignoredAPIPO{}, "id") {
|
||||
return nil
|
||||
}
|
||||
legacyTable := fmt.Sprintf("sys_ignore_apis_legacy_%d", time.Now().UnixNano())
|
||||
@@ -90,7 +98,7 @@ func migrateLegacyIgnoreAPITable(db *gorm.DB) error {
|
||||
Path string
|
||||
Method string
|
||||
}
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
return clean.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Migrator().RenameTable(ignoredAPIPO{}.TableName(), legacyTable); err != nil {
|
||||
return fmt.Errorf("rename legacy ignore API table: %w", err)
|
||||
}
|
||||
@@ -123,16 +131,17 @@ func migrateLegacyIgnoreAPITable(db *gorm.DB) error {
|
||||
// database has the root role but no stored API links, materialize the same
|
||||
// policy set and let normal authorization read it thereafter.
|
||||
func reconcileRootAuthorityAPIs(db *gorm.DB) error {
|
||||
clean := db.Session(&gorm.Session{NewDB: true})
|
||||
var authorityCount int64
|
||||
if err := db.Model(&authorityPO{}).Where("authority_id = ?", 888).Count(&authorityCount).Error; err != nil || authorityCount == 0 {
|
||||
if err := clean.Session(&gorm.Session{NewDB: true}).Model(&authorityPO{}).Where("authority_id = ?", 888).Count(&authorityCount).Error; err != nil || authorityCount == 0 {
|
||||
return err
|
||||
}
|
||||
var policyCount int64
|
||||
if err := policyScope(db).Where("v0 = ?", "888").Count(&policyCount).Error; err != nil || policyCount != 0 {
|
||||
if err := policyScope(clean).Where("v0 = ?", "888").Count(&policyCount).Error; err != nil || policyCount != 0 {
|
||||
return err
|
||||
}
|
||||
var ignored []ignoredAPIPO
|
||||
if err := db.Find(&ignored).Error; err != nil {
|
||||
if err := clean.Session(&gorm.Session{NewDB: true}).Find(&ignored).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
ignoreSet := make(map[string]struct{}, len(ignored))
|
||||
@@ -140,7 +149,7 @@ func reconcileRootAuthorityAPIs(db *gorm.DB) error {
|
||||
ignoreSet[item.Method+"\x00"+item.Path] = struct{}{}
|
||||
}
|
||||
var apis []apiPO
|
||||
if err := db.Find(&apis).Error; err != nil {
|
||||
if err := clean.Session(&gorm.Session{NewDB: true}).Find(&apis).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
rules := make([]casbinRulePO, 0, len(apis))
|
||||
@@ -153,13 +162,14 @@ func reconcileRootAuthorityAPIs(db *gorm.DB) error {
|
||||
if len(rules) == 0 {
|
||||
return nil
|
||||
}
|
||||
return db.Create(&rules).Error
|
||||
return clean.Session(&gorm.Session{NewDB: true}).Create(&rules).Error
|
||||
}
|
||||
|
||||
// reconcileReferenceIndexes removes constraints created by older Kra builds
|
||||
// that are not part of the administration data model. Business services own
|
||||
// duplicate checks and their user-facing error messages.
|
||||
func reconcileReferenceIndexes(db *gorm.DB) error {
|
||||
clean := db.Session(&gorm.Session{NewDB: true})
|
||||
obsolete := []struct {
|
||||
model any
|
||||
name string
|
||||
@@ -171,8 +181,9 @@ func reconcileReferenceIndexes(db *gorm.DB) error {
|
||||
{&exportTemplatePO{}, "idx_sys_export_templates_template_id"},
|
||||
}
|
||||
for _, item := range obsolete {
|
||||
if db.Migrator().HasIndex(item.model, item.name) {
|
||||
if err := db.Migrator().DropIndex(item.model, item.name); err != nil {
|
||||
migrator := clean.Session(&gorm.Session{NewDB: true}).Migrator()
|
||||
if migrator.HasIndex(item.model, item.name) {
|
||||
if err := migrator.DropIndex(item.model, item.name); err != nil {
|
||||
return fmt.Errorf("drop obsolete index %s: %w", item.name, err)
|
||||
}
|
||||
}
|
||||
@@ -181,17 +192,18 @@ func reconcileReferenceIndexes(db *gorm.DB) error {
|
||||
name string
|
||||
field string
|
||||
}{{"idx_sys_users_uuid", "UUID"}, {"idx_sys_users_username", "Username"}} {
|
||||
unique, err := indexIsUnique(db, &userPO{}, item.name)
|
||||
unique, err := indexIsUnique(clean.Session(&gorm.Session{NewDB: true}), &userPO{}, item.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !unique {
|
||||
continue
|
||||
}
|
||||
if err = db.Migrator().DropIndex(&userPO{}, item.name); err != nil {
|
||||
migrator := clean.Session(&gorm.Session{NewDB: true}).Migrator()
|
||||
if err = migrator.DropIndex(&userPO{}, item.name); err != nil {
|
||||
return fmt.Errorf("drop legacy unique index %s: %w", item.name, err)
|
||||
}
|
||||
if err = db.Migrator().CreateIndex(&userPO{}, item.field); err != nil {
|
||||
if err = migrator.CreateIndex(&userPO{}, item.field); err != nil {
|
||||
return fmt.Errorf("create reference index %s: %w", item.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user