Remove migration support from versions earlier than 1.6.0 (#10026)
* Remove migration support from versions earlier than 1.6.0 * Remove unused functions * Update gogs upgrade instructions * Improve "latest" link as per @jolheiser Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>tokarchuk/v1.17
parent
b3d8e2d4f7
commit
d816f7018b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,52 +0,0 @@ |
||||
// Copyright 2016 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 ( |
||||
"encoding/json" |
||||
"fmt" |
||||
"strings" |
||||
|
||||
"github.com/unknwon/com" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error { |
||||
results, err := x.Query("SELECT `id`,`cfg` FROM `login_source` WHERE `type` = 2 OR `type` = 5") |
||||
if err != nil { |
||||
if strings.Contains(err.Error(), "no such column") { |
||||
return nil |
||||
} |
||||
return fmt.Errorf("select LDAP login sources: %v", err) |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
if err = sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
for _, result := range results { |
||||
cfg := map[string]interface{}{} |
||||
if err = json.Unmarshal(result["cfg"], &cfg); err != nil { |
||||
return fmt.Errorf("decode JSON config: %v", err) |
||||
} |
||||
if com.ToStr(cfg["UseSSL"]) == "true" { |
||||
cfg["SecurityProtocol"] = 1 // LDAPS
|
||||
} |
||||
delete(cfg, "UseSSL") |
||||
|
||||
data, err := json.Marshal(&cfg) |
||||
if err != nil { |
||||
return fmt.Errorf("encode JSON config: %v", err) |
||||
} |
||||
|
||||
if _, err = sess.Exec("UPDATE `login_source` SET `cfg`=? WHERE `id`=?", |
||||
string(data), com.StrTo(result["id"]).MustInt64()); err != nil { |
||||
return fmt.Errorf("update config column: %v", err) |
||||
} |
||||
} |
||||
return sess.Commit() |
||||
} |
@ -1,38 +0,0 @@ |
||||
// Copyright 2016 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 ( |
||||
"fmt" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func setCommentUpdatedWithCreated(x *xorm.Engine) (err error) { |
||||
type Comment struct { |
||||
UpdatedUnix int64 |
||||
} |
||||
|
||||
if err = x.Sync2(new(Comment)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} else if _, err = x.Exec("UPDATE comment SET updated_unix = created_unix"); err != nil { |
||||
return fmt.Errorf("set update_unix: %v", err) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// UserV14 describes the added fields for migrating from v13 -> v14
|
||||
type UserV14 struct { |
||||
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"` |
||||
} |
||||
|
||||
// TableName will be invoked by XORM to customize the table name
|
||||
func (*UserV14) TableName() string { |
||||
return "user" |
||||
} |
||||
|
||||
func createUserColumnDiffViewStyle(x *xorm.Engine) error { |
||||
return x.Sync2(new(UserV14)) |
||||
} |
@ -1,25 +0,0 @@ |
||||
// Copyright 2016 Gitea. 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func createAllowCreateOrganizationColumn(x *xorm.Engine) error { |
||||
type User struct { |
||||
KeepEmailPrivate bool |
||||
AllowCreateOrganization bool |
||||
} |
||||
|
||||
if err := x.Sync2(new(User)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} else if _, err = x.Where("`type` = 0").Cols("allow_create_organization").Update(&User{AllowCreateOrganization: true}); err != nil { |
||||
return fmt.Errorf("set allow_create_organization: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,123 +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" |
||||
"time" |
||||
|
||||
"code.gitea.io/gitea/modules/markup" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
// Enumerate all the unit types
|
||||
const ( |
||||
V16UnitTypeCode = iota + 1 // 1 code
|
||||
V16UnitTypeIssues // 2 issues
|
||||
V16UnitTypePRs // 3 PRs
|
||||
V16UnitTypeCommits // 4 Commits
|
||||
V16UnitTypeReleases // 5 Releases
|
||||
V16UnitTypeWiki // 6 Wiki
|
||||
V16UnitTypeSettings // 7 Settings
|
||||
V16UnitTypeExternalWiki // 8 ExternalWiki
|
||||
V16UnitTypeExternalTracker // 9 ExternalTracker
|
||||
) |
||||
|
||||
func addUnitsToTables(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:"-"` |
||||
} |
||||
|
||||
// Repo describes a repository
|
||||
type Repo struct { |
||||
ID int64 |
||||
EnableWiki, EnableExternalWiki, EnableIssues, EnableExternalTracker, EnablePulls bool |
||||
ExternalWikiURL, ExternalTrackerURL, ExternalTrackerFormat, ExternalTrackerStyle string |
||||
} |
||||
|
||||
var repos []Repo |
||||
err := x.Table("repository").Select("*").Find(&repos) |
||||
if err != nil { |
||||
return fmt.Errorf("Query repositories: %v", err) |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
var repoUnit RepoUnit |
||||
if exist, err := sess.IsTableExist(&repoUnit); err != nil { |
||||
return fmt.Errorf("IsExist RepoUnit: %v", err) |
||||
} else if exist { |
||||
return nil |
||||
} |
||||
|
||||
if err := sess.CreateTable(&repoUnit); err != nil { |
||||
return fmt.Errorf("CreateTable RepoUnit: %v", err) |
||||
} |
||||
|
||||
if err := sess.CreateUniques(&repoUnit); err != nil { |
||||
return fmt.Errorf("CreateUniques RepoUnit: %v", err) |
||||
} |
||||
|
||||
if err := sess.CreateIndexes(&repoUnit); err != nil { |
||||
return fmt.Errorf("CreateIndexes RepoUnit: %v", err) |
||||
} |
||||
|
||||
for _, repo := range repos { |
||||
for i := 1; i <= 9; i++ { |
||||
if (i == V16UnitTypeWiki || i == V16UnitTypeExternalWiki) && !repo.EnableWiki { |
||||
continue |
||||
} |
||||
if i == V16UnitTypeExternalWiki && !repo.EnableExternalWiki { |
||||
continue |
||||
} |
||||
if i == V16UnitTypePRs && !repo.EnablePulls { |
||||
continue |
||||
} |
||||
if (i == V16UnitTypeIssues || i == V16UnitTypeExternalTracker) && !repo.EnableIssues { |
||||
continue |
||||
} |
||||
if i == V16UnitTypeExternalTracker && !repo.EnableExternalTracker { |
||||
continue |
||||
} |
||||
|
||||
var config = make(map[string]interface{}) |
||||
switch i { |
||||
case V16UnitTypeExternalTracker: |
||||
config["ExternalTrackerURL"] = repo.ExternalTrackerURL |
||||
config["ExternalTrackerFormat"] = repo.ExternalTrackerFormat |
||||
if len(repo.ExternalTrackerStyle) == 0 { |
||||
repo.ExternalTrackerStyle = markup.IssueNameStyleNumeric |
||||
} |
||||
config["ExternalTrackerStyle"] = repo.ExternalTrackerStyle |
||||
case V16UnitTypeExternalWiki: |
||||
config["ExternalWikiURL"] = repo.ExternalWikiURL |
||||
} |
||||
|
||||
if _, err = sess.Insert(&RepoUnit{ |
||||
RepoID: repo.ID, |
||||
Type: i, |
||||
Index: i, |
||||
Config: config, |
||||
}); err != nil { |
||||
return fmt.Errorf("Insert repo unit: %v", err) |
||||
} |
||||
} |
||||
} |
||||
|
||||
return sess.Commit() |
||||
} |
@ -1,29 +0,0 @@ |
||||
// Copyright 2016 Gitea. 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func setProtectedBranchUpdatedWithCreated(x *xorm.Engine) (err 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 |
||||
} |
||||
if err = x.Sync2(new(ProtectedBranch)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,25 +0,0 @@ |
||||
// Copyright 2016 Gitea. 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
// ExternalLoginUser makes the connecting between some existing user and additional external login sources
|
||||
type ExternalLoginUser struct { |
||||
ExternalID string `xorm:"NOT NULL"` |
||||
UserID int64 `xorm:"NOT NULL"` |
||||
LoginSourceID int64 `xorm:"NOT NULL"` |
||||
} |
||||
|
||||
func addExternalLoginUser(x *xorm.Engine) error { |
||||
if err := x.Sync2(new(ExternalLoginUser)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,91 +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" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
|
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"github.com/unknwon/com" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func generateAndMigrateGitHooks(x *xorm.Engine) (err error) { |
||||
type Repository struct { |
||||
ID int64 |
||||
OwnerID int64 |
||||
Name string |
||||
} |
||||
type User struct { |
||||
ID int64 |
||||
Name string |
||||
} |
||||
|
||||
var ( |
||||
hookNames = []string{"pre-receive", "update", "post-receive"} |
||||
hookTpls = []string{ |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/pre-receive.d\"`; do\n sh \"$SHELL_FOLDER/pre-receive.d/$i\"\ndone", setting.ScriptType), |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/update.d\"`; do\n sh \"$SHELL_FOLDER/update.d/$i\" $1 $2 $3\ndone", setting.ScriptType), |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/post-receive.d\"`; do\n sh \"$SHELL_FOLDER/post-receive.d/$i\"\ndone", setting.ScriptType), |
||||
} |
||||
giteaHookTpls = []string{ |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
} |
||||
) |
||||
|
||||
return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository), |
||||
func(idx int, bean interface{}) error { |
||||
repo := bean.(*Repository) |
||||
user := new(User) |
||||
has, err := x.Where("id = ?", repo.OwnerID).Get(user) |
||||
if err != nil { |
||||
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err) |
||||
} else if !has { |
||||
return nil |
||||
} |
||||
|
||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git" |
||||
hookDir := filepath.Join(repoPath, "hooks") |
||||
|
||||
for i, hookName := range hookNames { |
||||
oldHookPath := filepath.Join(hookDir, hookName) |
||||
newHookPath := filepath.Join(hookDir, hookName+".d", "gitea") |
||||
|
||||
customHooksDir := filepath.Join(hookDir, hookName+".d") |
||||
// if it's exist, that means you have upgraded ever
|
||||
if com.IsExist(customHooksDir) { |
||||
continue |
||||
} |
||||
|
||||
if err = os.MkdirAll(customHooksDir, os.ModePerm); err != nil { |
||||
return fmt.Errorf("create hooks dir '%s': %v", customHooksDir, err) |
||||
} |
||||
|
||||
// WARNING: Old server-side hooks will be moved to sub directory with the same name
|
||||
if hookName != "update" && com.IsExist(oldHookPath) { |
||||
newPlace := filepath.Join(hookDir, hookName+".d", hookName) |
||||
if err = os.Rename(oldHookPath, newPlace); err != nil { |
||||
return fmt.Errorf("Remove old hook file '%s' to '%s': %v", oldHookPath, newPlace, err) |
||||
} |
||||
} |
||||
|
||||
if err = ioutil.WriteFile(oldHookPath, []byte(hookTpls[i]), 0777); err != nil { |
||||
return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
|
||||
if err = ioutil.WriteFile(newHookPath, []byte(giteaHookTpls[i]), 0777); err != nil { |
||||
return fmt.Errorf("write new hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
} |
||||
return nil |
||||
}) |
||||
} |
@ -1,73 +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 ( |
||||
"crypto/md5" |
||||
"errors" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"strconv" |
||||
|
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func useNewNameAvatars(x *xorm.Engine) error { |
||||
d, err := os.Open(setting.AvatarUploadPath) |
||||
if err != nil { |
||||
if os.IsNotExist(err) { |
||||
// Nothing to do if AvatarUploadPath does not exist
|
||||
return nil |
||||
} |
||||
return err |
||||
} |
||||
names, err := d.Readdirnames(0) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
type User struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Avatar string |
||||
UseCustomAvatar bool |
||||
} |
||||
|
||||
for _, name := range names { |
||||
userID, err := strconv.ParseInt(name, 10, 64) |
||||
if err != nil { |
||||
log.Warn("ignore avatar %s rename: %v", name, err) |
||||
continue |
||||
} |
||||
|
||||
var user User |
||||
if has, err := x.ID(userID).Get(&user); err != nil { |
||||
return err |
||||
} else if !has { |
||||
return errors.New("Avatar user is not exist") |
||||
} |
||||
|
||||
fPath := filepath.Join(setting.AvatarUploadPath, name) |
||||
bs, err := ioutil.ReadFile(fPath) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
user.Avatar = fmt.Sprintf("%x", md5.Sum(bs)) |
||||
err = os.Rename(fPath, filepath.Join(setting.AvatarUploadPath, user.Avatar)) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
_, err = x.ID(userID).Cols("avatar").Update(&user) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
} |
||||
return nil |
||||
} |
@ -1,55 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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" |
||||
"os" |
||||
"path/filepath" |
||||
|
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"github.com/unknwon/com" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
const ( |
||||
tplCommentPrefix = `# gitea public key` |
||||
tplPublicKey = tplCommentPrefix + "\n" + `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n" |
||||
) |
||||
|
||||
func useNewPublickeyFormat(x *xorm.Engine) error { |
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys") |
||||
if !com.IsExist(fpath) { |
||||
return nil |
||||
} |
||||
|
||||
tmpPath := fpath + ".tmp" |
||||
f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer func() { |
||||
f.Close() |
||||
os.Remove(tmpPath) |
||||
}() |
||||
|
||||
type PublicKey struct { |
||||
ID int64 |
||||
Content string |
||||
} |
||||
|
||||
err = x.Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) { |
||||
key := bean.(*PublicKey) |
||||
_, err = f.WriteString(fmt.Sprintf(tplPublicKey, setting.AppPath, key.ID, setting.CustomConf, key.Content)) |
||||
return err |
||||
}) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
f.Close() |
||||
return os.Rename(tmpPath, fpath) |
||||
} |
@ -1,94 +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" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
|
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"github.com/unknwon/com" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func generateAndMigrateWikiGitHooks(x *xorm.Engine) (err error) { |
||||
type Repository struct { |
||||
ID int64 |
||||
OwnerID int64 |
||||
Name string |
||||
} |
||||
type User struct { |
||||
ID int64 |
||||
Name string |
||||
} |
||||
|
||||
var ( |
||||
hookNames = []string{"pre-receive", "update", "post-receive"} |
||||
hookTpls = []string{ |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/pre-receive.d\"`; do\n sh \"$SHELL_FOLDER/pre-receive.d/$i\"\ndone", setting.ScriptType), |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/update.d\"`; do\n sh \"$SHELL_FOLDER/update.d/$i\" $1 $2 $3\ndone", setting.ScriptType), |
||||
fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/post-receive.d\"`; do\n sh \"$SHELL_FOLDER/post-receive.d/$i\"\ndone", setting.ScriptType), |
||||
} |
||||
giteaHookTpls = []string{ |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf), |
||||
} |
||||
) |
||||
|
||||
return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository), |
||||
func(idx int, bean interface{}) error { |
||||
repo := bean.(*Repository) |
||||
user := new(User) |
||||
has, err := x.Where("id = ?", repo.OwnerID).Get(user) |
||||
if err != nil { |
||||
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err) |
||||
} else if !has { |
||||
return nil |
||||
} |
||||
|
||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".wiki.git" |
||||
if !com.IsExist(repoPath) { |
||||
return nil |
||||
} |
||||
hookDir := filepath.Join(repoPath, "hooks") |
||||
|
||||
for i, hookName := range hookNames { |
||||
oldHookPath := filepath.Join(hookDir, hookName) |
||||
newHookPath := filepath.Join(hookDir, hookName+".d", "gitea") |
||||
|
||||
customHooksDir := filepath.Join(hookDir, hookName+".d") |
||||
// if it's exist, that means you have upgraded ever
|
||||
if com.IsExist(customHooksDir) { |
||||
continue |
||||
} |
||||
|
||||
if err = os.MkdirAll(customHooksDir, os.ModePerm); err != nil { |
||||
return fmt.Errorf("create hooks dir '%s': %v", customHooksDir, err) |
||||
} |
||||
|
||||
// WARNING: Old server-side hooks will be moved to sub directory with the same name
|
||||
if hookName != "update" && com.IsExist(oldHookPath) { |
||||
newPlace := filepath.Join(hookDir, hookName+".d", hookName) |
||||
if err = os.Rename(oldHookPath, newPlace); err != nil { |
||||
return fmt.Errorf("Remove old hook file '%s' to '%s': %v", oldHookPath, newPlace, err) |
||||
} |
||||
} |
||||
|
||||
if err = ioutil.WriteFile(oldHookPath, []byte(hookTpls[i]), 0777); err != nil { |
||||
return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
|
||||
if err = ioutil.WriteFile(newHookPath, []byte(giteaHookTpls[i]), 0777); err != nil { |
||||
return fmt.Errorf("write new hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
} |
||||
return nil |
||||
}) |
||||
} |
@ -1,25 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
// UserOpenID is the list of all OpenID identities of a user.
|
||||
type UserOpenID struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
UID int64 `xorm:"INDEX NOT NULL"` |
||||
URI string `xorm:"UNIQUE NOT NULL"` |
||||
} |
||||
|
||||
func addUserOpenID(x *xorm.Engine) error { |
||||
if err := x.Sync2(new(UserOpenID)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,50 +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 ( |
||||
"time" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func changeGPGKeysColumns(x *xorm.Engine) error { |
||||
// EmailAddress is the list of all email addresses of a user. Can contain the
|
||||
// primary email address, but is not obligatory.
|
||||
type EmailAddress struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
UID int64 `xorm:"INDEX NOT NULL"` |
||||
Email string `xorm:"UNIQUE NOT NULL"` |
||||
IsActivated bool |
||||
IsPrimary bool `xorm:"-"` |
||||
} |
||||
|
||||
// GPGKey represents a GPG key.
|
||||
type GPGKey struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
OwnerID int64 `xorm:"INDEX NOT NULL"` |
||||
KeyID string `xorm:"INDEX CHAR(16) NOT NULL"` |
||||
PrimaryKeyID string `xorm:"CHAR(16)"` |
||||
Content string `xorm:"TEXT NOT NULL"` |
||||
Created time.Time `xorm:"-"` |
||||
CreatedUnix int64 |
||||
Expired time.Time `xorm:"-"` |
||||
ExpiredUnix int64 |
||||
Added time.Time `xorm:"-"` |
||||
AddedUnix int64 |
||||
SubsKey []*GPGKey `xorm:"-"` |
||||
Emails []*EmailAddress |
||||
CanSign bool |
||||
CanEncryptComms bool |
||||
CanEncryptStorage bool |
||||
CanCertify bool |
||||
} |
||||
|
||||
if err := x.DropTables(new(GPGKey)); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return x.Sync(new(GPGKey)) |
||||
} |
@ -1,18 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addUserOpenIDShow(x *xorm.Engine) error { |
||||
if err := x.Sync2(new(UserOpenID)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,87 +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 ( |
||||
"crypto/md5" |
||||
"encoding/hex" |
||||
"fmt" |
||||
"io" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
|
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"github.com/unknwon/com" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func generateAndMigrateGitHookChains(x *xorm.Engine) (err error) { |
||||
type Repository struct { |
||||
ID int64 |
||||
OwnerID int64 |
||||
Name string |
||||
} |
||||
type User struct { |
||||
ID int64 |
||||
Name string |
||||
} |
||||
|
||||
var ( |
||||
hookNames = []string{"pre-receive", "update", "post-receive"} |
||||
hookTpl = fmt.Sprintf("#!/usr/bin/env %s\ndata=$(cat)\nexitcodes=\"\"\nhookname=$(basename $0)\nGIT_DIR=${GIT_DIR:-$(dirname $0)}\n\nfor hook in ${GIT_DIR}/hooks/${hookname}.d/*; do\ntest -x \"${hook}\" || continue\necho \"${data}\" | \"${hook}\"\nexitcodes=\"${exitcodes} $?\"\ndone\n\nfor i in ${exitcodes}; do\n[ ${i} -eq 0 ] || exit ${i}\ndone\n", setting.ScriptType) |
||||
) |
||||
|
||||
return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository), |
||||
func(idx int, bean interface{}) error { |
||||
repo := bean.(*Repository) |
||||
user := new(User) |
||||
has, err := x.Where("id = ?", repo.OwnerID).Get(user) |
||||
if err != nil { |
||||
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err) |
||||
} else if !has { |
||||
return nil |
||||
} |
||||
|
||||
repoPaths := []string{ |
||||
filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git", |
||||
filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".wiki.git", |
||||
} |
||||
|
||||
for _, repoPath := range repoPaths { |
||||
if com.IsExist(repoPath) { |
||||
hookDir := filepath.Join(repoPath, "hooks") |
||||
|
||||
for _, hookName := range hookNames { |
||||
oldHookPath := filepath.Join(hookDir, hookName) |
||||
|
||||
// compare md5sums of hooks
|
||||
if com.IsExist(oldHookPath) { |
||||
|
||||
f, err := os.Open(oldHookPath) |
||||
if err != nil { |
||||
return fmt.Errorf("cannot open old hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
defer f.Close() |
||||
h := md5.New() |
||||
if _, err := io.Copy(h, f); err != nil { |
||||
return fmt.Errorf("cannot read old hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
if hex.EncodeToString(h.Sum(nil)) == "6718ef67d0834e0a7908259acd566e3f" { |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
if err = ioutil.WriteFile(oldHookPath, []byte(hookTpl), 0777); err != nil { |
||||
return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return nil |
||||
}) |
||||
} |
@ -1,72 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func convertIntervalToDuration(x *xorm.Engine) (err error) { |
||||
type Repository struct { |
||||
ID int64 |
||||
OwnerID int64 |
||||
Name string |
||||
} |
||||
type Mirror struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"INDEX"` |
||||
Repo *Repository `xorm:"-"` |
||||
Interval time.Duration |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
dialect := x.Dialect().DriverName() |
||||
|
||||
switch dialect { |
||||
case "mysql": |
||||
_, err = sess.Exec("ALTER TABLE mirror MODIFY `interval` BIGINT") |
||||
case "postgres": |
||||
_, err = sess.Exec("ALTER TABLE mirror ALTER COLUMN \"interval\" SET DATA TYPE bigint") |
||||
case "mssql": |
||||
_, err = sess.Exec("ALTER TABLE mirror ALTER COLUMN \"interval\" BIGINT") |
||||
case "sqlite3": |
||||
} |
||||
|
||||
if err != nil { |
||||
return fmt.Errorf("Error changing mirror interval column type: %v", err) |
||||
} |
||||
|
||||
var mirrors []Mirror |
||||
err = sess.Table("mirror").Select("*").Find(&mirrors) |
||||
if err != nil { |
||||
return fmt.Errorf("Query repositories: %v", err) |
||||
} |
||||
for _, mirror := range mirrors { |
||||
mirror.Interval *= time.Hour |
||||
if mirror.Interval < setting.Mirror.MinInterval { |
||||
log.Info("Mirror interval less than Mirror.MinInterval, setting default interval: repo id %v", mirror.RepoID) |
||||
mirror.Interval = setting.Mirror.DefaultInterval |
||||
} |
||||
log.Debug("Mirror interval set to %v for repo id %v", mirror.Interval, mirror.RepoID) |
||||
_, err := sess.ID(mirror.ID).Cols("interval").Update(mirror) |
||||
if err != nil { |
||||
return fmt.Errorf("update mirror interval failed: %v", err) |
||||
} |
||||
} |
||||
|
||||
return sess.Commit() |
||||
} |
@ -1,76 +0,0 @@ |
||||
// Copyright 2017 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2017 Gitea. 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" |
||||
"path/filepath" |
||||
"strings" |
||||
|
||||
"code.gitea.io/gitea/modules/git" |
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addRepoSize(x *xorm.Engine) (err error) { |
||||
log.Info("This migration could take up to minutes, please be patient.") |
||||
type Repository struct { |
||||
ID int64 |
||||
OwnerID int64 |
||||
Name string |
||||
Size int64 |
||||
} |
||||
type User struct { |
||||
ID int64 |
||||
Name string |
||||
} |
||||
if err = x.Sync2(new(Repository)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
// For the sake of SQLite3, we can't use x.Iterate here.
|
||||
offset := 0 |
||||
for { |
||||
repos := make([]*Repository, 0, 10) |
||||
if err = x.Table("repository").Asc("id").Limit(10, offset).Find(&repos); err != nil { |
||||
return fmt.Errorf("select repos [offset: %d]: %v", offset, err) |
||||
} |
||||
log.Trace("Select [offset: %d, repos: %d]", offset, len(repos)) |
||||
if len(repos) == 0 { |
||||
break |
||||
} |
||||
offset += 10 |
||||
|
||||
for _, repo := range repos { |
||||
if repo.Name == "." || repo.Name == ".." { |
||||
continue |
||||
} |
||||
|
||||
user := new(User) |
||||
has, err := x.Where("id = ?", repo.OwnerID).Get(user) |
||||
if err != nil { |
||||
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err) |
||||
} else if !has { |
||||
continue |
||||
} |
||||
|
||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git" |
||||
countObject, err := git.CountObjects(repoPath) |
||||
if err != nil { |
||||
log.Warn("CountObjects: %v", err) |
||||
continue |
||||
} |
||||
|
||||
repo.Size = countObject.Size + countObject.SizePack |
||||
if _, err = x.ID(repo.ID).Cols("size").Update(repo); err != nil { |
||||
return fmt.Errorf("update size: %v", err) |
||||
} |
||||
} |
||||
} |
||||
return nil |
||||
} |
@ -1,34 +0,0 @@ |
||||
// Copyright 2017 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 ( |
||||
"fmt" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
// CommitStatus see models/status.go
|
||||
type CommitStatus struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Index int64 `xorm:"INDEX UNIQUE(repo_sha_index)"` |
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_sha_index)"` |
||||
State string `xorm:"VARCHAR(7) NOT NULL"` |
||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"` |
||||
TargetURL string `xorm:"TEXT"` |
||||
Description string `xorm:"TEXT"` |
||||
Context string `xorm:"TEXT"` |
||||
CreatorID int64 `xorm:"INDEX"` |
||||
|
||||
CreatedUnix int64 `xorm:"INDEX"` |
||||
UpdatedUnix int64 `xorm:"INDEX"` |
||||
} |
||||
|
||||
func addCommitStatus(x *xorm.Engine) error { |
||||
if err := x.Sync2(new(CommitStatus)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,38 +0,0 @@ |
||||
// Copyright 2017 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 ( |
||||
"fmt" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addExternalLoginUserPK(x *xorm.Engine) error { |
||||
// ExternalLoginUser see models/external_login_user.go
|
||||
type ExternalLoginUser struct { |
||||
ExternalID string `xorm:"pk NOT NULL"` |
||||
UserID int64 `xorm:"INDEX NOT NULL"` |
||||
LoginSourceID int64 `xorm:"pk NOT NULL"` |
||||
} |
||||
|
||||
extlogins := make([]*ExternalLoginUser, 0, 6) |
||||
if err := x.Find(&extlogins); err != nil { |
||||
return fmt.Errorf("Find: %v", err) |
||||
} |
||||
|
||||
if err := x.DropTables(new(ExternalLoginUser)); err != nil { |
||||
return fmt.Errorf("DropTables: %v", err) |
||||
} |
||||
|
||||
if err := x.Sync2(new(ExternalLoginUser)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
if _, err := x.Insert(extlogins); err != nil { |
||||
return fmt.Errorf("Insert: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,35 +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" |
||||
"time" |
||||
|
||||
"xorm.io/core" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLoginSourceSyncEnabledColumn(x *xorm.Engine) error { |
||||
// LoginSource see models/login_source.go
|
||||
type LoginSource struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Type int |
||||
Name string `xorm:"UNIQUE"` |
||||
IsActived bool `xorm:"INDEX NOT NULL DEFAULT false"` |
||||
IsSyncEnabled bool `xorm:"INDEX NOT NULL DEFAULT false"` |
||||
Cfg core.Conversion `xorm:"TEXT"` |
||||
|
||||
Created time.Time `xorm:"-"` |
||||
CreatedUnix int64 `xorm:"INDEX"` |
||||
Updated time.Time `xorm:"-"` |
||||
UpdatedUnix int64 `xorm:"INDEX"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(LoginSource)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,23 +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 "xorm.io/xorm" |
||||
|
||||
func addUnitsToRepoTeam(x *xorm.Engine) error { |
||||
type Team struct { |
||||
UnitTypes []int `xorm:"json"` |
||||
} |
||||
|
||||
err := x.Sync(new(Team)) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
_, err = x.Update(&Team{ |
||||
UnitTypes: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}, |
||||
}) |
||||
return err |
||||
} |
@ -1,32 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeActionColumns(x *xorm.Engine) error { |
||||
switch { |
||||
case setting.Database.UseSQLite3: |
||||
log.Warn("Unable to drop columns in SQLite") |
||||
case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL: |
||||
if _, err := x.Exec("ALTER TABLE action DROP COLUMN act_user_name"); err != nil { |
||||
return fmt.Errorf("DROP COLUMN act_user_name: %v", err) |
||||
} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_user_name"); err != nil { |
||||
return fmt.Errorf("DROP COLUMN repo_user_name: %v", err) |
||||
} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_name"); err != nil { |
||||
return fmt.Errorf("DROP COLUMN repo_name: %v", err) |
||||
} |
||||
default: |
||||
log.Fatal("Unrecognized DB") |
||||
} |
||||
return nil |
||||
} |
@ -1,25 +0,0 @@ |
||||
// Copyright 2017 Gitea. 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 ( |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
// Team see models/team.go
|
||||
type Team struct { |
||||
UnitTypes []int `xorm:"json"` |
||||
} |
||||
|
||||
const ownerAccessMode = 4 |
||||
|
||||
var allUnitTypes = []int{1, 2, 3, 4, 5, 6, 7, 8, 9} |
||||
|
||||
func giveAllUnitsToOwnerTeams(x *xorm.Engine) error { |
||||
_, err := x.Cols("unit_types"). |
||||
Where("authorize = ?", ownerAccessMode). |
||||
Update(&Team{UnitTypes: allUnitTypes}) |
||||
return err |
||||
} |
@ -1,25 +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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addCommentIDToAction(x *xorm.Engine) error { |
||||
// Action see models/action.go
|
||||
type Action struct { |
||||
CommentID int64 `xorm:"INDEX"` |
||||
IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(Action)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,16 +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 ( |
||||
"code.gitea.io/gitea/modules/graceful" |
||||
repo_module "code.gitea.io/gitea/modules/repository" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func regenerateGitHooks36(x *xorm.Engine) (err error) { |
||||
return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) |
||||
} |
@ -1,35 +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 ( |
||||
"html" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func unescapeUserFullNames(x *xorm.Engine) (err error) { |
||||
type User struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
FullName string |
||||
} |
||||
|
||||
const batchSize = 100 |
||||
for start := 0; ; start += batchSize { |
||||
users := make([]*User, 0, batchSize) |
||||
if err := x.Limit(batchSize, start).Find(&users); err != nil { |
||||
return err |
||||
} |
||||
if len(users) == 0 { |
||||
return nil |
||||
} |
||||
for _, user := range users { |
||||
user.FullName = html.UnescapeString(user.FullName) |
||||
if _, err := x.ID(user.ID).Cols("full_name").Update(user); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,75 +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 ( |
||||
"time" |
||||
|
||||
"code.gitea.io/gitea/models" |
||||
|
||||
"xorm.io/core" |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeCommitsUnitType(x *xorm.Engine) (err 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 core.Conversion `xorm:"TEXT"` |
||||
CreatedUnix int64 `xorm:"INDEX CREATED"` |
||||
Created time.Time `xorm:"-"` |
||||
} |
||||
|
||||
type Team struct { |
||||
ID int64 |
||||
UnitTypes []int `xorm:"json"` |
||||
} |
||||
|
||||
// Update team unit types
|
||||
const batchSize = 100 |
||||
for start := 0; ; start += batchSize { |
||||
teams := make([]*Team, 0, batchSize) |
||||
if err := x.Limit(batchSize, start).Find(&teams); err != nil { |
||||
return err |
||||
} |
||||
if len(teams) == 0 { |
||||
break |
||||
} |
||||
for _, team := range teams { |
||||
ut := make([]int, 0, len(team.UnitTypes)) |
||||
for _, u := range team.UnitTypes { |
||||
if u < V16UnitTypeCommits { |
||||
ut = append(ut, u) |
||||
} else if u > V16UnitTypeSettings { |
||||
ut = append(ut, u-2) |
||||
} else if u > V16UnitTypeCommits && u != V16UnitTypeSettings { |
||||
ut = append(ut, u-1) |
||||
} |
||||
} |
||||
team.UnitTypes = ut |
||||
if _, err := x.ID(team.ID).Cols("unit_types").Update(team); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Delete commits and settings unit types
|
||||
if _, err = x.In("`type`", []models.UnitType{V16UnitTypeCommits, V16UnitTypeSettings}).Delete(new(RepoUnit)); err != nil { |
||||
return err |
||||
} |
||||
// Fix renumber unit types that where in enumeration after settings unit type
|
||||
if _, err = x.Where("`type` > ?", V16UnitTypeSettings).Decr("type").Decr("index").Update(new(RepoUnit)); err != nil { |
||||
return err |
||||
} |
||||
// Fix renumber unit types that where in enumeration after commits unit type
|
||||
if _, err = x.Where("`type` > ?", V16UnitTypeCommits).Decr("type").Decr("index").Update(new(RepoUnit)); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,59 +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/gitea/models" |
||||
"code.gitea.io/gitea/modules/git" |
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/repository" |
||||
|
||||
"xorm.io/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 := models.RepositoryListDefaultPageSize |
||||
for { |
||||
repos := make([]*models.Repository, 0, pageSize) |
||||
if err := x.Table("repository").Cols("id", "name", "owner_id").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 = repository.SyncReleasesWithTags(repo, gitRepo); err != nil { |
||||
log.Warn("SyncReleasesWithTags: %v", err) |
||||
} |
||||
gitRepo.Close() |
||||
} |
||||
if len(repos) < pageSize { |
||||
break |
||||
} |
||||
offset += pageSize |
||||
} |
||||
return nil |
||||
} |
@ -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" |
||||
|
||||
"xorm.io/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 |
||||
} |
@ -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" |
||||
|
||||
"xorm.io/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() |
||||
} |
@ -1,28 +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 ( |
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeIndexColumnFromRepoUnitTable(x *xorm.Engine) (err error) { |
||||
switch { |
||||
case setting.Database.UseSQLite3: |
||||
log.Warn("Unable to drop columns in SQLite") |
||||
case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL: |
||||
if _, err := x.Exec("ALTER TABLE repo_unit DROP COLUMN `index`"); err != nil { |
||||
// Ignoring this error in case we run this migration second time (after migration reordering)
|
||||
log.Warn("DROP COLUMN index: %v", err) |
||||
} |
||||
default: |
||||
log.Fatal("Unrecognized DB") |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,36 +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 ( |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeOrganizationWatchRepo(x *xorm.Engine) error { |
||||
// UserType defines the user type
|
||||
type UserType int |
||||
|
||||
const ( |
||||
// UserTypeIndividual defines an individual user
|
||||
UserTypeIndividual UserType = iota // Historic reason to make it starts at 0.
|
||||
|
||||
// UserTypeOrganization defines an organization
|
||||
UserTypeOrganization |
||||
) |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
if _, err := sess.Exec("DELETE FROM `watch` WHERE `user_id` IN (SELECT `id` FROM `user` WHERE `type` = ?)", UserTypeOrganization); err != nil { |
||||
return err |
||||
} |
||||
if _, err := sess.Exec("UPDATE `repository` SET num_watches = (SELECT count(*) FROM watch WHERE `repository`.`id` = watch.repo_id)"); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return sess.Commit() |
||||
} |
@ -1,29 +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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addDeletedBranch(x *xorm.Engine) (err error) { |
||||
// DeletedBranch contains the deleted branch information
|
||||
type DeletedBranch struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` |
||||
Name string `xorm:"UNIQUE(s) NOT NULL"` |
||||
Commit string `xorm:"UNIQUE(s) NOT NULL"` |
||||
DeletedByID int64 `xorm:"INDEX NOT NULL"` |
||||
DeletedUnix int64 `xorm:"INDEX"` |
||||
} |
||||
|
||||
if err = x.Sync2(new(DeletedBranch)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,25 +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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addRepoIndexerStatus(x *xorm.Engine) error { |
||||
// RepoIndexerStatus see models/repo_indexer.go
|
||||
type RepoIndexerStatus struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"INDEX NOT NULL"` |
||||
CommitSha string `xorm:"VARCHAR(40)"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(RepoIndexerStatus)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,73 +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" |
||||
"time" |
||||
|
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/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 |
||||
} |
@ -1,55 +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 ( |
||||
"time" |
||||
|
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/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.Database.UseSQLite3: |
||||
log.Warn("Unable to drop columns in SQLite") |
||||
case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL: |
||||
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 (skipping): %v", err) |
||||
} |
||||
default: |
||||
log.Fatal("Unrecognized DB") |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,42 +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 ( |
||||
"code.gitea.io/gitea/models" |
||||
"code.gitea.io/gitea/modules/log" |
||||
|
||||
"xorm.io/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 (skipping): %v", err) |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,31 +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" |
||||
"time" |
||||
|
||||
"code.gitea.io/gitea/models" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLFSLock(x *xorm.Engine) error { |
||||
// LFSLock see models/lfs_lock.go
|
||||
type LFSLock struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"INDEX NOT NULL"` |
||||
Owner *models.User `xorm:"-"` |
||||
OwnerID int64 `xorm:"INDEX NOT NULL"` |
||||
Path string `xorm:"TEXT"` |
||||
Created time.Time `xorm:"created"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(LFSLock)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,28 +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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addReactions(x *xorm.Engine) error { |
||||
// Reaction see models/issue_reaction.go
|
||||
type Reaction struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Type string `xorm:"INDEX UNIQUE(s) NOT NULL"` |
||||
IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` |
||||
CommentID int64 `xorm:"INDEX UNIQUE(s)"` |
||||
UserID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` |
||||
CreatedUnix int64 `xorm:"INDEX created"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(Reaction)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -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/gitea/modules/timeutil" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addPullRequestOptions(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 timeutil.TimeStamp `xorm:"INDEX CREATED"` |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
//Updating existing issue units
|
||||
units := make([]*RepoUnit, 0, 100) |
||||
if err := sess.Where("`type` = ?", V16UnitTypePRs).Find(&units); 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["IgnoreWhitespaceConflicts"]; !ok { |
||||
unit.Config["IgnoreWhitespaceConflicts"] = false |
||||
} |
||||
if _, ok := unit.Config["AllowMerge"]; !ok { |
||||
unit.Config["AllowMerge"] = true |
||||
} |
||||
if _, ok := unit.Config["AllowRebase"]; !ok { |
||||
unit.Config["AllowRebase"] = true |
||||
} |
||||
if _, ok := unit.Config["AllowSquash"]; !ok { |
||||
unit.Config["AllowSquash"] = true |
||||
} |
||||
if _, err := sess.ID(unit.ID).Cols("config").Update(unit); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
return sess.Commit() |
||||
} |
@ -1,24 +0,0 @@ |
||||
// Copyright 2018 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/gitea/models" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addModeToDeploKeys(x *xorm.Engine) error { |
||||
type DeployKey struct { |
||||
Mode models.AccessMode `xorm:"NOT NULL DEFAULT 1"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(DeployKey)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,23 +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 ( |
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) { |
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
if err = sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
if err := dropTableColumns(sess, "org_user", "is_owner", "num_teams"); err != nil { |
||||
return err |
||||
} |
||||
return sess.Commit() |
||||
} |
@ -1,30 +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/gitea/modules/timeutil" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addIssueClosedTime(x *xorm.Engine) error { |
||||
// Issue see models/issue.go
|
||||
type Issue struct { |
||||
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(Issue)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
if _, err := x.Exec("UPDATE `issue` SET `closed_unix` = `updated_unix` WHERE `is_closed` = ?", true); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,22 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLabelsDescriptions(x *xorm.Engine) error { |
||||
type Label struct { |
||||
Description string |
||||
} |
||||
|
||||
if err := x.Sync2(new(Label)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,24 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addProtectedBranchMergeWhitelist(x *xorm.Engine) error { |
||||
type ProtectedBranch struct { |
||||
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"` |
||||
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"` |
||||
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(ProtectedBranch)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,22 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addFsckEnabledToRepo(x *xorm.Engine) error { |
||||
type Repository struct { |
||||
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(Repository)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,45 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
"os" |
||||
"path" |
||||
|
||||
"code.gitea.io/gitea/modules/log" |
||||
"code.gitea.io/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addSizeToAttachment(x *xorm.Engine) error { |
||||
type Attachment struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
UUID string `xorm:"uuid UNIQUE"` |
||||
Size int64 `xorm:"DEFAULT 0"` |
||||
} |
||||
if err := x.Sync2(new(Attachment)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
attachments := make([]Attachment, 0, 100) |
||||
if err := x.Find(&attachments); err != nil { |
||||
return fmt.Errorf("query attachments: %v", err) |
||||
} |
||||
for _, attach := range attachments { |
||||
localPath := path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID) |
||||
fi, err := os.Stat(localPath) |
||||
if err != nil { |
||||
log.Error("calculate file size of attachment[UUID: %s]: %v", attach.UUID, err) |
||||
continue |
||||
} |
||||
attach.Size = fi.Size() |
||||
if _, err := x.ID(attach.ID).Cols("size").Update(attach); err != nil { |
||||
return fmt.Errorf("update size column: %v", err) |
||||
} |
||||
} |
||||
return nil |
||||
} |
@ -1,22 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLastUsedPasscodeTOTP(x *xorm.Engine) error { |
||||
type TwoFactor struct { |
||||
LastUsedPasscode string `xorm:"VARCHAR(10)"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(TwoFactor)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,23 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLanguageSetting(x *xorm.Engine) error { |
||||
type User struct { |
||||
Language string `xorm:"VARCHAR(5)"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(User)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,138 +0,0 @@ |
||||
// Copyright 2018 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/modules/timeutil" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addMultipleAssignees(x *xorm.Engine) error { |
||||
|
||||
// Redeclare issue struct
|
||||
type Issue struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"INDEX UNIQUE(repo_index)"` |
||||
Index int64 `xorm:"UNIQUE(repo_index)"` // Index in one repository.
|
||||
PosterID int64 `xorm:"INDEX"` |
||||
Title string `xorm:"name"` |
||||
Content string `xorm:"TEXT"` |
||||
MilestoneID int64 `xorm:"INDEX"` |
||||
Priority int |
||||
AssigneeID int64 `xorm:"INDEX"` |
||||
IsClosed bool `xorm:"INDEX"` |
||||
IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not.
|
||||
NumComments int |
||||
|
||||
DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"` |
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |
||||
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"` |
||||
} |
||||
|
||||
// Updated the comment table
|
||||
type Comment struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Type int |
||||
PosterID int64 `xorm:"INDEX"` |
||||
IssueID int64 `xorm:"INDEX"` |
||||
LabelID int64 |
||||
OldMilestoneID int64 |
||||
MilestoneID int64 |
||||
OldAssigneeID int64 |
||||
AssigneeID int64 |
||||
RemovedAssignee bool |
||||
OldTitle string |
||||
NewTitle string |
||||
|
||||
CommitID int64 |
||||
Line int64 |
||||
Content string `xorm:"TEXT"` |
||||
RenderedContent string `xorm:"-"` |
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |
||||
|
||||
// Reference issue in commit message
|
||||
CommitSHA string `xorm:"VARCHAR(40)"` |
||||
} |
||||
|
||||
// Create the table
|
||||
type IssueAssignees struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
AssigneeID int64 `xorm:"INDEX"` |
||||
IssueID int64 `xorm:"INDEX"` |
||||
} |
||||
|
||||
if err := x.Sync2(IssueAssignees{}); err != nil { |
||||
return err |
||||
} |
||||
|
||||
if err := x.Sync2(Comment{}); err != nil { |
||||
return err |
||||
} |
||||
|
||||
// Range over all issues and insert a new entry for each issue/assignee
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
allIssues := []*Issue{} |
||||
if err := sess.Find(&allIssues); err != nil { |
||||
return err |
||||
} |
||||
|
||||
for _, issue := range allIssues { |
||||
if issue.AssigneeID != 0 { |
||||
_, err := sess.Insert(IssueAssignees{IssueID: issue.ID, AssigneeID: issue.AssigneeID}) |
||||
if err != nil { |
||||
sess.Rollback() |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Migrate comments
|
||||
// First update everything to not have nulls in db
|
||||
if _, err := sess.Where("type = ?", 9).Cols("removed_assignee").Update(Comment{RemovedAssignee: false}); err != nil { |
||||
return err |
||||
} |
||||
|
||||
allAssignementComments := []*Comment{} |
||||
if err := sess.Where("type = ?", 9).Find(&allAssignementComments); err != nil { |
||||
return err |
||||
} |
||||
|
||||
for _, comment := range allAssignementComments { |
||||
// Everytime where OldAssigneeID is > 0, the assignement was removed.
|
||||
if comment.OldAssigneeID > 0 { |
||||
_, err := sess.ID(comment.ID).Update(Comment{RemovedAssignee: true}) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Commit and begin new transaction for dropping columns
|
||||
if err := sess.Commit(); err != nil { |
||||
return err |
||||
} |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
if err := dropTableColumns(sess, "issue", "assignee_id"); err != nil { |
||||
return err |
||||
} |
||||
|
||||
if err := dropTableColumns(sess, "issue_user", "is_assigned"); err != nil { |
||||
return err |
||||
} |
||||
return sess.Commit() |
||||
} |
@ -1,20 +0,0 @@ |
||||
package migrations |
||||
|
||||
import ( |
||||
"code.gitea.io/gitea/modules/timeutil" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addU2FReg(x *xorm.Engine) error { |
||||
type U2FRegistration struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Name string |
||||
UserID int64 `xorm:"INDEX"` |
||||
Raw []byte |
||||
Counter uint32 |
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |
||||
} |
||||
return x.Sync2(&U2FRegistration{}) |
||||
} |
@ -1,22 +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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func addLoginSourceIDToPublicKeyTable(x *xorm.Engine) error { |
||||
type PublicKey struct { |
||||
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(PublicKey)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
return nil |
||||
} |
@ -1,167 +0,0 @@ |
||||
// Copyright 2018 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/gitea/modules/setting" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func removeStaleWatches(x *xorm.Engine) error { |
||||
type Watch struct { |
||||
ID int64 |
||||
UserID int64 |
||||
RepoID int64 |
||||
} |
||||
|
||||
type IssueWatch struct { |
||||
ID int64 |
||||
UserID int64 |
||||
RepoID int64 |
||||
IsWatching bool |
||||
} |
||||
|
||||
type Repository struct { |
||||
ID int64 |
||||
IsPrivate bool |
||||
OwnerID int64 |
||||
} |
||||
|
||||
type Access struct { |
||||
UserID int64 |
||||
RepoID int64 |
||||
Mode int |
||||
} |
||||
|
||||
const ( |
||||
// AccessModeNone no access
|
||||
AccessModeNone int = iota // 0
|
||||
// AccessModeRead read access
|
||||
AccessModeRead // 1
|
||||
) |
||||
|
||||
accessLevel := func(e *xorm.Session, userID int64, repo *Repository) (int, error) { |
||||
mode := AccessModeNone |
||||
if !repo.IsPrivate { |
||||
mode = AccessModeRead |
||||
} |
||||
|
||||
if userID == 0 { |
||||
return mode, nil |
||||
} |
||||
|
||||
if userID == repo.OwnerID { |
||||
return 4, nil |
||||
} |
||||
|
||||
a := &Access{UserID: userID, RepoID: repo.ID} |
||||
if has, err := e.Get(a); !has || err != nil { |
||||
return mode, err |
||||
} |
||||
return a.Mode, nil |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
var issueWatch IssueWatch |
||||
if exist, err := sess.IsTableExist(&issueWatch); err != nil { |
||||
return fmt.Errorf("IsExist IssueWatch: %v", err) |
||||
} else if !exist { |
||||
return nil |
||||
} |
||||
|
||||
repoCache := make(map[int64]*Repository) |
||||
err := sess.BufferSize(setting.Database.IterateBufferSize).Iterate(new(Watch), |
||||
func(idx int, bean interface{}) error { |
||||
watch := bean.(*Watch) |
||||
|
||||
repo := repoCache[watch.RepoID] |
||||
if repo == nil { |
||||
repo = &Repository{ |
||||
ID: watch.RepoID, |
||||
} |
||||
if _, err := sess.Get(repo); err != nil { |
||||
return err |
||||
} |
||||
repoCache[watch.RepoID] = repo |
||||
} |
||||
|
||||
// Remove watches from now unaccessible repositories
|
||||
mode, err := accessLevel(sess, watch.UserID, repo) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
has := AccessModeRead <= mode |
||||
if has { |
||||
return nil |
||||
} |
||||
|
||||
if _, err = sess.Delete(&Watch{0, watch.UserID, repo.ID}); err != nil { |
||||
return err |
||||
} |
||||
_, err = sess.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repo.ID) |
||||
|
||||
return err |
||||
}) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
repoCache = make(map[int64]*Repository) |
||||
err = sess.BufferSize(setting.Database.IterateBufferSize). |
||||
Distinct("issue_watch.user_id", "issue.repo_id"). |
||||
Join("INNER", "issue", "issue_watch.issue_id = issue.id"). |
||||
Where("issue_watch.is_watching = ?", true). |
||||
Iterate(new(IssueWatch), |
||||
func(idx int, bean interface{}) error { |
||||
watch := bean.(*IssueWatch) |
||||
|
||||
repo := repoCache[watch.RepoID] |
||||
if repo == nil { |
||||
repo = &Repository{ |
||||
ID: watch.RepoID, |
||||
} |
||||
if _, err := sess.Get(repo); err != nil { |
||||
return err |
||||
} |
||||
repoCache[watch.RepoID] = repo |
||||
} |
||||
|
||||
// Remove issue watches from now unaccssible repositories
|
||||
mode, err := accessLevel(sess, watch.UserID, repo) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
has := AccessModeRead <= mode |
||||
if has { |
||||
return nil |
||||
} |
||||
|
||||
iw := &IssueWatch{ |
||||
IsWatching: false, |
||||
} |
||||
|
||||
_, err = sess. |
||||
Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", watch.RepoID). |
||||
Cols("is_watching", "updated_unix"). |
||||
Where("`issue_watch`.user_id = ?", watch.UserID). |
||||
Update(iw) |
||||
|
||||
return err |
||||
|
||||
}) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
return sess.Commit() |
||||
} |
@ -1,210 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
"regexp" |
||||
"strings" |
||||
|
||||
"code.gitea.io/gitea/modules/log" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) |
||||
|
||||
func validateTopic(topic string) bool { |
||||
return len(topic) <= 35 && topicPattern.MatchString(topic) |
||||
} |
||||
|
||||
func reformatAndRemoveIncorrectTopics(x *xorm.Engine) (err error) { |
||||
log.Info("This migration could take up to minutes, please be patient.") |
||||
|
||||
type Topic struct { |
||||
ID int64 |
||||
Name string `xorm:"UNIQUE VARCHAR(25)"` |
||||
RepoCount int |
||||
CreatedUnix int64 `xorm:"INDEX created"` |
||||
UpdatedUnix int64 `xorm:"INDEX updated"` |
||||
} |
||||
|
||||
type RepoTopic struct { |
||||
RepoID int64 `xorm:"UNIQUE(s)"` |
||||
TopicID int64 `xorm:"UNIQUE(s)"` |
||||
} |
||||
|
||||
type Repository struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
Topics []string `xorm:"TEXT JSON"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(Topic)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
if err := x.Sync2(new(RepoTopic)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
const batchSize = 100 |
||||
touchedRepo := make(map[int64]struct{}) |
||||
delTopicIDs := make([]int64, 0, batchSize) |
||||
|
||||
log.Info("Validating existed topics...") |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
for start := 0; ; start += batchSize { |
||||
topics := make([]*Topic, 0, batchSize) |
||||
if err := x.Cols("id", "name").Asc("id").Limit(batchSize, start).Find(&topics); err != nil { |
||||
return err |
||||
} |
||||
if len(topics) == 0 { |
||||
break |
||||
} |
||||
for _, topic := range topics { |
||||
if validateTopic(topic.Name) { |
||||
continue |
||||
} |
||||
log.Info("Incorrect topic: id = %v, name = %q", topic.ID, topic.Name) |
||||
|
||||
topic.Name = strings.Replace(strings.TrimSpace(strings.ToLower(topic.Name)), " ", "-", -1) |
||||
|
||||
ids := make([]int64, 0, 30) |
||||
if err := sess.Table("repo_topic").Cols("repo_id"). |
||||
Where("topic_id = ?", topic.ID).Find(&ids); err != nil { |
||||
return err |
||||
} |
||||
log.Info("Touched repo ids: %v", ids) |
||||
for _, id := range ids { |
||||
touchedRepo[id] = struct{}{} |
||||
} |
||||
|
||||
if validateTopic(topic.Name) { |
||||
unifiedTopic := Topic{Name: topic.Name} |
||||
exists, err := sess.Cols("id", "name").Get(&unifiedTopic) |
||||
log.Info("Exists topic with the name %q? %v, id = %v", topic.Name, exists, unifiedTopic.ID) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if exists { |
||||
log.Info("Updating repo_topic rows with topic_id = %v to topic_id = %v", topic.ID, unifiedTopic.ID) |
||||
if _, err := sess.Where("topic_id = ? AND repo_id NOT IN "+ |
||||
"(SELECT rt1.repo_id FROM repo_topic rt1 INNER JOIN repo_topic rt2 "+ |
||||
"ON rt1.repo_id = rt2.repo_id WHERE rt1.topic_id = ? AND rt2.topic_id = ?)", |
||||
topic.ID, topic.ID, unifiedTopic.ID).Update(&RepoTopic{TopicID: unifiedTopic.ID}); err != nil { |
||||
return err |
||||
} |
||||
log.Info("Updating topic `repo_count` field") |
||||
if _, err := sess.Exec( |
||||
"UPDATE topic SET repo_count = (SELECT COUNT(*) FROM repo_topic WHERE topic_id = ? GROUP BY topic_id) WHERE id = ?", |
||||
unifiedTopic.ID, unifiedTopic.ID); err != nil { |
||||
return err |
||||
} |
||||
} else { |
||||
log.Info("Updating topic: id = %v, name = %q", topic.ID, topic.Name) |
||||
if _, err := sess.Table("topic").ID(topic.ID). |
||||
Update(&Topic{Name: topic.Name}); err != nil { |
||||
return err |
||||
} |
||||
continue |
||||
} |
||||
} |
||||
delTopicIDs = append(delTopicIDs, topic.ID) |
||||
} |
||||
} |
||||
if err := sess.Commit(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
sess.Init() |
||||
|
||||
log.Info("Deleting incorrect topics...") |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
log.Info("Deleting 'repo_topic' rows for topics with ids = %v", delTopicIDs) |
||||
if _, err := sess.In("topic_id", delTopicIDs).Delete(&RepoTopic{}); err != nil { |
||||
return err |
||||
} |
||||
log.Info("Deleting topics with id = %v", delTopicIDs) |
||||
if _, err := sess.In("id", delTopicIDs).Delete(&Topic{}); err != nil { |
||||
return err |
||||
} |
||||
if err := sess.Commit(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
delRepoTopics := make([]*RepoTopic, 0, batchSize) |
||||
|
||||
log.Info("Checking the number of topics in the repositories...") |
||||
for start := 0; ; start += batchSize { |
||||
repoTopics := make([]*RepoTopic, 0, batchSize) |
||||
if err := x.Cols("repo_id").Asc("repo_id").Limit(batchSize, start). |
||||
GroupBy("repo_id").Having("COUNT(*) > 25").Find(&repoTopics); err != nil { |
||||
return err |
||||
} |
||||
if len(repoTopics) == 0 { |
||||
break |
||||
} |
||||
|
||||
log.Info("Number of repositories with more than 25 topics: %v", len(repoTopics)) |
||||
for _, repoTopic := range repoTopics { |
||||
touchedRepo[repoTopic.RepoID] = struct{}{} |
||||
|
||||
tmpRepoTopics := make([]*RepoTopic, 0, 30) |
||||
if err := x.Where("repo_id = ?", repoTopic.RepoID).Find(&tmpRepoTopics); err != nil { |
||||
return err |
||||
} |
||||
|
||||
log.Info("Repository with id = %v has %v topics", repoTopic.RepoID, len(tmpRepoTopics)) |
||||
|
||||
for i := len(tmpRepoTopics) - 1; i > 24; i-- { |
||||
delRepoTopics = append(delRepoTopics, tmpRepoTopics[i]) |
||||
} |
||||
} |
||||
} |
||||
|
||||
sess.Init() |
||||
|
||||
log.Info("Deleting superfluous topics for repositories (more than 25 topics)...") |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
for _, repoTopic := range delRepoTopics { |
||||
log.Info("Deleting 'repo_topic' rows for 'repository' with id = %v. Topic id = %v", |
||||
repoTopic.RepoID, repoTopic.TopicID) |
||||
|
||||
if _, err := sess.Where("repo_id = ? AND topic_id = ?", repoTopic.RepoID, |
||||
repoTopic.TopicID).Delete(&RepoTopic{}); err != nil { |
||||
return err |
||||
} |
||||
if _, err := sess.Exec( |
||||
"UPDATE topic SET repo_count = (SELECT repo_count FROM topic WHERE id = ?) - 1 WHERE id = ?", |
||||
repoTopic.TopicID, repoTopic.TopicID); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
|
||||
log.Info("Updating repositories 'topics' fields...") |
||||
for repoID := range touchedRepo { |
||||
topicNames := make([]string, 0, 30) |
||||
if err := sess.Table("topic").Cols("name"). |
||||
Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id"). |
||||
Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil { |
||||
return err |
||||
} |
||||
log.Info("Updating 'topics' field for repository with id = %v", repoID) |
||||
if _, err := sess.ID(repoID).Cols("topics"). |
||||
Update(&Repository{Topics: topicNames}); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
|
||||
return sess.Commit() |
||||
} |
@ -1,88 +0,0 @@ |
||||
// Copyright 2018 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" |
||||
|
||||
"xorm.io/xorm" |
||||
) |
||||
|
||||
func moveTeamUnitsToTeamUnitTable(x *xorm.Engine) error { |
||||
// Team see models/team.go
|
||||
type Team struct { |
||||
ID int64 |
||||
OrgID int64 |
||||
UnitTypes []int `xorm:"json"` |
||||
} |
||||
|
||||
// TeamUnit see models/org_team.go
|
||||
type TeamUnit struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
OrgID int64 `xorm:"INDEX"` |
||||
TeamID int64 `xorm:"UNIQUE(s)"` |
||||
Type int `xorm:"UNIQUE(s)"` |
||||
} |
||||
|
||||
if err := x.Sync2(new(TeamUnit)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
sess := x.NewSession() |
||||
defer sess.Close() |
||||
|
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
// Update team unit types
|
||||
const batchSize = 100 |
||||
for start := 0; ; start += batchSize { |
||||
teams := make([]*Team, 0, batchSize) |
||||
if err := x.Limit(batchSize, start).Find(&teams); err != nil { |
||||
return err |
||||
} |
||||
if len(teams) == 0 { |
||||
break |
||||
} |
||||
|
||||
for _, team := range teams { |
||||
var unitTypes []int |
||||
if len(team.UnitTypes) == 0 { |
||||
unitTypes = allUnitTypes |
||||
} else { |
||||
unitTypes = team.UnitTypes |
||||
} |
||||
|
||||
// insert units for team
|
||||
var units = make([]TeamUnit, 0, len(unitTypes)) |
||||
for _, tp := range unitTypes { |
||||
units = append(units, TeamUnit{ |
||||
OrgID: team.OrgID, |
||||
TeamID: team.ID, |
||||
Type: tp, |
||||
}) |
||||
} |
||||
|
||||
if _, err := sess.Insert(&units); err != nil { |
||||
return fmt.Errorf("Insert team units: %v", err) |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
// Commit and begin new transaction for dropping columns
|
||||
if err := sess.Commit(); err != nil { |
||||
return err |
||||
} |
||||
if err := sess.Begin(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
if err := dropTableColumns(sess, "team", "unit_types"); err != nil { |
||||
return err |
||||
} |
||||
return sess.Commit() |
||||
} |
Loading…
Reference in new issue