aboutsummaryrefslogtreecommitdiff
path: root/internal/db/migrations
diff options
context:
space:
mode:
authorJoe Chen <jc@unknwon.io>2022-06-12 14:15:01 +0800
committerGitHub <noreply@github.com>2022-06-12 14:15:01 +0800
commitb772603d78cb10f0501f3d08b01553bb33914b6e (patch)
tree5f160df17f1bbd357370b3aeeb5289b0a5c3c08d /internal/db/migrations
parent2e19f5a3c8193776685a5e9fea9ca8663f14dd8d (diff)
migrations: add tests and remove XORM (#7050)
Diffstat (limited to 'internal/db/migrations')
-rw-r--r--internal/db/migrations/main_test.go40
-rw-r--r--internal/db/migrations/migrations.go63
-rw-r--r--internal/db/migrations/v20_test.go70
3 files changed, 143 insertions, 30 deletions
diff --git a/internal/db/migrations/main_test.go b/internal/db/migrations/main_test.go
new file mode 100644
index 00000000..ee13c3e3
--- /dev/null
+++ b/internal/db/migrations/main_test.go
@@ -0,0 +1,40 @@
+// Copyright 2022 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "testing"
+
+ "gorm.io/gorm/logger"
+ _ "modernc.org/sqlite"
+ log "unknwon.dev/clog/v2"
+
+ "gogs.io/gogs/internal/testutil"
+)
+
+func TestMain(m *testing.M) {
+ flag.Parse()
+
+ level := logger.Silent
+ if !testing.Verbose() {
+ // Remove the primary logger and register a noop logger.
+ log.Remove(log.DefaultConsoleName)
+ err := log.New("noop", testutil.InitNoopLogger)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ } else {
+ level = logger.Info
+ }
+
+ // NOTE: AutoMigrate does not respect logger passed in gorm.Config.
+ logger.Default = logger.Default.LogMode(level)
+
+ os.Exit(m.Run())
+}
diff --git a/internal/db/migrations/migrations.go b/internal/db/migrations/migrations.go
index 1e89883f..4f93b9c5 100644
--- a/internal/db/migrations/migrations.go
+++ b/internal/db/migrations/migrations.go
@@ -5,11 +5,9 @@
package migrations
import (
- "fmt"
-
+ "github.com/pkg/errors"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
- "xorm.io/xorm"
)
const minDBVersion = 19
@@ -58,29 +56,32 @@ var migrations = []Migration{
NewMigration("migrate access tokens to store SHA56", migrateAccessTokenToSHA256),
}
-// Migrate database to current version
-func Migrate(x *xorm.Engine, db *gorm.DB) error {
- if err := x.Sync(new(Version)); err != nil {
- return fmt.Errorf("sync: %v", err)
+// Migrate migrates the database schema and/or data to the current version.
+func Migrate(db *gorm.DB) error {
+ err := db.AutoMigrate(new(Version))
+ if err != nil {
+ return errors.Wrap(err, `auto migrate "version" table`)
}
- currentVersion := &Version{ID: 1}
- has, err := x.Get(currentVersion)
- if err != nil {
- return fmt.Errorf("get: %v", err)
- } else if !has {
- // If the version record does not exist we think
- // it is a fresh installation and we can skip all migrations.
- currentVersion.ID = 0
- currentVersion.Version = int64(minDBVersion + len(migrations))
-
- if _, err = x.InsertOne(currentVersion); err != nil {
- return fmt.Errorf("insert: %v", err)
+ var current Version
+ err = db.Where("id = ?", 1).First(&current).Error
+ if err == gorm.ErrRecordNotFound {
+ err = db.Create(
+ &Version{
+ ID: 1,
+ Version: int64(minDBVersion + len(migrations)),
+ },
+ ).Error
+ if err != nil {
+ return errors.Wrap(err, "create the version record")
}
+ return nil
+
+ } else if err != nil {
+ return errors.Wrap(err, "get the version record")
}
- v := currentVersion.Version
- if minDBVersion > v {
+ if minDBVersion > current.Version {
log.Fatal(`
Hi there, thank you for using Gogs for so long!
However, Gogs has stopped supporting auto-migration from your previously installed version.
@@ -108,20 +109,22 @@ In case you're stilling getting this notice, go through instructions again until
return nil
}
- if int(v-minDBVersion) > len(migrations) {
+ if int(current.Version-minDBVersion) > len(migrations) {
// User downgraded Gogs.
- currentVersion.Version = int64(len(migrations) + minDBVersion)
- _, err = x.Id(1).Update(currentVersion)
- return err
+ current.Version = int64(len(migrations) + minDBVersion)
+ return db.Where("id = ?", current.ID).Updates(current).Error
}
- for i, m := range migrations[v-minDBVersion:] {
+
+ for i, m := range migrations[current.Version-minDBVersion:] {
log.Info("Migration: %s", m.Description())
if err = m.Migrate(db); err != nil {
- return fmt.Errorf("do migrate: %v", err)
+ return errors.Wrap(err, "do migrate")
}
- currentVersion.Version = v + int64(i) + 1
- if _, err = x.Id(1).Update(currentVersion); err != nil {
- return err
+
+ current.Version += int64(i) + 1
+ err = db.Where("id = ?", current.ID).Updates(current).Error
+ if err != nil {
+ return errors.Wrap(err, "update the version record")
}
}
return nil
diff --git a/internal/db/migrations/v20_test.go b/internal/db/migrations/v20_test.go
new file mode 100644
index 00000000..b95360de
--- /dev/null
+++ b/internal/db/migrations/v20_test.go
@@ -0,0 +1,70 @@
+// Copyright 2022 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "gogs.io/gogs/internal/dbtest"
+)
+
+type accessTokenPreV20 struct {
+ ID int64
+ UserID int64 `gorm:"COLUMN:uid;INDEX"`
+ Name string
+ Sha1 string `gorm:"TYPE:VARCHAR(40);UNIQUE"`
+ CreatedUnix int64
+ UpdatedUnix int64
+}
+
+func (*accessTokenPreV20) TableName() string {
+ return "access_token"
+}
+
+type accessTokenV20 struct {
+ ID int64
+ UserID int64 `gorm:"column:uid;index"`
+ Name string
+ Sha1 string `gorm:"type:VARCHAR(40);unique"`
+ SHA256 string `gorm:"type:VARCHAR(64);unique;not null"`
+ CreatedUnix int64
+ UpdatedUnix int64
+}
+
+func (*accessTokenV20) TableName() string {
+ return "access_token"
+}
+
+func TestMigrateAccessTokenToSHA256(t *testing.T) {
+ if testing.Short() {
+ t.Skip()
+ }
+ t.Parallel()
+
+ db := dbtest.NewDB(t, "migrateAccessTokenToSHA256", new(accessTokenPreV20))
+ err := db.Create(
+ &accessTokenPreV20{
+ ID: 1,
+ UserID: 1,
+ Name: "test",
+ Sha1: "73da7bb9d2a475bbc2ab79da7d4e94940cb9f9d5",
+ CreatedUnix: db.NowFunc().Unix(),
+ UpdatedUnix: db.NowFunc().Unix(),
+ },
+ ).Error
+ require.NoError(t, err)
+
+ err = migrateAccessTokenToSHA256(db)
+ require.NoError(t, err)
+
+ var got accessTokenV20
+ err = db.Where("id = ?", 1).First(&got).Error
+ require.NoError(t, err)
+ assert.Equal(t, "73da7bb9d2a475bbc2ab79da7d4e94940cb9f9d5", got.Sha1)
+ assert.Equal(t, "ab144c7bd170691bb9bb995f1541c608e33a78b40174f30fc8a1616c0bc3a477", got.SHA256)
+}