From 9424c49760812f29145e848371cabadbc1751021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Fri, 28 Oct 2022 09:54:11 +0200 Subject: [PATCH] fix: composite index on heartbeats table --- .../20221028_fix_heartbeats_time_user_idx.go | 41 +++++++++++++++++++ models/heartbeat.go | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 migrations/20221028_fix_heartbeats_time_user_idx.go diff --git a/migrations/20221028_fix_heartbeats_time_user_idx.go b/migrations/20221028_fix_heartbeats_time_user_idx.go new file mode 100644 index 0000000..60682d3 --- /dev/null +++ b/migrations/20221028_fix_heartbeats_time_user_idx.go @@ -0,0 +1,41 @@ +package migrations + +import ( + "github.com/emvi/logbuch" + "github.com/muety/wakapi/config" + "github.com/muety/wakapi/models" + "gorm.io/gorm" +) + +// due to an error in the model definition, idx_time_user used to only cover 'user_id', but not time column +// if that's the case in the current state of the database, drop the index and let it be recreated by auto migration afterwards +func init() { + const name = "20221028-fix_heartbeats_time_user_idx" + f := migrationFunc{ + name: name, + f: func(db *gorm.DB, cfg *config.Config) error { + migrator := db.Migrator() + + indexes, err := migrator.GetIndexes(&models.Heartbeat{}) + if err != nil { + return err + } + + for _, idx := range indexes { + if idx.Table() == "heartbeats" && idx.Name() == "idx_time_user" { + if len(idx.Columns()) == 1 { + if err := migrator.DropIndex(&models.Heartbeat{}, "idx_time_user"); err != nil { + return err + } + logbuch.Info("index 'idx_time_user' needs to be recreated, this may take a while") + return nil + } + } + } + + return nil + }, + } + + registerPreMigration(f) +} diff --git a/models/heartbeat.go b/models/heartbeat.go index 2101d9f..f9043b2 100644 --- a/models/heartbeat.go +++ b/models/heartbeat.go @@ -23,7 +23,7 @@ type Heartbeat struct { OperatingSystem string `json:"operating_system" gorm:"index:idx_operating_system" hash:"ignore"` // ignored because os might be parsed differently by wakatime Machine string `json:"machine" gorm:"index:idx_machine" hash:"ignore"` // ignored because wakatime api doesn't return machines currently UserAgent string `json:"user_agent" hash:"ignore" gorm:"type:varchar(255)"` - Time CustomTime `json:"time" gorm:"type:timestamp(3); index:idx_time,idx_time_user" swaggertype:"primitive,number"` + Time CustomTime `json:"time" gorm:"type:timestamp(3); index:idx_time; index:idx_time_user" swaggertype:"primitive,number"` Hash string `json:"-" gorm:"type:varchar(17); uniqueIndex"` Origin string `json:"-" hash:"ignore" gorm:"type:varchar(255)"` OriginId string `json:"-" hash:"ignore" gorm:"type:varchar(255)"`