Fix migration order v1.3 (#3157)

* FIx migration order

* Fix migration function file names to match version

* Fix typo

* Add note about ignored errors

* Fix typo, remove wrong comment
This commit is contained in:
Lauris BH 2017-12-12 13:15:26 +02:00 committed by Lunny Xiao
parent aee45d072e
commit 4b187f5167
10 changed files with 279 additions and 270 deletions

View file

@ -59,6 +59,10 @@ type Version struct {
Version int64
}
func emptyMigration(x *xorm.Engine) error {
return nil
}
// This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, remove it from the top of the list and
// update minDBVersion accordingly
@ -127,17 +131,17 @@ var migrations = []Migration{
// v38 -> v39
NewMigration("remove commits and settings unit types", removeCommitsUnitType),
// v39 -> v40
NewMigration("adds time tracking and stopwatches", addTimetracking),
// v40 -> v41
NewMigration("migrate protected branch struct", migrateProtectedBranchStruct),
// v41 -> v42
NewMigration("add default value to user prohibit_login", addDefaultValueToUserProhibitLogin),
// v42 -> v43
NewMigration("add tags to releases and sync existing repositories", releaseAddColumnIsTagAndSyncTags),
// v43 -> v44
NewMigration("fix protected branch can push value to false", fixProtectedBranchCanPushValue),
// v44 -> v45
// v40 -> v41
NewMigration("add tags to releases and sync existing repositories", releaseAddColumnIsTagAndSyncTags),
// v41 -> v42
NewMigration("remove duplicate unit types", removeDuplicateUnitTypes),
// v42 -> v43
NewMigration("empty step", emptyMigration),
// v43 -> v44
NewMigration("empty step", emptyMigration),
// v44 -> v45
NewMigration("empty step", emptyMigration),
// v45 -> v46
NewMigration("remove index column from repo_unit table", removeIndexColumnFromRepoUnitTable),
// v46 -> v47
@ -146,6 +150,12 @@ var migrations = []Migration{
NewMigration("add deleted branches", addDeletedBranch),
// v48 -> v49
NewMigration("add repo indexer status", addRepoIndexerStatus),
// v49 -> v50
NewMigration("adds time tracking and stopwatches", addTimetracking),
// v50 -> v51
NewMigration("migrate protected branch struct", migrateProtectedBranchStruct),
// v51 -> v52
NewMigration("add default value to user prohibit_login", addDefaultValueToUserProhibitLogin),
}
// Migrate database to current version

View file

@ -6,69 +6,21 @@ package migrations
import (
"fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addTimetracking(x *xorm.Engine) error {
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Index int
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix int64 `xorm:"INDEX CREATED"`
Created time.Time `xorm:"-"`
func fixProtectedBranchCanPushValue(x *xorm.Engine) error {
type ProtectedBranch struct {
CanPush bool `xorm:"NOT NULL DEFAULT false"`
}
// Stopwatch see models/issue_stopwatch.go
type Stopwatch struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"INDEX"`
UserID int64 `xorm:"INDEX"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
// TrackedTime see models/issue_tracked_time.go
type TrackedTime struct {
ID int64 `xorm:"pk autoincr" json:"id"`
IssueID int64 `xorm:"INDEX" json:"issue_id"`
UserID int64 `xorm:"INDEX" json:"user_id"`
Created time.Time `xorm:"-" json:"created"`
CreatedUnix int64 `json:"-"`
Time int64 `json:"time"`
}
if err := x.Sync2(new(Stopwatch)); err != nil {
if err := x.Sync2(new(ProtectedBranch)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
if err := x.Sync2(new(TrackedTime)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
err := x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
if err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["EnableTimetracker"]; !ok {
unit.Config["EnableTimetracker"] = setting.Service.DefaultEnableTimetracking
}
if _, ok := unit.Config["AllowOnlyContributorsToTrackTime"]; !ok {
unit.Config["AllowOnlyContributorsToTrackTime"] = setting.Service.DefaultAllowOnlyContributorsToTrackTime
}
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
_, err := x.Cols("can_push").Update(&ProtectedBranch{
CanPush: false,
})
return err
}
}
return nil
}

View file

@ -6,50 +6,52 @@ package migrations
import (
"fmt"
"time"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func migrateProtectedBranchStruct(x *xorm.Engine) error {
type ProtectedBranch struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s)"`
BranchName string `xorm:"UNIQUE(s)"`
CanPush bool
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
// ReleaseV39 describes the added field for Release
type ReleaseV39 struct {
IsTag bool `xorm:"NOT NULL DEFAULT false"`
}
// TableName will be invoked by XORM to customrize the table name
func (*ReleaseV39) TableName() string {
return "release"
}
func releaseAddColumnIsTagAndSyncTags(x *xorm.Engine) error {
if err := x.Sync2(new(ReleaseV39)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
var pbs []ProtectedBranch
err := x.Find(&pbs)
// For the sake of SQLite3, we can't use x.Iterate here.
offset := 0
pageSize := 20
for {
repos := make([]*models.Repository, 0, pageSize)
if err := x.Table("repository").Asc("id").Limit(pageSize, offset).Find(&repos); err != nil {
return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
}
for _, repo := range repos {
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
return err
log.Warn("OpenRepository: %v", err)
continue
}
for _, pb := range pbs {
if pb.CanPush {
if _, err = x.ID(pb.ID).Delete(new(ProtectedBranch)); err != nil {
return err
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
log.Warn("SyncReleasesWithTags: %v", err)
}
}
if len(repos) < pageSize {
break
}
switch {
case setting.UseSQLite3:
log.Warn("Unable to drop columns in SQLite")
case setting.UseMySQL, setting.UsePostgreSQL, setting.UseMSSQL, setting.UseTiDB:
if _, err := x.Exec("ALTER TABLE protected_branch DROP COLUMN can_push"); err != nil {
return fmt.Errorf("DROP COLUMN can_push: %v", err)
offset += pageSize
}
default:
log.Fatal(4, "Unrecognized DB")
}
return nil
}

View file

@ -7,36 +7,63 @@ package migrations
import (
"fmt"
"code.gitea.io/gitea/models"
"github.com/go-xorm/xorm"
)
func addDefaultValueToUserProhibitLogin(x *xorm.Engine) (err error) {
user := &models.User{
ProhibitLogin: false,
func removeDuplicateUnitTypes(x *xorm.Engine) error {
// RepoUnit describes all units of a repository
type RepoUnit struct {
RepoID int64
Type int
}
if _, err := x.Where("`prohibit_login` IS NULL").Cols("prohibit_login").Update(user); err != nil {
return err
}
dialect := x.Dialect().DriverName()
switch dialect {
case "mysql":
_, err = x.Exec("ALTER TABLE user MODIFY `prohibit_login` tinyint(1) NOT NULL DEFAULT 0")
case "postgres":
_, err = x.Exec("ALTER TABLE \"user\" ALTER COLUMN `prohibit_login` SET NOT NULL, ALTER COLUMN `prohibit_login` SET DEFAULT false")
case "mssql":
// xorm already set DEFAULT 0 for data type BIT in mssql
_, err = x.Exec(`ALTER TABLE [user] ALTER COLUMN "prohibit_login" BIT NOT NULL`)
case "sqlite3":
}
// Enumerate all the unit types
const (
UnitTypeCode = iota + 1 // 1 code
UnitTypeIssues // 2 issues
UnitTypePullRequests // 3 PRs
UnitTypeReleases // 4 Releases
UnitTypeWiki // 5 Wiki
UnitTypeExternalWiki // 6 ExternalWiki
UnitTypeExternalTracker // 7 ExternalTracker
)
var externalIssueRepoUnits []RepoUnit
err := x.Where("type = ?", UnitTypeExternalTracker).Find(&externalIssueRepoUnits)
if err != nil {
return fmt.Errorf("Error changing user prohibit_login column definition: %v", err)
return fmt.Errorf("Query repositories: %v", err)
}
var externalWikiRepoUnits []RepoUnit
err = x.Where("type = ?", UnitTypeExternalWiki).Find(&externalWikiRepoUnits)
if err != nil {
return fmt.Errorf("Query repositories: %v", err)
}
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
for _, repoUnit := range externalIssueRepoUnits {
if _, err = sess.Delete(&RepoUnit{
RepoID: repoUnit.RepoID,
Type: UnitTypeIssues,
}); err != nil {
return fmt.Errorf("Delete repo unit: %v", err)
}
}
for _, repoUnit := range externalWikiRepoUnits {
if _, err = sess.Delete(&RepoUnit{
RepoID: repoUnit.RepoID,
Type: UnitTypeWiki,
}); err != nil {
return fmt.Errorf("Delete repo unit: %v", err)
}
}
return sess.Commit()
}

View file

@ -1,57 +0,0 @@
// Copyright 2017 The Gitea 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 (
"fmt"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"github.com/go-xorm/xorm"
)
// ReleaseV39 describes the added field for Release
type ReleaseV39 struct {
IsTag bool `xorm:"NOT NULL DEFAULT false"`
}
// TableName will be invoked by XORM to customrize the table name
func (*ReleaseV39) TableName() string {
return "release"
}
func releaseAddColumnIsTagAndSyncTags(x *xorm.Engine) error {
if err := x.Sync2(new(ReleaseV39)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
// For the sake of SQLite3, we can't use x.Iterate here.
offset := 0
pageSize := 20
for {
repos := make([]*models.Repository, 0, pageSize)
if err := x.Table("repository").Asc("id").Limit(pageSize, offset).Find(&repos); err != nil {
return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
}
for _, repo := range repos {
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Warn("OpenRepository: %v", err)
continue
}
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
log.Warn("SyncReleasesWithTags: %v", err)
}
}
if len(repos) < pageSize {
break
}
offset += pageSize
}
return nil
}

View file

@ -1,26 +0,0 @@
// Copyright 2017 The Gitea 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 (
"fmt"
"github.com/go-xorm/xorm"
)
func fixProtectedBranchCanPushValue(x *xorm.Engine) error {
type ProtectedBranch struct {
CanPush bool `xorm:"NOT NULL DEFAULT false"`
}
if err := x.Sync2(new(ProtectedBranch)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
_, err := x.Cols("can_push").Update(&ProtectedBranch{
CanPush: false,
})
return err
}

View file

@ -1,69 +0,0 @@
// Copyright 2017 The Gitea 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 (
"fmt"
"github.com/go-xorm/xorm"
)
func removeDuplicateUnitTypes(x *xorm.Engine) error {
// RepoUnit describes all units of a repository
type RepoUnit struct {
RepoID int64
Type int
}
// Enumerate all the unit types
const (
UnitTypeCode = iota + 1 // 1 code
UnitTypeIssues // 2 issues
UnitTypePullRequests // 3 PRs
UnitTypeReleases // 4 Releases
UnitTypeWiki // 5 Wiki
UnitTypeExternalWiki // 6 ExternalWiki
UnitTypeExternalTracker // 7 ExternalTracker
)
var externalIssueRepoUnits []RepoUnit
err := x.Where("type = ?", UnitTypeExternalTracker).Find(&externalIssueRepoUnits)
if err != nil {
return fmt.Errorf("Query repositories: %v", err)
}
var externalWikiRepoUnits []RepoUnit
err = x.Where("type = ?", UnitTypeExternalWiki).Find(&externalWikiRepoUnits)
if err != nil {
return fmt.Errorf("Query repositories: %v", err)
}
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
for _, repoUnit := range externalIssueRepoUnits {
if _, err = sess.Delete(&RepoUnit{
RepoID: repoUnit.RepoID,
Type: UnitTypeIssues,
}); err != nil {
return fmt.Errorf("Delete repo unit: %v", err)
}
}
for _, repoUnit := range externalWikiRepoUnits {
if _, err = sess.Delete(&RepoUnit{
RepoID: repoUnit.RepoID,
Type: UnitTypeWiki,
}); err != nil {
return fmt.Errorf("Delete repo unit: %v", err)
}
}
return sess.Commit()
}

73
models/migrations/v49.go Normal file
View file

@ -0,0 +1,73 @@
// Copyright 2017 The Gitea 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 (
"fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addTimetracking(x *xorm.Engine) error {
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix int64 `xorm:"INDEX CREATED"`
Created time.Time `xorm:"-"`
}
// Stopwatch see models/issue_stopwatch.go
type Stopwatch struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"INDEX"`
UserID int64 `xorm:"INDEX"`
Created time.Time `xorm:"-"`
CreatedUnix int64
}
// TrackedTime see models/issue_tracked_time.go
type TrackedTime struct {
ID int64 `xorm:"pk autoincr" json:"id"`
IssueID int64 `xorm:"INDEX" json:"issue_id"`
UserID int64 `xorm:"INDEX" json:"user_id"`
Created time.Time `xorm:"-" json:"created"`
CreatedUnix int64 `json:"-"`
Time int64 `json:"time"`
}
if err := x.Sync2(new(Stopwatch)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
if err := x.Sync2(new(TrackedTime)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
err := x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
if err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["EnableTimetracker"]; !ok {
unit.Config["EnableTimetracker"] = setting.Service.DefaultEnableTimetracking
}
if _, ok := unit.Config["AllowOnlyContributorsToTrackTime"]; !ok {
unit.Config["AllowOnlyContributorsToTrackTime"] = setting.Service.DefaultAllowOnlyContributorsToTrackTime
}
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return nil
}

55
models/migrations/v50.go Normal file
View file

@ -0,0 +1,55 @@
// Copyright 2017 The Gitea 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 (
"time"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func migrateProtectedBranchStruct(x *xorm.Engine) error {
type ProtectedBranch struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s)"`
BranchName string `xorm:"UNIQUE(s)"`
CanPush bool
Created time.Time `xorm:"-"`
CreatedUnix int64
Updated time.Time `xorm:"-"`
UpdatedUnix int64
}
var pbs []ProtectedBranch
err := x.Find(&pbs)
if err != nil {
return err
}
for _, pb := range pbs {
if pb.CanPush {
if _, err = x.ID(pb.ID).Delete(new(ProtectedBranch)); err != nil {
return err
}
}
}
switch {
case setting.UseSQLite3:
log.Warn("Unable to drop columns in SQLite")
case setting.UseMySQL, setting.UsePostgreSQL, setting.UseMSSQL, setting.UseTiDB:
if _, err := x.Exec("ALTER TABLE protected_branch DROP COLUMN can_push"); err != nil {
// Ignoring this error in case we run this migration second time (after migration reordering)
log.Warn("DROP COLUMN can_push: %v", err)
}
default:
log.Fatal(4, "Unrecognized DB")
}
return nil
}

42
models/migrations/v51.go Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2017 The Gitea 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 (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"github.com/go-xorm/xorm"
)
func addDefaultValueToUserProhibitLogin(x *xorm.Engine) (err error) {
user := &models.User{
ProhibitLogin: false,
}
if _, err := x.Where("`prohibit_login` IS NULL").Cols("prohibit_login").Update(user); err != nil {
return err
}
dialect := x.Dialect().DriverName()
switch dialect {
case "mysql":
_, err = x.Exec("ALTER TABLE user MODIFY `prohibit_login` tinyint(1) NOT NULL DEFAULT 0")
case "postgres":
_, err = x.Exec("ALTER TABLE \"user\" ALTER COLUMN `prohibit_login` SET NOT NULL, ALTER COLUMN `prohibit_login` SET DEFAULT false")
case "mssql":
// xorm already set DEFAULT 0 for data type BIT in mssql
_, err = x.Exec(`ALTER TABLE [user] ALTER COLUMN "prohibit_login" BIT NOT NULL`)
case "sqlite3":
}
if err != nil {
// Ignoring this error in case we run this migration second time (after migration reordering)
log.Warn("Error changing user prohibit_login column definition: %v", err)
}
return nil
}