2020-08-08 15:04:59 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"forge.cadoles.com/Cadoles/guesstimate/internal/model"
|
|
|
|
"forge.cadoles.com/Cadoles/guesstimate/internal/orm"
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"gitlab.com/wpetit/goweb/logger"
|
|
|
|
"gitlab.com/wpetit/goweb/service"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
migrateUp = "up"
|
|
|
|
migrateLatest = "latest"
|
|
|
|
migrateDown = "down"
|
|
|
|
)
|
|
|
|
|
|
|
|
func applyMigration(ctx context.Context, ctn *service.Container) error {
|
|
|
|
orm, err := orm.From(ctn)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
migr := orm.Migration()
|
|
|
|
|
|
|
|
// Register available migrations
|
|
|
|
migr.Register(
|
|
|
|
m000initialSchema(),
|
|
|
|
)
|
|
|
|
|
|
|
|
currentVersion, err := migr.CurrentVersion(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "could not retrieve current data schema version")
|
|
|
|
}
|
|
|
|
|
|
|
|
switch migrate {
|
|
|
|
case migrateUp:
|
|
|
|
if err := migr.Up(ctx); err != nil {
|
|
|
|
return errors.Wrap(err, "could not apply up migration")
|
|
|
|
}
|
|
|
|
|
|
|
|
case migrateLatest:
|
|
|
|
latestVersion, err := migr.LatestVersion()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "could not retrieve latest data schema version")
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info(
|
|
|
|
ctx,
|
|
|
|
"migrating data schema to latest version",
|
|
|
|
logger.F("currentVersion", currentVersion),
|
|
|
|
logger.F("latestVersion", latestVersion),
|
|
|
|
)
|
|
|
|
|
|
|
|
// Execute migration to latest available version
|
|
|
|
if err := migr.Latest(ctx); err != nil {
|
|
|
|
return errors.Wrap(err, "could not migrate to latest data schema")
|
|
|
|
}
|
|
|
|
|
|
|
|
case migrateDown:
|
|
|
|
if err := migr.Down(ctx); err != nil {
|
|
|
|
return errors.Wrap(err, "could not apply down migration")
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return errors.Errorf("unknown migration command: '%s'", migrate)
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info(
|
|
|
|
ctx,
|
|
|
|
"migration completed",
|
|
|
|
)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// nolint: gochecknoglobals
|
|
|
|
var initialModels = []interface{}{
|
|
|
|
&model.User{},
|
2020-09-11 09:19:18 +02:00
|
|
|
&model.Project{},
|
|
|
|
&model.Access{},
|
|
|
|
&model.TaskCategory{},
|
|
|
|
&model.Task{},
|
2020-08-08 15:04:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func m000initialSchema() orm.Migration {
|
|
|
|
return orm.NewDBMigration(
|
|
|
|
"00_initial_schema",
|
|
|
|
func(ctx context.Context, tx *gorm.DB) error {
|
|
|
|
for _, m := range initialModels {
|
|
|
|
if err := tx.AutoMigrate(m).Error; err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-11 09:19:18 +02:00
|
|
|
// Create foreign keys indexes
|
|
|
|
err := tx.Model(&model.Access{}).
|
|
|
|
AddForeignKey("user_id", "users(id)", "CASCADE", "CASCADE").Error
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Model(&model.TaskCategory{}).
|
|
|
|
AddForeignKey("project_id", "projects(id)", "CASCADE", "CASCADE").Error
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Model(&model.Access{}).
|
|
|
|
AddForeignKey("project_id", "projects(id)", "CASCADE", "CASCADE").Error
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Model(&model.Access{}).
|
|
|
|
AddForeignKey("user_id", "users(id)", "CASCADE", "CASCADE").Error
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Model(&model.Task{}).
|
|
|
|
AddForeignKey("category_id", "task_categories(id)", "CASCADE", "CASCADE").Error
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
2020-08-08 15:04:59 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
func(ctx context.Context, tx *gorm.DB) error {
|
2020-09-11 09:19:18 +02:00
|
|
|
for i := len(initialModels) - 1; i >= 0; i-- {
|
|
|
|
if err := tx.DropTableIfExists(initialModels[i]).Error; err != nil {
|
2020-08-08 15:04:59 +02:00
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-11 09:19:18 +02:00
|
|
|
if err := tx.DropTableIfExists("sessions").Error; err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
2020-08-08 15:04:59 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|