diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index c9747c11..357aa786 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -15,14 +15,14 @@ const minDBVersion = 0 type Migration interface { Version() string Description() string - Migrate(*xorm.Engine) error + Migrate(ctx context.Context, x *xorm.Engine) error ShouldCleanCache() bool } type migration struct { version string description string - migrate func(*xorm.Engine) error + migrate func(ctx context.Context, x *xorm.Engine) error shouldCleanCache bool } @@ -37,8 +37,8 @@ func (m *migration) Description() string { } // Migrate executes the migration -func (m *migration) Migrate(x *xorm.Engine) error { - return m.migrate(x) +func (m *migration) Migrate(ctx context.Context, x *xorm.Engine) error { + return m.migrate(ctx, x) } // ShouldCleanCache should clean the cache @@ -47,12 +47,12 @@ func (m *migration) ShouldCleanCache() bool { } // NewMigration creates a new migration -func NewMigration(version, desc string, fn func(*xorm.Engine) error, shouldCleanCache bool) Migration { +func NewMigration(version, desc string, fn func(ctx context.Context, x *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 -var noopMigration = func(_ *xorm.Engine) error { return nil } +var noopMigration = func(_ context.Context, _ *xorm.Engine) error { return nil } var migrations = []Migration{ // 0->1 @@ -72,6 +72,10 @@ var migrations = []Migration{ NewMigration("v1.1.0", "add gravatar base url", updateCount, true), } +func GetMigrations() []Migration { + return migrations +} + // GetCurrentDBVersion returns the current db version func GetCurrentDBVersion(engine *xorm.Engine) (int64, error) { if err := engine.Sync(new(entity.Version)); err != nil { @@ -130,7 +134,7 @@ func Migrate(dbConf *data.Database, cacheConf *data.CacheConf, upgradeToSpecific currentDBVersion, currentDBVersion+1, expectedVersion) migrationFunc := migrations[currentDBVersion] fmt.Printf("[migrate] try to migrate Answer version %s, description: %s\n", migrationFunc.Version(), migrationFunc.Description()) - if err := migrationFunc.Migrate(engine); err != nil { + if err := migrationFunc.Migrate(context.Background(), engine); err != nil { fmt.Printf("[migrate] migrate to db version %d failed: %s\n", currentDBVersion+1, err.Error()) return err } diff --git a/internal/migrations/v1.go b/internal/migrations/v1.go index e929d45c..de6ba987 100644 --- a/internal/migrations/v1.go +++ b/internal/migrations/v1.go @@ -1,14 +1,15 @@ package migrations import ( + "context" "xorm.io/xorm" ) -func addUserLanguage(x *xorm.Engine) error { +func addUserLanguage(ctx context.Context, x *xorm.Engine) error { type User struct { ID string `xorm:"not null pk autoincr BIGINT(20) id"` Username string `xorm:"not null default '' VARCHAR(50) UNIQUE username"` Language string `xorm:"not null default '' VARCHAR(100) language"` } - return x.Sync(new(User)) + return x.Context(ctx).Sync(new(User)) } diff --git a/internal/migrations/v10.go b/internal/migrations/v10.go index 2d669b19..6d8eb240 100644 --- a/internal/migrations/v10.go +++ b/internal/migrations/v10.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "encoding/json" "fmt" @@ -11,11 +12,11 @@ import ( "xorm.io/xorm" ) -func addLoginLimitations(x *xorm.Engine) error { +func addLoginLimitations(ctx context.Context, x *xorm.Engine) error { loginSiteInfo := &entity.SiteInfo{ Type: constant.SiteTypeLogin, } - exist, err := x.Get(loginSiteInfo) + exist, err := x.Context(ctx).Get(loginSiteInfo) if err != nil { return fmt.Errorf("get config failed: %w", err) } @@ -26,7 +27,7 @@ func addLoginLimitations(x *xorm.Engine) error { content.AllowEmailDomains = make([]string, 0) data, _ := json.Marshal(content) loginSiteInfo.Content = string(data) - _, err = x.ID(loginSiteInfo.ID).Cols("content").Update(loginSiteInfo) + _, err = x.Context(ctx).ID(loginSiteInfo.ID).Cols("content").Update(loginSiteInfo) if err != nil { return fmt.Errorf("update site info failed: %w", err) } @@ -35,7 +36,7 @@ func addLoginLimitations(x *xorm.Engine) error { interfaceSiteInfo := &entity.SiteInfo{ Type: constant.SiteTypeInterface, } - exist, err = x.Get(interfaceSiteInfo) + exist, err = x.Context(ctx).Get(interfaceSiteInfo) if err != nil { return fmt.Errorf("get config failed: %w", err) } @@ -52,7 +53,7 @@ func addLoginLimitations(x *xorm.Engine) error { } data, _ := json.Marshal(siteUsers) - exist, err = x.Get(&entity.SiteInfo{Type: constant.SiteTypeUsers}) + exist, err = x.Context(ctx).Get(&entity.SiteInfo{Type: constant.SiteTypeUsers}) if err != nil { return fmt.Errorf("get config failed: %w", err) } @@ -62,7 +63,7 @@ func addLoginLimitations(x *xorm.Engine) error { Content: string(data), Status: 1, } - _, err = x.InsertOne(usersSiteInfo) + _, err = x.Context(ctx).Insert(usersSiteInfo) if err != nil { return fmt.Errorf("insert site info failed: %w", err) } diff --git a/internal/migrations/v11.go b/internal/migrations/v11.go index 5d9b8725..409320be 100644 --- a/internal/migrations/v11.go +++ b/internal/migrations/v11.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "github.com/answerdev/answer/internal/entity" @@ -8,8 +9,7 @@ import ( "xorm.io/xorm" ) -func updateRolePinAndHideFeatures(x *xorm.Engine) error { - +func updateRolePinAndHideFeatures(ctx context.Context, x *xorm.Engine) error { defaultConfigTable := []*entity.Config{ {ID: 119, Key: "question.pin", Value: `0`}, {ID: 120, Key: "question.unpin", Value: `0`}, @@ -21,18 +21,18 @@ func updateRolePinAndHideFeatures(x *xorm.Engine) error { {ID: 126, Key: "rank.question.hide", Value: `-1`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { - if _, err = x.Update(c, &entity.Config{ID: c.ID}); err != nil { + if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil { log.Errorf("update %+v config failed: %s", c, err) return fmt.Errorf("update config failed: %w", err) } continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { log.Errorf("insert %+v config failed: %s", c, err) return fmt.Errorf("add config failed: %w", err) } diff --git a/internal/migrations/v12.go b/internal/migrations/v12.go index 850146ed..6f547a15 100644 --- a/internal/migrations/v12.go +++ b/internal/migrations/v12.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "time" @@ -37,9 +38,9 @@ func (QuestionPostTime) TableName() string { return "question" } -func updateQuestionPostTime(x *xorm.Engine) error { +func updateQuestionPostTime(ctx context.Context, x *xorm.Engine) error { questionList := make([]QuestionPostTime, 0) - err := x.Find(&questionList, &entity.Question{}) + err := x.Context(ctx).Find(&questionList, &entity.Question{}) if err != nil { return fmt.Errorf("get questions failed: %w", err) } @@ -50,7 +51,7 @@ func updateQuestionPostTime(x *xorm.Engine) error { } else if !item.CreatedAt.IsZero() { item.PostUpdateTime = item.CreatedAt } - if _, err = x.Update(item, &QuestionPostTime{ID: item.ID}); err != nil { + if _, err = x.Context(ctx).Update(item, &QuestionPostTime{ID: item.ID}); err != nil { log.Errorf("update %+v config failed: %s", item, err) return fmt.Errorf("update question failed: %w", err) } diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go index d467a4a4..abf7982f 100644 --- a/internal/migrations/v13.go +++ b/internal/migrations/v13.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "encoding/json" "fmt" "time" @@ -13,8 +14,8 @@ import ( "xorm.io/xorm" ) -func updateCount(x *xorm.Engine) error { - fns := []func(*xorm.Engine) error{ +func updateCount(ctx context.Context, x *xorm.Engine) error { + fns := []func(ctx context.Context, x *xorm.Engine) error{ inviteAnswer, addPrivilegeForInviteSomeoneToAnswer, addGravatarBaseURL, @@ -25,18 +26,18 @@ func updateCount(x *xorm.Engine) error { inBoxData, } for _, fn := range fns { - if err := fn(x); err != nil { + if err := fn(ctx, x); err != nil { return err } } return nil } -func addGravatarBaseURL(x *xorm.Engine) error { +func addGravatarBaseURL(ctx context.Context, x *xorm.Engine) error { usersSiteInfo := &entity.SiteInfo{ Type: constant.SiteTypeUsers, } - exist, err := x.Get(usersSiteInfo) + exist, err := x.Context(ctx).Get(usersSiteInfo) if err != nil { return fmt.Errorf("get config failed: %w", err) } @@ -47,7 +48,7 @@ func addGravatarBaseURL(x *xorm.Engine) error { data, _ := json.Marshal(content) usersSiteInfo.Content = string(data) - _, err = x.ID(usersSiteInfo.ID).Cols("content").Update(usersSiteInfo) + _, err = x.Context(ctx).ID(usersSiteInfo.ID).Cols("content").Update(usersSiteInfo) if err != nil { return fmt.Errorf("update site info failed: %w", err) } @@ -55,20 +56,20 @@ func addGravatarBaseURL(x *xorm.Engine) error { return nil } -func addPrivilegeForInviteSomeoneToAnswer(x *xorm.Engine) error { +func addPrivilegeForInviteSomeoneToAnswer(ctx context.Context, x *xorm.Engine) error { // add rank for invite to answer powers := []*entity.Power{ {ID: 38, Name: "invite someone to answer", PowerType: permission.AnswerInviteSomeoneToAnswer, Description: "invite someone to answer"}, } for _, power := range powers { - exist, err := x.Get(&entity.Power{PowerType: power.PowerType}) + exist, err := x.Context(ctx).Get(&entity.Power{PowerType: power.PowerType}) if err != nil { return err } if exist { - _, err = x.ID(power.ID).Update(power) + _, err = x.Context(ctx).ID(power.ID).Update(power) } else { - _, err = x.Insert(power) + _, err = x.Context(ctx).Insert(power) } if err != nil { return err @@ -79,14 +80,14 @@ func addPrivilegeForInviteSomeoneToAnswer(x *xorm.Engine) error { {RoleID: 3, PowerType: permission.AnswerInviteSomeoneToAnswer}, } for _, rel := range rolePowerRels { - exist, err := x.Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) + exist, err := x.Context(ctx).Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) if err != nil { return err } if exist { continue } - _, err = x.Insert(rel) + _, err = x.Context(ctx).Insert(rel) if err != nil { return err } @@ -96,27 +97,27 @@ func addPrivilegeForInviteSomeoneToAnswer(x *xorm.Engine) error { {ID: 127, Key: "rank.answer.invite_someone_to_answer", Value: `1000`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { - if _, err = x.Update(c, &entity.Config{ID: c.ID}); err != nil { + if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil { return fmt.Errorf("update config failed: %w", err) } continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { return fmt.Errorf("add config failed: %w", err) } } return nil } -func updateQuestionCount(x *xorm.Engine) error { +func updateQuestionCount(ctx context.Context, x *xorm.Engine) error { //question answer count answers := make([]AnswerV13, 0) - err := x.Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable}) + err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable}) if err != nil { return fmt.Errorf("get answers failed: %w", err) } @@ -130,7 +131,7 @@ func updateQuestionCount(x *xorm.Engine) error { } } questionList := make([]QuestionV13, 0) - err = x.Find(&questionList, &QuestionV13{}) + err = x.Context(ctx).Find(&questionList, &QuestionV13{}) if err != nil { return fmt.Errorf("get questions failed: %w", err) } @@ -138,7 +139,7 @@ func updateQuestionCount(x *xorm.Engine) error { _, ok := questionAnswerCount[item.ID] if ok { item.AnswerCount = questionAnswerCount[item.ID] - if _, err = x.Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err != nil { + if _, err = x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err != nil { log.Errorf("update %+v config failed: %s", item, err) return fmt.Errorf("update question failed: %w", err) } @@ -149,9 +150,9 @@ func updateQuestionCount(x *xorm.Engine) error { } // updateTagCount update tag count -func updateTagCount(x *xorm.Engine) error { +func updateTagCount(ctx context.Context, x *xorm.Engine) error { tagRelList := make([]entity.TagRel, 0) - err := x.Find(&tagRelList, &entity.TagRel{}) + err := x.Context(ctx).Find(&tagRelList, &entity.TagRel{}) if err != nil { return fmt.Errorf("get tag rel failed: %w", err) } @@ -164,7 +165,7 @@ func updateTagCount(x *xorm.Engine) error { questionsHideMap[item.ObjectID] = false } questionList := make([]QuestionV13, 0) - err = x.In("id", questionIDs).In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed}).Find(&questionList, &QuestionV13{}) + err = x.Context(ctx).In("id", questionIDs).In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed}).Find(&questionList, &QuestionV13{}) if err != nil { return fmt.Errorf("get questions failed: %w", err) } @@ -180,7 +181,7 @@ func updateTagCount(x *xorm.Engine) error { for id, ok := range questionsHideMap { if ok { - if _, err = x.Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusHide}, &entity.TagRel{ObjectID: id}); err != nil { + if _, err = x.Context(ctx).Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusHide}, &entity.TagRel{ObjectID: id}); err != nil { log.Errorf("update %+v config failed: %s", id, err) } } @@ -188,7 +189,7 @@ func updateTagCount(x *xorm.Engine) error { for id, ok := range questionsAvailableMap { if !ok { - if _, err = x.Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusDeleted}, &entity.TagRel{ObjectID: id}); err != nil { + if _, err = x.Context(ctx).Cols("status").Update(&entity.TagRel{Status: entity.TagRelStatusDeleted}, &entity.TagRel{ObjectID: id}); err != nil { log.Errorf("update %+v config failed: %s", id, err) } } @@ -196,7 +197,7 @@ func updateTagCount(x *xorm.Engine) error { //select tag count newTagRelList := make([]entity.TagRel, 0) - err = x.Find(&newTagRelList, &entity.TagRel{Status: entity.TagRelStatusAvailable}) + err = x.Context(ctx).Find(&newTagRelList, &entity.TagRel{Status: entity.TagRelStatusAvailable}) if err != nil { return fmt.Errorf("get tag rel failed: %w", err) } @@ -210,7 +211,7 @@ func updateTagCount(x *xorm.Engine) error { } } TagList := make([]entity.Tag, 0) - err = x.Find(&TagList, &entity.Tag{}) + err = x.Context(ctx).Find(&TagList, &entity.Tag{}) if err != nil { return fmt.Errorf("get tag failed: %w", err) } @@ -218,13 +219,13 @@ func updateTagCount(x *xorm.Engine) error { _, ok := tagCountMap[tag.ID] if ok { tag.QuestionCount = tagCountMap[tag.ID] - if _, err = x.Update(tag, &entity.Tag{ID: tag.ID}); err != nil { + if _, err = x.Context(ctx).Update(tag, &entity.Tag{ID: tag.ID}); err != nil { log.Errorf("update %+v tag failed: %s", tag.ID, err) return fmt.Errorf("update tag failed: %w", err) } } else { tag.QuestionCount = 0 - if _, err = x.Cols("question_count").Update(tag, &entity.Tag{ID: tag.ID}); err != nil { + if _, err = x.Context(ctx).Cols("question_count").Update(tag, &entity.Tag{ID: tag.ID}); err != nil { log.Errorf("update %+v tag failed: %s", tag.ID, err) return fmt.Errorf("update tag failed: %w", err) } @@ -234,9 +235,9 @@ func updateTagCount(x *xorm.Engine) error { } // updateUserQuestionCount update user question count -func updateUserQuestionCount(x *xorm.Engine) error { +func updateUserQuestionCount(ctx context.Context, x *xorm.Engine) error { questionList := make([]QuestionV13, 0) - err := x.In("status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed}).Find(&questionList, &QuestionV13{}) + err := x.Context(ctx).In("status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed}).Find(&questionList, &QuestionV13{}) if err != nil { return fmt.Errorf("get question failed: %w", err) } @@ -250,7 +251,7 @@ func updateUserQuestionCount(x *xorm.Engine) error { } } userList := make([]entity.User, 0) - err = x.Find(&userList, &entity.User{}) + err = x.Context(ctx).Find(&userList, &entity.User{}) if err != nil { return fmt.Errorf("get user failed: %w", err) } @@ -258,13 +259,13 @@ func updateUserQuestionCount(x *xorm.Engine) error { _, ok := userQuestionCountMap[user.ID] if ok { user.QuestionCount = userQuestionCountMap[user.ID] - if _, err = x.Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil { + if _, err = x.Context(ctx).Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil { log.Errorf("update %+v user failed: %s", user.ID, err) return fmt.Errorf("update user failed: %w", err) } } else { user.QuestionCount = 0 - if _, err = x.Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil { + if _, err = x.Context(ctx).Cols("question_count").Update(user, &entity.User{ID: user.ID}); err != nil { log.Errorf("update %+v user failed: %s", user.ID, err) return fmt.Errorf("update user failed: %w", err) } @@ -286,9 +287,9 @@ func (AnswerV13) TableName() string { } // updateUserAnswerCount update user answer count -func updateUserAnswerCount(x *xorm.Engine) error { +func updateUserAnswerCount(ctx context.Context, x *xorm.Engine) error { answers := make([]AnswerV13, 0) - err := x.Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable}) + err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable}) if err != nil { return fmt.Errorf("get answers failed: %w", err) } @@ -302,7 +303,7 @@ func updateUserAnswerCount(x *xorm.Engine) error { } } userList := make([]entity.User, 0) - err = x.Find(&userList, &entity.User{}) + err = x.Context(ctx).Find(&userList, &entity.User{}) if err != nil { return fmt.Errorf("get user failed: %w", err) } @@ -310,13 +311,13 @@ func updateUserAnswerCount(x *xorm.Engine) error { _, ok := userAnswerCount[user.ID] if ok { user.AnswerCount = userAnswerCount[user.ID] - if _, err = x.Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil { + if _, err = x.Context(ctx).Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil { log.Errorf("update %+v user failed: %s", user.ID, err) return fmt.Errorf("update user failed: %w", err) } } else { user.AnswerCount = 0 - if _, err = x.Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil { + if _, err = x.Context(ctx).Cols("answer_count").Update(user, &entity.User{ID: user.ID}); err != nil { log.Errorf("update %+v user failed: %s", user.ID, err) return fmt.Errorf("update user failed: %w", err) } @@ -354,8 +355,8 @@ func (QuestionV13) TableName() string { return "question" } -func inviteAnswer(x *xorm.Engine) error { - err := x.Sync(new(QuestionV13)) +func inviteAnswer(ctx context.Context, x *xorm.Engine) error { + err := x.Context(ctx).Sync(new(QuestionV13)) if err != nil { return err } @@ -363,7 +364,7 @@ func inviteAnswer(x *xorm.Engine) error { } // inBoxData Classify messages -func inBoxData(x *xorm.Engine) error { +func inBoxData(ctx context.Context, x *xorm.Engine) error { type Notification struct { ID string `xorm:"not null pk autoincr BIGINT(20) id"` CreatedAt time.Time `xorm:"created TIMESTAMP created_at"` @@ -376,12 +377,12 @@ func inBoxData(x *xorm.Engine) error { IsRead int `xorm:"not null default 1 INT(11) is_read"` Status int `xorm:"not null default 1 INT(11) status"` } - err := x.Sync(new(Notification)) + err := x.Context(ctx).Sync(new(Notification)) if err != nil { return err } msglist := make([]entity.Notification, 0) - err = x.Find(&msglist, &entity.Notification{}) + err = x.Context(ctx).Find(&msglist, &entity.Notification{}) if err != nil { return fmt.Errorf("get Notification failed: %w", err) } @@ -394,7 +395,7 @@ func inBoxData(x *xorm.Engine) error { _, ok := constant.NotificationMsgTypeMapping[Content.NotificationAction] if ok { v.MsgType = constant.NotificationMsgTypeMapping[Content.NotificationAction] - if _, err = x.Update(v, &entity.Notification{ID: v.ID}); err != nil { + if _, err = x.Context(ctx).Update(v, &entity.Notification{ID: v.ID}); err != nil { log.Errorf("update %+v Notification failed: %s", v.ID, err) } } diff --git a/internal/migrations/v2.go b/internal/migrations/v2.go index 368124ef..92b1b3c0 100644 --- a/internal/migrations/v2.go +++ b/internal/migrations/v2.go @@ -1,15 +1,16 @@ package migrations import ( + "context" "xorm.io/xorm" ) -func addTagRecommendedAndReserved(x *xorm.Engine) error { +func addTagRecommendedAndReserved(ctx context.Context, x *xorm.Engine) error { type Tag struct { ID string `xorm:"not null pk comment('tag_id') BIGINT(20) id"` SlugName string `xorm:"not null default '' unique VARCHAR(35) slug_name"` Recommend bool `xorm:"not null default false BOOL recommend"` Reserved bool `xorm:"not null default false BOOL reserved"` } - return x.Sync(new(Tag)) + return x.Context(ctx).Sync(new(Tag)) } diff --git a/internal/migrations/v3.go b/internal/migrations/v3.go index 5b32bb81..a0833645 100644 --- a/internal/migrations/v3.go +++ b/internal/migrations/v3.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "time" @@ -10,28 +11,28 @@ import ( "xorm.io/xorm/schemas" ) -func addActivityTimeline(x *xorm.Engine) (err error) { +func addActivityTimeline(ctx context.Context, x *xorm.Engine) (err error) { switch x.Dialect().URI().DBType { case schemas.MYSQL: - _, err = x.Exec("ALTER TABLE `answer` CHANGE `updated_at` `updated_at` TIMESTAMP NULL DEFAULT NULL") + _, err = x.Context(ctx).Exec("ALTER TABLE `answer` CHANGE `updated_at` `updated_at` TIMESTAMP NULL DEFAULT NULL") if err != nil { return err } - _, err = x.Exec("ALTER TABLE `question` CHANGE `updated_at` `updated_at` TIMESTAMP NULL DEFAULT NULL") + _, err = x.Context(ctx).Exec("ALTER TABLE `question` CHANGE `updated_at` `updated_at` TIMESTAMP NULL DEFAULT NULL") if err != nil { return err } case schemas.POSTGRES: - _, err = x.Exec(`ALTER TABLE "answer" ALTER COLUMN "updated_at" DROP NOT NULL, ALTER COLUMN "updated_at" SET DEFAULT NULL`) + _, err = x.Context(ctx).Exec(`ALTER TABLE "answer" ALTER COLUMN "updated_at" DROP NOT NULL, ALTER COLUMN "updated_at" SET DEFAULT NULL`) if err != nil { return err } - _, err = x.Exec(`ALTER TABLE "question" ALTER COLUMN "updated_at" DROP NOT NULL, ALTER COLUMN "updated_at" SET DEFAULT NULL`) + _, err = x.Context(ctx).Exec(`ALTER TABLE "question" ALTER COLUMN "updated_at" DROP NOT NULL, ALTER COLUMN "updated_at" SET DEFAULT NULL`) if err != nil { return err } case schemas.SQLITE: - _, err = x.Exec(`DROP INDEX "IDX_answer_user_id"; + _, err = x.Context(ctx).Exec(`DROP INDEX "IDX_answer_user_id"; ALTER TABLE "answer" RENAME TO "_answer_old_v3"; @@ -98,7 +99,7 @@ ON "question" ( ID int `xorm:"not null pk autoincr INT(11) id"` Key string `xorm:"unique VARCHAR(128) key"` } - if err := x.Sync(new(Config)); err != nil { + if err := x.Context(ctx).Sync(new(Config)); err != nil { return fmt.Errorf("sync config table failed: %w", err) } defaultConfigTable := []*entity.Config{ @@ -155,18 +156,18 @@ ON "question" ( {ID: 114, Key: "rank.tag.audit", Value: `20000`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID, Key: c.Key}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID, Key: c.Key}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { - if _, err = x.Update(c, &entity.Config{ID: c.ID, Key: c.Key}); err != nil { + if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID, Key: c.Key}); err != nil { log.Errorf("update %+v config failed: %s", c, err) return fmt.Errorf("update config failed: %w", err) } continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { log.Errorf("insert %+v config failed: %s", c, err) return fmt.Errorf("add config failed: %w", err) } @@ -205,7 +206,7 @@ ON "question" ( LastEditUserID string `xorm:"not null default 0 BIGINT(20) last_edit_user_id"` } - err = x.Sync(new(Activity), new(Revision), new(Tag), new(Question), new(Answer)) + err = x.Context(ctx).Sync(new(Activity), new(Revision), new(Tag), new(Question), new(Answer)) if err != nil { return fmt.Errorf("sync table failed %w", err) } diff --git a/internal/migrations/v4.go b/internal/migrations/v4.go index 9d32b13f..b0aca5e5 100644 --- a/internal/migrations/v4.go +++ b/internal/migrations/v4.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "github.com/answerdev/answer/internal/entity" @@ -9,8 +10,8 @@ import ( "xorm.io/xorm" ) -func addRoleFeatures(x *xorm.Engine) error { - err := x.Sync(new(entity.Role), new(entity.RolePowerRel), new(entity.Power), new(entity.UserRoleRel)) +func addRoleFeatures(ctx context.Context, x *xorm.Engine) error { + err := x.Context(ctx).Sync(new(entity.Role), new(entity.RolePowerRel), new(entity.Power), new(entity.UserRoleRel)) if err != nil { return err } @@ -23,14 +24,14 @@ func addRoleFeatures(x *xorm.Engine) error { // insert default roles for _, role := range roles { - exist, err := x.Get(&entity.Role{ID: role.ID, Name: role.Name}) + exist, err := x.Context(ctx).Get(&entity.Role{ID: role.ID, Name: role.Name}) if err != nil { return err } if exist { continue } - _, err = x.Insert(role) + _, err = x.Context(ctx).Insert(role) if err != nil { return err } @@ -73,14 +74,14 @@ func addRoleFeatures(x *xorm.Engine) error { } // insert default powers for _, power := range powers { - exist, err := x.Get(&entity.Power{ID: power.ID}) + exist, err := x.Context(ctx).Get(&entity.Power{ID: power.ID}) if err != nil { return err } if exist { - _, err = x.ID(power.ID).Update(power) + _, err = x.Context(ctx).ID(power.ID).Update(power) } else { - _, err = x.Insert(power) + _, err = x.Context(ctx).Insert(power) } if err != nil { return err @@ -160,14 +161,14 @@ func addRoleFeatures(x *xorm.Engine) error { // insert default powers for _, rel := range rolePowerRels { - exist, err := x.Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) + exist, err := x.Context(ctx).Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) if err != nil { return err } if exist { continue } - _, err = x.Insert(rel) + _, err = x.Context(ctx).Insert(rel) if err != nil { return err } @@ -178,12 +179,12 @@ func addRoleFeatures(x *xorm.Engine) error { RoleID: 2, } - exist, err := x.Get(adminUserRoleRel) + exist, err := x.Context(ctx).Get(adminUserRoleRel) if err != nil { return err } if !exist { - _, err = x.Insert(adminUserRoleRel) + _, err = x.Context(ctx).Insert(adminUserRoleRel) if err != nil { return err } @@ -195,18 +196,18 @@ func addRoleFeatures(x *xorm.Engine) error { {ID: 117, Key: "rank.tag.use_reserved_tag", Value: `-1`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID, Key: c.Key}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID, Key: c.Key}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { - if _, err = x.Update(c, &entity.Config{ID: c.ID, Key: c.Key}); err != nil { + if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID, Key: c.Key}); err != nil { log.Errorf("update %+v config failed: %s", c, err) return fmt.Errorf("update config failed: %w", err) } continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { log.Errorf("insert %+v config failed: %s", c, err) return fmt.Errorf("add config failed: %w", err) } diff --git a/internal/migrations/v5.go b/internal/migrations/v5.go index c4e3a4cc..8357837d 100644 --- a/internal/migrations/v5.go +++ b/internal/migrations/v5.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "encoding/json" "fmt" @@ -8,7 +9,7 @@ import ( "xorm.io/xorm" ) -func addThemeAndPrivateMode(x *xorm.Engine) error { +func addThemeAndPrivateMode(ctx context.Context, x *xorm.Engine) error { loginConfig := map[string]bool{ "allow_new_registrations": true, "login_required": false, @@ -19,12 +20,12 @@ func addThemeAndPrivateMode(x *xorm.Engine) error { Content: string(loginConfigDataBytes), Status: 1, } - exist, err := x.Get(&entity.SiteInfo{Type: siteInfo.Type}) + exist, err := x.Context(ctx).Get(&entity.SiteInfo{Type: siteInfo.Type}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if !exist { - _, err = x.InsertOne(siteInfo) + _, err = x.Context(ctx).Insert(siteInfo) if err != nil { return fmt.Errorf("insert site info failed: %w", err) } @@ -36,12 +37,12 @@ func addThemeAndPrivateMode(x *xorm.Engine) error { Content: themeConfig, Status: 1, } - exist, err = x.Get(&entity.SiteInfo{Type: themeSiteInfo.Type}) + exist, err = x.Context(ctx).Get(&entity.SiteInfo{Type: themeSiteInfo.Type}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if !exist { - _, err = x.InsertOne(themeSiteInfo) + _, err = x.Context(ctx).Insert(themeSiteInfo) } return err } diff --git a/internal/migrations/v6.go b/internal/migrations/v6.go index 0f87b367..32747c64 100644 --- a/internal/migrations/v6.go +++ b/internal/migrations/v6.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "encoding/json" "fmt" @@ -8,15 +9,15 @@ import ( "xorm.io/xorm" ) -func addNewAnswerNotification(x *xorm.Engine) error { +func addNewAnswerNotification(ctx context.Context, x *xorm.Engine) error { cond := &entity.Config{Key: "email.config"} - exists, err := x.Get(cond) + exists, err := x.Context(ctx).Get(cond) if err != nil { return fmt.Errorf("get email config failed: %w", err) } if !exists { // This should be impossible except that the config was deleted manually by user. - _, err = x.InsertOne(&entity.Config{ + _, err = x.Context(ctx).Insert(&entity.Config{ Key: "email.config", Value: `{"from_name":"","from_email":"","smtp_host":"","smtp_port":465,"smtp_password":"","smtp_username":"","smtp_authentication":true,"encryption":"","register_title":"[{{.SiteName}}] Confirm your new account","register_body":"Welcome to {{.SiteName}}

\n\nClick the following link to confirm and activate your new account:
\n{{.RegisterUrl}}

\n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n","pass_reset_title":"[{{.SiteName }}] Password reset","pass_reset_body":"Somebody asked to reset your password on [{{.SiteName}}].

\n\nIf it was not you, you can safely ignore this email.

\n\nClick the following link to choose a new password:
\n{{.PassResetUrl}}\n","change_title":"[{{.SiteName}}] Confirm your new email address","change_body":"Confirm your new email address for {{.SiteName}} by clicking on the following link:

\n\n{{.ChangeEmailUrl}}

\n\nIf you did not request this change, please ignore this email.\n","test_title":"[{{.SiteName}}] Test Email","test_body":"This is a test email.","new_answer_title":"[{{.SiteName}}] {{.DisplayName}} answered your question","new_answer_body":"{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.AnswerSummary}}

\nView it on {{.SiteName}}

\n\nYou are receiving this because you authored the thread. Unsubscribe","new_comment_title":"[{{.SiteName}}] {{.DisplayName}} commented on your post","new_comment_body":"{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.CommentSummary}}

\nView it on {{.SiteName}}

\n\nYou are receiving this because you authored the thread. Unsubscribe"}`, }) @@ -33,7 +34,7 @@ func addNewAnswerNotification(x *xorm.Engine) error { m["new_comment_body"] = "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.CommentSummary}}

\nView it on {{.SiteName}}

\n\nYou are receiving this because you authored the thread. Unsubscribe" val, _ := json.Marshal(m) - _, err = x.ID(cond.ID).Update(&entity.Config{Value: string(val)}) + _, err = x.Context(ctx).ID(cond.ID).Update(&entity.Config{Value: string(val)}) if err != nil { return fmt.Errorf("update email config failed: %v", err) } diff --git a/internal/migrations/v7.go b/internal/migrations/v7.go index 1770a80d..23f62024 100644 --- a/internal/migrations/v7.go +++ b/internal/migrations/v7.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "github.com/answerdev/answer/internal/entity" @@ -8,23 +9,23 @@ import ( "xorm.io/xorm" ) -func addPlugin(x *xorm.Engine) error { +func addPlugin(ctx context.Context, x *xorm.Engine) error { defaultConfigTable := []*entity.Config{ {ID: 118, Key: "plugin.status", Value: `{}`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID, Key: c.Key}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID, Key: c.Key}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { log.Errorf("insert %+v config failed: %s", c, err) return fmt.Errorf("add config failed: %w", err) } } - return x.Sync(new(entity.PluginConfig), new(entity.UserExternalLogin)) + return x.Context(ctx).Sync(new(entity.PluginConfig), new(entity.UserExternalLogin)) } diff --git a/internal/migrations/v8.go b/internal/migrations/v8.go index 0b3674c3..c4db5ba9 100644 --- a/internal/migrations/v8.go +++ b/internal/migrations/v8.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "time" @@ -10,8 +11,7 @@ import ( "xorm.io/xorm" ) -func addRolePinAndHideFeatures(x *xorm.Engine) error { - +func addRolePinAndHideFeatures(ctx context.Context, x *xorm.Engine) error { powers := []*entity.Power{ {ID: 34, Name: "question pin", PowerType: permission.QuestionPin, Description: "top the question"}, {ID: 35, Name: "question hide", PowerType: permission.QuestionHide, Description: "hide the question"}, @@ -20,14 +20,14 @@ func addRolePinAndHideFeatures(x *xorm.Engine) error { } // insert default powers for _, power := range powers { - exist, err := x.Get(&entity.Power{ID: power.ID}) + exist, err := x.Context(ctx).Get(&entity.Power{ID: power.ID}) if err != nil { return err } if exist { - _, err = x.ID(power.ID).Update(power) + _, err = x.Context(ctx).ID(power.ID).Update(power) } else { - _, err = x.Insert(power) + _, err = x.Context(ctx).Insert(power) } if err != nil { return err @@ -49,14 +49,14 @@ func addRolePinAndHideFeatures(x *xorm.Engine) error { // insert default powers for _, rel := range rolePowerRels { - exist, err := x.Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) + exist, err := x.Context(ctx).Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType}) if err != nil { return err } if exist { continue } - _, err = x.Insert(rel) + _, err = x.Context(ctx).Insert(rel) if err != nil { return err } @@ -73,18 +73,18 @@ func addRolePinAndHideFeatures(x *xorm.Engine) error { {ID: 126, Key: "rank.question.hide", Value: `-1`}, } for _, c := range defaultConfigTable { - exist, err := x.Get(&entity.Config{ID: c.ID}) + exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID}) if err != nil { return fmt.Errorf("get config failed: %w", err) } if exist { - if _, err = x.Update(c, &entity.Config{ID: c.ID}); err != nil { + if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil { log.Errorf("update %+v config failed: %s", c, err) return fmt.Errorf("update config failed: %w", err) } continue } - if _, err = x.Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { log.Errorf("insert %+v config failed: %s", c, err) return fmt.Errorf("add config failed: %w", err) } @@ -113,7 +113,7 @@ func addRolePinAndHideFeatures(x *xorm.Engine) error { PostUpdateTime time.Time `xorm:"post_update_time TIMESTAMP"` RevisionID string `xorm:"not null default 0 BIGINT(20) revision_id"` } - err := x.Sync(new(Question)) + err := x.Context(ctx).Sync(new(Question)) if err != nil { return err } diff --git a/internal/migrations/v9.go b/internal/migrations/v9.go index fadd1bc6..c731c227 100644 --- a/internal/migrations/v9.go +++ b/internal/migrations/v9.go @@ -1,6 +1,7 @@ package migrations import ( + "context" "fmt" "github.com/answerdev/answer/internal/entity" @@ -8,9 +9,9 @@ import ( "xorm.io/xorm" ) -func updateAcceptAnswerRank(x *xorm.Engine) error { +func updateAcceptAnswerRank(ctx context.Context, x *xorm.Engine) error { c := &entity.Config{ID: 44, Key: "rank.answer.accept", Value: `-1`} - if _, err := x.Update(c, &entity.Config{ID: 44, Key: "rank.answer.accept"}); err != nil { + if _, err := x.Context(ctx).Update(c, &entity.Config{ID: 44, Key: "rank.answer.accept"}); err != nil { log.Errorf("update %+v config failed: %s", c, err) return fmt.Errorf("update config failed: %w", err) }