Skip to content

Commit 496c166

Browse files
chore: Migrate github.com/jinzhu/gorm to gorm.io/gorm (#863)
* chore: Migrate github.com/jinzhu/gorm to gorm.io/gorm Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * chore: drop singleton connection limit on sqlite3 backend Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * enhance: database logging Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * Revert "chore: drop singleton connection limit on sqlite3 backend" This reverts commit b494a3b. Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * typo Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * rename unique_index -> uniqueIndex Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * drop uniqueIndex on primary key Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * migrate fully to new gorm tag format Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * specify unique index name Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * remove pluginConf duplicate index Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * disable auto migrate FK Signed-off-by: eternal-flame-AD <yume@yumechi.jp> --------- Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
1 parent 6de7720 commit 496c166

25 files changed

Lines changed: 151 additions & 150 deletions

api/application_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,16 +611,16 @@ func upload(values map[string]*os.File) (contentType string, buffer bytes.Buffer
611611
for key, r := range values {
612612
var fw io.Writer
613613
if fw, err = w.CreateFormFile(key, r.Name()); err != nil {
614-
return
614+
return contentType, buffer, err
615615
}
616616

617617
if _, err = io.Copy(fw, r); err != nil {
618-
return
618+
return contentType, buffer, err
619619
}
620620
}
621621
contentType = w.FormDataContentType()
622622
w.Close()
623-
return
623+
return contentType, buffer, err
624624
}
625625

626626
func mustOpen(f string) *os.File {

api/user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type UserDatabase interface {
1919
DeleteUserByID(id uint) error
2020
UpdateUser(user *model.User) error
2121
CreateUser(user *model.User) error
22-
CountUser(condition ...interface{}) (int, error)
22+
CountUser(condition ...interface{}) (int64, error)
2323
}
2424

2525
// UserChangeNotifier notifies listeners for user changes.

auth/authentication_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (s *AuthenticationSuite) assertQueryRequest(key, value string, f fMiddlewar
8484
ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/?%s=%s", key, value), nil)
8585
f()(ctx)
8686
assert.Equal(s.T(), code, recorder.Code)
87-
return
87+
return ctx
8888
}
8989

9090
func (s *AuthenticationSuite) TestNothingProvided() {
@@ -217,7 +217,7 @@ func (s *AuthenticationSuite) assertHeaderRequest(key, value string, f fMiddlewa
217217
ctx.Request.Header.Set(key, value)
218218
f()(ctx)
219219
assert.Equal(s.T(), code, recorder.Code)
220-
return
220+
return ctx
221221
}
222222

223223
type fMiddleware func() gin.HandlerFunc

database/application.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"time"
55

66
"github.com/gotify/server/v2/model"
7-
"github.com/jinzhu/gorm"
7+
"gorm.io/gorm"
88
)
99

1010
// GetApplicationByToken returns the application for the given token or nil.

database/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"time"
55

66
"github.com/gotify/server/v2/model"
7-
"github.com/jinzhu/gorm"
7+
"gorm.io/gorm"
88
)
99

1010
// GetClientByID returns the client for the given id or nil.

database/database.go

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package database
22

33
import (
4+
"errors"
5+
"log"
46
"os"
57
"path/filepath"
68
"time"
79

810
"github.com/gotify/server/v2/auth/password"
11+
"github.com/gotify/server/v2/mode"
912
"github.com/gotify/server/v2/model"
10-
"github.com/jinzhu/gorm"
11-
_ "github.com/jinzhu/gorm/dialects/mysql" // enable the mysql dialect.
12-
_ "github.com/jinzhu/gorm/dialects/postgres" // enable the postgres dialect.
13-
_ "github.com/jinzhu/gorm/dialects/sqlite" // enable the sqlite3 dialect.
13+
"github.com/mattn/go-isatty"
14+
"gorm.io/driver/mysql"
15+
"gorm.io/driver/postgres"
16+
"gorm.io/driver/sqlite"
17+
"gorm.io/gorm"
18+
"gorm.io/gorm/logger"
1419
)
1520

1621
var mkdirAll = os.MkdirAll
@@ -19,40 +24,68 @@ var mkdirAll = os.MkdirAll
1924
func New(dialect, connection, defaultUser, defaultPass string, strength int, createDefaultUserIfNotExist bool) (*GormDatabase, error) {
2025
createDirectoryIfSqlite(dialect, connection)
2126

22-
db, err := gorm.Open(dialect, connection)
27+
logLevel := logger.Info
28+
if mode.Get() == mode.Prod {
29+
logLevel = logger.Warn
30+
}
31+
32+
dbLogger := logger.New(log.New(os.Stderr, "\r\n", log.LstdFlags), logger.Config{
33+
SlowThreshold: 200 * time.Millisecond,
34+
LogLevel: logLevel,
35+
IgnoreRecordNotFoundError: true,
36+
Colorful: isatty.IsTerminal(os.Stderr.Fd()),
37+
})
38+
gormConfig := &gorm.Config{
39+
Logger: dbLogger,
40+
DisableForeignKeyConstraintWhenMigrating: true,
41+
}
42+
43+
var db *gorm.DB
44+
err := errors.New("unsupported dialect: " + dialect)
45+
46+
switch dialect {
47+
case "mysql":
48+
db, err = gorm.Open(mysql.Open(connection), gormConfig)
49+
case "postgres":
50+
db, err = gorm.Open(postgres.Open(connection), gormConfig)
51+
case "sqlite3":
52+
db, err = gorm.Open(sqlite.Open(connection), gormConfig)
53+
}
54+
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
sqldb, err := db.DB()
2360
if err != nil {
2461
return nil, err
2562
}
2663

2764
// We normally don't need that much connections, so we limit them. F.ex. mysql complains about
2865
// "too many connections", while load testing Gotify.
29-
db.DB().SetMaxOpenConns(10)
66+
sqldb.SetMaxOpenConns(10)
3067

3168
if dialect == "sqlite3" {
3269
// We use the database connection inside the handlers from the http
3370
// framework, therefore concurrent access occurs. Sqlite cannot handle
3471
// concurrent writes, so we limit sqlite to one connection.
3572
// see https://github.com/mattn/go-sqlite3/issues/274
36-
db.DB().SetMaxOpenConns(1)
73+
sqldb.SetMaxOpenConns(1)
3774
}
3875

3976
if dialect == "mysql" {
4077
// Mysql has a setting called wait_timeout, which defines the duration
4178
// after which a connection may not be used anymore.
4279
// The default for this setting on mariadb is 10 minutes.
4380
// See https://github.com/docker-library/mariadb/issues/113
44-
db.DB().SetConnMaxLifetime(9 * time.Minute)
81+
sqldb.SetConnMaxLifetime(9 * time.Minute)
4582
}
4683

47-
if err := db.AutoMigrate(new(model.User), new(model.Application), new(model.Message), new(model.Client), new(model.PluginConf)).Error; err != nil {
84+
if err := db.AutoMigrate(new(model.User), new(model.Application), new(model.Message), new(model.Client), new(model.PluginConf)); err != nil {
4885
return nil, err
4986
}
5087

51-
if err := prepareBlobColumn(dialect, db); err != nil {
52-
return nil, err
53-
}
54-
55-
userCount := 0
88+
userCount := int64(0)
5689
db.Find(new(model.User)).Count(&userCount)
5790
if createDefaultUserIfNotExist && userCount == 0 {
5891
db.Create(&model.User{Name: defaultUser, Pass: password.CreatePassword(defaultPass, strength), Admin: true})
@@ -61,31 +94,6 @@ func New(dialect, connection, defaultUser, defaultPass string, strength int, cre
6194
return &GormDatabase{DB: db}, nil
6295
}
6396

64-
func prepareBlobColumn(dialect string, db *gorm.DB) error {
65-
blobType := ""
66-
switch dialect {
67-
case "mysql":
68-
blobType = "longblob"
69-
case "postgres":
70-
blobType = "bytea"
71-
}
72-
if blobType != "" {
73-
for _, target := range []struct {
74-
Table interface{}
75-
Column string
76-
}{
77-
{model.Message{}, "extras"},
78-
{model.PluginConf{}, "config"},
79-
{model.PluginConf{}, "storage"},
80-
} {
81-
if err := db.Model(target.Table).ModifyColumn(target.Column, blobType).Error; err != nil {
82-
return err
83-
}
84-
}
85-
}
86-
return nil
87-
}
88-
8997
func createDirectoryIfSqlite(dialect, connection string) {
9098
if dialect == "sqlite3" {
9199
if _, err := os.Stat(filepath.Dir(connection)); os.IsNotExist(err) {
@@ -103,5 +111,9 @@ type GormDatabase struct {
103111

104112
// Close closes the gorm database connection.
105113
func (d *GormDatabase) Close() {
106-
d.DB.Close()
114+
sqldb, err := d.DB.DB()
115+
if err != nil {
116+
return
117+
}
118+
sqldb.Close()
107119
}

database/message.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package database
22

33
import (
44
"github.com/gotify/server/v2/model"
5-
"github.com/jinzhu/gorm"
5+
"gorm.io/gorm"
66
)
77

88
// GetMessageByID returns the messages for the given id or nil.
@@ -27,7 +27,7 @@ func (d *GormDatabase) CreateMessage(message *model.Message) error {
2727
func (d *GormDatabase) GetMessagesByUser(userID uint) ([]*model.Message, error) {
2828
var messages []*model.Message
2929
err := d.DB.Joins("JOIN applications ON applications.user_id = ?", userID).
30-
Where("messages.application_id = applications.id").Order("id desc").Find(&messages).Error
30+
Where("messages.application_id = applications.id").Order("messages.id desc").Find(&messages).Error
3131
if err == gorm.ErrRecordNotFound {
3232
err = nil
3333
}
@@ -39,7 +39,7 @@ func (d *GormDatabase) GetMessagesByUser(userID uint) ([]*model.Message, error)
3939
func (d *GormDatabase) GetMessagesByUserSince(userID uint, limit int, since uint) ([]*model.Message, error) {
4040
var messages []*model.Message
4141
db := d.DB.Joins("JOIN applications ON applications.user_id = ?", userID).
42-
Where("messages.application_id = applications.id").Order("id desc").Limit(limit)
42+
Where("messages.application_id = applications.id").Order("messages.id desc").Limit(limit)
4343
if since != 0 {
4444
db = db.Where("messages.id < ?", since)
4545
}
@@ -53,7 +53,7 @@ func (d *GormDatabase) GetMessagesByUserSince(userID uint, limit int, since uint
5353
// GetMessagesByApplication returns all messages from an application.
5454
func (d *GormDatabase) GetMessagesByApplication(tokenID uint) ([]*model.Message, error) {
5555
var messages []*model.Message
56-
err := d.DB.Where("application_id = ?", tokenID).Order("id desc").Find(&messages).Error
56+
err := d.DB.Where("application_id = ?", tokenID).Order("messages.id desc").Find(&messages).Error
5757
if err == gorm.ErrRecordNotFound {
5858
err = nil
5959
}
@@ -64,7 +64,7 @@ func (d *GormDatabase) GetMessagesByApplication(tokenID uint) ([]*model.Message,
6464
// If since is 0 it will be ignored.
6565
func (d *GormDatabase) GetMessagesByApplicationSince(appID uint, limit int, since uint) ([]*model.Message, error) {
6666
var messages []*model.Message
67-
db := d.DB.Where("application_id = ?", appID).Order("id desc").Limit(limit)
67+
db := d.DB.Where("application_id = ?", appID).Order("messages.id desc").Limit(limit)
6868
if since != 0 {
6969
db = db.Where("messages.id < ?", since)
7070
}

database/migration_test.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import (
55

66
"github.com/gotify/server/v2/model"
77
"github.com/gotify/server/v2/test"
8-
"github.com/jinzhu/gorm"
98
"github.com/stretchr/testify/assert"
109
"github.com/stretchr/testify/suite"
10+
"gorm.io/driver/sqlite"
11+
"gorm.io/gorm"
1112
)
1213

1314
func TestMigration(t *testing.T) {
@@ -21,18 +22,20 @@ type MigrationSuite struct {
2122

2223
func (s *MigrationSuite) BeforeTest(suiteName, testName string) {
2324
s.tmpDir = test.NewTmpDir("gotify_migrationsuite")
24-
db, err := gorm.Open("sqlite3", s.tmpDir.Path("test_obsolete.db"))
25-
assert.Nil(s.T(), err)
26-
defer db.Close()
25+
db, err := gorm.Open(sqlite.Open(s.tmpDir.Path("test_obsolete.db")), &gorm.Config{})
26+
assert.NoError(s.T(), err)
27+
sqlDB, err := db.DB()
28+
assert.NoError(s.T(), err)
29+
defer sqlDB.Close()
2730

28-
assert.Nil(s.T(), db.CreateTable(new(model.User)).Error)
31+
assert.Nil(s.T(), db.Migrator().CreateTable(new(model.User)))
2932
assert.Nil(s.T(), db.Create(&model.User{
3033
Name: "test_user",
3134
Admin: true,
3235
}).Error)
3336

3437
// we should not be able to create applications by now
35-
assert.False(s.T(), db.HasTable(new(model.Application)))
38+
assert.False(s.T(), db.Migrator().HasTable(new(model.Application)))
3639
}
3740

3841
func (s *MigrationSuite) AfterTest(suiteName, testName string) {
@@ -44,7 +47,7 @@ func (s *MigrationSuite) TestMigration() {
4447
assert.Nil(s.T(), err)
4548
defer db.Close()
4649

47-
assert.True(s.T(), db.DB.HasTable(new(model.Application)))
50+
assert.True(s.T(), db.DB.Migrator().HasTable(new(model.Application)))
4851

4952
// a user already exist, not adding a new user
5053
if user, err := db.GetUserByName("admin"); assert.NoError(s.T(), err) {

database/ping.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,9 @@ package database
22

33
// Ping pings the database to verify the connection.
44
func (d *GormDatabase) Ping() error {
5-
return d.DB.DB().Ping()
5+
sqldb, err := d.DB.DB()
6+
if err != nil {
7+
return err
8+
}
9+
return sqldb.Ping()
610
}

database/plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package database
22

33
import (
44
"github.com/gotify/server/v2/model"
5-
"github.com/jinzhu/gorm"
5+
"gorm.io/gorm"
66
)
77

88
// GetPluginConfByUser gets plugin configurations from a user.

0 commit comments

Comments
 (0)