Complete XORM to GORM migration for issue.go and pull.go

Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-24 15:43:22 +00:00
parent eebe4065c6
commit 04d063c65d
2 changed files with 320 additions and 377 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,8 @@ import (
"github.com/cockroachdb/errors"
"github.com/unknwon/com"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
"xorm.io/xorm"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
@@ -71,35 +71,31 @@ func (pr *PullRequest) BeforeUpdate() {
}
// Note: don't try to get Issue because will end up recursive querying.
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "merged_unix":
if !pr.HasMerged {
return
}
func (pr *PullRequest) AfterFind(tx *gorm.DB) error {
if pr.HasMerged {
pr.Merged = time.Unix(pr.MergedUnix, 0).Local()
}
return nil
}
// Note: don't try to get Issue because will end up recursive querying.
func (pr *PullRequest) loadAttributes(e Engine) (err error) {
func (pr *PullRequest) loadAttributes(db *gorm.DB) (err error) {
if pr.HeadRepo == nil {
pr.HeadRepo, err = getRepositoryByID(e, pr.HeadRepoID)
pr.HeadRepo, err = getRepositoryByID(db, pr.HeadRepoID)
if err != nil && !IsErrRepoNotExist(err) {
return errors.Newf("get head repository by ID: %v", err)
}
}
if pr.BaseRepo == nil {
pr.BaseRepo, err = getRepositoryByID(e, pr.BaseRepoID)
pr.BaseRepo, err = getRepositoryByID(db, pr.BaseRepoID)
if err != nil {
return errors.Newf("get base repository by ID: %v", err)
}
}
if pr.HasMerged && pr.Merger == nil {
pr.Merger, err = getUserByID(e, pr.MergerID)
pr.Merger, err = getUserByID(db, pr.MergerID)
if IsErrUserNotExist(err) {
pr.MergerID = -1
pr.Merger = NewGhostUser()
@@ -112,7 +108,7 @@ func (pr *PullRequest) loadAttributes(e Engine) (err error) {
}
func (pr *PullRequest) LoadAttributes() error {
return pr.loadAttributes(x)
return pr.loadAttributes(db)
}
func (pr *PullRequest) LoadIssue() (err error) {
@@ -199,15 +195,10 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false)
}()
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
if err = pr.Issue.changeStatus(sess, doer, pr.Issue.Repo, true); err != nil {
return errors.Newf("Issue.changeStatus: %v", err)
}
return db.Transaction(func(tx *gorm.DB) error {
if err := pr.Issue.changeStatus(tx, doer, pr.Issue.Repo, true); err != nil {
return errors.Newf("Issue.changeStatus: %v", err)
}
headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
headGitRepo, err := git.Open(headRepoPath)
@@ -443,30 +434,25 @@ func (pr *PullRequest) testPatch() (err error) {
// NewPullRequest creates new pull request with labels for repository.
func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []string, pr *PullRequest, patch []byte) (err error) {
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
err = db.Transaction(func(tx *gorm.DB) error {
if err := newIssue(tx, NewIssueOptions{
Repo: repo,
Issue: pull,
LableIDs: labelIDs,
Attachments: uuids,
IsPull: true,
}); err != nil {
return errors.Newf("newIssue: %v", err)
}
if err = newIssue(sess, NewIssueOptions{
Repo: repo,
Issue: pull,
LableIDs: labelIDs,
Attachments: uuids,
IsPull: true,
}); err != nil {
return errors.Newf("newIssue: %v", err)
}
pr.Index = pull.Index
if err := repo.SavePatch(pr.Index, patch); err != nil {
return errors.Newf("SavePatch: %v", err)
}
pr.Index = pull.Index
if err = repo.SavePatch(pr.Index, patch); err != nil {
return errors.Newf("SavePatch: %v", err)
}
pr.BaseRepo = repo
if err = pr.testPatch(); err != nil {
return errors.Newf("testPatch: %v", err)
pr.BaseRepo = repo
if err := pr.testPatch(); err != nil {
return errors.Newf("testPatch: %v", err)
}
// No conflict appears after test means mergeable.
if pr.Status == PullRequestStatusChecking {
@@ -517,18 +503,20 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
// by given head/base and repo/branch.
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) {
pr := new(PullRequest)
has, err := x.Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
headRepoID, headBranch, baseRepoID, baseBranch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").Get(pr)
err := db.Joins("INNER JOIN issue ON issue.id = pull_request.issue_id").
Where("pull_request.head_repo_id = ? AND pull_request.head_branch = ? AND pull_request.base_repo_id = ? AND pull_request.base_branch = ? AND pull_request.has_merged = ? AND issue.is_closed = ?",
headRepoID, headBranch, baseRepoID, baseBranch, false, false).
First(pr).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrPullRequestNotExist{args: map[string]any{
"headRepoID": headRepoID,
"baseRepoID": baseRepoID,
"headBranch": headBranch,
"baseBranch": baseBranch,
}}
}
return nil, err
} else if !has {
return nil, ErrPullRequestNotExist{args: map[string]any{
"headRepoID": headRepoID,
"baseRepoID": baseRepoID,
"headBranch": headBranch,
"baseBranch": baseBranch,
}}
}
return pr, nil
@@ -538,18 +526,22 @@ func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch
// by given head information (repo and branch).
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id = pull_request.issue_id").Find(&prs)
err := db.Joins("INNER JOIN issue ON issue.id = pull_request.issue_id").
Where("pull_request.head_repo_id = ? AND pull_request.head_branch = ? AND pull_request.has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Find(&prs).Error
return prs, err
}
// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged
// by given base information (repo and branch).
func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").Find(&prs)
err := db.Joins("INNER JOIN issue ON issue.id = pull_request.issue_id").
Where("pull_request.base_repo_id = ? AND pull_request.base_branch = ? AND pull_request.has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Find(&prs).Error
return prs, err
}
var _ errutil.NotFound = (*ErrPullRequestNotExist)(nil)
@@ -571,50 +563,65 @@ func (ErrPullRequestNotExist) NotFound() bool {
return true
}
func getPullRequestByID(e Engine, id int64) (*PullRequest, error) {
func getPullRequestByID(db *gorm.DB, id int64) (*PullRequest, error) {
pr := new(PullRequest)
has, err := e.ID(id).Get(pr)
err := db.First(pr, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrPullRequestNotExist{args: map[string]any{"pullRequestID": id}}
}
return nil, err
} else if !has {
return nil, ErrPullRequestNotExist{args: map[string]any{"pullRequestID": id}}
}
return pr, pr.loadAttributes(e)
return pr, pr.loadAttributes(db)
}
// GetPullRequestByID returns a pull request by given ID.
func GetPullRequestByID(id int64) (*PullRequest, error) {
return getPullRequestByID(x, id)
return getPullRequestByID(db, id)
}
func getPullRequestByIssueID(e Engine, issueID int64) (*PullRequest, error) {
pr := &PullRequest{
IssueID: issueID,
}
has, err := e.Get(pr)
func getPullRequestByIssueID(db *gorm.DB, issueID int64) (*PullRequest, error) {
pr := &PullRequest{}
err := db.Where("issue_id = ?", issueID).First(pr).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrPullRequestNotExist{args: map[string]any{"issueID": issueID}}
}
return nil, err
} else if !has {
return nil, ErrPullRequestNotExist{args: map[string]any{"issueID": issueID}}
}
return pr, pr.loadAttributes(e)
return pr, pr.loadAttributes(db)
}
// GetPullRequestByIssueID returns pull request by given issue ID.
func GetPullRequestByIssueID(issueID int64) (*PullRequest, error) {
return getPullRequestByIssueID(x, issueID)
return getPullRequestByIssueID(db, issueID)
}
// Update updates all fields of pull request.
func (pr *PullRequest) Update() error {
_, err := x.Id(pr.ID).AllCols().Update(pr)
return err
return db.Model(&PullRequest{}).Where("id = ?", pr.ID).Updates(pr).Error
}
// Update updates specific fields of pull request.
func (pr *PullRequest) UpdateCols(cols ...string) error {
_, err := x.Id(pr.ID).Cols(cols...).Update(pr)
return err
updates := make(map[string]any)
for _, col := range cols {
switch col {
case "status":
updates["status"] = pr.Status
case "merge_base":
updates["merge_base"] = pr.MergeBase
case "has_merged":
updates["has_merged"] = pr.HasMerged
case "merged_commit_id":
updates["merged_commit_id"] = pr.MergedCommitID
case "merger_id":
updates["merger_id"] = pr.MergerID
case "merged_unix":
updates["merged_unix"] = pr.MergedUnix
}
}
return db.Model(&PullRequest{}).Where("id = ?", pr.ID).Updates(updates).Error
}
// UpdatePatch generates and saves a new patch.
@@ -711,7 +718,7 @@ func (pr *PullRequest) AddToTaskQueue() {
type PullRequestList []*PullRequest
func (prs PullRequestList) loadAttributes(e Engine) (err error) {
func (prs PullRequestList) loadAttributes(db *gorm.DB) (err error) {
if len(prs) == 0 {
return nil
}
@@ -726,7 +733,7 @@ func (prs PullRequestList) loadAttributes(e Engine) (err error) {
issueIDs = append(issueIDs, issueID)
}
issues := make([]*Issue, 0, len(issueIDs))
if err = e.Where("id > 0").In("id", issueIDs).Find(&issues); err != nil {
if err = db.Where("id IN ?", issueIDs).Find(&issues).Error; err != nil {
return errors.Newf("find issues: %v", err)
}
for i := range issues {
@@ -839,24 +846,22 @@ func (pr *PullRequest) checkAndUpdateStatus() {
// TODO: test more pull requests at same time.
func TestPullRequests() {
prs := make([]*PullRequest, 0, 10)
_ = x.Iterate(PullRequest{
Status: PullRequestStatusChecking,
},
func(idx int, bean any) error {
pr := bean.(*PullRequest)
db.Where("status = ?", PullRequestStatusChecking).FindInBatches(&prs, 100, func(tx *gorm.DB, batch int) error {
for i := range prs {
pr := prs[i]
if err := pr.LoadAttributes(); err != nil {
log.Error("LoadAttributes: %v", err)
return nil
continue
}
if err := pr.testPatch(); err != nil {
log.Error("testPatch: %v", err)
return nil
continue
}
prs = append(prs, pr)
return nil
})
}
return nil
})
// Update pull request status.
for _, pr := range prs {