diff --git a/internal/database/index_tags_test.go b/internal/database/index_tags_test.go new file mode 100644 index 000000000..e7a27c1ca --- /dev/null +++ b/internal/database/index_tags_test.go @@ -0,0 +1,40 @@ +package database + +import ( + "testing" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" + + "github.com/mhsanaei/3x-ui/v3/internal/database/model" + "github.com/mhsanaei/3x-ui/v3/internal/xray" +) + +// AutoMigrate must create the hot-path indexes added for client group filters +// and client_traffics inbound lookups. gorm creates missing indexes on migrate, +// so this also protects existing DBs after upgrade. +func TestAutoMigrateCreatesHotPathIndexes(t *testing.T) { + db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Silent), + }) + if err != nil { + t.Fatalf("open sqlite: %v", err) + } + if err := db.AutoMigrate(&model.ClientRecord{}, &xray.ClientTraffic{}); err != nil { + t.Fatalf("automigrate: %v", err) + } + + cases := []struct { + model any + index string + }{ + {&model.ClientRecord{}, "idx_client_record_group"}, + {&xray.ClientTraffic{}, "idx_client_traffics_inbound"}, + } + for _, c := range cases { + if !db.Migrator().HasIndex(c.model, c.index) { + t.Errorf("expected index %q to exist after AutoMigrate", c.index) + } + } +} diff --git a/internal/database/model/model.go b/internal/database/model/model.go index d80eecf6e..40f5427e0 100644 --- a/internal/database/model/model.go +++ b/internal/database/model/model.go @@ -571,7 +571,7 @@ type ClientRecord struct { ExpiryTime int64 `json:"expiryTime" gorm:"column:expiry_time"` Enable bool `json:"enable" gorm:"default:true"` TgID int64 `json:"tgId" gorm:"column:tg_id"` - Group string `json:"group" gorm:"column:group_name;default:''"` + Group string `json:"group" gorm:"column:group_name;default:'';index:idx_client_record_group"` Comment string `json:"comment"` Reset int `json:"reset" gorm:"default:0"` CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime:milli"` diff --git a/internal/xray/client_traffic.go b/internal/xray/client_traffic.go index 27449435b..9c75a12d2 100644 --- a/internal/xray/client_traffic.go +++ b/internal/xray/client_traffic.go @@ -4,7 +4,7 @@ package xray // It tracks upload/download usage, expiry times, and online status for inbound clients. type ClientTraffic struct { Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement" example:"14825"` - InboundId int `json:"inboundId" form:"inboundId" example:"1"` + InboundId int `json:"inboundId" form:"inboundId" gorm:"index:idx_client_traffics_inbound" example:"1"` Enable bool `json:"enable" form:"enable" example:"true"` Email string `json:"email" form:"email" gorm:"unique" example:"user1"` UUID string `json:"uuid" form:"uuid" gorm:"-" example:"e18c9a96-71bf-48d4-933f-8b9a46d4290c"`