mirror of https://gitee.com/answerdev/answer.git
feat(upgrade): support upgrade from specific version manually
This commit is contained in:
parent
8e46fe3ecd
commit
acad5b2811
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/install"
|
||||
"github.com/answerdev/answer/internal/migrations"
|
||||
"github.com/answerdev/answer/plugin"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -22,10 +23,9 @@ var (
|
|||
buildWithPlugins []string
|
||||
// build output path
|
||||
buildOutput string
|
||||
// This config is used to upgrade the database from a specific version number manually.
|
||||
// The version number is calculated with `migrations.go` migrations length.
|
||||
// If you want to upgrade the database from version 1 to version 2, you can use `answer upgrade -f 1`.
|
||||
upgradeFromVersionNumber int
|
||||
// This config is used to upgrade the database from a specific version manually.
|
||||
// If you want to upgrade the database to version 1.1.0, you can use `answer upgrade -f v1.1.0`.
|
||||
upgradeVersion string
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -39,7 +39,7 @@ func init() {
|
|||
|
||||
buildCmd.Flags().StringVarP(&buildOutput, "output", "o", "", "build output path")
|
||||
|
||||
upgradeCmd.Flags().IntVarP(&upgradeFromVersionNumber, "from", "f", 0, "upgrade from specific version number that in database version table")
|
||||
upgradeCmd.Flags().StringVarP(&upgradeVersion, "from", "f", "", "upgrade from specific version, eg: -f v1.1.0")
|
||||
|
||||
for _, cmd := range []*cobra.Command{initCmd, checkCmd, runCmd, dumpCmd, upgradeCmd, buildCmd, pluginCmd} {
|
||||
rootCmd.AddCommand(cmd)
|
||||
|
@ -106,6 +106,7 @@ To run answer, use:
|
|||
Short: "upgrade Answer version",
|
||||
Long: `upgrade Answer version`,
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
log.SetLogger(log.NewStdLogger(os.Stdout))
|
||||
cli.FormatAllPath(dataDirPath)
|
||||
cli.InstallI18nBundle(true)
|
||||
c, err := conf.ReadConfig(cli.GetConfigFilePath())
|
||||
|
@ -113,7 +114,7 @@ To run answer, use:
|
|||
fmt.Println("read config failed: ", err.Error())
|
||||
return
|
||||
}
|
||||
if err = migrations.Migrate(c.Data.Database, c.Data.Cache, upgradeFromVersionNumber); err != nil {
|
||||
if err = migrations.Migrate(c.Data.Database, c.Data.Cache, upgradeVersion); err != nil {
|
||||
fmt.Println("migrate failed: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
|
|
@ -9,21 +9,28 @@ import (
|
|||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const minDBVersion = 0 // answer 1.0.0
|
||||
const minDBVersion = 0
|
||||
|
||||
// Migration describes on migration from lower version to high version
|
||||
type Migration interface {
|
||||
Version() string
|
||||
Description() string
|
||||
Migrate(*xorm.Engine) error
|
||||
ShouldCleanCache() bool
|
||||
}
|
||||
|
||||
type migration struct {
|
||||
version string
|
||||
description string
|
||||
migrate func(*xorm.Engine) error
|
||||
shouldCleanCache bool
|
||||
}
|
||||
|
||||
// Version returns the migration's version
|
||||
func (m *migration) Version() string {
|
||||
return m.version
|
||||
}
|
||||
|
||||
// Description returns the migration's description
|
||||
func (m *migration) Description() string {
|
||||
return m.description
|
||||
|
@ -40,8 +47,8 @@ func (m *migration) ShouldCleanCache() bool {
|
|||
}
|
||||
|
||||
// NewMigration creates a new migration
|
||||
func NewMigration(desc string, fn func(*xorm.Engine) error, shouldCleanCache bool) Migration {
|
||||
return &migration{description: desc, migrate: fn, shouldCleanCache: shouldCleanCache}
|
||||
func NewMigration(version, desc string, fn func(*xorm.Engine) error, shouldCleanCache bool) Migration {
|
||||
return &migration{version: version, description: desc, migrate: fn, shouldCleanCache: shouldCleanCache}
|
||||
}
|
||||
|
||||
// Use noopMigration when there is a migration that has been no-oped
|
||||
|
@ -49,20 +56,20 @@ var noopMigration = func(_ *xorm.Engine) error { return nil }
|
|||
|
||||
var migrations = []Migration{
|
||||
// 0->1
|
||||
NewMigration("this is first version, no operation", noopMigration, false),
|
||||
NewMigration("add user language", addUserLanguage, false),
|
||||
NewMigration("add recommend and reserved tag fields", addTagRecommendedAndReserved, false),
|
||||
NewMigration("add activity timeline", addActivityTimeline, false),
|
||||
NewMigration("add user role", addRoleFeatures, false),
|
||||
NewMigration("add theme and private mode", addThemeAndPrivateMode, true),
|
||||
NewMigration("add new answer notification", addNewAnswerNotification, true),
|
||||
NewMigration("add plugin", addPlugin, false),
|
||||
NewMigration("add user pin hide features", addRolePinAndHideFeatures, true),
|
||||
NewMigration("update accept answer rank", updateAcceptAnswerRank, true),
|
||||
NewMigration("add login limitations", addLoginLimitations, true),
|
||||
NewMigration("update user pin hide features", updateRolePinAndHideFeatures, true),
|
||||
NewMigration("update question post time", updateQuestionPostTime, true),
|
||||
NewMigration("add gravatar base url", addGravatarBaseURL, false),
|
||||
NewMigration("v0.0.1", "this is first version, no operation", noopMigration, false),
|
||||
NewMigration("v0.3.0", "add user language", addUserLanguage, false),
|
||||
NewMigration("v0.4.1", "add recommend and reserved tag fields", addTagRecommendedAndReserved, false),
|
||||
NewMigration("v0.5.0", "add activity timeline", addActivityTimeline, false),
|
||||
NewMigration("v0.6.0", "add user role", addRoleFeatures, false),
|
||||
NewMigration("v1.0.0", "add theme and private mode", addThemeAndPrivateMode, true),
|
||||
NewMigration("v1.0.2", "add new answer notification", addNewAnswerNotification, true),
|
||||
NewMigration("v1.0.5", "add plugin", addPlugin, false),
|
||||
NewMigration("v1.0.7", "add user pin hide features", addRolePinAndHideFeatures, true),
|
||||
NewMigration("v1.0.8", "update accept answer rank", updateAcceptAnswerRank, true),
|
||||
NewMigration("v1.0.9", "add login limitations", addLoginLimitations, true),
|
||||
NewMigration("v1.1.0-beta.1", "update user pin hide features", updateRolePinAndHideFeatures, true),
|
||||
NewMigration("v1.1.0-beta.2", "update question post time", updateQuestionPostTime, true),
|
||||
NewMigration("v1.1.0", "add gravatar base url", addGravatarBaseURL, false),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
@ -92,7 +99,7 @@ func ExpectedVersion() int64 {
|
|||
}
|
||||
|
||||
// Migrate database to current version
|
||||
func Migrate(dbConf *data.Database, cacheConf *data.CacheConf, upgradeFromVersionNumber int) error {
|
||||
func Migrate(dbConf *data.Database, cacheConf *data.CacheConf, upgradeToSpecificVersion string) error {
|
||||
cache, cacheCleanup, err := data.NewCache(cacheConf)
|
||||
if err != nil {
|
||||
fmt.Println("new check failed:", err.Error())
|
||||
|
@ -108,16 +115,21 @@ func Migrate(dbConf *data.Database, cacheConf *data.CacheConf, upgradeFromVersio
|
|||
return err
|
||||
}
|
||||
expectedVersion := ExpectedVersion()
|
||||
if upgradeFromVersionNumber > 0 {
|
||||
fmt.Printf("[migrate] user set upgrade from version number %d\n", upgradeFromVersionNumber)
|
||||
currentDBVersion = int64(upgradeFromVersionNumber)
|
||||
if len(upgradeToSpecificVersion) > 0 {
|
||||
fmt.Printf("[migrate] user set upgrade to version: %s\n", upgradeToSpecificVersion)
|
||||
for i, m := range migrations {
|
||||
if m.Version() == upgradeToSpecificVersion {
|
||||
currentDBVersion = int64(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for currentDBVersion < expectedVersion {
|
||||
fmt.Printf("[migrate] current db version is %d, try to migrate version %d, latest version is %d\n",
|
||||
currentDBVersion, currentDBVersion+1, expectedVersion)
|
||||
migrationFunc := migrations[currentDBVersion]
|
||||
fmt.Printf("[migrate] try to migrate db version %d, description: %s\n", currentDBVersion+1, migrationFunc.Description())
|
||||
fmt.Printf("[migrate] try to migrate Answer version %s, description: %s\n", migrationFunc.Version(), migrationFunc.Description())
|
||||
if err := migrationFunc.Migrate(engine); err != nil {
|
||||
fmt.Printf("[migrate] migrate to db version %d failed: %s\n", currentDBVersion+1, err.Error())
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue