92 lines
3.7 KiB
Go
92 lines
3.7 KiB
Go
package business
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
"kra/pkg/database/migration"
|
|
)
|
|
|
|
// These source tables carry history. An incomplete copy must not be replaced
|
|
// with empty tables. SDK and OA schemas belong to their respective databases.
|
|
var importedTables = []string{
|
|
"tab_game", "tab_game_server", "tab_promote", "tab_promote_apply",
|
|
"tab_spend", "tab_user", "tab_user_day_login", "tab_user_play_info",
|
|
"tab_sw_report_day", "tab_sw_report_day_key", "tab_sw_report_server_day", "tab_sw_report_server_day_key",
|
|
}
|
|
|
|
func CheckPrerequisites(db *gorm.DB) error {
|
|
if db.Dialector.Name() != "mysql" {
|
|
return nil
|
|
}
|
|
if db.Migrator().HasTable("sys_user") && !db.Migrator().HasTable("sys_users") {
|
|
return fmt.Errorf("legacy framework conversion must run before incremental migrations")
|
|
}
|
|
var missing []string
|
|
for _, table := range importedTables {
|
|
if !db.Migrator().HasTable(table) {
|
|
missing = append(missing, table)
|
|
}
|
|
}
|
|
if len(missing) > 0 {
|
|
return fmt.Errorf("incomplete legacy copy, missing tables: %s", strings.Join(missing, ", "))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CheckSchema(db *gorm.DB) error {
|
|
if err := CheckPrerequisites(db); err != nil {
|
|
return err
|
|
}
|
|
if err := migration.CheckModels(db,
|
|
&preferencePO{}, &bindingPO{}, &bindingLockPO{}, &resetCodePO{}, &resetTokenPO{},
|
|
&alertRulePO{}, &alertRecordPO{}, &alertLogPO{}, &alertGapPO{}, &alertExemptionPO{}, &alertChannelLockPO{},
|
|
&alertTriggerLockPO{}, &reportBuildLockPO{}, &businessGroupPO{}, &businessGroupMemberPO{},
|
|
&businessMemberProfilePO{}, &businessGroupStatePO{}, &performanceGoalPO{}, &effectivenessStatePO{}, &effectivenessPO{},
|
|
); err != nil {
|
|
return err
|
|
}
|
|
if db.Dialector.Name() != "mysql" {
|
|
return nil
|
|
}
|
|
indexes := append([]businessQueryIndex{}, businessQueryIndexes...)
|
|
var idType string
|
|
if err := db.Raw("SELECT data_type FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='tab_promote' AND column_name='id'").Scan(&idType).Error; err != nil {
|
|
return err
|
|
}
|
|
if idType != "bigint" {
|
|
return fmt.Errorf("tab_promote.id must be BIGINT after capacity migration")
|
|
}
|
|
indexes = append(indexes, reportBuildQueryIndexes...)
|
|
indexes = append(indexes, alertV2QueryIndexes...)
|
|
indexes = append(indexes,
|
|
businessQueryIndex{"tab_spend", "idx_sw_spend_effective_scan", []string{"promote_id", "source_db", "pay_status", "pay_time", "id", "pay_amount"}},
|
|
businessQueryIndex{"tab_promote_apply", "idx_sw_apply_game_scope", []string{"game_id", "source_db", "status", "promote_id"}},
|
|
businessQueryIndex{"tab_user", "idx_sw_user_registration", []string{"source_db", "puid", "sw_register_time_unix", "id"}},
|
|
businessQueryIndex{"tab_user_play_info", "idx_sw_play_create_time", []string{"create_time"}},
|
|
businessQueryIndex{"sys_alert_record", "uk_alert_record_v2_open", []string{"business_id", "platform_code", "target_promote_id", "rule_type", "v2_open_key"}},
|
|
)
|
|
for _, index := range indexes {
|
|
var existing []struct {
|
|
ColumnName string
|
|
NonUnique int
|
|
SubPart *int
|
|
}
|
|
if err := db.Raw("SELECT column_name,non_unique,sub_part FROM information_schema.statistics WHERE table_schema=DATABASE() AND table_name=? AND index_name=? ORDER BY seq_in_index", index.table, index.name).Scan(&existing).Error; err != nil {
|
|
return err
|
|
}
|
|
columns := []string{}
|
|
for _, field := range existing {
|
|
if field.SubPart != nil || index.name == "uk_alert_record_v2_open" && field.NonUnique != 0 {
|
|
return fmt.Errorf("invalid index %s.%s", index.table, index.name)
|
|
}
|
|
columns = append(columns, field.ColumnName)
|
|
}
|
|
if strings.Join(columns, ",") != strings.Join(index.columns, ",") {
|
|
return fmt.Errorf("missing or incompatible index %s.%s", index.table, index.name)
|
|
}
|
|
}
|
|
return nil
|
|
}
|