fix: migrate id column type to bigint (resolve #281)

This commit is contained in:
Ferdinand Mütsch 2021-12-15 10:50:16 +01:00
parent 1c0477f861
commit 259f711f2d
11 changed files with 111 additions and 90 deletions

View File

@ -243,6 +243,14 @@ func (c *dbConfig) IsSQLite() bool {
return c.Dialect == "sqlite3"
}
func (c *dbConfig) IsMySQL() bool {
return c.Dialect == "mysql"
}
func (c *dbConfig) IsPostgres() bool {
return c.Dialect == "postgres"
}
func (c *serverConfig) GetPublicUrl() string {
return strings.TrimSuffix(c.PublicUrl, "/")
}
@ -289,6 +297,12 @@ func resolveDbDialect(dbType string) string {
if dbType == "cockroach" {
return "postgres"
}
if dbType == "sqlite" {
return "sqlite3"
}
if dbType == "mariadb" {
return "mysql"
}
return dbType
}

View File

@ -31,13 +31,7 @@ func init() {
return nil
}
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
if hasRun(name, db) {
return nil
}
@ -64,13 +58,7 @@ func init() {
}
}
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -26,13 +26,7 @@ func init() {
return nil
}
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
if hasRun(name, db) {
return nil
}
@ -43,13 +37,7 @@ func init() {
}
}
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -1,9 +1,7 @@
package migrations
import (
"github.com/emvi/logbuch"
"github.com/muety/wakapi/config"
"github.com/muety/wakapi/models"
"gorm.io/gorm"
)
@ -12,13 +10,7 @@ func init() {
f := migrationFunc{
name: name,
f: func(db *gorm.DB, cfg *config.Config) error {
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
if hasRun(name, db) {
return nil
}
@ -26,13 +18,7 @@ func init() {
return err
}
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -1,9 +1,7 @@
package migrations
import (
"github.com/emvi/logbuch"
"github.com/muety/wakapi/config"
"github.com/muety/wakapi/models"
"gorm.io/gorm"
)
@ -12,13 +10,7 @@ func init() {
f := migrationFunc{
name: name,
f: func(db *gorm.DB, cfg *config.Config) error {
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
if hasRun(name, db) {
return nil
}
@ -26,13 +18,7 @@ func init() {
return err
}
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -1,7 +1,6 @@
package migrations
import (
"github.com/emvi/logbuch"
"github.com/muety/wakapi/config"
"github.com/muety/wakapi/models"
"gorm.io/gorm"
@ -13,15 +12,14 @@ func init() {
f := migrationFunc{
name: name,
f: func(db *gorm.DB, cfg *config.Config) error {
if hasRun(name, db) {
return nil
}
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
return nil
}
imprintKv := &models.KeyStringValue{Key: "imprint", Value: "no content here"}
if err := db.
@ -32,13 +30,7 @@ func init() {
return err
}
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -13,14 +13,7 @@ func init() {
f := migrationFunc{
name: name,
f: func(db *gorm.DB, cfg *config.Config) error {
condition := "key = ?"
if cfg.Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
if hasRun(name, db) {
return nil
}
@ -35,13 +28,7 @@ func init() {
}
logbuch.Info("successfully deleted project label summary items")
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
return err
}
setHasRun(name, db)
return nil
},
}

View File

@ -0,0 +1,50 @@
package migrations
import (
"github.com/emvi/logbuch"
"github.com/muety/wakapi/config"
"gorm.io/gorm"
)
func init() {
const name = "20211215-migrate_id_to_bigint-add_has_data_field"
f := migrationFunc{
name: name,
f: func(db *gorm.DB, cfg *config.Config) error {
if hasRun(name, db) {
return nil
}
if cfg.Db.IsMySQL() {
tx := db.Begin()
if err := tx.Exec("ALTER TABLE heartbeats MODIFY COLUMN id BIGINT UNSIGNED").Error; err != nil {
return err
}
if err := tx.Exec("ALTER TABLE summary_items MODIFY COLUMN id BIGINT UNSIGNED").Error; err != nil {
return err
}
tx.Commit()
} else if cfg.Db.IsPostgres() {
// postgres does not have unsigned data types
// https://www.postgresql.org/docs/10/datatype-numeric.html
tx := db.Begin()
if err := tx.Exec("ALTER TABLE heartbeats ALTER COLUMN id TYPE BIGINT").Error; err != nil {
return err
}
if err := tx.Exec("ALTER TABLE summary_items ALTER COLUMN id TYPE BIGINT").Error; err != nil {
return err
}
tx.Commit()
} else {
// sqlite doesn't allow for changing column type easily
// https://stackoverflow.com/a/2083562/3112139
logbuch.Warn("unable to migrate id columns to bigint on %s", cfg.Db.Dialect)
}
setHasRun(name, db)
return nil
},
}
registerPostMigration(f)
}

30
migrations/shared.go Normal file
View File

@ -0,0 +1,30 @@
package migrations
import (
"github.com/emvi/logbuch"
"github.com/muety/wakapi/config"
"github.com/muety/wakapi/models"
"gorm.io/gorm"
)
func hasRun(name string, db *gorm.DB) bool {
condition := "key = ?"
if config.Get().Db.Dialect == config.SQLDialectMysql {
condition = "`key` = ?"
}
lookupResult := db.Where(condition, name).First(&models.KeyStringValue{})
if lookupResult.Error == nil && lookupResult.RowsAffected > 0 {
logbuch.Info("no need to migrate '%s'", name)
return true
}
return false
}
func setHasRun(name string, db *gorm.DB) {
if err := db.Create(&models.KeyStringValue{
Key: name,
Value: "done",
}).Error; err != nil {
logbuch.Error("failed to mark migration %s as run - %v", name, err)
}
}

View File

@ -9,7 +9,7 @@ import (
)
type Heartbeat struct {
ID uint `gorm:"primary_key" hash:"ignore"`
ID uint64 `gorm:"primary_key" hash:"ignore"`
User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" hash:"ignore"`
UserID string `json:"-" gorm:"not null; index:idx_time_user"`
Entity string `json:"entity" gorm:"not null; index:idx_entity"`

View File

@ -36,7 +36,7 @@ type Summary struct {
type SummaryItems []*SummaryItem
type SummaryItem struct {
ID uint `json:"-" gorm:"primary_key"`
ID uint64 `json:"-" gorm:"primary_key"`
Summary *Summary `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
SummaryID uint `json:"-"`
Type uint8 `json:"-" gorm:"index:idx_type"`