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