fix: validate explicit migrations and preserve large business ids
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package business
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func migrateBindingStatusIndex(db *gorm.DB) error {
|
||||
const name = "idx_sys_user_bind_platform_status"
|
||||
if !db.Migrator().HasTable(&bindingPO{}) {
|
||||
return nil
|
||||
}
|
||||
if db.Migrator().HasIndex(&bindingPO{}, name) {
|
||||
return nil
|
||||
}
|
||||
return db.Migrator().CreateIndex(&bindingPO{}, name)
|
||||
}
|
||||
|
||||
// Preserve IDs and the high-water mark: lowering AUTO_INCREMENT could reuse
|
||||
// a deleted ID that still appears in historical records or external systems.
|
||||
func migratePromoteIDCapacity(db *gorm.DB) error {
|
||||
if db.Dialector.Name() != "mysql" || !db.Migrator().HasTable("tab_promote") {
|
||||
return nil
|
||||
}
|
||||
var column struct {
|
||||
DataType, ColumnType, IsNullable, Extra, ColumnComment string
|
||||
}
|
||||
if err := db.Raw("SELECT data_type,column_type,is_nullable,extra,column_comment FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tab_promote' AND column_name='id'").Scan(&column).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if column.DataType == "bigint" {
|
||||
return nil
|
||||
}
|
||||
if column.DataType != "int" || column.IsNullable != "NO" || column.Extra != "auto_increment" {
|
||||
return fmt.Errorf("unexpected tab_promote.id definition; capacity migration stopped")
|
||||
}
|
||||
var next uint64
|
||||
if err := db.Raw("SELECT auto_increment FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='tab_promote'").Scan(&next).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
typeName := "BIGINT"
|
||||
if strings.Contains(column.ColumnType, "unsigned") {
|
||||
typeName += " UNSIGNED"
|
||||
}
|
||||
// MySQL 5.7 rebuilds the table when widening an integer. Execute before
|
||||
// starting writers and retain the original next ID and column comment.
|
||||
return db.Connection(func(conn *gorm.DB) error {
|
||||
var mode string
|
||||
if err := conn.Raw("SELECT @@session.sql_mode").Scan(&mode).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
comment := column.ColumnComment
|
||||
if !strings.Contains(mode, "NO_BACKSLASH_ESCAPES") {
|
||||
comment = strings.ReplaceAll(comment, `\`, `\\`)
|
||||
}
|
||||
comment = "'" + strings.ReplaceAll(comment, "'", "''") + "'"
|
||||
// MySQL does not permit a prepared-statement placeholder in COMMENT.
|
||||
return conn.Session(&gorm.Session{NewDB: true}).Exec(fmt.Sprintf("ALTER TABLE tab_promote MODIFY COLUMN id %s NOT NULL AUTO_INCREMENT COMMENT %s, AUTO_INCREMENT=%d", typeName, comment, next)).Error
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user