fix: enhance migrateTokenModelLimitsToText function to return errors and improve migration checks

This commit is contained in:
RedwindA 2026-02-28 19:08:03 +08:00
parent f1b3627274
commit f3d38ca195

View File

@ -251,7 +251,9 @@ func migrateDB() error {
// Migrate price_amount column from float/double to decimal for existing tables // Migrate price_amount column from float/double to decimal for existing tables
migrateSubscriptionPlanPriceAmount() migrateSubscriptionPlanPriceAmount()
// Migrate model_limits column from varchar to text for existing tables // Migrate model_limits column from varchar to text for existing tables
migrateTokenModelLimitsToText() if err := migrateTokenModelLimitsToText(); err != nil {
return err
}
err := DB.AutoMigrate( err := DB.AutoMigrate(
&Channel{}, &Channel{},
@ -449,52 +451,55 @@ PRIMARY KEY (` + "`id`" + `)
// migrateTokenModelLimitsToText migrates model_limits column from varchar(1024) to text // migrateTokenModelLimitsToText migrates model_limits column from varchar(1024) to text
// This is safe to run multiple times - it checks the column type first // This is safe to run multiple times - it checks the column type first
func migrateTokenModelLimitsToText() { func migrateTokenModelLimitsToText() error {
// SQLite uses type affinity, so TEXT and VARCHAR are effectively the same — no migration needed // SQLite uses type affinity, so TEXT and VARCHAR are effectively the same — no migration needed
if common.UsingSQLite { if common.UsingSQLite {
return return nil
} }
tableName := "tokens" tableName := "tokens"
columnName := "model_limits" columnName := "model_limits"
if !DB.Migrator().HasTable(tableName) { if !DB.Migrator().HasTable(tableName) {
return return nil
} }
if !DB.Migrator().HasColumn(&Token{}, columnName) { if !DB.Migrator().HasColumn(&Token{}, columnName) {
return return nil
} }
var alterSQL string var alterSQL string
if common.UsingPostgreSQL { if common.UsingPostgreSQL {
var dataType string var dataType string
DB.Raw(`SELECT data_type FROM information_schema.columns if err := DB.Raw(`SELECT data_type FROM information_schema.columns
WHERE table_name = ? AND column_name = ?`, tableName, columnName).Scan(&dataType) WHERE table_schema = current_schema() AND table_name = ? AND column_name = ?`,
if dataType == "text" { tableName, columnName).Scan(&dataType).Error; err != nil {
return common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err))
} else if dataType == "text" {
return nil
} }
alterSQL = fmt.Sprintf(`ALTER TABLE %s ALTER COLUMN %s TYPE text`, tableName, columnName) alterSQL = fmt.Sprintf(`ALTER TABLE %s ALTER COLUMN %s TYPE text`, tableName, columnName)
} else if common.UsingMySQL { } else if common.UsingMySQL {
var columnType string var columnType string
DB.Raw(`SELECT COLUMN_TYPE FROM information_schema.columns if err := DB.Raw(`SELECT COLUMN_TYPE FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?`, WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?`,
tableName, columnName).Scan(&columnType) tableName, columnName).Scan(&columnType).Error; err != nil {
if strings.ToLower(columnType) == "text" { common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err))
return } else if strings.ToLower(columnType) == "text" {
return nil
} }
alterSQL = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s text", tableName, columnName) alterSQL = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s text", tableName, columnName)
} else { } else {
return return nil
} }
if alterSQL != "" { if alterSQL != "" {
if err := DB.Exec(alterSQL).Error; err != nil { if err := DB.Exec(alterSQL).Error; err != nil {
common.SysLog(fmt.Sprintf("Warning: failed to migrate %s.%s to text: %v", tableName, columnName, err)) return fmt.Errorf("failed to migrate %s.%s to text: %w", tableName, columnName, err)
} else {
common.SysLog(fmt.Sprintf("Successfully migrated %s.%s to text", tableName, columnName))
} }
common.SysLog(fmt.Sprintf("Successfully migrated %s.%s to text", tableName, columnName))
} }
return nil
} }
// migrateSubscriptionPlanPriceAmount migrates price_amount column from float/double to decimal(10,6) // migrateSubscriptionPlanPriceAmount migrates price_amount column from float/double to decimal(10,6)
@ -523,9 +528,11 @@ func migrateSubscriptionPlanPriceAmount() {
if common.UsingPostgreSQL { if common.UsingPostgreSQL {
// PostgreSQL: Check if already decimal/numeric // PostgreSQL: Check if already decimal/numeric
var dataType string var dataType string
DB.Raw(`SELECT data_type FROM information_schema.columns if err := DB.Raw(`SELECT data_type FROM information_schema.columns
WHERE table_name = ? AND column_name = ?`, tableName, columnName).Scan(&dataType) WHERE table_schema = current_schema() AND table_name = ? AND column_name = ?`,
if dataType == "numeric" { tableName, columnName).Scan(&dataType).Error; err != nil {
common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err))
} else if dataType == "numeric" {
return // Already decimal/numeric return // Already decimal/numeric
} }
alterSQL = fmt.Sprintf(`ALTER TABLE %s ALTER COLUMN %s TYPE decimal(10,6) USING %s::decimal(10,6)`, alterSQL = fmt.Sprintf(`ALTER TABLE %s ALTER COLUMN %s TYPE decimal(10,6) USING %s::decimal(10,6)`,
@ -533,10 +540,11 @@ func migrateSubscriptionPlanPriceAmount() {
} else if common.UsingMySQL { } else if common.UsingMySQL {
// MySQL: Check if already decimal // MySQL: Check if already decimal
var columnType string var columnType string
DB.Raw(`SELECT COLUMN_TYPE FROM information_schema.columns if err := DB.Raw(`SELECT COLUMN_TYPE FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?`, WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?`,
tableName, columnName).Scan(&columnType) tableName, columnName).Scan(&columnType).Error; err != nil {
if strings.HasPrefix(strings.ToLower(columnType), "decimal") { common.SysLog(fmt.Sprintf("Warning: failed to query metadata for %s.%s: %v", tableName, columnName, err))
} else if strings.HasPrefix(strings.ToLower(columnType), "decimal") {
return // Already decimal return // Already decimal
} }
alterSQL = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s decimal(10,6) NOT NULL DEFAULT 0", alterSQL = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s decimal(10,6) NOT NULL DEFAULT 0",