@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
@ -60,7 +61,7 @@ type Issue struct {
UpdatedUnix timeutil . TimeStamp ` xorm:"INDEX updated" `
ClosedUnix timeutil . TimeStamp ` xorm:"INDEX" `
Attachments [ ] * Attachment ` xorm:"-" `
Attachments [ ] * repo_model . Attachment ` xorm:"-" `
Comments [ ] * Comment ` xorm:"-" `
Reactions ReactionList ` xorm:"-" `
TotalTrackedTime int64 ` xorm:"-" `
@ -273,7 +274,8 @@ func (issue *Issue) loadMilestone(e db.Engine) (err error) {
return nil
}
func ( issue * Issue ) loadAttributes ( e db . Engine ) ( err error ) {
func ( issue * Issue ) loadAttributes ( ctx context . Context ) ( err error ) {
e := db . GetEngine ( ctx )
if err = issue . loadRepo ( e ) ; err != nil {
return
}
@ -304,7 +306,7 @@ func (issue *Issue) loadAttributes(e db.Engine) (err error) {
}
if issue . Attachments == nil {
issue . Attachments , err = getAttachmentsByIssueID ( e , issue . ID )
issue . Attachments , err = repo_model . GetAttachmentsByIssueIDCtx ( ctx , issue . ID )
if err != nil {
return fmt . Errorf ( "getAttachmentsByIssueID [%d]: %v" , issue . ID , err )
}
@ -328,7 +330,7 @@ func (issue *Issue) loadAttributes(e db.Engine) (err error) {
// LoadAttributes loads the attribute of this issue.
func ( issue * Issue ) LoadAttributes ( ) error {
return issue . loadAttributes ( db . GetEngine ( db . DefaultContext ) )
return issue . loadAttributes ( db . DefaultContext )
}
// LoadMilestone load milestone of this issue.
@ -426,12 +428,12 @@ func (issue *Issue) HasLabel(labelID int64) bool {
return issue . hasLabel ( db . GetEngine ( db . DefaultContext ) , labelID )
}
func ( issue * Issue ) addLabel ( e db . Engine , label * Label , doer * User ) error {
return newIssueLabel ( e , issue , label , doer )
func ( issue * Issue ) addLabel ( ctx context . Context , label * Label , doer * User ) error {
return newIssueLabel ( ctx , issue , label , doer )
}
func ( issue * Issue ) addLabels ( e db . Engine , labels [ ] * Label , doer * User ) error {
return newIssueLabels ( e , issue , labels , doer )
func ( issue * Issue ) addLabels ( ctx context . Context , labels [ ] * Label , doer * User ) error {
return newIssueLabels ( ctx , issue , labels , doer )
}
func ( issue * Issue ) getLabels ( e db . Engine ) ( err error ) {
@ -446,17 +448,17 @@ func (issue *Issue) getLabels(e db.Engine) (err error) {
return nil
}
func ( issue * Issue ) removeLabel ( e db . Engine , doer * User , label * Label ) error {
return deleteIssueLabel ( e , issue , label , doer )
func ( issue * Issue ) removeLabel ( ctx context . Context , doer * User , label * Label ) error {
return deleteIssueLabel ( ctx , issue , label , doer )
}
func ( issue * Issue ) clearLabels ( e db . Engine , doer * User ) ( err error ) {
if err = issue . getLabels ( e ) ; err != nil {
func ( issue * Issue ) clearLabels ( ctx context . Context , doer * User ) ( err error ) {
if err = issue . getLabels ( db . G etEngine ( ctx ) ) ; err != nil {
return fmt . Errorf ( "getLabels: %v" , err )
}
for i := range issue . Labels {
if err = issue . removeLabel ( e , doer , issue . Labels [ i ] ) ; err != nil {
if err = issue . removeLabel ( ctx , doer , issue . Labels [ i ] ) ; err != nil {
return fmt . Errorf ( "removeLabel: %v" , err )
}
}
@ -487,7 +489,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return ErrRepoLabelNotExist { }
}
if err = issue . clearLabels ( db . GetEngine ( ctx ) , doer ) ; err != nil {
if err = issue . clearLabels ( ctx , doer ) ; err != nil {
return err
}
@ -561,13 +563,13 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) {
toRemove = append ( toRemove , issue . Labels [ removeIndex : ] ... )
if len ( toAdd ) > 0 {
if err = issue . addLabels ( db . GetEngine ( ctx ) , toAdd , doer ) ; err != nil {
if err = issue . addLabels ( ctx , toAdd , doer ) ; err != nil {
return fmt . Errorf ( "addLabels: %v" , err )
}
}
for _ , l := range toRemove {
if err = issue . removeLabel ( db . GetEngine ( ctx ) , doer , l ) ; err != nil {
if err = issue . removeLabel ( ctx , doer , l ) ; err != nil {
return fmt . Errorf ( "removeLabel: %v" , err )
}
}
@ -596,9 +598,9 @@ func updateIssueCols(e db.Engine, issue *Issue, cols ...string) error {
return nil
}
func ( issue * Issue ) changeStatus ( e db . Engine , doer * User , isClosed , isMergePull bool ) ( * Comment , error ) {
func ( issue * Issue ) changeStatus ( ctx context . Context , doer * User , isClosed , isMergePull bool ) ( * Comment , error ) {
// Reload the issue
currentIssue , err := getIssueByID ( e , issue . ID )
currentIssue , err := getIssueByID ( db . G etEngine ( ctx ) , issue . ID )
if err != nil {
return nil , err
}
@ -616,10 +618,11 @@ func (issue *Issue) changeStatus(e db.Engine, doer *User, isClosed, isMergePull
}
issue . IsClosed = isClosed
return issue . doChangeStatus ( e , doer , isMergePull )
return issue . doChangeStatus ( ctx , doer , isMergePull )
}
func ( issue * Issue ) doChangeStatus ( e db . Engine , doer * User , isMergePull bool ) ( * Comment , error ) {
func ( issue * Issue ) doChangeStatus ( ctx context . Context , doer * User , isMergePull bool ) ( * Comment , error ) {
e := db . GetEngine ( ctx )
// 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
@ -672,7 +675,7 @@ func (issue *Issue) doChangeStatus(e db.Engine, doer *User, isMergePull bool) (*
cmtType = CommentTypeMergePull
}
return createComment ( e , & CreateCommentOptions {
return createComment ( ctx , & CreateCommentOptions {
Type : cmtType ,
Doer : doer ,
Repo : issue . Repo ,
@ -695,7 +698,7 @@ func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (*Comment, error) {
return nil , err
}
comment , err := issue . changeStatus ( db . GetEngine ( ctx ) , doer , isClosed , false )
comment , err := issue . changeStatus ( ctx , doer , isClosed , false )
if err != nil {
return nil , err
}
@ -731,10 +734,10 @@ func (issue *Issue) ChangeTitle(doer *User, oldTitle string) (err error) {
OldTitle : oldTitle ,
NewTitle : issue . Title ,
}
if _ , err = createComment ( db . GetEngine ( ctx ) , opts ) ; err != nil {
if _ , err = createComment ( ctx , opts ) ; err != nil {
return fmt . Errorf ( "createComment: %v" , err )
}
if err = issue . addCrossReferences ( db . GetEngine ( ctx ) , doer , true ) ; err != nil {
if err = issue . addCrossReferences ( ctx , doer , true ) ; err != nil {
return err
}
@ -767,7 +770,7 @@ func (issue *Issue) ChangeRef(doer *User, oldRef string) (err error) {
OldRef : oldRefFriendly ,
NewRef : newRefFriendly ,
}
if _ , err = createComment ( db . GetEngine ( ctx ) , opts ) ; err != nil {
if _ , err = createComment ( ctx , opts ) ; err != nil {
return fmt . Errorf ( "createComment: %v" , err )
}
@ -792,7 +795,7 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc
Issue : issue ,
OldRef : branchName ,
}
if _ , err = createComment ( db . GetEngine ( ctx ) , opts ) ; err != nil {
if _ , err = createComment ( ctx , opts ) ; err != nil {
return err
}
@ -806,13 +809,13 @@ func (issue *Issue) UpdateAttachments(uuids []string) (err error) {
return err
}
defer committer . Close ( )
attachments , err := getAttachmentsByUUIDs ( db . GetEngine ( ctx ) , uuids )
attachments , err := repo_model . GetAttachmentsByUUIDs ( ctx , 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 ( db . GetEngine ( ctx ) , attachments [ i ] ) ; err != nil {
if err := repo_model . UpdateAttachmentCtx ( ctx , attachments [ i ] ) ; err != nil {
return fmt . Errorf ( "update attachment [id: %d]: %v" , attachments [ i ] . ID , err )
}
}
@ -838,7 +841,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return fmt . Errorf ( "SaveIssueContentHistory: %v" , err )
}
if err = issue . addCrossReferences ( ctx . Engine ( ) , doer , true ) ; err != nil {
if err = issue . addCrossReferences ( ctx , doer , true ) ; err != nil {
return fmt . Errorf ( "addCrossReferences: %v" , err )
}
@ -908,7 +911,8 @@ type NewIssueOptions struct {
IsPull bool
}
func newIssue ( e db . Engine , doer * User , opts NewIssueOptions ) ( err error ) {
func newIssue ( ctx context . Context , doer * User , opts NewIssueOptions ) ( err error ) {
e := db . GetEngine ( ctx )
opts . Issue . Title = strings . TrimSpace ( opts . Issue . Title )
if opts . Issue . MilestoneID > 0 {
@ -949,7 +953,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
OldMilestoneID : 0 ,
MilestoneID : opts . Issue . MilestoneID ,
}
if _ , err = createComment ( e , opts ) ; err != nil {
if _ , err = createComment ( ctx , opts ) ; err != nil {
return err
}
}
@ -981,7 +985,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
continue
}
if err = opts . Issue . addLabel ( e , label , opts . Issue . Poster ) ; err != nil {
if err = opts . Issue . addLabel ( ctx , label , opts . Issue . Poster ) ; err != nil {
return fmt . Errorf ( "addLabel [id: %d]: %v" , label . ID , err )
}
}
@ -992,7 +996,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
}
if len ( opts . Attachments ) > 0 {
attachments , err := getAttachmentsByUUIDs ( e , opts . Attachments )
attachments , err := repo_model . GetAttachmentsByUUIDs ( ctx , opts . Attachments )
if err != nil {
return fmt . Errorf ( "getAttachmentsByUUIDs [uuids: %v]: %v" , opts . Attachments , err )
}
@ -1004,7 +1008,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
}
}
}
if err = opts . Issue . loadAttributes ( e ) ; err != nil {
if err = opts . Issue . loadAttributes ( ctx ) ; err != nil {
return err
}
@ -1013,7 +1017,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) {
return err
}
return opts . Issue . addCrossReferences ( e , doer , false )
return opts . Issue . addCrossReferences ( ctx , doer , false )
}
// RecalculateIssueIndexForRepo create issue_index for repo if not exist and
@ -1056,7 +1060,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
}
defer committer . Close ( )
if err = newIssue ( db . GetEngine ( ctx ) , issue . Poster , NewIssueOptions {
if err = newIssue ( ctx , issue . Poster , NewIssueOptions {
Repo : repo ,
Issue : issue ,
LabelIDs : labelIDs ,
@ -1119,7 +1123,7 @@ func GetIssueWithAttrsByID(id int64) (*Issue, error) {
if err != nil {
return nil , err
}
return issue , issue . loadAttributes ( db . GetEngine ( db . DefaultContext ) )
return issue , issue . loadAttributes ( db . DefaultContext )
}
// GetIssueByID returns an issue by given ID.
@ -1838,11 +1842,12 @@ 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 := db . NewSession ( db . DefaultContext )
defer sess . Close ( )
if err := sess . Begin ( ) ; err != nil {
ctx , committer , err := db . TxContext ( )
if err != nil {
return nil , false , err
}
defer committer . Close ( )
sess := db . GetEngine ( ctx )
if err := issue . loadRepo ( sess ) ; err != nil {
return nil , false , fmt . Errorf ( "loadRepo: %v" , err )
@ -1871,23 +1876,23 @@ func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, t
OldTitle : currentIssue . Title ,
NewTitle : issue . Title ,
}
_ , err := createComment ( sess , opts )
_ , err := createComment ( ctx , opts )
if err != nil {
return nil , false , fmt . Errorf ( "createComment: %v" , err )
}
}
if currentIssue . IsClosed != issue . IsClosed {
statusChangeComment , err = issue . doChangeStatus ( sess , doer , false )
statusChangeComment , err = issue . doChangeStatus ( ctx , doer , false )
if err != nil {
return nil , false , err
}
}
if err := issue . addCrossReferences ( sess , doer , true ) ; err != nil {
if err := issue . addCrossReferences ( ctx , doer , true ) ; err != nil {
return nil , false , err
}
return statusChangeComment , titleChanged , sess . Commit ( )
return statusChangeComment , titleChanged , committer . Commit ( )
}
// UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
@ -1897,11 +1902,12 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us
return nil
}
sess := db . NewSession ( db . DefaultContext )
defer sess . Close ( )
if err := sess . Begin ( ) ; err != nil {
ctx , committer , err := db . TxContext ( )
if err != nil {
return err
}
defer committer . Close ( )
sess := db . GetEngine ( ctx )
// Update the deadline
if err = updateIssueCols ( sess , & Issue { ID : issue . ID , DeadlineUnix : deadlineUnix } , "deadline_unix" ) ; err != nil {
@ -1909,11 +1915,11 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us
}
// Make the comment
if _ , err = createDeadlineComment ( sess , doer , issue , deadlineUnix ) ; err != nil {
if _ , err = createDeadlineComment ( ctx , doer , issue , deadlineUnix ) ; err != nil {
return fmt . Errorf ( "createRemovedDueDateComment: %v" , err )
}
return sess . Commit ( )
return committer . Commit ( )
}
// DependencyInfo represents high level information about an issue which is a dependency of another issue.
@ -2244,7 +2250,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin
return
}
var attachments [ ] * Attachment
var attachments [ ] * repo_model . Attachment
if err = sess . In ( "issue_id" , deleteCond ) .
Find ( & attachments ) ; err != nil {
return
@ -2255,7 +2261,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin
}
if _ , err = sess . In ( "issue_id" , deleteCond ) .
Delete ( & Attachment { } ) ; err != nil {
Delete ( & repo_model . Attachment { } ) ; err != nil {
return
}