mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 01:40:36 +00:00
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>
This commit is contained in:
parent
b3d8e2d4f7
commit
d816f7018b
63 changed files with 53 additions and 3443 deletions
|
@ -70,9 +70,14 @@ There are some basic steps to follow. On a Linux system run as the Gogs user:
|
||||||
|
|
||||||
## Upgrading to most recent `gitea` version
|
## Upgrading to most recent `gitea` version
|
||||||
|
|
||||||
After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgrade to the recent `gitea` version.
|
After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgrade `gitea` to a modern version
|
||||||
Simply download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea)
|
in a two steps process.
|
||||||
and replace the binary.
|
|
||||||
|
Upgrade to [`gitea 1.6.4`](https://dl.gitea.io/gitea/1.6.4/) first. Download the file matching
|
||||||
|
the destination platform from the [downloads page](https://dl.gitea.io/gitea/1.6.4/) and replace the binary.
|
||||||
|
Run Gitea at least once and check that everything works as expected.
|
||||||
|
|
||||||
|
Then repeat the procedure, but this time using the [lastest release](https://dl.gitea.io/gitea/{{< version >}}/).
|
||||||
|
|
||||||
## Upgrading from a more recent version of Gogs
|
## Upgrading from a more recent version of Gogs
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -6,28 +6,17 @@
|
||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
|
||||||
"github.com/unknwon/com"
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
const minDBVersion = 4
|
const minDBVersion = 70 // Gitea 1.5.3
|
||||||
|
|
||||||
// Migration describes on migration from lower version to high version
|
// Migration describes on migration from lower version to high version
|
||||||
type Migration interface {
|
type Migration interface {
|
||||||
|
@ -61,151 +50,31 @@ type Version struct {
|
||||||
Version int64
|
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.
|
// 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
|
// If you want to "retire" a migration, remove it from the top of the list and
|
||||||
// update minDBVersion accordingly
|
// update minDBVersion accordingly
|
||||||
var migrations = []Migration{
|
var migrations = []Migration{
|
||||||
// v0 -> v4: before 0.6.0 -> 0.7.33
|
|
||||||
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
|
|
||||||
NewMigration("trim action compare URL prefix", trimCommitActionAppURLPrefix), // V5 -> V6:v0.6.3
|
|
||||||
NewMigration("generate issue-label from issue", issueToIssueLabel), // V6 -> V7:v0.6.4
|
|
||||||
NewMigration("refactor attachment table", attachmentRefactor), // V7 -> V8:v0.6.4
|
|
||||||
NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16
|
|
||||||
NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo), // V9 -> V10:v0.6.20
|
|
||||||
NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5
|
|
||||||
NewMigration("convert date to unix timestamp", convertDateToUnix), // V11 -> V12:v0.9.2
|
|
||||||
NewMigration("convert LDAP UseSSL option to SecurityProtocol", ldapUseSSLToSecurityProtocol), // V12 -> V13:v0.9.37
|
|
||||||
|
|
||||||
// v13 -> v14:v0.9.87
|
// Gitea 1.5.3 ends at v70
|
||||||
NewMigration("set comment updated with created", setCommentUpdatedWithCreated),
|
|
||||||
// v14 -> v15
|
|
||||||
NewMigration("create user column diff view style", createUserColumnDiffViewStyle),
|
|
||||||
// v15 -> v16
|
|
||||||
NewMigration("create user column allow create organization", createAllowCreateOrganizationColumn),
|
|
||||||
// V16 -> v17
|
|
||||||
NewMigration("create repo unit table and add units for all repos", addUnitsToTables),
|
|
||||||
// v17 -> v18
|
|
||||||
NewMigration("set protect branches updated with created", setProtectedBranchUpdatedWithCreated),
|
|
||||||
// v18 -> v19
|
|
||||||
NewMigration("add external login user", addExternalLoginUser),
|
|
||||||
// v19 -> v20
|
|
||||||
NewMigration("generate and migrate Git hooks", generateAndMigrateGitHooks),
|
|
||||||
// v20 -> v21
|
|
||||||
NewMigration("use new avatar path name for security reason", useNewNameAvatars),
|
|
||||||
// v21 -> v22
|
|
||||||
NewMigration("rewrite authorized_keys file via new format", useNewPublickeyFormat),
|
|
||||||
// v22 -> v23
|
|
||||||
NewMigration("generate and migrate wiki Git hooks", generateAndMigrateWikiGitHooks),
|
|
||||||
// v23 -> v24
|
|
||||||
NewMigration("add user openid table", addUserOpenID),
|
|
||||||
// v24 -> v25
|
|
||||||
NewMigration("change the key_id and primary_key_id type", changeGPGKeysColumns),
|
|
||||||
// v25 -> v26
|
|
||||||
NewMigration("add show field in user openid table", addUserOpenIDShow),
|
|
||||||
// v26 -> v27
|
|
||||||
NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains),
|
|
||||||
// v27 -> v28
|
|
||||||
NewMigration("change mirror interval from hours to time.Duration", convertIntervalToDuration),
|
|
||||||
// v28 -> v29
|
|
||||||
NewMigration("add field for repo size", addRepoSize),
|
|
||||||
// v29 -> v30
|
|
||||||
NewMigration("add commit status table", addCommitStatus),
|
|
||||||
// v30 -> 31
|
|
||||||
NewMigration("add primary key to external login user", addExternalLoginUserPK),
|
|
||||||
// v31 -> 32
|
|
||||||
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
|
|
||||||
// v32 -> v33
|
|
||||||
NewMigration("add units for team", addUnitsToRepoTeam),
|
|
||||||
// v33 -> v34
|
|
||||||
NewMigration("remove columns from action", removeActionColumns),
|
|
||||||
// v34 -> v35
|
|
||||||
NewMigration("give all units to owner teams", giveAllUnitsToOwnerTeams),
|
|
||||||
// v35 -> v36
|
|
||||||
NewMigration("adds comment to an action", addCommentIDToAction),
|
|
||||||
// v36 -> v37
|
|
||||||
NewMigration("regenerate git hooks", regenerateGitHooks36),
|
|
||||||
// v37 -> v38
|
|
||||||
NewMigration("unescape user full names", unescapeUserFullNames),
|
|
||||||
// v38 -> v39
|
|
||||||
NewMigration("remove commits and settings unit types", removeCommitsUnitType),
|
|
||||||
// v39 -> v40
|
|
||||||
NewMigration("add tags to releases and sync existing repositories", releaseAddColumnIsTagAndSyncTags),
|
|
||||||
// v40 -> v41
|
|
||||||
NewMigration("fix protected branch can push value to false", fixProtectedBranchCanPushValue),
|
|
||||||
// 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
|
|
||||||
NewMigration("remove organization watch repositories", removeOrganizationWatchRepo),
|
|
||||||
// v47 -> v48
|
|
||||||
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),
|
|
||||||
// v52 -> v53
|
|
||||||
NewMigration("add lfs lock table", addLFSLock),
|
|
||||||
// v53 -> v54
|
|
||||||
NewMigration("add reactions", addReactions),
|
|
||||||
// v54 -> v55
|
|
||||||
NewMigration("add pull request options", addPullRequestOptions),
|
|
||||||
// v55 -> v56
|
|
||||||
NewMigration("add writable deploy keys", addModeToDeploKeys),
|
|
||||||
// v56 -> v57
|
|
||||||
NewMigration("remove is_owner, num_teams columns from org_user", removeIsOwnerColumnFromOrgUser),
|
|
||||||
// v57 -> v58
|
|
||||||
NewMigration("add closed_unix column for issues", addIssueClosedTime),
|
|
||||||
// v58 -> v59
|
|
||||||
NewMigration("add label descriptions", addLabelsDescriptions),
|
|
||||||
// v59 -> v60
|
|
||||||
NewMigration("add merge whitelist for protected branches", addProtectedBranchMergeWhitelist),
|
|
||||||
// v60 -> v61
|
|
||||||
NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
|
|
||||||
// v61 -> v62
|
|
||||||
NewMigration("add size column for attachments", addSizeToAttachment),
|
|
||||||
// v62 -> v63
|
|
||||||
NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
|
|
||||||
// v63 -> v64
|
|
||||||
NewMigration("add language column for user setting", addLanguageSetting),
|
|
||||||
// v64 -> v65
|
|
||||||
NewMigration("add multiple assignees", addMultipleAssignees),
|
|
||||||
// v65 -> v66
|
|
||||||
NewMigration("add u2f", addU2FReg),
|
|
||||||
// v66 -> v67
|
|
||||||
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
|
|
||||||
// v67 -> v68
|
|
||||||
NewMigration("remove stale watches", removeStaleWatches),
|
|
||||||
// v68 -> V69
|
|
||||||
NewMigration("Reformat and remove incorrect topics", reformatAndRemoveIncorrectTopics),
|
|
||||||
// v69 -> v70
|
|
||||||
NewMigration("move team units to team_unit table", moveTeamUnitsToTeamUnitTable),
|
|
||||||
// v70 -> v71
|
// v70 -> v71
|
||||||
NewMigration("add issue_dependencies", addIssueDependencies),
|
NewMigration("add issue_dependencies", addIssueDependencies),
|
||||||
// v71 -> v72
|
// v71 -> v72
|
||||||
NewMigration("protect each scratch token", addScratchHash),
|
NewMigration("protect each scratch token", addScratchHash),
|
||||||
// v72 -> v73
|
// v72 -> v73
|
||||||
NewMigration("add review", addReview),
|
NewMigration("add review", addReview),
|
||||||
|
|
||||||
|
// Gitea 1.6.4 ends at v73
|
||||||
|
|
||||||
// v73 -> v74
|
// v73 -> v74
|
||||||
NewMigration("add must_change_password column for users table", addMustChangePassword),
|
NewMigration("add must_change_password column for users table", addMustChangePassword),
|
||||||
// v74 -> v75
|
// v74 -> v75
|
||||||
NewMigration("add approval whitelists to protected branches", addApprovalWhitelistsToProtectedBranches),
|
NewMigration("add approval whitelists to protected branches", addApprovalWhitelistsToProtectedBranches),
|
||||||
// v75 -> v76
|
// v75 -> v76
|
||||||
NewMigration("clear nonused data which not deleted when user was deleted", clearNonusedData),
|
NewMigration("clear nonused data which not deleted when user was deleted", clearNonusedData),
|
||||||
|
|
||||||
|
// Gitea 1.7.6 ends at v76
|
||||||
|
|
||||||
// v76 -> v77
|
// v76 -> v77
|
||||||
NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge),
|
NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge),
|
||||||
// v77 -> v78
|
// v77 -> v78
|
||||||
|
@ -218,6 +87,9 @@ var migrations = []Migration{
|
||||||
NewMigration("add is locked to issues", addIsLockedToIssues),
|
NewMigration("add is locked to issues", addIsLockedToIssues),
|
||||||
// v81 -> v82
|
// v81 -> v82
|
||||||
NewMigration("update U2F counter type", changeU2FCounterType),
|
NewMigration("update U2F counter type", changeU2FCounterType),
|
||||||
|
|
||||||
|
// Gitea 1.8.3 ends at v82
|
||||||
|
|
||||||
// v82 -> v83
|
// v82 -> v83
|
||||||
NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable),
|
NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable),
|
||||||
// v83 -> v84
|
// v83 -> v84
|
||||||
|
@ -230,6 +102,9 @@ var migrations = []Migration{
|
||||||
NewMigration("add http method to webhook", addHTTPMethodToWebhook),
|
NewMigration("add http method to webhook", addHTTPMethodToWebhook),
|
||||||
// v87 -> v88
|
// v87 -> v88
|
||||||
NewMigration("add avatar field to repository", addAvatarFieldToRepository),
|
NewMigration("add avatar field to repository", addAvatarFieldToRepository),
|
||||||
|
|
||||||
|
// Gitea 1.9.6 ends at v88
|
||||||
|
|
||||||
// v88 -> v89
|
// v88 -> v89
|
||||||
NewMigration("add commit status context field to commit_status", addCommitStatusContext),
|
NewMigration("add commit status context field to commit_status", addCommitStatusContext),
|
||||||
// v89 -> v90
|
// v89 -> v90
|
||||||
|
@ -252,6 +127,9 @@ var migrations = []Migration{
|
||||||
NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser),
|
NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser),
|
||||||
// v98 -> v99
|
// v98 -> v99
|
||||||
NewMigration("add original author name and id on migrated release", addOriginalAuthorOnMigratedReleases),
|
NewMigration("add original author name and id on migrated release", addOriginalAuthorOnMigratedReleases),
|
||||||
|
|
||||||
|
// Gitea 1.10.3 ends at v99
|
||||||
|
|
||||||
// v99 -> v100
|
// v99 -> v100
|
||||||
NewMigration("add task table and status column for repository table", addTaskTable),
|
NewMigration("add task table and status column for repository table", addTaskTable),
|
||||||
// v100 -> v101
|
// v100 -> v101
|
||||||
|
@ -334,7 +212,7 @@ func Migrate(x *xorm.Engine) error {
|
||||||
v := currentVersion.Version
|
v := currentVersion.Version
|
||||||
if minDBVersion > v {
|
if minDBVersion > v {
|
||||||
log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
|
log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
|
||||||
Please try to upgrade to a lower version (>= v0.6.0) first, then upgrade to current version.`)
|
Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,591 +390,3 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixLocaleFileLoadPanic(_ *xorm.Engine) error {
|
|
||||||
cfg, err := ini.Load(setting.CustomConf)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("load custom config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.DeleteSection("i18n")
|
|
||||||
if err = cfg.SaveTo(setting.CustomConf); err != nil {
|
|
||||||
return fmt.Errorf("save custom config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
setting.Langs = strings.Split(strings.Replace(strings.Join(setting.Langs, ","), "fr-CA", "fr-FR", 1), ",")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func trimCommitActionAppURLPrefix(x *xorm.Engine) error {
|
|
||||||
type PushCommit struct {
|
|
||||||
Sha1 string
|
|
||||||
Message string
|
|
||||||
AuthorEmail string
|
|
||||||
AuthorName string
|
|
||||||
}
|
|
||||||
|
|
||||||
type PushCommits struct {
|
|
||||||
Len int
|
|
||||||
Commits []*PushCommit
|
|
||||||
CompareURL string `json:"CompareUrl"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Action struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
Content string `xorm:"TEXT"`
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := x.Query("SELECT `id`,`content` FROM `action` WHERE `op_type`=?", 5)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("select commit actions: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := x.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
if err = sess.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pushCommits *PushCommits
|
|
||||||
for _, action := range results {
|
|
||||||
actID := com.StrTo(string(action["id"])).MustInt64()
|
|
||||||
if actID == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pushCommits = new(PushCommits)
|
|
||||||
if err = json.Unmarshal(action["content"], pushCommits); err != nil {
|
|
||||||
return fmt.Errorf("unmarshal action content[%d]: %v", actID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
infos := strings.Split(pushCommits.CompareURL, "/")
|
|
||||||
if len(infos) <= 4 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pushCommits.CompareURL = strings.Join(infos[len(infos)-4:], "/")
|
|
||||||
|
|
||||||
p, err := json.Marshal(pushCommits)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("marshal action content[%d]: %v", actID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = sess.ID(actID).Update(&Action{
|
|
||||||
Content: string(p),
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("update action[%d]: %v", actID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sess.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func issueToIssueLabel(x *xorm.Engine) error {
|
|
||||||
type IssueLabel struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
IssueID int64 `xorm:"UNIQUE(s)"`
|
|
||||||
LabelID int64 `xorm:"UNIQUE(s)"`
|
|
||||||
}
|
|
||||||
|
|
||||||
issueLabels := make([]*IssueLabel, 0, 50)
|
|
||||||
results, err := x.Query("SELECT `id`,`label_ids` FROM `issue`")
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "no such column") ||
|
|
||||||
strings.Contains(err.Error(), "Unknown column") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("select issues: %v", err)
|
|
||||||
}
|
|
||||||
for _, issue := range results {
|
|
||||||
issueID := com.StrTo(issue["id"]).MustInt64()
|
|
||||||
|
|
||||||
// Just in case legacy code can have duplicated IDs for same label.
|
|
||||||
mark := make(map[int64]bool)
|
|
||||||
for _, idStr := range strings.Split(string(issue["label_ids"]), "|") {
|
|
||||||
labelID := com.StrTo(strings.TrimPrefix(idStr, "$")).MustInt64()
|
|
||||||
if labelID == 0 || mark[labelID] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
mark[labelID] = true
|
|
||||||
issueLabels = append(issueLabels, &IssueLabel{
|
|
||||||
IssueID: issueID,
|
|
||||||
LabelID: labelID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := x.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
if err = sess.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = sess.Sync2(new(IssueLabel)); err != nil {
|
|
||||||
return fmt.Errorf("Sync2: %v", err)
|
|
||||||
} else if _, err = sess.Insert(issueLabels); err != nil {
|
|
||||||
return fmt.Errorf("insert issue-labels: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func attachmentRefactor(x *xorm.Engine) error {
|
|
||||||
type Attachment struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
UUID string `xorm:"uuid INDEX"`
|
|
||||||
|
|
||||||
// For rename purpose.
|
|
||||||
Path string `xorm:"-"`
|
|
||||||
NewPath string `xorm:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := x.Query("SELECT * FROM `attachment`")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("select attachments: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
attachments := make([]*Attachment, 0, len(results))
|
|
||||||
for _, attach := range results {
|
|
||||||
if !com.IsExist(string(attach["path"])) {
|
|
||||||
// If the attachment is already missing, there is no point to update it.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
attachments = append(attachments, &Attachment{
|
|
||||||
ID: com.StrTo(attach["id"]).MustInt64(),
|
|
||||||
UUID: gouuid.NewV4().String(),
|
|
||||||
Path: string(attach["path"]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := x.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
if err = sess.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = sess.Sync2(new(Attachment)); err != nil {
|
|
||||||
return fmt.Errorf("Sync2: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: Roll back for rename can be a dead loop,
|
|
||||||
// so produces a backup file.
|
|
||||||
var buf bytes.Buffer
|
|
||||||
buf.WriteString("# old path -> new path\n")
|
|
||||||
|
|
||||||
// Update database first because this is where error happens the most often.
|
|
||||||
for _, attach := range attachments {
|
|
||||||
if _, err = sess.ID(attach.ID).Update(attach); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
attach.NewPath = path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID)
|
|
||||||
buf.WriteString(attach.Path)
|
|
||||||
buf.WriteString("\t")
|
|
||||||
buf.WriteString(attach.NewPath)
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then rename attachments.
|
|
||||||
isSucceed := true
|
|
||||||
defer func() {
|
|
||||||
if isSucceed {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dumpPath := path.Join(setting.LogRootPath, "attachment_path.dump")
|
|
||||||
ioutil.WriteFile(dumpPath, buf.Bytes(), 0666)
|
|
||||||
log.Info("Failed to rename some attachments, old and new paths are saved into: %s", dumpPath)
|
|
||||||
}()
|
|
||||||
for _, attach := range attachments {
|
|
||||||
if err = os.MkdirAll(path.Dir(attach.NewPath), os.ModePerm); err != nil {
|
|
||||||
isSucceed = false
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = os.Rename(attach.Path, attach.NewPath); err != nil {
|
|
||||||
isSucceed = false
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func renamePullRequestFields(x *xorm.Engine) (err error) {
|
|
||||||
type PullRequest struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
PullID int64 `xorm:"INDEX"`
|
|
||||||
PullIndex int64
|
|
||||||
HeadBarcnh string
|
|
||||||
|
|
||||||
IssueID int64 `xorm:"INDEX"`
|
|
||||||
Index int64
|
|
||||||
HeadBranch string
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = x.Sync(new(PullRequest)); err != nil {
|
|
||||||
return fmt.Errorf("sync: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := x.Query("SELECT `id`,`pull_id`,`pull_index`,`head_barcnh` FROM `pull_request`")
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "no such column") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("select pull requests: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := x.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
if err = sess.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pull *PullRequest
|
|
||||||
for _, pr := range results {
|
|
||||||
pull = &PullRequest{
|
|
||||||
ID: com.StrTo(pr["id"]).MustInt64(),
|
|
||||||
IssueID: com.StrTo(pr["pull_id"]).MustInt64(),
|
|
||||||
Index: com.StrTo(pr["pull_index"]).MustInt64(),
|
|
||||||
HeadBranch: string(pr["head_barcnh"]),
|
|
||||||
}
|
|
||||||
if pull.Index == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, err = sess.ID(pull.ID).Update(pull); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanUpMigrateRepoInfo(x *xorm.Engine) (err error) {
|
|
||||||
type (
|
|
||||||
User struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
LowerName string
|
|
||||||
}
|
|
||||||
Repository struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
OwnerID int64
|
|
||||||
LowerName string
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
repos := make([]*Repository, 0, 25)
|
|
||||||
if err = x.Where("is_mirror=?", false).Find(&repos); err != nil {
|
|
||||||
return fmt.Errorf("select all non-mirror repositories: %v", err)
|
|
||||||
}
|
|
||||||
var user *User
|
|
||||||
for _, repo := range repos {
|
|
||||||
user = &User{ID: repo.OwnerID}
|
|
||||||
has, err := x.Get(user)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("get owner of repository[%d - %d]: %v", repo.ID, repo.OwnerID, err)
|
|
||||||
} else if !has {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
configPath := filepath.Join(setting.RepoRootPath, user.LowerName, repo.LowerName+".git/config")
|
|
||||||
|
|
||||||
// In case repository file is somehow missing.
|
|
||||||
if !com.IsFile(configPath) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg, err := ini.Load(configPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("open config file: %v", err)
|
|
||||||
}
|
|
||||||
cfg.DeleteSection("remote \"origin\"")
|
|
||||||
if err = cfg.SaveToIndent(configPath, "\t"); err != nil {
|
|
||||||
return fmt.Errorf("save config file: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
|
|
||||||
type User struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
Rands string `xorm:"VARCHAR(10)"`
|
|
||||||
Salt string `xorm:"VARCHAR(10)"`
|
|
||||||
}
|
|
||||||
|
|
||||||
orgs := make([]*User, 0, 10)
|
|
||||||
if err = x.Where("type=1").And("rands=''").Find(&orgs); err != nil {
|
|
||||||
return fmt.Errorf("select all organizations: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := x.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
if err = sess.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, org := range orgs {
|
|
||||||
if org.Rands, err = generate.GetRandomString(10); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if org.Salt, err = generate.GetRandomString(10); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err = sess.ID(org.ID).Update(org); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TAction defines the struct for migrating table action
|
|
||||||
type TAction struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TAction) TableName() string { return "action" }
|
|
||||||
|
|
||||||
// TNotice defines the struct for migrating table notice
|
|
||||||
type TNotice struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TNotice) TableName() string { return "notice" }
|
|
||||||
|
|
||||||
// TComment defines the struct for migrating table comment
|
|
||||||
type TComment struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TComment) TableName() string { return "comment" }
|
|
||||||
|
|
||||||
// TIssue defines the struct for migrating table issue
|
|
||||||
type TIssue struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
DeadlineUnix int64
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TIssue) TableName() string { return "issue" }
|
|
||||||
|
|
||||||
// TMilestone defines the struct for migrating table milestone
|
|
||||||
type TMilestone struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
DeadlineUnix int64
|
|
||||||
ClosedDateUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TMilestone) TableName() string { return "milestone" }
|
|
||||||
|
|
||||||
// TAttachment defines the struct for migrating table attachment
|
|
||||||
type TAttachment struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TAttachment) TableName() string { return "attachment" }
|
|
||||||
|
|
||||||
// TLoginSource defines the struct for migrating table login_source
|
|
||||||
type TLoginSource struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TLoginSource) TableName() string { return "login_source" }
|
|
||||||
|
|
||||||
// TPull defines the struct for migrating table pull_request
|
|
||||||
type TPull struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
MergedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TPull) TableName() string { return "pull_request" }
|
|
||||||
|
|
||||||
// TRelease defines the struct for migrating table release
|
|
||||||
type TRelease struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TRelease) TableName() string { return "release" }
|
|
||||||
|
|
||||||
// TRepo defines the struct for migrating table repository
|
|
||||||
type TRepo struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TRepo) TableName() string { return "repository" }
|
|
||||||
|
|
||||||
// TMirror defines the struct for migrating table mirror
|
|
||||||
type TMirror struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
UpdatedUnix int64
|
|
||||||
NextUpdateUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TMirror) TableName() string { return "mirror" }
|
|
||||||
|
|
||||||
// TPublicKey defines the struct for migrating table public_key
|
|
||||||
type TPublicKey struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TPublicKey) TableName() string { return "public_key" }
|
|
||||||
|
|
||||||
// TDeployKey defines the struct for migrating table deploy_key
|
|
||||||
type TDeployKey struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TDeployKey) TableName() string { return "deploy_key" }
|
|
||||||
|
|
||||||
// TAccessToken defines the struct for migrating table access_token
|
|
||||||
type TAccessToken struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TAccessToken) TableName() string { return "access_token" }
|
|
||||||
|
|
||||||
// TUser defines the struct for migrating table user
|
|
||||||
type TUser struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TUser) TableName() string { return "user" }
|
|
||||||
|
|
||||||
// TWebhook defines the struct for migrating table webhook
|
|
||||||
type TWebhook struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
CreatedUnix int64
|
|
||||||
UpdatedUnix int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName will be invoked by XORM to customrize the table name
|
|
||||||
func (t *TWebhook) TableName() string { return "webhook" }
|
|
||||||
|
|
||||||
func convertDateToUnix(x *xorm.Engine) (err error) {
|
|
||||||
log.Info("This migration could take up to minutes, please be patient.")
|
|
||||||
type Bean struct {
|
|
||||||
ID int64 `xorm:"pk autoincr"`
|
|
||||||
Created time.Time
|
|
||||||
Updated time.Time
|
|
||||||
Merged time.Time
|
|
||||||
Deadline time.Time
|
|
||||||
ClosedDate time.Time
|
|
||||||
NextUpdate time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
var tables = []struct {
|
|
||||||
name string
|
|
||||||
cols []string
|
|
||||||
bean interface{}
|
|
||||||
}{
|
|
||||||
{"action", []string{"created"}, new(TAction)},
|
|
||||||
{"notice", []string{"created"}, new(TNotice)},
|
|
||||||
{"comment", []string{"created"}, new(TComment)},
|
|
||||||
{"issue", []string{"deadline", "created", "updated"}, new(TIssue)},
|
|
||||||
{"milestone", []string{"deadline", "closed_date"}, new(TMilestone)},
|
|
||||||
{"attachment", []string{"created"}, new(TAttachment)},
|
|
||||||
{"login_source", []string{"created", "updated"}, new(TLoginSource)},
|
|
||||||
{"pull_request", []string{"merged"}, new(TPull)},
|
|
||||||
{"release", []string{"created"}, new(TRelease)},
|
|
||||||
{"repository", []string{"created", "updated"}, new(TRepo)},
|
|
||||||
{"mirror", []string{"updated", "next_update"}, new(TMirror)},
|
|
||||||
{"public_key", []string{"created", "updated"}, new(TPublicKey)},
|
|
||||||
{"deploy_key", []string{"created", "updated"}, new(TDeployKey)},
|
|
||||||
{"access_token", []string{"created", "updated"}, new(TAccessToken)},
|
|
||||||
{"user", []string{"created", "updated"}, new(TUser)},
|
|
||||||
{"webhook", []string{"created", "updated"}, new(TWebhook)},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, table := range tables {
|
|
||||||
log.Info("Converting table: %s", table.name)
|
|
||||||
if err = x.Sync2(table.bean); err != nil {
|
|
||||||
return fmt.Errorf("Sync [table: %s]: %v", table.name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := 0
|
|
||||||
for {
|
|
||||||
beans := make([]*Bean, 0, 100)
|
|
||||||
if err = x.Table(table.name).Asc("id").Limit(100, offset).Find(&beans); err != nil {
|
|
||||||
return fmt.Errorf("select beans [table: %s, offset: %d]: %v", table.name, offset, err)
|
|
||||||
}
|
|
||||||
log.Trace("Table [%s]: offset: %d, beans: %d", table.name, offset, len(beans))
|
|
||||||
if len(beans) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
offset += 100
|
|
||||||
|
|
||||||
baseSQL := "UPDATE `" + table.name + "` SET "
|
|
||||||
for _, bean := range beans {
|
|
||||||
valSQLs := make([]string, 0, len(table.cols))
|
|
||||||
for _, col := range table.cols {
|
|
||||||
fieldSQL := ""
|
|
||||||
fieldSQL += col + "_unix = "
|
|
||||||
|
|
||||||
switch col {
|
|
||||||
case "deadline":
|
|
||||||
if bean.Deadline.IsZero() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fieldSQL += com.ToStr(bean.Deadline.Unix())
|
|
||||||
case "created":
|
|
||||||
fieldSQL += com.ToStr(bean.Created.Unix())
|
|
||||||
case "updated":
|
|
||||||
fieldSQL += com.ToStr(bean.Updated.Unix())
|
|
||||||
case "closed_date":
|
|
||||||
fieldSQL += com.ToStr(bean.ClosedDate.Unix())
|
|
||||||
case "merged":
|
|
||||||
fieldSQL += com.ToStr(bean.Merged.Unix())
|
|
||||||
case "next_update":
|
|
||||||
fieldSQL += com.ToStr(bean.NextUpdate.Unix())
|
|
||||||
}
|
|
||||||
|
|
||||||
valSQLs = append(valSQLs, fieldSQL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(valSQLs) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = x.Exec(baseSQL + strings.Join(valSQLs, ",") + " WHERE id = " + com.ToStr(bean.ID)); err != nil {
|
|
||||||
return fmt.Errorf("update bean [table: %s, id: %d]: %v", table.name, bean.ID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
|
@ -26,6 +26,18 @@ func addIssueDependencies(x *xorm.Engine) (err error) {
|
||||||
UpdatedUnix int64 `xorm:"updated"`
|
UpdatedUnix int64 `xorm:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
if err = x.Sync(new(IssueDependency)); err != nil {
|
if err = x.Sync(new(IssueDependency)); err != nil {
|
||||||
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
|
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +92,7 @@ func addIssueDependencies(x *xorm.Engine) (err error) {
|
||||||
|
|
||||||
//Updating existing issue units
|
//Updating existing issue units
|
||||||
units := make([]*RepoUnit, 0, 100)
|
units := make([]*RepoUnit, 0, 100)
|
||||||
err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
|
err = x.Where("`type` = ?", v16UnitTypeIssues).Find(&units)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Query repo units: %v", err)
|
return fmt.Errorf("Query repo units: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,18 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error {
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
if err := sess.Begin(); err != nil {
|
if err := sess.Begin(); err != nil {
|
||||||
|
@ -30,7 +42,7 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error {
|
||||||
|
|
||||||
//Updating existing issue units
|
//Updating existing issue units
|
||||||
units := make([]*RepoUnit, 0, 100)
|
units := make([]*RepoUnit, 0, 100)
|
||||||
if err := sess.Where("`type` = ?", V16UnitTypePRs).Find(&units); err != nil {
|
if err := sess.Where("`type` = ?", v16UnitTypePRs).Find(&units); err != nil {
|
||||||
return fmt.Errorf("Query repo units: %v", err)
|
return fmt.Errorf("Query repo units: %v", err)
|
||||||
}
|
}
|
||||||
for _, unit := range units {
|
for _, unit := range units {
|
||||||
|
|
Loading…
Reference in a new issue