summaryrefslogtreecommitdiffstats
path: root/models/issue.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/issue.go')
-rw-r--r--models/issue.go301
1 files changed, 156 insertions, 145 deletions
diff --git a/models/issue.go b/models/issue.go
index 9e63ac4e58..a1f5373583 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -12,6 +12,7 @@ import (
"strconv"
"strings"
+ "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
@@ -82,12 +83,18 @@ const (
issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
)
+// IssueIndex represents the issue index table
+type IssueIndex db.ResourceIndex
+
func init() {
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
issueTasksDonePat = regexp.MustCompile(issueTasksDoneRegexpStr)
+
+ db.RegisterModel(new(Issue))
+ db.RegisterModel(new(IssueIndex))
}
-func (issue *Issue) loadTotalTimes(e Engine) (err error) {
+func (issue *Issue) loadTotalTimes(e db.Engine) (err error) {
opts := FindTrackedTimesOptions{IssueID: issue.ID}
issue.TotalTrackedTime, err = opts.toSession(e).SumInt(&TrackedTime{}, "time")
if err != nil {
@@ -106,10 +113,10 @@ func (issue *Issue) IsOverdue() bool {
// LoadRepo loads issue's repository
func (issue *Issue) LoadRepo() error {
- return issue.loadRepo(x)
+ return issue.loadRepo(db.DefaultContext().Engine())
}
-func (issue *Issue) loadRepo(e Engine) (err error) {
+func (issue *Issue) loadRepo(e db.Engine) (err error) {
if issue.Repo == nil {
issue.Repo, err = getRepositoryByID(e, issue.RepoID)
if err != nil {
@@ -121,10 +128,10 @@ func (issue *Issue) loadRepo(e Engine) (err error) {
// IsTimetrackerEnabled returns true if the repo enables timetracking
func (issue *Issue) IsTimetrackerEnabled() bool {
- return issue.isTimetrackerEnabled(x)
+ return issue.isTimetrackerEnabled(db.DefaultContext().Engine())
}
-func (issue *Issue) isTimetrackerEnabled(e Engine) bool {
+func (issue *Issue) isTimetrackerEnabled(e db.Engine) bool {
if err := issue.loadRepo(e); err != nil {
log.Error(fmt.Sprintf("loadRepo: %v", err))
return false
@@ -138,7 +145,7 @@ func (issue *Issue) GetPullRequest() (pr *PullRequest, err error) {
return nil, fmt.Errorf("Issue is not a pull request")
}
- pr, err = getPullRequestByIssueID(x, issue.ID)
+ pr, err = getPullRequestByIssueID(db.DefaultContext().Engine(), issue.ID)
if err != nil {
return nil, err
}
@@ -148,10 +155,10 @@ func (issue *Issue) GetPullRequest() (pr *PullRequest, err error) {
// LoadLabels loads labels
func (issue *Issue) LoadLabels() error {
- return issue.loadLabels(x)
+ return issue.loadLabels(db.DefaultContext().Engine())
}
-func (issue *Issue) loadLabels(e Engine) (err error) {
+func (issue *Issue) loadLabels(e db.Engine) (err error) {
if issue.Labels == nil {
issue.Labels, err = getLabelsByIssueID(e, issue.ID)
if err != nil {
@@ -163,10 +170,10 @@ func (issue *Issue) loadLabels(e Engine) (err error) {
// LoadPoster loads poster
func (issue *Issue) LoadPoster() error {
- return issue.loadPoster(x)
+ return issue.loadPoster(db.DefaultContext().Engine())
}
-func (issue *Issue) loadPoster(e Engine) (err error) {
+func (issue *Issue) loadPoster(e db.Engine) (err error) {
if issue.Poster == nil {
issue.Poster, err = getUserByID(e, issue.PosterID)
if err != nil {
@@ -182,7 +189,7 @@ func (issue *Issue) loadPoster(e Engine) (err error) {
return
}
-func (issue *Issue) loadPullRequest(e Engine) (err error) {
+func (issue *Issue) loadPullRequest(e db.Engine) (err error) {
if issue.IsPull && issue.PullRequest == nil {
issue.PullRequest, err = getPullRequestByIssueID(e, issue.ID)
if err != nil {
@@ -198,19 +205,19 @@ func (issue *Issue) loadPullRequest(e Engine) (err error) {
// LoadPullRequest loads pull request info
func (issue *Issue) LoadPullRequest() error {
- return issue.loadPullRequest(x)
+ return issue.loadPullRequest(db.DefaultContext().Engine())
}
-func (issue *Issue) loadComments(e Engine) (err error) {
+func (issue *Issue) loadComments(e db.Engine) (err error) {
return issue.loadCommentsByType(e, CommentTypeUnknown)
}
// LoadDiscussComments loads discuss comments
func (issue *Issue) LoadDiscussComments() error {
- return issue.loadCommentsByType(x, CommentTypeComment)
+ return issue.loadCommentsByType(db.DefaultContext().Engine(), CommentTypeComment)
}
-func (issue *Issue) loadCommentsByType(e Engine, tp CommentType) (err error) {
+func (issue *Issue) loadCommentsByType(e db.Engine, tp CommentType) (err error) {
if issue.Comments != nil {
return nil
}
@@ -221,7 +228,7 @@ func (issue *Issue) loadCommentsByType(e Engine, tp CommentType) (err error) {
return err
}
-func (issue *Issue) loadReactions(e Engine) (err error) {
+func (issue *Issue) loadReactions(e db.Engine) (err error) {
if issue.Reactions != nil {
return nil
}
@@ -255,7 +262,7 @@ func (issue *Issue) loadReactions(e Engine) (err error) {
return nil
}
-func (issue *Issue) loadMilestone(e Engine) (err error) {
+func (issue *Issue) loadMilestone(e db.Engine) (err error) {
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
if err != nil && !IsErrMilestoneNotExist(err) {
@@ -265,7 +272,7 @@ func (issue *Issue) loadMilestone(e Engine) (err error) {
return nil
}
-func (issue *Issue) loadAttributes(e Engine) (err error) {
+func (issue *Issue) loadAttributes(e db.Engine) (err error) {
if err = issue.loadRepo(e); err != nil {
return
}
@@ -320,18 +327,18 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
// LoadAttributes loads the attribute of this issue.
func (issue *Issue) LoadAttributes() error {
- return issue.loadAttributes(x)
+ return issue.loadAttributes(db.DefaultContext().Engine())
}
// LoadMilestone load milestone of this issue.
func (issue *Issue) LoadMilestone() error {
- return issue.loadMilestone(x)
+ return issue.loadMilestone(db.DefaultContext().Engine())
}
// GetIsRead load the `IsRead` field of the issue
func (issue *Issue) GetIsRead(userID int64) error {
issueUser := &IssueUser{IssueID: issue.ID, UID: userID}
- if has, err := x.Get(issueUser); err != nil {
+ if has, err := db.DefaultContext().Engine().Get(issueUser); err != nil {
return err
} else if !has {
issue.IsRead = false
@@ -398,13 +405,13 @@ func (issue *Issue) IsPoster(uid int64) bool {
return issue.OriginalAuthorID == 0 && issue.PosterID == uid
}
-func (issue *Issue) hasLabel(e Engine, labelID int64) bool {
+func (issue *Issue) hasLabel(e db.Engine, labelID int64) bool {
return hasIssueLabel(e, issue.ID, labelID)
}
// HasLabel returns true if issue has been labeled by given ID.
func (issue *Issue) HasLabel(labelID int64) bool {
- return issue.hasLabel(x, labelID)
+ return issue.hasLabel(db.DefaultContext().Engine(), labelID)
}
// ReplyReference returns tokenized address to use for email reply headers
@@ -419,15 +426,15 @@ func (issue *Issue) ReplyReference() string {
return fmt.Sprintf("%s/%s/%d@%s", issue.Repo.FullName(), path, issue.Index, setting.Domain)
}
-func (issue *Issue) addLabel(e *xorm.Session, label *Label, doer *User) error {
+func (issue *Issue) addLabel(e db.Engine, label *Label, doer *User) error {
return newIssueLabel(e, issue, label, doer)
}
-func (issue *Issue) addLabels(e *xorm.Session, labels []*Label, doer *User) error {
+func (issue *Issue) addLabels(e db.Engine, labels []*Label, doer *User) error {
return newIssueLabels(e, issue, labels, doer)
}
-func (issue *Issue) getLabels(e Engine) (err error) {
+func (issue *Issue) getLabels(e db.Engine) (err error) {
if len(issue.Labels) > 0 {
return nil
}
@@ -439,11 +446,11 @@ func (issue *Issue) getLabels(e Engine) (err error) {
return nil
}
-func (issue *Issue) removeLabel(e *xorm.Session, doer *User, label *Label) error {
+func (issue *Issue) removeLabel(e db.Engine, doer *User, label *Label) error {
return deleteIssueLabel(e, issue, label, doer)
}
-func (issue *Issue) clearLabels(e *xorm.Session, doer *User) (err error) {
+func (issue *Issue) clearLabels(e db.Engine, doer *User) (err error) {
if err = issue.getLabels(e); err != nil {
return fmt.Errorf("getLabels: %v", err)
}
@@ -460,19 +467,19 @@ func (issue *Issue) clearLabels(e *xorm.Session, doer *User) (err error) {
// ClearLabels removes all issue labels as the given user.
// Triggers appropriate WebHooks, if any.
func (issue *Issue) ClearLabels(doer *User) (err error) {
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err := issue.loadRepo(sess); err != nil {
+ if err := issue.loadRepo(ctx.Engine()); err != nil {
return err
- } else if err = issue.loadPullRequest(sess); err != nil {
+ } else if err = issue.loadPullRequest(ctx.Engine()); err != nil {
return err
}
- perm, err := getUserRepoPermission(sess, issue.Repo, doer)
+ perm, err := getUserRepoPermission(ctx.Engine(), issue.Repo, doer)
if err != nil {
return err
}
@@ -480,11 +487,11 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return ErrRepoLabelNotExist{}
}
- if err = issue.clearLabels(sess, doer); err != nil {
+ if err = issue.clearLabels(ctx.Engine(), doer); err != nil {
return err
}
- if err = sess.Commit(); err != nil {
+ if err = committer.Commit(); err != nil {
return fmt.Errorf("Commit: %v", err)
}
@@ -508,17 +515,17 @@ func (ts labelSorter) Swap(i, j int) {
// ReplaceLabels removes all current labels and add new labels to the issue.
// Triggers appropriate WebHooks, if any.
func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) {
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err = issue.loadRepo(sess); err != nil {
+ if err = issue.loadRepo(ctx.Engine()); err != nil {
return err
}
- if err = issue.loadLabels(sess); err != nil {
+ if err = issue.loadLabels(ctx.Engine()); err != nil {
return err
}
@@ -554,23 +561,23 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) {
toRemove = append(toRemove, issue.Labels[removeIndex:]...)
if len(toAdd) > 0 {
- if err = issue.addLabels(sess, toAdd, doer); err != nil {
+ if err = issue.addLabels(ctx.Engine(), toAdd, doer); err != nil {
return fmt.Errorf("addLabels: %v", err)
}
}
for _, l := range toRemove {
- if err = issue.removeLabel(sess, doer, l); err != nil {
+ if err = issue.removeLabel(ctx.Engine(), doer, l); err != nil {
return fmt.Errorf("removeLabel: %v", err)
}
}
issue.Labels = nil
- if err = issue.loadLabels(sess); err != nil {
+ if err = issue.loadLabels(ctx.Engine()); err != nil {
return err
}
- return sess.Commit()
+ return committer.Commit()
}
// ReadBy sets issue to be read by given user.
@@ -579,17 +586,17 @@ func (issue *Issue) ReadBy(userID int64) error {
return err
}
- return setIssueNotificationStatusReadIfUnread(x, userID, issue.ID)
+ return setIssueNotificationStatusReadIfUnread(db.DefaultContext().Engine(), userID, issue.ID)
}
-func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
+func updateIssueCols(e db.Engine, issue *Issue, cols ...string) error {
if _, err := e.ID(issue.ID).Cols(cols...).Update(issue); err != nil {
return err
}
return nil
}
-func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed, isMergePull bool) (*Comment, error) {
+func (issue *Issue) changeStatus(e db.Engine, doer *User, isClosed, isMergePull bool) (*Comment, error) {
// Reload the issue
currentIssue, err := getIssueByID(e, issue.ID)
if err != nil {
@@ -612,7 +619,7 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed, isMergeP
return issue.doChangeStatus(e, doer, isMergePull)
}
-func (issue *Issue) doChangeStatus(e *xorm.Session, doer *User, isMergePull bool) (*Comment, error) {
+func (issue *Issue) doChangeStatus(e db.Engine, doer *User, isMergePull bool) (*Comment, error) {
// Check for open dependencies
if issue.IsClosed && issue.Repo.isDependenciesEnabled(e) {
// only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies
@@ -675,25 +682,25 @@ func (issue *Issue) doChangeStatus(e *xorm.Session, doer *User, isMergePull bool
// ChangeStatus changes issue status to open or closed.
func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (*Comment, error) {
- sess := x.NewSession()
- defer sess.Close()
- if err := sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return nil, err
}
+ defer committer.Close()
- if err := issue.loadRepo(sess); err != nil {
+ if err := issue.loadRepo(ctx.Engine()); err != nil {
return nil, err
}
- if err := issue.loadPoster(sess); err != nil {
+ if err := issue.loadPoster(ctx.Engine()); err != nil {
return nil, err
}
- comment, err := issue.changeStatus(sess, doer, isClosed, false)
+ comment, err := issue.changeStatus(ctx.Engine(), doer, isClosed, false)
if err != nil {
return nil, err
}
- if err = sess.Commit(); err != nil {
+ if err = committer.Commit(); err != nil {
return nil, fmt.Errorf("Commit: %v", err)
}
@@ -702,18 +709,17 @@ func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (*Comment, error) {
// ChangeTitle changes the title of this issue, as the given user.
func (issue *Issue) ChangeTitle(doer *User, oldTitle string) (err error) {
- sess := x.NewSession()
- defer sess.Close()
-
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err = updateIssueCols(sess, issue, "name"); err != nil {
+ if err = updateIssueCols(ctx.Engine(), issue, "name"); err != nil {
return fmt.Errorf("updateIssueCols: %v", err)
}
- if err = issue.loadRepo(sess); err != nil {
+ if err = issue.loadRepo(ctx.Engine()); err != nil {
return fmt.Errorf("loadRepo: %v", err)
}
@@ -725,43 +731,42 @@ func (issue *Issue) ChangeTitle(doer *User, oldTitle string) (err error) {
OldTitle: oldTitle,
NewTitle: issue.Title,
}
- if _, err = createComment(sess, opts); err != nil {
+ if _, err = createComment(ctx.Engine(), opts); err != nil {
return fmt.Errorf("createComment: %v", err)
}
- if err = issue.addCrossReferences(sess, doer, true); err != nil {
+ if err = issue.addCrossReferences(ctx.Engine(), doer, true); err != nil {
return err
}
- return sess.Commit()
+ return committer.Commit()
}
// ChangeRef changes the branch of this issue, as the given user.
func (issue *Issue) ChangeRef(doer *User, oldRef string) (err error) {
- sess := x.NewSession()
- defer sess.Close()
-
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err = updateIssueCols(sess, issue, "ref"); err != nil {
+ if err = updateIssueCols(ctx.Engine(), issue, "ref"); err != nil {
return fmt.Errorf("updateIssueCols: %v", err)
}
- return sess.Commit()
+ return committer.Commit()
}
// AddDeletePRBranchComment adds delete branch comment for pull request issue
func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branchName string) error {
- issue, err := getIssueByID(x, issueID)
+ issue, err := getIssueByID(db.DefaultContext().Engine(), issueID)
if err != nil {
return err
}
- sess := x.NewSession()
- defer sess.Close()
- if err := sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
opts := &CreateCommentOptions{
Type: CommentTypeDeleteBranch,
Doer: doer,
@@ -769,52 +774,52 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc
Issue: issue,
OldRef: branchName,
}
- if _, err = createComment(sess, opts); err != nil {
+ if _, err = createComment(ctx.Engine(), opts); err != nil {
return err
}
- return sess.Commit()
+ return committer.Commit()
}
// UpdateAttachments update attachments by UUIDs for the issue
func (issue *Issue) UpdateAttachments(uuids []string) (err error) {
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
- attachments, err := getAttachmentsByUUIDs(sess, uuids)
+ defer committer.Close()
+ attachments, err := getAttachmentsByUUIDs(ctx.Engine(), uuids)
if err != nil {
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err)
}
for i := 0; i < len(attachments); i++ {
attachments[i].IssueID = issue.ID
- if err := updateAttachment(sess, attachments[i]); err != nil {
+ if err := updateAttachment(ctx.Engine(), attachments[i]); err != nil {
return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err)
}
}
- return sess.Commit()
+ return committer.Commit()
}
// ChangeContent changes issue content, as the given user.
func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
issue.Content = content
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err = updateIssueCols(sess, issue, "content"); err != nil {
+ if err = updateIssueCols(ctx.Engine(), issue, "content"); err != nil {
return fmt.Errorf("UpdateIssueCols: %v", err)
}
- if err = issue.addCrossReferences(sess, doer, true); err != nil {
+ if err = issue.addCrossReferences(ctx.Engine(), doer, true); err != nil {
return err
}
- return sess.Commit()
+ return committer.Commit()
}
// GetTasks returns the amount of tasks in the issues content
@@ -849,7 +854,7 @@ func (issue *Issue) GetLastEventLabel() string {
// GetLastComment return last comment for the current issue.
func (issue *Issue) GetLastComment() (*Comment, error) {
var c Comment
- exist, err := x.Where("type = ?", CommentTypeComment).
+ exist, err := db.DefaultContext().Engine().Where("type = ?", CommentTypeComment).
And("issue_id = ?", issue.ID).Desc("id").Get(&c)
if err != nil {
return nil, err
@@ -880,7 +885,7 @@ type NewIssueOptions struct {
IsPull bool
}
-func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
+func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
opts.Issue.Title = strings.TrimSpace(opts.Issue.Title)
if opts.Issue.MilestoneID > 0 {
@@ -985,44 +990,44 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
// RecalculateIssueIndexForRepo create issue_index for repo if not exist and
// update it based on highest index of existing issues assigned to a repo
func RecalculateIssueIndexForRepo(repoID int64) error {
- sess := x.NewSession()
- defer sess.Close()
- if err := sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err := upsertResourceIndex(sess, "issue_index", repoID); err != nil {
+ if err := db.UpsertResourceIndex(ctx.Engine(), "issue_index", repoID); err != nil {
return err
}
var max int64
- if _, err := sess.Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
+ if _, err := ctx.Engine().Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
return err
}
- if _, err := sess.Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil {
+ if _, err := ctx.Engine().Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil {
return err
}
- return sess.Commit()
+ return committer.Commit()
}
// NewIssue creates new issue with labels for repository.
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
- idx, err := GetNextResourceIndex("issue_index", repo.ID)
+ idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate issue index failed: %v", err)
}
issue.Index = idx
- sess := x.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
return err
}
+ defer committer.Close()
- if err = newIssue(sess, issue.Poster, NewIssueOptions{
+ if err = newIssue(ctx.Engine(), issue.Poster, NewIssueOptions{
Repo: repo,
Issue: issue,
LabelIDs: labelIDs,
@@ -1034,7 +1039,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
return fmt.Errorf("newIssue: %v", err)
}
- if err = sess.Commit(); err != nil {
+ if err = committer.Commit(); err != nil {
return fmt.Errorf("Commit: %v", err)
}
@@ -1050,7 +1055,7 @@ func GetIssueByIndex(repoID, index int64) (*Issue, error) {
RepoID: repoID,
Index: index,
}
- has, err := x.Get(issue)
+ has, err := db.DefaultContext().Engine().Get(issue)
if err != nil {
return nil, err
} else if !has {
@@ -1068,7 +1073,7 @@ func GetIssueWithAttrsByIndex(repoID, index int64) (*Issue, error) {
return issue, issue.LoadAttributes()
}
-func getIssueByID(e Engine, id int64) (*Issue, error) {
+func getIssueByID(e db.Engine, id int64) (*Issue, error) {
issue := new(Issue)
has, err := e.ID(id).Get(issue)
if err != nil {
@@ -1081,24 +1086,24 @@ func getIssueByID(e Engine, id int64) (*Issue, error) {
// GetIssueWithAttrsByID returns an issue with attributes by given ID.
func GetIssueWithAttrsByID(id int64) (*Issue, error) {
- issue, err := getIssueByID(x, id)
+ issue, err := getIssueByID(db.DefaultContext().Engine(), id)
if err != nil {
return nil, err
}
- return issue, issue.loadAttributes(x)
+ return issue, issue.loadAttributes(db.DefaultContext().Engine())
}
// GetIssueByID returns an issue by given ID.
func GetIssueByID(id int64) (*Issue, error) {
- return getIssueByID(x, id)
+ return getIssueByID(db.DefaultContext().Engine(), id)
}
-func getIssuesByIDs(e Engine, issueIDs []int64) ([]*Issue, error) {
+func getIssuesByIDs(e db.Engine, issueIDs []int64) ([]*Issue, error) {
issues := make([]*Issue, 0, 10)
return issues, e.In("id", issueIDs).Find(&issues)
}
-func getIssueIDsByRepoID(e Engine, repoID int64) ([]int64, error) {
+func getIssueIDsByRepoID(e db.Engine, repoID int64) ([]int64, error) {
ids := make([]int64, 0, 10)
err := e.Table("issue").Cols("id").Where("repo_id = ?", repoID).Find(&ids)
return ids, err
@@ -1106,12 +1111,12 @@ func getIssueIDsByRepoID(e Engine, repoID int64) ([]int64, error) {
// GetIssueIDsByRepoID returns all issue ids by repo id
func GetIssueIDsByRepoID(repoID int64) ([]int64, error) {
- return getIssueIDsByRepoID(x, repoID)
+ return getIssueIDsByRepoID(db.DefaultContext().Engine(), repoID)
}
// GetIssuesByIDs return issues with the given IDs.
func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) {
- return getIssuesByIDs(x, issueIDs)
+ return getIssuesByIDs(db.DefaultContext().Engine(), issueIDs)
}
// IssuesOptions represents options of an issue.
@@ -1311,7 +1316,7 @@ func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64)
// CountIssuesByRepo map from repoID to number of issues matching the options
func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
@@ -1339,7 +1344,7 @@ func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
// GetRepoIDsForIssuesOptions find all repo ids for the given options
func GetRepoIDsForIssuesOptions(opts *IssuesOptions, user *User) ([]int64, error) {
repoIDs := make([]int64, 0, 5)
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
@@ -1359,7 +1364,7 @@ func GetRepoIDsForIssuesOptions(opts *IssuesOptions, user *User) ([]int64, error
// Issues returns a list of issues by given conditions.
func Issues(opts *IssuesOptions) ([]*Issue, error) {
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
sess.Join("INNER", "repository", "`issue`.repo_id = `repository`.id")
@@ -1381,7 +1386,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
// CountIssues number return of issues by given conditions.
func CountIssues(opts *IssuesOptions) (int64, error) {
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
countsSlice := make([]*struct {
@@ -1406,7 +1411,7 @@ func CountIssues(opts *IssuesOptions) (int64, error) {
// User permissions must be verified elsewhere if required.
func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) {
userIDs := make([]int64, 0, 5)
- return userIDs, x.Table("comment").
+ return userIDs, db.DefaultContext().Engine().Table("comment").
Cols("poster_id").
Where("issue_id = ?", issueID).
And("type in (?,?,?)", CommentTypeComment, CommentTypeCode, CommentTypeReview).
@@ -1416,7 +1421,7 @@ func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) {
// IsUserParticipantsOfIssue return true if user is participants of an issue
func IsUserParticipantsOfIssue(user *User, issue *Issue) bool {
- userIDs, err := issue.getParticipantIDsByIssue(x)
+ userIDs, err := issue.getParticipantIDsByIssue(db.DefaultContext().Engine())
if err != nil {
log.Error(err.Error())
return false
@@ -1425,7 +1430,7 @@ func IsUserParticipantsOfIssue(user *User, issue *Issue) bool {
}
// UpdateIssueMentions updates issue-user relations for mentioned users.
-func UpdateIssueMentions(ctx DBContext, issueID int64, mentions []*User) error {
+func UpdateIssueMentions(ctx *db.Context, issueID int64, mentions []*User) error {
if len(mentions) == 0 {
return nil
}
@@ -1482,6 +1487,12 @@ type IssueStatsOptions struct {
IssueIDs []int64
}
+const (
+ // When queries are broken down in parts because of the number
+ // of parameters, attempt to break by this amount
+ maxQueryParameters = 300
+)
+
// GetIssueStats returns issue statistic information by given conditions.
func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
if len(opts.IssueIDs) <= maxQueryParameters {
@@ -1518,7 +1529,7 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
stats := &IssueStats{}
countSession := func(opts *IssueStatsOptions) *xorm.Session {
- sess := x.
+ sess := db.DefaultContext().Engine().
Where("issue.repo_id = ?", opts.RepoID)
if len(opts.IssueIDs) > 0 {
@@ -1612,7 +1623,7 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
}
sess := func(cond builder.Cond) *xorm.Session {
- s := x.Where(cond)
+ s := db.DefaultContext().Engine().Where(cond)
if len(opts.LabelIDs) > 0 {
s.Join("INNER", "issue_label", "issue_label.issue_id = issue.id").
In("issue_label.label_id", opts.LabelIDs)
@@ -1724,7 +1735,7 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen, numClosed int64) {
countSession := func(isClosed, isPull bool, repoID int64) *xorm.Session {
- sess := x.
+ sess := db.DefaultContext().Engine().
Where("is_closed = ?", isClosed).
And("is_pull = ?", isPull).
And("repo_id = ?", repoID)
@@ -1776,7 +1787,7 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6
ID int64
UpdatedUnix int64
}, 0, limit)
- err := x.Distinct("id", "updated_unix").Table("issue").Where(cond).
+ err := db.DefaultContext().Engine().Distinct("id", "updated_unix").Table("issue").Where(cond).
OrderBy("`updated_unix` DESC").Limit(limit, start).
Find(&res)
if err != nil {
@@ -1786,7 +1797,7 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6
ids = append(ids, r.ID)
}
- total, err := x.Distinct("id").Table("issue").Where(cond).Count()
+ total, err := db.DefaultContext().Engine().Distinct("id").Table("issue").Where(cond).Count()
if err != nil {
return 0, nil, err
}
@@ -1798,7 +1809,7 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6
// If the issue status is changed a statusChangeComment is returned
// similarly if the title is changed the titleChanged bool is set to true
func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, titleChanged bool, err error) {
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return nil, false, err
@@ -1857,7 +1868,7 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us
return nil
}
- sess := x.NewSession()
+ sess := db.DefaultContext().NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
@@ -1883,7 +1894,7 @@ type DependencyInfo struct {
}
// getParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author
-func (issue *Issue) getParticipantIDsByIssue(e Engine) ([]int64, error) {
+func (issue *Issue) getParticipantIDsByIssue(e db.Engine) ([]int64, error) {
if issue == nil {
return nil, nil
}
@@ -1905,7 +1916,7 @@ func (issue *Issue) getParticipantIDsByIssue(e Engine) ([]int64, error) {
}
// Get Blocked By Dependencies, aka all issues this issue is blocked by.
-func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) {
+func (issue *Issue) getBlockedByDependencies(e db.Engine) (issueDeps []*DependencyInfo, err error) {
return issueDeps, e.
Table("issue").
Join("INNER", "repository", "repository.id = issue.repo_id").
@@ -1917,7 +1928,7 @@ func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyI
}
// Get Blocking Dependencies, aka all issues this issue blocks.
-func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) {
+func (issue *Issue) getBlockingDependencies(e db.Engine) (issueDeps []*DependencyInfo, err error) {
return issueDeps, e.
Table("issue").
Join("INNER", "repository", "repository.id = issue.repo_id").
@@ -1930,15 +1941,15 @@ func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyIn
// BlockedByDependencies finds all Dependencies an issue is blocked by
func (issue *Issue) BlockedByDependencies() ([]*DependencyInfo, error) {
- return issue.getBlockedByDependencies(x)
+ return issue.getBlockedByDependencies(db.DefaultContext().Engine())
}
// BlockingDependencies returns all blocking dependencies, aka all other issues a given issue blocks
func (issue *Issue) BlockingDependencies() ([]*DependencyInfo, error) {
- return issue.getBlockingDependencies(x)
+ return issue.getBlockingDependencies(db.DefaultContext().Engine())
}
-func (issue *Issue) updateClosedNum(e Engine) (err error) {
+func (issue *Issue) updateClosedNum(e db.Engine) (err error) {
if issue.IsPull {
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=(SELECT count(*) FROM issue WHERE repo_id=? AND is_pull=? AND is_closed=?) WHERE id=?",
issue.RepoID,
@@ -1958,7 +1969,7 @@ func (issue *Issue) updateClosedNum(e Engine) (err error) {
}
// FindAndUpdateIssueMentions finds users mentioned in the given content string, and saves them in the database.
-func (issue *Issue) FindAndUpdateIssueMentions(ctx DBContext, doer *User, content string) (mentions []*User, err error) {
+func (issue *Issue) FindAndUpdateIssueMentions(ctx *db.Context, doer *User, content string) (mentions []*User, err error) {
rawMentions := references.FindAllMentionsMarkdown(content)
mentions, err = issue.ResolveMentionsByVisibility(ctx, doer, rawMentions)
if err != nil {
@@ -1972,18 +1983,18 @@ func (issue *Issue) FindAndUpdateIssueMentions(ctx DBContext, doer *User, conten
// ResolveMentionsByVisibility returns the users mentioned in an issue, removing those that
// don't have access to reading it. Teams are expanded into their users, but organizations are ignored.
-func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, mentions []string) (users []*User, err error) {
+func (issue *Issue) ResolveMentionsByVisibility(ctx *db.Context, doer *User, mentions []string) (users []*User, err error) {
if len(mentions) == 0 {
return
}
- if err = issue.loadRepo(ctx.e); err != nil {
+ if err = issue.loadRepo(ctx.Engine()); err != nil {
return
}
resolved := make(map[string]bool, 10)
var mentionTeams []string
- if err := issue.Repo.getOwner(ctx.e); err != nil {
+ if err := issue.Repo.getOwner(ctx.Engine()); err != nil {
return nil, err
}
@@ -2012,7 +2023,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
if issue.Repo.Owner.IsOrganization() && len(mentionTeams) > 0 {
teams := make([]*Team, 0, len(mentionTeams))
- if err := ctx.e.
+ if err := ctx.Engine().
Join("INNER", "team_repo", "team_repo.team_id = team.id").
Where("team_repo.repo_id=?", issue.Repo.ID).
In("team.lower_name", mentionTeams).
@@ -2031,7 +2042,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true
continue
}
- has, err := ctx.e.Get(&TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
+ has, err := ctx.Engine().Get(&TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
if err != nil {
return nil, fmt.Errorf("get team units (%d): %v", team.ID, err)
}
@@ -2042,7 +2053,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
}
if len(checked) != 0 {
teamusers := make([]*User, 0, 20)
- if err := ctx.e.
+ if err := ctx.Engine().
Join("INNER", "team_user", "team_user.uid = `user`.id").
In("`team_user`.team_id", checked).
And("`user`.is_active = ?", true).
@@ -2079,7 +2090,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
}
unchecked := make([]*User, 0, len(mentionUsers))
- if err := ctx.e.
+ if err := ctx.Engine().
Where("`user`.is_active = ?", true).
And("`user`.prohibit_login = ?", false).
In("`user`.lower_name", mentionUsers).
@@ -2091,7 +2102,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
continue
}
// Normal users must have read access to the referencing issue
- perm, err := getUserRepoPermission(ctx.e, issue.Repo, user)
+ perm, err := getUserRepoPermission(ctx.Engine(), issue.Repo, user)
if err != nil {
return nil, fmt.Errorf("getUserRepoPermission [%d]: %v", user.ID, err)
}
@@ -2106,7 +2117,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
// UpdateIssuesMigrationsByType updates all migrated repositories' issues from gitServiceType to replace originalAuthorID to posterID
func UpdateIssuesMigrationsByType(gitServiceType structs.GitServiceType, originalAuthorID string, posterID int64) error {
- _, err := x.Table("issue").
+ _, err := db.DefaultContext().Engine().Table("issue").
Where("repo_id IN (SELECT id FROM repository WHERE original_service_type = ?)", gitServiceType).
And("original_author_id = ?", originalAuthorID).
Update(map[string]interface{}{
@@ -2119,7 +2130,7 @@ func UpdateIssuesMigrationsByType(gitServiceType structs.GitServiceType, origina
// UpdateReactionsMigrationsByType updates all migrated repositories' reactions from gitServiceType to replace originalAuthorID to posterID
func UpdateReactionsMigrationsByType(gitServiceType structs.GitServiceType, originalAuthorID string, userID int64) error {
- _, err := x.Table("reaction").
+ _, err := db.DefaultContext().Engine().Table("reaction").
Where("original_author_id = ?", originalAuthorID).
And(migratedIssueCond(gitServiceType)).
Update(map[string]interface{}{
@@ -2130,7 +2141,7 @@ func UpdateReactionsMigrationsByType(gitServiceType structs.GitServiceType, orig
return err
}
-func deleteIssuesByRepoID(sess Engine, repoID int64) (attachmentPaths []string, err error) {
+func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []string, err error) {
deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID})
// Delete comments and attachments