mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Move attachment into models/repo/ (#17650)
* Move attachment into models/repo/ * Fix test * Fix bug
This commit is contained in:
		| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/migrations" | 	"code.gitea.io/gitea/models/migrations" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| @@ -79,7 +80,7 @@ var CmdMigrateStorage = cli.Command{ | |||||||
| } | } | ||||||
|  |  | ||||||
| func migrateAttachments(dstStorage storage.ObjectStorage) error { | func migrateAttachments(dstStorage storage.ObjectStorage) error { | ||||||
| 	return models.IterateAttachment(func(attach *models.Attachment) error { | 	return repo_model.IterateAttachment(func(attach *repo_model.Attachment) error { | ||||||
| 		_, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath()) | 		_, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath()) | ||||||
| 		return err | 		return err | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| 	"code.gitea.io/gitea/modules/test" | 	"code.gitea.io/gitea/modules/test" | ||||||
|  |  | ||||||
| @@ -122,7 +122,7 @@ func TestGetAttachment(t *testing.T) { | |||||||
| 		t.Run(tc.name, func(t *testing.T) { | 		t.Run(tc.name, func(t *testing.T) { | ||||||
| 			//Write empty file to be available for response | 			//Write empty file to be available for response | ||||||
| 			if tc.createFile { | 			if tc.createFile { | ||||||
| 				_, err := storage.Attachments.Save(models.AttachmentRelativePath(tc.uuid), strings.NewReader("hello world"), -1) | 				_, err := storage.Attachments.Save(repo_model.AttachmentRelativePath(tc.uuid), strings.NewReader("hello world"), -1) | ||||||
| 				assert.NoError(t, err) | 				assert.NoError(t, err) | ||||||
| 			} | 			} | ||||||
| 			//Actual test | 			//Actual test | ||||||
|   | |||||||
| @@ -1679,29 +1679,6 @@ func (err ErrMilestoneNotExist) Error() string { | |||||||
| 	return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID) | 	return fmt.Sprintf("milestone does not exist [id: %d, repo_id: %d]", err.ID, err.RepoID) | ||||||
| } | } | ||||||
|  |  | ||||||
| //    _____   __    __                .__                           __ |  | ||||||
| //   /  _  \_/  |__/  |______    ____ |  |__   _____   ____   _____/  |_ |  | ||||||
| //  /  /_\  \   __\   __\__  \ _/ ___\|  |  \ /     \_/ __ \ /    \   __\ |  | ||||||
| // /    |    \  |  |  |  / __ \\  \___|   Y  \  Y Y  \  ___/|   |  \  | |  | ||||||
| // \____|__  /__|  |__| (____  /\___  >___|  /__|_|  /\___  >___|  /__| |  | ||||||
| //         \/                \/     \/     \/      \/     \/     \/ |  | ||||||
|  |  | ||||||
| // ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error. |  | ||||||
| type ErrAttachmentNotExist struct { |  | ||||||
| 	ID   int64 |  | ||||||
| 	UUID string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrAttachmentNotExist checks if an error is a ErrAttachmentNotExist. |  | ||||||
| func IsErrAttachmentNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrAttachmentNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrAttachmentNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ___________ | // ___________ | ||||||
| // \__    ___/___ _____    _____ | // \__    ___/___ _____    _____ | ||||||
| //   |    |_/ __ \\__  \  /     \ | //   |    |_/ __ \\__  \  /     \ | ||||||
| @@ -1758,7 +1735,7 @@ type ErrUploadNotExist struct { | |||||||
|  |  | ||||||
| // IsErrUploadNotExist checks if an error is a ErrUploadNotExist. | // IsErrUploadNotExist checks if an error is a ErrUploadNotExist. | ||||||
| func IsErrUploadNotExist(err error) bool { | func IsErrUploadNotExist(err error) bool { | ||||||
| 	_, ok := err.(ErrAttachmentNotExist) | 	_, ok := err.(ErrUploadNotExist) | ||||||
| 	return ok | 	return ok | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										108
									
								
								models/issue.go
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								models/issue.go
									
									
									
									
									
								
							| @@ -15,6 +15,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/issues" | 	"code.gitea.io/gitea/models/issues" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -60,7 +61,7 @@ type Issue struct { | |||||||
| 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	ClosedUnix  timeutil.TimeStamp `xorm:"INDEX"` | 	ClosedUnix  timeutil.TimeStamp `xorm:"INDEX"` | ||||||
|  |  | ||||||
| 	Attachments      []*Attachment `xorm:"-"` | 	Attachments      []*repo_model.Attachment `xorm:"-"` | ||||||
| 	Comments         []*Comment               `xorm:"-"` | 	Comments         []*Comment               `xorm:"-"` | ||||||
| 	Reactions        ReactionList             `xorm:"-"` | 	Reactions        ReactionList             `xorm:"-"` | ||||||
| 	TotalTrackedTime int64                    `xorm:"-"` | 	TotalTrackedTime int64                    `xorm:"-"` | ||||||
| @@ -273,7 +274,8 @@ func (issue *Issue) loadMilestone(e db.Engine) (err error) { | |||||||
| 	return nil | 	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 { | 	if err = issue.loadRepo(e); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -304,7 +306,7 @@ func (issue *Issue) loadAttributes(e db.Engine) (err error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if issue.Attachments == nil { | 	if issue.Attachments == nil { | ||||||
| 		issue.Attachments, err = getAttachmentsByIssueID(e, issue.ID) | 		issue.Attachments, err = repo_model.GetAttachmentsByIssueIDCtx(ctx, issue.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("getAttachmentsByIssueID [%d]: %v", issue.ID, err) | 			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. | // LoadAttributes loads the attribute of this issue. | ||||||
| func (issue *Issue) LoadAttributes() error { | func (issue *Issue) LoadAttributes() error { | ||||||
| 	return issue.loadAttributes(db.GetEngine(db.DefaultContext)) | 	return issue.loadAttributes(db.DefaultContext) | ||||||
| } | } | ||||||
|  |  | ||||||
| // LoadMilestone load milestone of this issue. | // 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) | 	return issue.hasLabel(db.GetEngine(db.DefaultContext), labelID) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) addLabel(e db.Engine, label *Label, doer *User) error { | func (issue *Issue) addLabel(ctx context.Context, label *Label, doer *User) error { | ||||||
| 	return newIssueLabel(e, issue, label, doer) | 	return newIssueLabel(ctx, issue, label, doer) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) addLabels(e db.Engine, labels []*Label, doer *User) error { | func (issue *Issue) addLabels(ctx context.Context, labels []*Label, doer *User) error { | ||||||
| 	return newIssueLabels(e, issue, labels, doer) | 	return newIssueLabels(ctx, issue, labels, doer) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) getLabels(e db.Engine) (err error) { | func (issue *Issue) getLabels(e db.Engine) (err error) { | ||||||
| @@ -446,17 +448,17 @@ func (issue *Issue) getLabels(e db.Engine) (err error) { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) removeLabel(e db.Engine, doer *User, label *Label) error { | func (issue *Issue) removeLabel(ctx context.Context, doer *User, label *Label) error { | ||||||
| 	return deleteIssueLabel(e, issue, label, doer) | 	return deleteIssueLabel(ctx, issue, label, doer) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) clearLabels(e db.Engine, doer *User) (err error) { | func (issue *Issue) clearLabels(ctx context.Context, doer *User) (err error) { | ||||||
| 	if err = issue.getLabels(e); err != nil { | 	if err = issue.getLabels(db.GetEngine(ctx)); err != nil { | ||||||
| 		return fmt.Errorf("getLabels: %v", err) | 		return fmt.Errorf("getLabels: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for i := range issue.Labels { | 	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) | 			return fmt.Errorf("removeLabel: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -487,7 +489,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) { | |||||||
| 		return ErrRepoLabelNotExist{} | 		return ErrRepoLabelNotExist{} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = issue.clearLabels(db.GetEngine(ctx), doer); err != nil { | 	if err = issue.clearLabels(ctx, doer); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -561,13 +563,13 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) { | |||||||
| 	toRemove = append(toRemove, issue.Labels[removeIndex:]...) | 	toRemove = append(toRemove, issue.Labels[removeIndex:]...) | ||||||
|  |  | ||||||
| 	if len(toAdd) > 0 { | 	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) | 			return fmt.Errorf("addLabels: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, l := range toRemove { | 	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) | 			return fmt.Errorf("removeLabel: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -596,9 +598,9 @@ func updateIssueCols(e db.Engine, issue *Issue, cols ...string) error { | |||||||
| 	return nil | 	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 | 	// Reload the issue | ||||||
| 	currentIssue, err := getIssueByID(e, issue.ID) | 	currentIssue, err := getIssueByID(db.GetEngine(ctx), issue.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -616,10 +618,11 @@ func (issue *Issue) changeStatus(e db.Engine, doer *User, isClosed, isMergePull | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	issue.IsClosed = isClosed | 	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 | 	// Check for open dependencies | ||||||
| 	if issue.IsClosed && issue.Repo.isDependenciesEnabled(e) { | 	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 | 		// 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 | 		cmtType = CommentTypeMergePull | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return createComment(e, &CreateCommentOptions{ | 	return createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:  cmtType, | 		Type:  cmtType, | ||||||
| 		Doer:  doer, | 		Doer:  doer, | ||||||
| 		Repo:  issue.Repo, | 		Repo:  issue.Repo, | ||||||
| @@ -695,7 +698,7 @@ func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (*Comment, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comment, err := issue.changeStatus(db.GetEngine(ctx), doer, isClosed, false) | 	comment, err := issue.changeStatus(ctx, doer, isClosed, false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -731,10 +734,10 @@ func (issue *Issue) ChangeTitle(doer *User, oldTitle string) (err error) { | |||||||
| 		OldTitle: oldTitle, | 		OldTitle: oldTitle, | ||||||
| 		NewTitle: issue.Title, | 		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) | 		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 | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -767,7 +770,7 @@ func (issue *Issue) ChangeRef(doer *User, oldRef string) (err error) { | |||||||
| 		OldRef: oldRefFriendly, | 		OldRef: oldRefFriendly, | ||||||
| 		NewRef: newRefFriendly, | 		NewRef: newRefFriendly, | ||||||
| 	} | 	} | ||||||
| 	if _, err = createComment(db.GetEngine(ctx), opts); err != nil { | 	if _, err = createComment(ctx, opts); err != nil { | ||||||
| 		return fmt.Errorf("createComment: %v", err) | 		return fmt.Errorf("createComment: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -792,7 +795,7 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc | |||||||
| 		Issue:  issue, | 		Issue:  issue, | ||||||
| 		OldRef: branchName, | 		OldRef: branchName, | ||||||
| 	} | 	} | ||||||
| 	if _, err = createComment(db.GetEngine(ctx), opts); err != nil { | 	if _, err = createComment(ctx, opts); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -806,13 +809,13 @@ func (issue *Issue) UpdateAttachments(uuids []string) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
| 	attachments, err := getAttachmentsByUUIDs(db.GetEngine(ctx), uuids) | 	attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) | 		return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) | ||||||
| 	} | 	} | ||||||
| 	for i := 0; i < len(attachments); i++ { | 	for i := 0; i < len(attachments); i++ { | ||||||
| 		attachments[i].IssueID = issue.ID | 		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) | 			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) | 		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) | 		return fmt.Errorf("addCrossReferences: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -908,7 +911,8 @@ type NewIssueOptions struct { | |||||||
| 	IsPull      bool | 	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) | 	opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) | ||||||
|  |  | ||||||
| 	if opts.Issue.MilestoneID > 0 { | 	if opts.Issue.MilestoneID > 0 { | ||||||
| @@ -949,7 +953,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { | |||||||
| 			OldMilestoneID: 0, | 			OldMilestoneID: 0, | ||||||
| 			MilestoneID:    opts.Issue.MilestoneID, | 			MilestoneID:    opts.Issue.MilestoneID, | ||||||
| 		} | 		} | ||||||
| 		if _, err = createComment(e, opts); err != nil { | 		if _, err = createComment(ctx, opts); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -981,7 +985,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { | |||||||
| 				continue | 				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) | 				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 { | 	if len(opts.Attachments) > 0 { | ||||||
| 		attachments, err := getAttachmentsByUUIDs(e, opts.Attachments) | 		attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) | 			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 | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1013,7 +1017,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { | |||||||
| 		return err | 		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 | // 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() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if err = newIssue(db.GetEngine(ctx), issue.Poster, NewIssueOptions{ | 	if err = newIssue(ctx, issue.Poster, NewIssueOptions{ | ||||||
| 		Repo:        repo, | 		Repo:        repo, | ||||||
| 		Issue:       issue, | 		Issue:       issue, | ||||||
| 		LabelIDs:    labelIDs, | 		LabelIDs:    labelIDs, | ||||||
| @@ -1119,7 +1123,7 @@ func GetIssueWithAttrsByID(id int64) (*Issue, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return issue, issue.loadAttributes(db.GetEngine(db.DefaultContext)) | 	return issue, issue.loadAttributes(db.DefaultContext) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetIssueByID returns an issue by given ID. | // 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 | // If the issue status is changed a statusChangeComment is returned | ||||||
| // similarly if the title is changed the titleChanged bool is set to true | // 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) { | func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, titleChanged bool, err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, false, err | 		return nil, false, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if err := issue.loadRepo(sess); err != nil { | 	if err := issue.loadRepo(sess); err != nil { | ||||||
| 		return nil, false, fmt.Errorf("loadRepo: %v", err) | 		return nil, false, fmt.Errorf("loadRepo: %v", err) | ||||||
| @@ -1871,23 +1876,23 @@ func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, t | |||||||
| 			OldTitle: currentIssue.Title, | 			OldTitle: currentIssue.Title, | ||||||
| 			NewTitle: issue.Title, | 			NewTitle: issue.Title, | ||||||
| 		} | 		} | ||||||
| 		_, err := createComment(sess, opts) | 		_, err := createComment(ctx, opts) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, false, fmt.Errorf("createComment: %v", err) | 			return nil, false, fmt.Errorf("createComment: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if currentIssue.IsClosed != issue.IsClosed { | 	if currentIssue.IsClosed != issue.IsClosed { | ||||||
| 		statusChangeComment, err = issue.doChangeStatus(sess, doer, false) | 		statusChangeComment, err = issue.doChangeStatus(ctx, doer, false) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, false, err | 			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 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. | // 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 | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	// Update the deadline | 	// Update the deadline | ||||||
| 	if err = updateIssueCols(sess, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil { | 	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 | 	// 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 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. | // 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 | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var attachments []*Attachment | 	var attachments []*repo_model.Attachment | ||||||
| 	if err = sess.In("issue_id", deleteCond). | 	if err = sess.In("issue_id", deleteCond). | ||||||
| 		Find(&attachments); err != nil { | 		Find(&attachments); err != nil { | ||||||
| 		return | 		return | ||||||
| @@ -2255,7 +2261,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err = sess.In("issue_id", deleteCond). | 	if _, err = sess.In("issue_id", deleteCond). | ||||||
| 		Delete(&Attachment{}); err != nil { | 		Delete(&repo_model.Attachment{}); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,12 +5,11 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"xorm.io/xorm" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // IssueAssignees saves all issue assignees | // IssueAssignees saves all issue assignees | ||||||
| @@ -94,26 +93,26 @@ func clearAssigneeByUserID(sess db.Engine, userID int64) (err error) { | |||||||
|  |  | ||||||
| // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. | // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. | ||||||
| func (issue *Issue) ToggleAssignee(doer *User, assigneeID int64) (removed bool, comment *Comment, err error) { | func (issue *Issue) ToggleAssignee(doer *User, assigneeID int64) (removed bool, comment *Comment, err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
|  |  | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return false, nil, err | 		return false, nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	removed, comment, err = issue.toggleAssignee(sess, doer, assigneeID, false) | 	removed, comment, err = issue.toggleAssignee(ctx, doer, assigneeID, false) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, nil, err | 		return false, nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := sess.Commit(); err != nil { | 	if err := committer.Commit(); err != nil { | ||||||
| 		return false, nil, err | 		return false, nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return removed, comment, nil | 	return removed, comment, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) toggleAssignee(sess *xorm.Session, doer *User, assigneeID int64, isCreate bool) (removed bool, comment *Comment, err error) { | func (issue *Issue) toggleAssignee(ctx context.Context, doer *User, assigneeID int64, isCreate bool) (removed bool, comment *Comment, err error) { | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
| 	removed, err = toggleUserAssignee(sess, issue, assigneeID) | 	removed, err = toggleUserAssignee(sess, issue, assigneeID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %v", err) | 		return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %v", err) | ||||||
| @@ -133,7 +132,7 @@ func (issue *Issue) toggleAssignee(sess *xorm.Session, doer *User, assigneeID in | |||||||
| 		AssigneeID:      assigneeID, | 		AssigneeID:      assigneeID, | ||||||
| 	} | 	} | ||||||
| 	// Comment | 	// Comment | ||||||
| 	comment, err = createComment(sess, opts) | 	comment, err = createComment(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, nil, fmt.Errorf("createComment: %v", err) | 		return false, nil, fmt.Errorf("createComment: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -147,7 +146,7 @@ func (issue *Issue) toggleAssignee(sess *xorm.Session, doer *User, assigneeID in | |||||||
| } | } | ||||||
|  |  | ||||||
| // toggles user assignee state in database | // toggles user assignee state in database | ||||||
| func toggleUserAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) { | func toggleUserAssignee(e db.Engine, issue *Issue, assigneeID int64) (removed bool, err error) { | ||||||
| 	// Check if the user exists | 	// Check if the user exists | ||||||
| 	assignee, err := getUserByID(e, assigneeID) | 	assignee, err := getUserByID(e, assigneeID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @@ -15,6 +16,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/issues" | 	"code.gitea.io/gitea/models/issues" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/json" | 	"code.gitea.io/gitea/modules/json" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -198,7 +200,7 @@ type Comment struct { | |||||||
| 	// Reference issue in commit message | 	// Reference issue in commit message | ||||||
| 	CommitSHA string `xorm:"VARCHAR(40)"` | 	CommitSHA string `xorm:"VARCHAR(40)"` | ||||||
|  |  | ||||||
| 	Attachments []*Attachment `xorm:"-"` | 	Attachments []*repo_model.Attachment `xorm:"-"` | ||||||
| 	Reactions   ReactionList             `xorm:"-"` | 	Reactions   ReactionList             `xorm:"-"` | ||||||
|  |  | ||||||
| 	// For view issue page. | 	// For view issue page. | ||||||
| @@ -300,7 +302,7 @@ func (c *Comment) AfterDelete() { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, err := DeleteAttachmentsByComment(c.ID, true) | 	_, err := repo_model.DeleteAttachmentsByComment(c.ID, true) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err) | 		log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err) | ||||||
| 	} | 	} | ||||||
| @@ -483,7 +485,7 @@ func (c *Comment) LoadAttachments() error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var err error | 	var err error | ||||||
| 	c.Attachments, err = getAttachmentsByCommentID(db.GetEngine(db.DefaultContext), c.ID) | 	c.Attachments, err = repo_model.GetAttachmentsByCommentIDCtx(db.DefaultContext, c.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("getAttachmentsByCommentID[%d]: %v", c.ID, err) | 		log.Error("getAttachmentsByCommentID[%d]: %v", c.ID, err) | ||||||
| 	} | 	} | ||||||
| @@ -492,23 +494,24 @@ func (c *Comment) LoadAttachments() error { | |||||||
|  |  | ||||||
| // UpdateAttachments update attachments by UUIDs for the comment | // UpdateAttachments update attachments by UUIDs for the comment | ||||||
| func (c *Comment) UpdateAttachments(uuids []string) error { | func (c *Comment) UpdateAttachments(uuids []string) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	attachments, err := getAttachmentsByUUIDs(sess, uuids) | 	defer committer.Close() | ||||||
|  |  | ||||||
|  | 	attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) | 		return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) | ||||||
| 	} | 	} | ||||||
| 	for i := 0; i < len(attachments); i++ { | 	for i := 0; i < len(attachments); i++ { | ||||||
| 		attachments[i].IssueID = c.IssueID | 		attachments[i].IssueID = c.IssueID | ||||||
| 		attachments[i].CommentID = c.ID | 		attachments[i].CommentID = c.ID | ||||||
| 		if err := updateAttachment(sess, 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) | 			return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // LoadAssigneeUserAndTeam if comment.Type is CommentTypeAssignees, then load assignees | // LoadAssigneeUserAndTeam if comment.Type is CommentTypeAssignees, then load assignees | ||||||
| @@ -715,7 +718,8 @@ func (c *Comment) LoadPushCommits() (err error) { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func createComment(e db.Engine, opts *CreateCommentOptions) (_ *Comment, err error) { | func createComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	var LabelID int64 | 	var LabelID int64 | ||||||
| 	if opts.Label != nil { | 	if opts.Label != nil { | ||||||
| 		LabelID = opts.Label.ID | 		LabelID = opts.Label.ID | ||||||
| @@ -763,18 +767,19 @@ func createComment(e db.Engine, opts *CreateCommentOptions) (_ *Comment, err err | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = updateCommentInfos(e, opts, comment); err != nil { | 	if err = updateCommentInfos(ctx, opts, comment); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = comment.addCrossReferences(e, opts.Doer, false); err != nil { | 	if err = comment.addCrossReferences(ctx, opts.Doer, false); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return comment, nil | 	return comment, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func updateCommentInfos(e db.Engine, opts *CreateCommentOptions, comment *Comment) (err error) { | func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment *Comment) (err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	// Check comment type. | 	// Check comment type. | ||||||
| 	switch opts.Type { | 	switch opts.Type { | ||||||
| 	case CommentTypeCode: | 	case CommentTypeCode: | ||||||
| @@ -797,7 +802,7 @@ func updateCommentInfos(e db.Engine, opts *CreateCommentOptions, comment *Commen | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Check attachments | 		// Check attachments | ||||||
| 		attachments, err := getAttachmentsByUUIDs(e, opts.Attachments) | 		attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) | 			return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) | ||||||
| 		} | 		} | ||||||
| @@ -819,7 +824,7 @@ func updateCommentInfos(e db.Engine, opts *CreateCommentOptions, comment *Commen | |||||||
| 	return updateIssueCols(e, opts.Issue, "updated_unix") | 	return updateIssueCols(e, opts.Issue, "updated_unix") | ||||||
| } | } | ||||||
|  |  | ||||||
| func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) { | func createDeadlineComment(ctx context.Context, doer *User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) { | ||||||
| 	var content string | 	var content string | ||||||
| 	var commentType CommentType | 	var commentType CommentType | ||||||
|  |  | ||||||
| @@ -837,7 +842,7 @@ func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlin | |||||||
| 		content = newDeadlineUnix.Format("2006-01-02") + "|" + issue.DeadlineUnix.Format("2006-01-02") | 		content = newDeadlineUnix.Format("2006-01-02") + "|" + issue.DeadlineUnix.Format("2006-01-02") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := issue.loadRepo(e); err != nil { | 	if err := issue.loadRepo(db.GetEngine(ctx)); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -848,7 +853,7 @@ func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlin | |||||||
| 		Issue:   issue, | 		Issue:   issue, | ||||||
| 		Content: content, | 		Content: content, | ||||||
| 	} | 	} | ||||||
| 	comment, err := createComment(e, opts) | 	comment, err := createComment(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -856,12 +861,12 @@ func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlin | |||||||
| } | } | ||||||
|  |  | ||||||
| // Creates issue dependency comment | // Creates issue dependency comment | ||||||
| func createIssueDependencyComment(e *xorm.Session, doer *User, issue, dependentIssue *Issue, add bool) (err error) { | func createIssueDependencyComment(ctx context.Context, doer *User, issue, dependentIssue *Issue, add bool) (err error) { | ||||||
| 	cType := CommentTypeAddDependency | 	cType := CommentTypeAddDependency | ||||||
| 	if !add { | 	if !add { | ||||||
| 		cType = CommentTypeRemoveDependency | 		cType = CommentTypeRemoveDependency | ||||||
| 	} | 	} | ||||||
| 	if err = issue.loadRepo(e); err != nil { | 	if err = issue.loadRepo(db.GetEngine(ctx)); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -873,7 +878,7 @@ func createIssueDependencyComment(e *xorm.Session, doer *User, issue, dependentI | |||||||
| 		Issue:            issue, | 		Issue:            issue, | ||||||
| 		DependentIssueID: dependentIssue.ID, | 		DependentIssueID: dependentIssue.ID, | ||||||
| 	} | 	} | ||||||
| 	if _, err = createComment(e, opts); err != nil { | 	if _, err = createComment(ctx, opts); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -884,7 +889,7 @@ func createIssueDependencyComment(e *xorm.Session, doer *User, issue, dependentI | |||||||
| 		Issue:            dependentIssue, | 		Issue:            dependentIssue, | ||||||
| 		DependentIssueID: issue.ID, | 		DependentIssueID: issue.ID, | ||||||
| 	} | 	} | ||||||
| 	_, err = createComment(e, opts) | 	_, err = createComment(ctx, opts) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -928,18 +933,18 @@ type CreateCommentOptions struct { | |||||||
|  |  | ||||||
| // CreateComment creates comment of issue or commit. | // CreateComment creates comment of issue or commit. | ||||||
| func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) { | func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	comment, err = createComment(sess, opts) | 	comment, err = createComment(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = sess.Commit(); err != nil { | 	if err = committer.Commit(); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1068,11 +1073,12 @@ func CountComments(opts *FindCommentsOptions) (int64, error) { | |||||||
|  |  | ||||||
| // UpdateComment updates information of comment. | // UpdateComment updates information of comment. | ||||||
| func UpdateComment(c *Comment, doer *User) error { | func UpdateComment(c *Comment, doer *User) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if _, err := sess.ID(c.ID).AllCols().Update(c); err != nil { | 	if _, err := sess.ID(c.ID).AllCols().Update(c); err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -1080,10 +1086,10 @@ func UpdateComment(c *Comment, doer *User) error { | |||||||
| 	if err := c.loadIssue(sess); err != nil { | 	if err := c.loadIssue(sess); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := c.addCrossReferences(sess, doer, true); err != nil { | 	if err := c.addCrossReferences(ctx, doer, true); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := sess.Commit(); err != nil { | 	if err := committer.Commit(); err != nil { | ||||||
| 		return fmt.Errorf("Commit: %v", err) | 		return fmt.Errorf("Commit: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,7 +4,10 @@ | |||||||
|  |  | ||||||
| package models | package models | ||||||
|  |  | ||||||
| import "code.gitea.io/gitea/models/db" | import ( | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | ) | ||||||
|  |  | ||||||
| // CommentList defines a list of comments | // CommentList defines a list of comments | ||||||
| type CommentList []*Comment | type CommentList []*Comment | ||||||
| @@ -393,7 +396,7 @@ func (comments CommentList) loadAttachments(e db.Engine) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attachments := make(map[int64][]*Attachment, len(comments)) | 	attachments := make(map[int64][]*repo_model.Attachment, len(comments)) | ||||||
| 	commentsIDs := comments.getCommentIDs() | 	commentsIDs := comments.getCommentIDs() | ||||||
| 	left := len(commentsIDs) | 	left := len(commentsIDs) | ||||||
| 	for left > 0 { | 	for left > 0 { | ||||||
| @@ -404,13 +407,13 @@ func (comments CommentList) loadAttachments(e db.Engine) (err error) { | |||||||
| 		rows, err := e.Table("attachment"). | 		rows, err := e.Table("attachment"). | ||||||
| 			Join("INNER", "comment", "comment.id = attachment.comment_id"). | 			Join("INNER", "comment", "comment.id = attachment.comment_id"). | ||||||
| 			In("comment.id", commentsIDs[:limit]). | 			In("comment.id", commentsIDs[:limit]). | ||||||
| 			Rows(new(Attachment)) | 			Rows(new(repo_model.Attachment)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for rows.Next() { | 		for rows.Next() { | ||||||
| 			var attachment Attachment | 			var attachment repo_model.Attachment | ||||||
| 			err = rows.Scan(&attachment) | 			err = rows.Scan(&attachment) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				_ = rows.Close() | 				_ = rows.Close() | ||||||
|   | |||||||
| @@ -37,11 +37,12 @@ const ( | |||||||
|  |  | ||||||
| // CreateIssueDependency creates a new dependency for an issue | // CreateIssueDependency creates a new dependency for an issue | ||||||
| func CreateIssueDependency(user *User, issue, dep *Issue) error { | func CreateIssueDependency(user *User, issue, dep *Issue) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	// Check if it aleready exists | 	// Check if it aleready exists | ||||||
| 	exists, err := issueDepExists(sess, issue.ID, dep.ID) | 	exists, err := issueDepExists(sess, issue.ID, dep.ID) | ||||||
| @@ -69,20 +70,20 @@ func CreateIssueDependency(user *User, issue, dep *Issue) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Add comment referencing the new dependency | 	// Add comment referencing the new dependency | ||||||
| 	if err = createIssueDependencyComment(sess, user, issue, dep, true); err != nil { | 	if err = createIssueDependencyComment(ctx, user, issue, dep, true); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveIssueDependency removes a dependency from an issue | // RemoveIssueDependency removes a dependency from an issue | ||||||
| func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType) (err error) { | func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType) (err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	var issueDepToDelete IssueDependency | 	var issueDepToDelete IssueDependency | ||||||
|  |  | ||||||
| @@ -95,7 +96,7 @@ func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType | |||||||
| 		return ErrUnknownDependencyType{depType} | 		return ErrUnknownDependencyType{depType} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	affected, err := sess.Delete(&issueDepToDelete) | 	affected, err := db.GetEngine(ctx).Delete(&issueDepToDelete) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -106,10 +107,10 @@ func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Add comment referencing the removed dependency | 	// Add comment referencing the removed dependency | ||||||
| 	if err = createIssueDependencyComment(sess, user, issue, dep, false); err != nil { | 	if err = createIssueDependencyComment(ctx, user, issue, dep, false); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // Check if the dependency already exists | // Check if the dependency already exists | ||||||
|   | |||||||
| @@ -663,7 +663,8 @@ func HasIssueLabel(issueID, labelID int64) bool { | |||||||
|  |  | ||||||
| // newIssueLabel this function creates a new label it does not check if the label is valid for the issue | // newIssueLabel this function creates a new label it does not check if the label is valid for the issue | ||||||
| // YOU MUST CHECK THIS BEFORE THIS FUNCTION | // YOU MUST CHECK THIS BEFORE THIS FUNCTION | ||||||
| func newIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err error) { | func newIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *User) (err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	if _, err = e.Insert(&IssueLabel{ | 	if _, err = e.Insert(&IssueLabel{ | ||||||
| 		IssueID: issue.ID, | 		IssueID: issue.ID, | ||||||
| 		LabelID: label.ID, | 		LabelID: label.ID, | ||||||
| @@ -683,7 +684,7 @@ func newIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err err | |||||||
| 		Label:   label, | 		Label:   label, | ||||||
| 		Content: "1", | 		Content: "1", | ||||||
| 	} | 	} | ||||||
| 	if _, err = createComment(e, opts); err != nil { | 	if _, err = createComment(ctx, opts); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -696,11 +697,12 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if err = issue.loadRepo(sess); err != nil { | 	if err = issue.loadRepo(sess); err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -711,7 +713,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = newIssueLabel(sess, issue, label, doer); err != nil { | 	if err = newIssueLabel(ctx, issue, label, doer); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -720,11 +722,12 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // newIssueLabels add labels to an issue. It will check if the labels are valid for the issue | // newIssueLabels add labels to an issue. It will check if the labels are valid for the issue | ||||||
| func newIssueLabels(e db.Engine, issue *Issue, labels []*Label, doer *User) (err error) { | func newIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *User) (err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	if err = issue.loadRepo(e); err != nil { | 	if err = issue.loadRepo(e); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -735,7 +738,7 @@ func newIssueLabels(e db.Engine, issue *Issue, labels []*Label, doer *User) (err | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if err = newIssueLabel(e, issue, label, doer); err != nil { | 		if err = newIssueLabel(ctx, issue, label, doer); err != nil { | ||||||
| 			return fmt.Errorf("newIssueLabel: %v", err) | 			return fmt.Errorf("newIssueLabel: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -751,7 +754,7 @@ func NewIssueLabels(issue *Issue, labels []*Label, doer *User) (err error) { | |||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if err = newIssueLabels(db.GetEngine(ctx), issue, labels, doer); err != nil { | 	if err = newIssueLabels(ctx, issue, labels, doer); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -763,7 +766,8 @@ func NewIssueLabels(issue *Issue, labels []*Label, doer *User) (err error) { | |||||||
| 	return committer.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func deleteIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err error) { | func deleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *User) (err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	if count, err := e.Delete(&IssueLabel{ | 	if count, err := e.Delete(&IssueLabel{ | ||||||
| 		IssueID: issue.ID, | 		IssueID: issue.ID, | ||||||
| 		LabelID: label.ID, | 		LabelID: label.ID, | ||||||
| @@ -784,7 +788,7 @@ func deleteIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err | |||||||
| 		Issue: issue, | 		Issue: issue, | ||||||
| 		Label: label, | 		Label: label, | ||||||
| 	} | 	} | ||||||
| 	if _, err = createComment(e, opts); err != nil { | 	if _, err = createComment(ctx, opts); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -793,22 +797,22 @@ func deleteIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err | |||||||
|  |  | ||||||
| // DeleteIssueLabel deletes issue-label relation. | // DeleteIssueLabel deletes issue-label relation. | ||||||
| func DeleteIssueLabel(issue *Issue, label *Label, doer *User) (err error) { | func DeleteIssueLabel(issue *Issue, label *Label, doer *User) (err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if err = deleteIssueLabel(sess, issue, label, doer); err != nil { | 	if err = deleteIssueLabel(ctx, issue, label, doer); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	issue.Labels = nil | 	issue.Labels = nil | ||||||
| 	if err = issue.loadLabels(sess); err != nil { | 	if err = issue.loadLabels(db.GetEngine(ctx)); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func deleteLabelsByRepoID(sess db.Engine, repoID int64) error { | func deleteLabelsByRepoID(sess db.Engine, repoID int64) error { | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  |  | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
| @@ -322,7 +323,7 @@ func (issues IssueList) loadAttachments(e db.Engine) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attachments := make(map[int64][]*Attachment, len(issues)) | 	attachments := make(map[int64][]*repo_model.Attachment, len(issues)) | ||||||
| 	issuesIDs := issues.getIssueIDs() | 	issuesIDs := issues.getIssueIDs() | ||||||
| 	left := len(issuesIDs) | 	left := len(issuesIDs) | ||||||
| 	for left > 0 { | 	for left > 0 { | ||||||
| @@ -333,13 +334,13 @@ func (issues IssueList) loadAttachments(e db.Engine) (err error) { | |||||||
| 		rows, err := e.Table("attachment"). | 		rows, err := e.Table("attachment"). | ||||||
| 			Join("INNER", "issue", "issue.id = attachment.issue_id"). | 			Join("INNER", "issue", "issue.id = attachment.issue_id"). | ||||||
| 			In("issue.id", issuesIDs[:limit]). | 			In("issue.id", issuesIDs[:limit]). | ||||||
| 			Rows(new(Attachment)) | 			Rows(new(repo_model.Attachment)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for rows.Next() { | 		for rows.Next() { | ||||||
| 			var attachment Attachment | 			var attachment repo_model.Attachment | ||||||
| 			err = rows.Scan(&attachment) | 			err = rows.Scan(&attachment) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if err1 := rows.Close(); err1 != nil { | 				if err1 := rows.Close(); err1 != nil { | ||||||
|   | |||||||
| @@ -37,13 +37,13 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { | |||||||
| 		commentType = CommentTypeUnlock | 		commentType = CommentTypeUnlock | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if err := updateIssueCols(sess, opts.Issue, "is_locked"); err != nil { | 	if err := updateIssueCols(db.GetEngine(ctx), opts.Issue, "is_locked"); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -54,9 +54,9 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { | |||||||
| 		Type:    commentType, | 		Type:    commentType, | ||||||
| 		Content: opts.Reason, | 		Content: opts.Reason, | ||||||
| 	} | 	} | ||||||
| 	if _, err := createComment(sess, opt); err != nil { | 	if _, err := createComment(ctx, opt); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -15,7 +16,6 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  |  | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| 	"xorm.io/xorm" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Milestone represents a milestone of repository. | // Milestone represents a milestone of repository. | ||||||
| @@ -263,7 +263,8 @@ func changeMilestoneStatus(e db.Engine, m *Milestone, isClosed bool) error { | |||||||
| 	return updateRepoMilestoneNum(e, m.RepoID) | 	return updateRepoMilestoneNum(e, m.RepoID) | ||||||
| } | } | ||||||
|  |  | ||||||
| func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilestoneID int64) error { | func changeMilestoneAssign(ctx context.Context, doer *User, issue *Issue, oldMilestoneID int64) error { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	if err := updateIssueCols(e, issue, "milestone_id"); err != nil { | 	if err := updateIssueCols(e, issue, "milestone_id"); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -293,7 +294,7 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto | |||||||
| 			OldMilestoneID: oldMilestoneID, | 			OldMilestoneID: oldMilestoneID, | ||||||
| 			MilestoneID:    issue.MilestoneID, | 			MilestoneID:    issue.MilestoneID, | ||||||
| 		} | 		} | ||||||
| 		if _, err := createComment(e, opts); err != nil { | 		if _, err := createComment(ctx, opts); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -303,17 +304,17 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto | |||||||
|  |  | ||||||
| // ChangeMilestoneAssign changes assignment of milestone for issue. | // ChangeMilestoneAssign changes assignment of milestone for issue. | ||||||
| func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err error) { | func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
|  | 	if err = changeMilestoneAssign(ctx, doer, issue, oldMilestoneID); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = changeMilestoneAssign(sess, doer, issue, oldMilestoneID); err != nil { | 	if err = committer.Commit(); err != nil { | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = sess.Commit(); err != nil { |  | ||||||
| 		return fmt.Errorf("Commit: %v", err) | 		return fmt.Errorf("Commit: %v", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
| @@ -5,13 +5,12 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  |  | ||||||
| 	"xorm.io/xorm" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Stopwatch represents a stopwatch for time tracking. | // Stopwatch represents a stopwatch for time tracking. | ||||||
| @@ -86,18 +85,19 @@ func hasUserStopwatch(e db.Engine, userID int64) (exists bool, sw *Stopwatch, er | |||||||
|  |  | ||||||
| // CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline. | // CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline. | ||||||
| func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { | func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := createOrStopIssueStopwatch(sess, user, issue); err != nil { | 	defer committer.Close() | ||||||
|  | 	if err := createOrStopIssueStopwatch(ctx, user, issue); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error { | func createOrStopIssueStopwatch(ctx context.Context, user *User, issue *Issue) error { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	sw, exists, err := getStopwatch(e, user.ID, issue.ID) | 	sw, exists, err := getStopwatch(e, user.ID, issue.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -122,7 +122,7 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := createComment(e, &CreateCommentOptions{ | 		if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 			Doer:    user, | 			Doer:    user, | ||||||
| 			Issue:   issue, | 			Issue:   issue, | ||||||
| 			Repo:    issue.Repo, | 			Repo:    issue.Repo, | ||||||
| @@ -146,7 +146,7 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			if err := createOrStopIssueStopwatch(e, user, issue); err != nil { | 			if err := createOrStopIssueStopwatch(ctx, user, issue); err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -157,11 +157,11 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error | |||||||
| 			IssueID: issue.ID, | 			IssueID: issue.ID, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := e.Insert(sw); err != nil { | 		if err := db.Insert(ctx, sw); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := createComment(e, &CreateCommentOptions{ | 		if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 			Doer:  user, | 			Doer:  user, | ||||||
| 			Issue: issue, | 			Issue: issue, | ||||||
| 			Repo:  issue.Repo, | 			Repo:  issue.Repo, | ||||||
| @@ -175,18 +175,19 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error | |||||||
|  |  | ||||||
| // CancelStopwatch removes the given stopwatch and logs it into issue's timeline. | // CancelStopwatch removes the given stopwatch and logs it into issue's timeline. | ||||||
| func CancelStopwatch(user *User, issue *Issue) error { | func CancelStopwatch(user *User, issue *Issue) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := cancelStopwatch(sess, user, issue); err != nil { | 	defer committer.Close() | ||||||
|  | 	if err := cancelStopwatch(ctx, user, issue); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func cancelStopwatch(e *xorm.Session, user *User, issue *Issue) error { | func cancelStopwatch(ctx context.Context, user *User, issue *Issue) error { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	sw, exists, err := getStopwatch(e, user.ID, issue.ID) | 	sw, exists, err := getStopwatch(e, user.ID, issue.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -201,7 +202,7 @@ func cancelStopwatch(e *xorm.Session, user *User, issue *Issue) error { | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := createComment(e, &CreateCommentOptions{ | 		if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 			Doer:  user, | 			Doer:  user, | ||||||
| 			Issue: issue, | 			Issue: issue, | ||||||
| 			Repo:  issue.Repo, | 			Repo:  issue.Repo, | ||||||
|   | |||||||
| @@ -154,12 +154,12 @@ func GetTrackedSeconds(opts FindTrackedTimesOptions) (int64, error) { | |||||||
|  |  | ||||||
| // AddTime will add the given time (in seconds) to the issue | // AddTime will add the given time (in seconds) to the issue | ||||||
| func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { | func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
|  |  | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	t, err := addTime(sess, user, issue, amount, created) | 	t, err := addTime(sess, user, issue, amount, created) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -170,7 +170,7 @@ func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*Tracke | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err := createComment(sess, &CreateCommentOptions{ | 	if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Issue:   issue, | 		Issue:   issue, | ||||||
| 		Repo:    issue.Repo, | 		Repo:    issue.Repo, | ||||||
| 		Doer:    user, | 		Doer:    user, | ||||||
| @@ -181,7 +181,7 @@ func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*Tracke | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return t, sess.Commit() | 	return t, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func addTime(e db.Engine, user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { | func addTime(e db.Engine, user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { | ||||||
| @@ -230,12 +230,12 @@ func TotalTimes(options *FindTrackedTimesOptions) (map[*User]string, error) { | |||||||
|  |  | ||||||
| // DeleteIssueUserTimes deletes times for issue | // DeleteIssueUserTimes deletes times for issue | ||||||
| func DeleteIssueUserTimes(issue *Issue, user *User) error { | func DeleteIssueUserTimes(issue *Issue, user *User) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
|  |  | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	opts := FindTrackedTimesOptions{ | 	opts := FindTrackedTimesOptions{ | ||||||
| 		IssueID: issue.ID, | 		IssueID: issue.ID, | ||||||
| @@ -253,7 +253,7 @@ func DeleteIssueUserTimes(issue *Issue, user *User) error { | |||||||
| 	if err := issue.loadRepo(sess); err != nil { | 	if err := issue.loadRepo(sess); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if _, err := createComment(sess, &CreateCommentOptions{ | 	if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Issue:   issue, | 		Issue:   issue, | ||||||
| 		Repo:    issue.Repo, | 		Repo:    issue.Repo, | ||||||
| 		Doer:    user, | 		Doer:    user, | ||||||
| @@ -263,17 +263,17 @@ func DeleteIssueUserTimes(issue *Issue, user *User) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteTime delete a specific Time | // DeleteTime delete a specific Time | ||||||
| func DeleteTime(t *TrackedTime) error { | func DeleteTime(t *TrackedTime) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
|  |  | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if err := t.loadAttributes(sess); err != nil { | 	if err := t.loadAttributes(sess); err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -283,7 +283,7 @@ func DeleteTime(t *TrackedTime) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err := createComment(sess, &CreateCommentOptions{ | 	if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Issue:   t.Issue, | 		Issue:   t.Issue, | ||||||
| 		Repo:    t.Issue.Repo, | 		Repo:    t.Issue.Repo, | ||||||
| 		Doer:    t.User, | 		Doer:    t.User, | ||||||
| @@ -293,7 +293,7 @@ func DeleteTime(t *TrackedTime) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sess.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func deleteTimes(e db.Engine, opts FindTrackedTimesOptions) (removedTime int64, err error) { | func deleteTimes(e db.Engine, opts FindTrackedTimesOptions) (removedTime int64, err error) { | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| @@ -59,7 +60,7 @@ func neuterCrossReferencesIds(e db.Engine, ids []int64) error { | |||||||
| //          \/     \/            \/ | //          \/     \/            \/ | ||||||
| // | // | ||||||
|  |  | ||||||
| func (issue *Issue) addCrossReferences(e db.Engine, doer *User, removeOld bool) error { | func (issue *Issue) addCrossReferences(stdCtx context.Context, doer *User, removeOld bool) error { | ||||||
| 	var commentType CommentType | 	var commentType CommentType | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		commentType = CommentTypePullRef | 		commentType = CommentTypePullRef | ||||||
| @@ -72,10 +73,11 @@ func (issue *Issue) addCrossReferences(e db.Engine, doer *User, removeOld bool) | |||||||
| 		OrigIssue: issue, | 		OrigIssue: issue, | ||||||
| 		RemoveOld: removeOld, | 		RemoveOld: removeOld, | ||||||
| 	} | 	} | ||||||
| 	return issue.createCrossReferences(e, ctx, issue.Title, issue.Content) | 	return issue.createCrossReferences(stdCtx, ctx, issue.Title, issue.Content) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (issue *Issue) createCrossReferences(e db.Engine, ctx *crossReferencesContext, plaincontent, mdcontent string) error { | func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossReferencesContext, plaincontent, mdcontent string) error { | ||||||
|  | 	e := db.GetEngine(stdCtx) | ||||||
| 	xreflist, err := ctx.OrigIssue.getCrossReferences(e, ctx, plaincontent, mdcontent) | 	xreflist, err := ctx.OrigIssue.getCrossReferences(e, ctx, plaincontent, mdcontent) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -125,7 +127,7 @@ func (issue *Issue) createCrossReferences(e db.Engine, ctx *crossReferencesConte | |||||||
| 			RefAction:    xref.Action, | 			RefAction:    xref.Action, | ||||||
| 			RefIsPull:    ctx.OrigIssue.IsPull, | 			RefIsPull:    ctx.OrigIssue.IsPull, | ||||||
| 		} | 		} | ||||||
| 		_, err := createComment(e, opts) | 		_, err := createComment(stdCtx, opts) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -240,11 +242,11 @@ func (issue *Issue) verifyReferencedIssue(e db.Engine, ctx *crossReferencesConte | |||||||
| //         \/             \/      \/     \/     \/ | //         \/             \/      \/     \/     \/ | ||||||
| // | // | ||||||
|  |  | ||||||
| func (comment *Comment) addCrossReferences(e db.Engine, doer *User, removeOld bool) error { | func (comment *Comment) addCrossReferences(stdCtx context.Context, doer *User, removeOld bool) error { | ||||||
| 	if comment.Type != CommentTypeCode && comment.Type != CommentTypeComment { | 	if comment.Type != CommentTypeCode && comment.Type != CommentTypeComment { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if err := comment.loadIssue(e); err != nil { | 	if err := comment.loadIssue(db.GetEngine(stdCtx)); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	ctx := &crossReferencesContext{ | 	ctx := &crossReferencesContext{ | ||||||
| @@ -254,7 +256,7 @@ func (comment *Comment) addCrossReferences(e db.Engine, doer *User, removeOld bo | |||||||
| 		OrigComment: comment, | 		OrigComment: comment, | ||||||
| 		RemoveOld:   removeOld, | 		RemoveOld:   removeOld, | ||||||
| 	} | 	} | ||||||
| 	return comment.Issue.createCrossReferences(e, ctx, "", comment.Content) | 	return comment.Issue.createCrossReferences(stdCtx, ctx, "", comment.Content) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (comment *Comment) neuterCrossReferences(e db.Engine) error { | func (comment *Comment) neuterCrossReferences(e db.Engine) error { | ||||||
|   | |||||||
| @@ -140,19 +140,18 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu | |||||||
| 		Index:    idx, | 		Index:    idx, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	assert.NoError(t, err) | ||||||
|  | 	defer committer.Close() | ||||||
| 	assert.NoError(t, sess.Begin()) | 	err = newIssue(ctx, d, NewIssueOptions{ | ||||||
| 	err = newIssue(sess, d, NewIssueOptions{ |  | ||||||
| 		Repo:  r, | 		Repo:  r, | ||||||
| 		Issue: i, | 		Issue: i, | ||||||
| 	}) | 	}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	i, err = getIssueByID(sess, i.ID) | 	i, err = getIssueByID(db.GetEngine(ctx), i.ID) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, i.addCrossReferences(sess, d, false)) | 	assert.NoError(t, i.addCrossReferences(ctx, d, false)) | ||||||
| 	assert.NoError(t, sess.Commit()) | 	assert.NoError(t, committer.Commit()) | ||||||
| 	return i | 	return i | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -171,12 +170,12 @@ func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *C | |||||||
| 	i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue) | 	i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue) | ||||||
| 	c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} | 	c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() |  | ||||||
| 	assert.NoError(t, sess.Begin()) |  | ||||||
| 	_, err := sess.Insert(c) |  | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, c.addCrossReferences(sess, d, false)) | 	defer committer.Close() | ||||||
| 	assert.NoError(t, sess.Commit()) | 	err = db.Insert(ctx, c) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.NoError(t, c.addCrossReferences(ctx, d, false)) | ||||||
|  | 	assert.NoError(t, committer.Commit()) | ||||||
| 	return c | 	return c | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @@ -391,14 +392,15 @@ func countUnread(e db.Engine, userID int64) int64 { | |||||||
|  |  | ||||||
| // LoadAttributes load Repo Issue User and Comment if not loaded | // LoadAttributes load Repo Issue User and Comment if not loaded | ||||||
| func (n *Notification) LoadAttributes() (err error) { | func (n *Notification) LoadAttributes() (err error) { | ||||||
| 	return n.loadAttributes(db.GetEngine(db.DefaultContext)) | 	return n.loadAttributes(db.DefaultContext) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (n *Notification) loadAttributes(e db.Engine) (err error) { | func (n *Notification) loadAttributes(ctx context.Context) (err error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	if err = n.loadRepo(e); err != nil { | 	if err = n.loadRepo(e); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err = n.loadIssue(e); err != nil { | 	if err = n.loadIssue(ctx); err != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err = n.loadUser(e); err != nil { | 	if err = n.loadUser(e); err != nil { | ||||||
| @@ -420,13 +422,13 @@ func (n *Notification) loadRepo(e db.Engine) (err error) { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (n *Notification) loadIssue(e db.Engine) (err error) { | func (n *Notification) loadIssue(ctx context.Context) (err error) { | ||||||
| 	if n.Issue == nil && n.IssueID != 0 { | 	if n.Issue == nil && n.IssueID != 0 { | ||||||
| 		n.Issue, err = getIssueByID(e, n.IssueID) | 		n.Issue, err = getIssueByID(db.GetEngine(ctx), n.IssueID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) | 			return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) | ||||||
| 		} | 		} | ||||||
| 		return n.Issue.loadAttributes(e) | 		return n.Issue.loadAttributes(ctx) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -464,7 +466,7 @@ func (n *Notification) GetRepo() (*Repository, error) { | |||||||
|  |  | ||||||
| // GetIssue returns the issue of the notification | // GetIssue returns the issue of the notification | ||||||
| func (n *Notification) GetIssue() (*Issue, error) { | func (n *Notification) GetIssue() (*Issue, error) { | ||||||
| 	return n.Issue, n.loadIssue(db.GetEngine(db.DefaultContext)) | 	return n.Issue, n.loadIssue(db.DefaultContext) | ||||||
| } | } | ||||||
|  |  | ||||||
| // HTMLURL formats a URL-string to the notification | // HTMLURL formats a URL-string to the notification | ||||||
|   | |||||||
| @@ -5,11 +5,10 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  |  | ||||||
| 	"xorm.io/xorm" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ProjectIssue saves relation from issue to a project | // ProjectIssue saves relation from issue to a project | ||||||
| @@ -132,20 +131,21 @@ func (p *Project) NumOpenIssues() int { | |||||||
|  |  | ||||||
| // ChangeProjectAssign changes the project associated with an issue | // ChangeProjectAssign changes the project associated with an issue | ||||||
| func ChangeProjectAssign(issue *Issue, doer *User, newProjectID int64) error { | func ChangeProjectAssign(issue *Issue, doer *User, newProjectID int64) error { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
|  | 	if err := addUpdateIssueProject(ctx, issue, doer, newProjectID); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := addUpdateIssueProject(sess, issue, doer, newProjectID); err != nil { | 	return committer.Commit() | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return sess.Commit() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func addUpdateIssueProject(e *xorm.Session, issue *Issue, doer *User, newProjectID int64) error { | func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *User, newProjectID int64) error { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
| 	oldProjectID := issue.projectID(e) | 	oldProjectID := issue.projectID(e) | ||||||
|  |  | ||||||
| 	if _, err := e.Where("project_issue.issue_id=?", issue.ID).Delete(&ProjectIssue{}); err != nil { | 	if _, err := e.Where("project_issue.issue_id=?", issue.ID).Delete(&ProjectIssue{}); err != nil { | ||||||
| @@ -157,7 +157,7 @@ func addUpdateIssueProject(e *xorm.Session, issue *Issue, doer *User, newProject | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if oldProjectID > 0 || newProjectID > 0 { | 	if oldProjectID > 0 || newProjectID > 0 { | ||||||
| 		if _, err := createComment(e, &CreateCommentOptions{ | 		if _, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 			Type:         CommentTypeProject, | 			Type:         CommentTypeProject, | ||||||
| 			Doer:         doer, | 			Doer:         doer, | ||||||
| 			Repo:         issue.Repo, | 			Repo:         issue.Repo, | ||||||
|   | |||||||
| @@ -394,11 +394,12 @@ func (pr *PullRequest) SetMerged() (bool, error) { | |||||||
|  |  | ||||||
| 	pr.HasMerged = true | 	pr.HasMerged = true | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if _, err := sess.Exec("UPDATE `issue` SET `repo_id` = `repo_id` WHERE `id` = ?", pr.IssueID); err != nil { | 	if _, err := sess.Exec("UPDATE `issue` SET `repo_id` = `repo_id` WHERE `id` = ?", pr.IssueID); err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| @@ -432,7 +433,7 @@ func (pr *PullRequest) SetMerged() (bool, error) { | |||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err := pr.Issue.changeStatus(sess, pr.Merger, true, true); err != nil { | 	if _, err := pr.Issue.changeStatus(ctx, pr.Merger, true, true); err != nil { | ||||||
| 		return false, fmt.Errorf("Issue.changeStatus: %v", err) | 		return false, fmt.Errorf("Issue.changeStatus: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -441,7 +442,7 @@ func (pr *PullRequest) SetMerged() (bool, error) { | |||||||
| 		return false, fmt.Errorf("Failed to update pr[%d]: %v", pr.ID, err) | 		return false, fmt.Errorf("Failed to update pr[%d]: %v", pr.ID, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := sess.Commit(); err != nil { | 	if err := committer.Commit(); err != nil { | ||||||
| 		return false, fmt.Errorf("Commit: %v", err) | 		return false, fmt.Errorf("Commit: %v", err) | ||||||
| 	} | 	} | ||||||
| 	return true, nil | 	return true, nil | ||||||
| @@ -456,13 +457,13 @@ func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []st | |||||||
|  |  | ||||||
| 	issue.Index = idx | 	issue.Index = idx | ||||||
|  |  | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err = sess.Begin(); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	if err = newIssue(sess, issue.Poster, NewIssueOptions{ | 	if err = newIssue(ctx, issue.Poster, NewIssueOptions{ | ||||||
| 		Repo:        repo, | 		Repo:        repo, | ||||||
| 		Issue:       issue, | 		Issue:       issue, | ||||||
| 		LabelIDs:    labelIDs, | 		LabelIDs:    labelIDs, | ||||||
| @@ -478,11 +479,11 @@ func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []st | |||||||
| 	pr.Index = issue.Index | 	pr.Index = issue.Index | ||||||
| 	pr.BaseRepo = repo | 	pr.BaseRepo = repo | ||||||
| 	pr.IssueID = issue.ID | 	pr.IssueID = issue.ID | ||||||
| 	if _, err = sess.Insert(pr); err != nil { | 	if err = db.Insert(ctx, pr); err != nil { | ||||||
| 		return fmt.Errorf("insert pull repo: %v", err) | 		return fmt.Errorf("insert pull repo: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = sess.Commit(); err != nil { | 	if err = committer.Commit(); err != nil { | ||||||
| 		return fmt.Errorf("Commit: %v", err) | 		return fmt.Errorf("Commit: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| @@ -42,7 +43,7 @@ type Release struct { | |||||||
| 	IsDraft          bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsDraft          bool                     `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsPrerelease     bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsPrerelease     bool                     `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsTag            bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsTag            bool                     `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	Attachments      []*Attachment      `xorm:"-"` | 	Attachments      []*repo_model.Attachment `xorm:"-"` | ||||||
| 	CreatedUnix      timeutil.TimeStamp       `xorm:"INDEX"` | 	CreatedUnix      timeutil.TimeStamp       `xorm:"INDEX"` | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -126,7 +127,7 @@ func UpdateRelease(ctx context.Context, rel *Release) error { | |||||||
| // AddReleaseAttachments adds a release attachments | // AddReleaseAttachments adds a release attachments | ||||||
| func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { | func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { | ||||||
| 	// Check attachments | 	// Check attachments | ||||||
| 	attachments, err := getAttachmentsByUUIDs(db.GetEngine(ctx), attachmentUUIDs) | 	attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, attachmentUUIDs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) | 		return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) | ||||||
| 	} | 	} | ||||||
| @@ -295,9 +296,9 @@ func getReleaseAttachments(e db.Engine, rels ...*Release) (err error) { | |||||||
|  |  | ||||||
| 	// Sort | 	// Sort | ||||||
| 	sortedRels := releaseMetaSearch{ID: make([]int64, len(rels)), Rel: make([]*Release, len(rels))} | 	sortedRels := releaseMetaSearch{ID: make([]int64, len(rels)), Rel: make([]*Release, len(rels))} | ||||||
| 	var attachments []*Attachment | 	var attachments []*repo_model.Attachment | ||||||
| 	for index, element := range rels { | 	for index, element := range rels { | ||||||
| 		element.Attachments = []*Attachment{} | 		element.Attachments = []*repo_model.Attachment{} | ||||||
| 		sortedRels.ID[index] = element.ID | 		sortedRels.ID[index] = element.ID | ||||||
| 		sortedRels.Rel[index] = element | 		sortedRels.Rel[index] = element | ||||||
| 	} | 	} | ||||||
| @@ -307,7 +308,7 @@ func getReleaseAttachments(e db.Engine, rels ...*Release) (err error) { | |||||||
| 	err = e. | 	err = e. | ||||||
| 		Asc("release_id", "name"). | 		Asc("release_id", "name"). | ||||||
| 		In("release_id", sortedRels.ID). | 		In("release_id", sortedRels.ID). | ||||||
| 		Find(&attachments, Attachment{}) | 		Find(&attachments, repo_model.Attachment{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import ( | |||||||
|  |  | ||||||
| 	admin_model "code.gitea.io/gitea/models/admin" | 	admin_model "code.gitea.io/gitea/models/admin" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/models/webhook" | 	"code.gitea.io/gitea/models/webhook" | ||||||
| 	"code.gitea.io/gitea/modules/lfs" | 	"code.gitea.io/gitea/modules/lfs" | ||||||
| @@ -1485,7 +1486,7 @@ func DeleteRepository(doer *User, uid, repoID int64) error { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attachments := make([]*Attachment, 0, 20) | 	attachments := make([]*repo_model.Attachment, 0, 20) | ||||||
| 	if err = sess.Join("INNER", "`release`", "`release`.id = `attachment`.release_id"). | 	if err = sess.Join("INNER", "`release`", "`release`.id = `attachment`.release_id"). | ||||||
| 		Where("`release`.repo_id = ?", repoID). | 		Where("`release`.repo_id = ?", repoID). | ||||||
| 		Find(&attachments); err != nil { | 		Find(&attachments); err != nil { | ||||||
| @@ -1620,7 +1621,7 @@ func DeleteRepository(doer *User, uid, repoID int64) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Get all attachments with both issue_id and release_id are zero | 	// Get all attachments with both issue_id and release_id are zero | ||||||
| 	var newAttachments []*Attachment | 	var newAttachments []*repo_model.Attachment | ||||||
| 	if err := sess.Where(builder.Eq{ | 	if err := sess.Where(builder.Eq{ | ||||||
| 		"repo_id":    repo.ID, | 		"repo_id":    repo.ID, | ||||||
| 		"issue_id":   0, | 		"issue_id":   0, | ||||||
| @@ -1634,7 +1635,7 @@ func DeleteRepository(doer *User, uid, repoID int64) error { | |||||||
| 		newAttachmentPaths = append(newAttachmentPaths, attach.RelativePath()) | 		newAttachmentPaths = append(newAttachmentPaths, attach.RelativePath()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err := sess.Where("repo_id=?", repo.ID).Delete(new(Attachment)); err != nil { | 	if _, err := sess.Where("repo_id=?", repo.ID).Delete(new(repo_model.Attachment)); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2191,3 +2192,27 @@ func IterateRepository(f func(repo *Repository) error) error { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // LinkedRepository returns the linked repo if any | ||||||
|  | func LinkedRepository(a *repo_model.Attachment) (*Repository, unit.Type, error) { | ||||||
|  | 	if a.IssueID != 0 { | ||||||
|  | 		iss, err := GetIssueByID(a.IssueID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, unit.TypeIssues, err | ||||||
|  | 		} | ||||||
|  | 		repo, err := GetRepositoryByID(iss.RepoID) | ||||||
|  | 		unitType := unit.TypeIssues | ||||||
|  | 		if iss.IsPull { | ||||||
|  | 			unitType = unit.TypePullRequests | ||||||
|  | 		} | ||||||
|  | 		return repo, unitType, err | ||||||
|  | 	} else if a.ReleaseID != 0 { | ||||||
|  | 		rel, err := GetReleaseByID(a.ReleaseID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, unit.TypeReleases, err | ||||||
|  | 		} | ||||||
|  | 		repo, err := GetRepositoryByID(rel.RepoID) | ||||||
|  | 		return repo, unit.TypeReleases, err | ||||||
|  | 	} | ||||||
|  | 	return nil, -1, nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package repo | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -11,12 +11,9 @@ import ( | |||||||
| 	"path" | 	"path" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unit" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 |  | ||||||
| 	"xorm.io/xorm" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Attachment represent a attachment of issue/comment/release. | // Attachment represent a attachment of issue/comment/release. | ||||||
| @@ -63,35 +60,34 @@ func (a *Attachment) DownloadURL() string { | |||||||
| 	return setting.AppURL + "attachments/" + url.PathEscape(a.UUID) | 	return setting.AppURL + "attachments/" + url.PathEscape(a.UUID) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // LinkedRepository returns the linked repo if any |  | ||||||
| func (a *Attachment) LinkedRepository() (*Repository, unit.Type, error) { |  | ||||||
| 	if a.IssueID != 0 { |  | ||||||
| 		iss, err := GetIssueByID(a.IssueID) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, unit.TypeIssues, err |  | ||||||
| 		} |  | ||||||
| 		repo, err := GetRepositoryByID(iss.RepoID) |  | ||||||
| 		unitType := unit.TypeIssues |  | ||||||
| 		if iss.IsPull { |  | ||||||
| 			unitType = unit.TypePullRequests |  | ||||||
| 		} |  | ||||||
| 		return repo, unitType, err |  | ||||||
| 	} else if a.ReleaseID != 0 { |  | ||||||
| 		rel, err := GetReleaseByID(a.ReleaseID) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, unit.TypeReleases, err |  | ||||||
| 		} |  | ||||||
| 		repo, err := GetRepositoryByID(rel.RepoID) |  | ||||||
| 		return repo, unit.TypeReleases, err |  | ||||||
| 	} |  | ||||||
| 	return nil, -1, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetAttachmentByID returns attachment by given id | // GetAttachmentByID returns attachment by given id | ||||||
| func GetAttachmentByID(id int64) (*Attachment, error) { | func GetAttachmentByID(id int64) (*Attachment, error) { | ||||||
| 	return getAttachmentByID(db.GetEngine(db.DefaultContext), id) | 	return getAttachmentByID(db.GetEngine(db.DefaultContext), id) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //    _____   __    __                .__                           __ | ||||||
|  | //   /  _  \_/  |__/  |______    ____ |  |__   _____   ____   _____/  |_ | ||||||
|  | //  /  /_\  \   __\   __\__  \ _/ ___\|  |  \ /     \_/ __ \ /    \   __\ | ||||||
|  | // /    |    \  |  |  |  / __ \\  \___|   Y  \  Y Y  \  ___/|   |  \  | | ||||||
|  | // \____|__  /__|  |__| (____  /\___  >___|  /__|_|  /\___  >___|  /__| | ||||||
|  | //         \/                \/     \/     \/      \/     \/     \/ | ||||||
|  | 
 | ||||||
|  | // ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error. | ||||||
|  | type ErrAttachmentNotExist struct { | ||||||
|  | 	ID   int64 | ||||||
|  | 	UUID string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsErrAttachmentNotExist checks if an error is a ErrAttachmentNotExist. | ||||||
|  | func IsErrAttachmentNotExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrAttachmentNotExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrAttachmentNotExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func getAttachmentByID(e db.Engine, id int64) (*Attachment, error) { | func getAttachmentByID(e db.Engine, id int64) (*Attachment, error) { | ||||||
| 	attach := &Attachment{} | 	attach := &Attachment{} | ||||||
| 	if has, err := e.ID(id).Get(attach); err != nil { | 	if has, err := e.ID(id).Get(attach); err != nil { | ||||||
| @@ -143,24 +139,26 @@ func GetAttachmentByReleaseIDFileName(releaseID int64, fileName string) (*Attach | |||||||
| 	return getAttachmentByReleaseIDFileName(db.GetEngine(db.DefaultContext), releaseID, fileName) | 	return getAttachmentByReleaseIDFileName(db.GetEngine(db.DefaultContext), releaseID, fileName) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getAttachmentsByIssueID(e db.Engine, issueID int64) ([]*Attachment, error) { | // GetAttachmentsByIssueIDCtx returns all attachments of an issue. | ||||||
|  | func GetAttachmentsByIssueIDCtx(ctx context.Context, issueID int64) ([]*Attachment, error) { | ||||||
| 	attachments := make([]*Attachment, 0, 10) | 	attachments := make([]*Attachment, 0, 10) | ||||||
| 	return attachments, e.Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments) | 	return attachments, db.GetEngine(ctx).Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetAttachmentsByIssueID returns all attachments of an issue. | // GetAttachmentsByIssueID returns all attachments of an issue. | ||||||
| func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) { | func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) { | ||||||
| 	return getAttachmentsByIssueID(db.GetEngine(db.DefaultContext), issueID) | 	return GetAttachmentsByIssueIDCtx(db.DefaultContext, issueID) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetAttachmentsByCommentID returns all attachments if comment by given ID. | // GetAttachmentsByCommentID returns all attachments if comment by given ID. | ||||||
| func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) { | func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) { | ||||||
| 	return getAttachmentsByCommentID(db.GetEngine(db.DefaultContext), commentID) | 	return GetAttachmentsByCommentIDCtx(db.DefaultContext, commentID) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getAttachmentsByCommentID(e db.Engine, commentID int64) ([]*Attachment, error) { | // GetAttachmentsByCommentIDCtx returns all attachments if comment by given ID. | ||||||
|  | func GetAttachmentsByCommentIDCtx(ctx context.Context, commentID int64) ([]*Attachment, error) { | ||||||
| 	attachments := make([]*Attachment, 0, 10) | 	attachments := make([]*Attachment, 0, 10) | ||||||
| 	return attachments, e.Where("comment_id=?", commentID).Find(&attachments) | 	return attachments, db.GetEngine(ctx).Where("comment_id=?", commentID).Find(&attachments) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getAttachmentByReleaseIDFileName return a file based on the the following infos: | // getAttachmentByReleaseIDFileName return a file based on the the following infos: | ||||||
| @@ -229,7 +227,7 @@ func DeleteAttachmentsByComment(commentID int64, remove bool) (int, error) { | |||||||
| 
 | 
 | ||||||
| // UpdateAttachment updates the given attachment in database | // UpdateAttachment updates the given attachment in database | ||||||
| func UpdateAttachment(atta *Attachment) error { | func UpdateAttachment(atta *Attachment) error { | ||||||
| 	return updateAttachment(db.GetEngine(db.DefaultContext), atta) | 	return UpdateAttachmentCtx(db.DefaultContext, atta) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UpdateAttachmentByUUID Updates attachment via uuid | // UpdateAttachmentByUUID Updates attachment via uuid | ||||||
| @@ -241,15 +239,16 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func updateAttachment(e db.Engine, atta *Attachment) error { | // UpdateAttachmentCtx updates the given attachment in database | ||||||
| 	var sess *xorm.Session | func UpdateAttachmentCtx(ctx context.Context, atta *Attachment) error { | ||||||
|  | 	var sess = db.GetEngine(ctx).Cols("name", "issue_id", "release_id", "comment_id", "download_count") | ||||||
| 	if atta.ID != 0 && atta.UUID == "" { | 	if atta.ID != 0 && atta.UUID == "" { | ||||||
| 		sess = e.ID(atta.ID) | 		sess = sess.ID(atta.ID) | ||||||
| 	} else { | 	} else { | ||||||
| 		// Use uuid only if id is not set and uuid is set | 		// Use uuid only if id is not set and uuid is set | ||||||
| 		sess = e.Where("uuid = ?", atta.UUID) | 		sess = sess.Where("uuid = ?", atta.UUID) | ||||||
| 	} | 	} | ||||||
| 	_, err := sess.Cols("name", "issue_id", "release_id", "comment_id", "download_count").Update(atta) | 	_, err := sess.Update(atta) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -2,13 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package repo | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unit" |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -103,30 +102,3 @@ func TestGetAttachmentsByUUIDs(t *testing.T) { | |||||||
| 	assert.Equal(t, int64(1), attachList[0].IssueID) | 	assert.Equal(t, int64(1), attachList[0].IssueID) | ||||||
| 	assert.Equal(t, int64(5), attachList[1].IssueID) | 	assert.Equal(t, int64(5), attachList[1].IssueID) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func TestLinkedRepository(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
| 	testCases := []struct { |  | ||||||
| 		name             string |  | ||||||
| 		attachID         int64 |  | ||||||
| 		expectedRepo     *Repository |  | ||||||
| 		expectedUnitType unit.Type |  | ||||||
| 	}{ |  | ||||||
| 		{"LinkedIssue", 1, &Repository{ID: 1}, unit.TypeIssues}, |  | ||||||
| 		{"LinkedComment", 3, &Repository{ID: 1}, unit.TypePullRequests}, |  | ||||||
| 		{"LinkedRelease", 9, &Repository{ID: 1}, unit.TypeReleases}, |  | ||||||
| 		{"Notlinked", 10, nil, -1}, |  | ||||||
| 	} |  | ||||||
| 	for _, tc := range testCases { |  | ||||||
| 		t.Run(tc.name, func(t *testing.T) { |  | ||||||
| 			attach, err := GetAttachmentByID(tc.attachID) |  | ||||||
| 			assert.NoError(t, err) |  | ||||||
| 			repo, unitType, err := attach.LinkedRepository() |  | ||||||
| 			assert.NoError(t, err) |  | ||||||
| 			if tc.expectedRepo != nil { |  | ||||||
| 				assert.Equal(t, tc.expectedRepo.ID, repo.ID) |  | ||||||
| 			} |  | ||||||
| 			assert.Equal(t, tc.expectedUnitType, unitType) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										18
									
								
								models/repo/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								models/repo/main_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | // Copyright 2020 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 repo | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMain(m *testing.M) { | ||||||
|  | 	unittest.MainTest(m, filepath.Join("..", ".."), | ||||||
|  | 		"attachment.yml", | ||||||
|  | 	) | ||||||
|  | } | ||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| @@ -224,3 +225,30 @@ func TestRepoGetReviewerTeams(t *testing.T) { | |||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Len(t, teams, 2) | 	assert.Len(t, teams, 2) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestLinkedRepository(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  | 	testCases := []struct { | ||||||
|  | 		name             string | ||||||
|  | 		attachID         int64 | ||||||
|  | 		expectedRepo     *Repository | ||||||
|  | 		expectedUnitType unit.Type | ||||||
|  | 	}{ | ||||||
|  | 		{"LinkedIssue", 1, &Repository{ID: 1}, unit.TypeIssues}, | ||||||
|  | 		{"LinkedComment", 3, &Repository{ID: 1}, unit.TypePullRequests}, | ||||||
|  | 		{"LinkedRelease", 9, &Repository{ID: 1}, unit.TypeReleases}, | ||||||
|  | 		{"Notlinked", 10, nil, -1}, | ||||||
|  | 	} | ||||||
|  | 	for _, tc := range testCases { | ||||||
|  | 		t.Run(tc.name, func(t *testing.T) { | ||||||
|  | 			attach, err := repo_model.GetAttachmentByID(tc.attachID) | ||||||
|  | 			assert.NoError(t, err) | ||||||
|  | 			repo, unitType, err := LinkedRepository(attach) | ||||||
|  | 			assert.NoError(t, err) | ||||||
|  | 			if tc.expectedRepo != nil { | ||||||
|  | 				assert.Equal(t, tc.expectedRepo.ID, repo.ID) | ||||||
|  | 			} | ||||||
|  | 			assert.Equal(t, tc.expectedUnitType, unitType) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -359,11 +359,12 @@ func IsContentEmptyErr(err error) bool { | |||||||
|  |  | ||||||
| // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist | // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist | ||||||
| func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, commitID string, stale bool, attachmentUUIDs []string) (*Review, *Comment, error) { | func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, commitID string, stale bool, attachmentUUIDs []string) (*Review, *Comment, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, nil, err | 		return nil, nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	official := false | 	official := false | ||||||
|  |  | ||||||
| @@ -429,7 +430,7 @@ func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, comm | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comm, err := createComment(sess, &CreateCommentOptions{ | 	comm, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:        CommentTypeReview, | 		Type:        CommentTypeReview, | ||||||
| 		Doer:        doer, | 		Doer:        doer, | ||||||
| 		Content:     review.Content, | 		Content:     review.Content, | ||||||
| @@ -464,7 +465,7 @@ func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, comm | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comm.Review = review | 	comm.Review = review | ||||||
| 	return review, comm, sess.Commit() | 	return review, comm, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetReviewersByIssueID gets the latest review of each reviewer for a pull request | // GetReviewersByIssueID gets the latest review of each reviewer for a pull request | ||||||
| @@ -631,11 +632,12 @@ func InsertReviews(reviews []*Review) error { | |||||||
|  |  | ||||||
| // AddReviewRequest add a review request from one reviewer | // AddReviewRequest add a review request from one reviewer | ||||||
| func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) | 	review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) | ||||||
| 	if err != nil && !IsErrReviewNotExist(err) { | 	if err != nil && !IsErrReviewNotExist(err) { | ||||||
| @@ -667,7 +669,7 @@ func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comment, err := createComment(sess, &CreateCommentOptions{ | 	comment, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:            CommentTypeReviewRequest, | 		Type:            CommentTypeReviewRequest, | ||||||
| 		Doer:            doer, | 		Doer:            doer, | ||||||
| 		Repo:            issue.Repo, | 		Repo:            issue.Repo, | ||||||
| @@ -680,16 +682,17 @@ func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return comment, sess.Commit() | 	return comment, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveReviewRequest remove a review request from one reviewer | // RemoveReviewRequest remove a review request from one reviewer | ||||||
| func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) | 	review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) | ||||||
| 	if err != nil && !IsErrReviewNotExist(err) { | 	if err != nil && !IsErrReviewNotExist(err) { | ||||||
| @@ -721,7 +724,7 @@ func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comment, err := createComment(sess, &CreateCommentOptions{ | 	comment, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:            CommentTypeReviewRequest, | 		Type:            CommentTypeReviewRequest, | ||||||
| 		Doer:            doer, | 		Doer:            doer, | ||||||
| 		Repo:            issue.Repo, | 		Repo:            issue.Repo, | ||||||
| @@ -733,16 +736,17 @@ func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return comment, sess.Commit() | 	return comment, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddTeamReviewRequest add a review request from one team | // AddTeamReviewRequest add a review request from one team | ||||||
| func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { | func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) | 	review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) | ||||||
| 	if err != nil && !IsErrReviewNotExist(err) { | 	if err != nil && !IsErrReviewNotExist(err) { | ||||||
| @@ -779,7 +783,7 @@ func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, e | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comment, err := createComment(sess, &CreateCommentOptions{ | 	comment, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:            CommentTypeReviewRequest, | 		Type:            CommentTypeReviewRequest, | ||||||
| 		Doer:            doer, | 		Doer:            doer, | ||||||
| 		Repo:            issue.Repo, | 		Repo:            issue.Repo, | ||||||
| @@ -792,16 +796,17 @@ func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, e | |||||||
| 		return nil, fmt.Errorf("createComment(): %v", err) | 		return nil, fmt.Errorf("createComment(): %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return comment, sess.Commit() | 	return comment, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveTeamReviewRequest remove a review request from one team | // RemoveTeamReviewRequest remove a review request from one team | ||||||
| func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { | func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { | ||||||
| 	sess := db.NewSession(db.DefaultContext) | 	ctx, committer, err := db.TxContext() | ||||||
| 	defer sess.Close() | 	if err != nil { | ||||||
| 	if err := sess.Begin(); err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) | 	review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) | ||||||
| 	if err != nil && !IsErrReviewNotExist(err) { | 	if err != nil && !IsErrReviewNotExist(err) { | ||||||
| @@ -836,10 +841,10 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if doer == nil { | 	if doer == nil { | ||||||
| 		return nil, sess.Commit() | 		return nil, committer.Commit() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	comment, err := createComment(sess, &CreateCommentOptions{ | 	comment, err := createComment(ctx, &CreateCommentOptions{ | ||||||
| 		Type:            CommentTypeReviewRequest, | 		Type:            CommentTypeReviewRequest, | ||||||
| 		Doer:            doer, | 		Doer:            doer, | ||||||
| 		Repo:            issue.Repo, | 		Repo:            issue.Repo, | ||||||
| @@ -851,7 +856,7 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment | |||||||
| 		return nil, fmt.Errorf("createComment(): %v", err) | 		return nil, fmt.Errorf("createComment(): %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return comment, sess.Commit() | 	return comment, committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // MarkConversation Add or remove Conversation mark for a code comment | // MarkConversation Add or remove Conversation mark for a code comment | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/login" | 	"code.gitea.io/gitea/models/login" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/models/webhook" | 	"code.gitea.io/gitea/models/webhook" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| @@ -102,7 +103,7 @@ func GetStatistic() (stats Statistic) { | |||||||
| 	stats.Counter.Label, _ = e.Count(new(Label)) | 	stats.Counter.Label, _ = e.Count(new(Label)) | ||||||
| 	stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) | 	stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) | ||||||
| 	stats.Counter.Team, _ = e.Count(new(Team)) | 	stats.Counter.Team, _ = e.Count(new(Team)) | ||||||
| 	stats.Counter.Attachment, _ = e.Count(new(Attachment)) | 	stats.Counter.Attachment, _ = e.Count(new(repo_model.Attachment)) | ||||||
| 	stats.Counter.Project, _ = e.Count(new(Project)) | 	stats.Counter.Project, _ = e.Count(new(Project)) | ||||||
| 	stats.Counter.ProjectBoard, _ = e.Count(new(ProjectBoard)) | 	stats.Counter.ProjectBoard, _ = e.Count(new(ProjectBoard)) | ||||||
| 	return | 	return | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ package convert | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -35,7 +36,7 @@ func ToRelease(r *models.Release) *api.Release { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ToReleaseAttachment converts models.Attachment to api.Attachment | // ToReleaseAttachment converts models.Attachment to api.Attachment | ||||||
| func ToReleaseAttachment(a *models.Attachment) *api.Attachment { | func ToReleaseAttachment(a *repo_model.Attachment) *api.Attachment { | ||||||
| 	return &api.Attachment{ | 	return &api.Attachment{ | ||||||
| 		ID:            a.ID, | 		ID:            a.ID, | ||||||
| 		Name:          a.Name, | 		Name:          a.Name, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/migrations" | 	"code.gitea.io/gitea/models/migrations" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| ) | ) | ||||||
| @@ -110,8 +111,8 @@ func checkDBConsistency(logger log.Logger, autofix bool) error { | |||||||
| 		// find attachments without existing issues or releases | 		// find attachments without existing issues or releases | ||||||
| 		{ | 		{ | ||||||
| 			Name:    "Orphaned Attachments without existing issues or releases", | 			Name:    "Orphaned Attachments without existing issues or releases", | ||||||
| 			Counter: models.CountOrphanedAttachments, | 			Counter: repo_model.CountOrphanedAttachments, | ||||||
| 			Fixer:   asFixer(models.DeleteOrphanedAttachments), | 			Fixer:   asFixer(repo_model.DeleteOrphanedAttachments), | ||||||
| 		}, | 		}, | ||||||
| 		// find null archived repositories | 		// find null archived repositories | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| package doctor | package doctor | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| ) | ) | ||||||
| @@ -21,7 +21,7 @@ func checkAttachmentStorageFiles(logger log.Logger, autofix bool) error { | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		exist, err := models.ExistAttachmentsByUUID(stat.Name()) | 		exist, err := repo_model.ExistAttachmentsByUUID(stat.Name()) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -54,7 +55,7 @@ func GetReleaseAttachment(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	releaseID := ctx.ParamsInt64(":id") | 	releaseID := ctx.ParamsInt64(":id") | ||||||
| 	attachID := ctx.ParamsInt64(":asset") | 	attachID := ctx.ParamsInt64(":asset") | ||||||
| 	attach, err := models.GetAttachmentByID(attachID) | 	attach, err := repo_model.GetAttachmentByID(attachID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | ||||||
| 		return | 		return | ||||||
| @@ -241,7 +242,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { | |||||||
| 	// Check if release exists an load release | 	// Check if release exists an load release | ||||||
| 	releaseID := ctx.ParamsInt64(":id") | 	releaseID := ctx.ParamsInt64(":id") | ||||||
| 	attachID := ctx.ParamsInt64(":asset") | 	attachID := ctx.ParamsInt64(":asset") | ||||||
| 	attach, err := models.GetAttachmentByID(attachID) | 	attach, err := repo_model.GetAttachmentByID(attachID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | ||||||
| 		return | 		return | ||||||
| @@ -256,7 +257,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { | |||||||
| 		attach.Name = form.Name | 		attach.Name = form.Name | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.UpdateAttachment(attach); err != nil { | 	if err := repo_model.UpdateAttachment(attach); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) | 		ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) | ||||||
| 	} | 	} | ||||||
| 	ctx.JSON(http.StatusCreated, convert.ToReleaseAttachment(attach)) | 	ctx.JSON(http.StatusCreated, convert.ToReleaseAttachment(attach)) | ||||||
| @@ -299,7 +300,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { | |||||||
| 	// Check if release exists an load release | 	// Check if release exists an load release | ||||||
| 	releaseID := ctx.ParamsInt64(":id") | 	releaseID := ctx.ParamsInt64(":id") | ||||||
| 	attachID := ctx.ParamsInt64(":asset") | 	attachID := ctx.ParamsInt64(":asset") | ||||||
| 	attach, err := models.GetAttachmentByID(attachID) | 	attach, err := repo_model.GetAttachmentByID(attachID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) | ||||||
| 		return | 		return | ||||||
| @@ -311,7 +312,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
| 	// FIXME Should prove the existence of the given repo, but results in unnecessary database requests | 	// FIXME Should prove the existence of the given repo, but results in unnecessary database requests | ||||||
|  |  | ||||||
| 	if err := models.DeleteAttachment(attach, true); err != nil { | 	if err := repo_model.DeleteAttachment(attach, true); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) | 		ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/httpcache" | 	"code.gitea.io/gitea/modules/httpcache" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -62,7 +63,7 @@ func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) { | |||||||
| // DeleteAttachment response for deleting issue's attachment | // DeleteAttachment response for deleting issue's attachment | ||||||
| func DeleteAttachment(ctx *context.Context) { | func DeleteAttachment(ctx *context.Context) { | ||||||
| 	file := ctx.FormString("file") | 	file := ctx.FormString("file") | ||||||
| 	attach, err := models.GetAttachmentByUUID(file) | 	attach, err := repo_model.GetAttachmentByUUID(file) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusBadRequest, err.Error()) | 		ctx.Error(http.StatusBadRequest, err.Error()) | ||||||
| 		return | 		return | ||||||
| @@ -71,7 +72,7 @@ func DeleteAttachment(ctx *context.Context) { | |||||||
| 		ctx.Error(http.StatusForbidden) | 		ctx.Error(http.StatusForbidden) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	err = models.DeleteAttachment(attach, true) | 	err = repo_model.DeleteAttachment(attach, true) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteAttachment: %v", err)) | 		ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteAttachment: %v", err)) | ||||||
| 		return | 		return | ||||||
| @@ -83,9 +84,9 @@ func DeleteAttachment(ctx *context.Context) { | |||||||
|  |  | ||||||
| // GetAttachment serve attachements | // GetAttachment serve attachements | ||||||
| func GetAttachment(ctx *context.Context) { | func GetAttachment(ctx *context.Context) { | ||||||
| 	attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid")) | 	attach, err := repo_model.GetAttachmentByUUID(ctx.Params(":uuid")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrAttachmentNotExist(err) { | 		if repo_model.IsErrAttachmentNotExist(err) { | ||||||
| 			ctx.Error(http.StatusNotFound) | 			ctx.Error(http.StatusNotFound) | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.ServerError("GetAttachmentByUUID", err) | 			ctx.ServerError("GetAttachmentByUUID", err) | ||||||
| @@ -93,7 +94,7 @@ func GetAttachment(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	repository, unitType, err := attach.LinkedRepository() | 	repository, unitType, err := models.LinkedRepository(attach) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("LinkedRepository", err) | 		ctx.ServerError("LinkedRepository", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -2516,7 +2517,7 @@ func GetCommentAttachments(ctx *context.Context) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func updateAttachments(item interface{}, files []string) error { | func updateAttachments(item interface{}, files []string) error { | ||||||
| 	var attachments []*models.Attachment | 	var attachments []*repo_model.Attachment | ||||||
| 	switch content := item.(type) { | 	switch content := item.(type) { | ||||||
| 	case *models.Issue: | 	case *models.Issue: | ||||||
| 		attachments = content.Attachments | 		attachments = content.Attachments | ||||||
| @@ -2529,7 +2530,7 @@ func updateAttachments(item interface{}, files []string) error { | |||||||
| 		if util.IsStringInSlice(attachments[i].UUID, files) { | 		if util.IsStringInSlice(attachments[i].UUID, files) { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		if err := models.DeleteAttachment(attachments[i], true); err != nil { | 		if err := repo_model.DeleteAttachment(attachments[i], true); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -2549,16 +2550,16 @@ func updateAttachments(item interface{}, files []string) error { | |||||||
| 	} | 	} | ||||||
| 	switch content := item.(type) { | 	switch content := item.(type) { | ||||||
| 	case *models.Issue: | 	case *models.Issue: | ||||||
| 		content.Attachments, err = models.GetAttachmentsByIssueID(content.ID) | 		content.Attachments, err = repo_model.GetAttachmentsByIssueID(content.ID) | ||||||
| 	case *models.Comment: | 	case *models.Comment: | ||||||
| 		content.Attachments, err = models.GetAttachmentsByCommentID(content.ID) | 		content.Attachments, err = repo_model.GetAttachmentsByCommentID(content.ID) | ||||||
| 	default: | 	default: | ||||||
| 		return fmt.Errorf("Unknown Type: %T", content) | 		return fmt.Errorf("Unknown Type: %T", content) | ||||||
| 	} | 	} | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func attachmentsHTML(ctx *context.Context, attachments []*models.Attachment, content string) string { | func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment, content string) string { | ||||||
| 	attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{ | 	attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{ | ||||||
| 		"ctx":         ctx.Data, | 		"ctx":         ctx.Data, | ||||||
| 		"Attachments": attachments, | 		"Attachments": attachments, | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -346,7 +347,7 @@ func RedirectDownload(ctx *context.Context) { | |||||||
| 	curRepo := ctx.Repo.Repository | 	curRepo := ctx.Repo.Repository | ||||||
| 	releases, err := models.GetReleasesByRepoIDAndNames(db.DefaultContext, curRepo.ID, tagNames) | 	releases, err := models.GetReleasesByRepoIDAndNames(db.DefaultContext, curRepo.ID, tagNames) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrAttachmentNotExist(err) { | 		if repo_model.IsErrAttachmentNotExist(err) { | ||||||
| 			ctx.Error(http.StatusNotFound) | 			ctx.Error(http.StatusNotFound) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -355,7 +356,7 @@ func RedirectDownload(ctx *context.Context) { | |||||||
| 	} | 	} | ||||||
| 	if len(releases) == 1 { | 	if len(releases) == 1 { | ||||||
| 		release := releases[0] | 		release := releases[0] | ||||||
| 		att, err := models.GetAttachmentByReleaseIDFileName(release.ID, fileName) | 		att, err := repo_model.GetAttachmentByReleaseIDFileName(release.ID, fileName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusNotFound) | 			ctx.Error(http.StatusNotFound) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -10,8 +10,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| 	"code.gitea.io/gitea/modules/upload" | 	"code.gitea.io/gitea/modules/upload" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| @@ -20,7 +20,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| // NewAttachment creates a new attachment object, but do not verify. | // NewAttachment creates a new attachment object, but do not verify. | ||||||
| func NewAttachment(attach *models.Attachment, file io.Reader) (*models.Attachment, error) { | func NewAttachment(attach *repo_model.Attachment, file io.Reader) (*repo_model.Attachment, error) { | ||||||
| 	if attach.RepoID == 0 { | 	if attach.RepoID == 0 { | ||||||
| 		return nil, fmt.Errorf("attachment %s should belong to a repository", attach.Name) | 		return nil, fmt.Errorf("attachment %s should belong to a repository", attach.Name) | ||||||
| 	} | 	} | ||||||
| @@ -40,7 +40,7 @@ func NewAttachment(attach *models.Attachment, file io.Reader) (*models.Attachmen | |||||||
| } | } | ||||||
|  |  | ||||||
| // UploadAttachment upload new attachment into storage and update database | // UploadAttachment upload new attachment into storage and update database | ||||||
| func UploadAttachment(file io.Reader, actorID, repoID, releaseID int64, fileName string, allowedTypes string) (*models.Attachment, error) { | func UploadAttachment(file io.Reader, actorID, repoID, releaseID int64, fileName string, allowedTypes string) (*repo_model.Attachment, error) { | ||||||
| 	buf := make([]byte, 1024) | 	buf := make([]byte, 1024) | ||||||
| 	n, _ := util.ReadAtMost(file, buf) | 	n, _ := util.ReadAtMost(file, buf) | ||||||
| 	buf = buf[:n] | 	buf = buf[:n] | ||||||
| @@ -49,7 +49,7 @@ func UploadAttachment(file io.Reader, actorID, repoID, releaseID int64, fileName | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return NewAttachment(&models.Attachment{ | 	return NewAttachment(&repo_model.Attachment{ | ||||||
| 		RepoID:     repoID, | 		RepoID:     repoID, | ||||||
| 		UploaderID: actorID, | 		UploaderID: actorID, | ||||||
| 		ReleaseID:  releaseID, | 		ReleaseID:  releaseID, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -29,14 +30,14 @@ func TestUploadAttachment(t *testing.T) { | |||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	defer f.Close() | 	defer f.Close() | ||||||
|  |  | ||||||
| 	attach, err := NewAttachment(&models.Attachment{ | 	attach, err := NewAttachment(&repo_model.Attachment{ | ||||||
| 		RepoID:     1, | 		RepoID:     1, | ||||||
| 		UploaderID: user.ID, | 		UploaderID: user.ID, | ||||||
| 		Name:       filepath.Base(fPath), | 		Name:       filepath.Base(fPath), | ||||||
| 	}, f) | 	}, f) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	attachment, err := models.GetAttachmentByUUID(attach.UUID) | 	attachment, err := repo_model.GetAttachmentByUUID(attach.UUID) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, user.ID, attachment.UploaderID) | 	assert.EqualValues(t, user.ID, attachment.UploaderID) | ||||||
| 	assert.Equal(t, int64(0), attachment.DownloadCount) | 	assert.Equal(t, int64(0), attachment.DownloadCount) | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	base "code.gitea.io/gitea/modules/migration" | 	base "code.gitea.io/gitea/modules/migration" | ||||||
| @@ -295,7 +296,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { | |||||||
| 					asset.Created = release.Created | 					asset.Created = release.Created | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			var attach = models.Attachment{ | 			var attach = repo_model.Attachment{ | ||||||
| 				UUID:          gouuid.New().String(), | 				UUID:          gouuid.New().String(), | ||||||
| 				Name:          asset.Name, | 				Name:          asset.Name, | ||||||
| 				DownloadCount: int64(*asset.DownloadCount), | 				DownloadCount: int64(*asset.DownloadCount), | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/notification" | 	"code.gitea.io/gitea/modules/notification" | ||||||
| @@ -206,7 +207,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea | |||||||
| 	var deletedUUIDsMap = make(map[string]bool) | 	var deletedUUIDsMap = make(map[string]bool) | ||||||
| 	if len(delAttachmentUUIDs) > 0 { | 	if len(delAttachmentUUIDs) > 0 { | ||||||
| 		// Check attachments | 		// Check attachments | ||||||
| 		attachments, err := models.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) | 		attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", delAttachmentUUIDs, err) | 			return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", delAttachmentUUIDs, err) | ||||||
| 		} | 		} | ||||||
| @@ -217,7 +218,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea | |||||||
| 			deletedUUIDsMap[attach.UUID] = true | 			deletedUUIDsMap[attach.UUID] = true | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := models.DeleteAttachments(ctx, attachments, false); err != nil { | 		if _, err := repo_model.DeleteAttachments(ctx, attachments, false); err != nil { | ||||||
| 			return fmt.Errorf("DeleteAttachments [uuids: %v]: %v", delAttachmentUUIDs, err) | 			return fmt.Errorf("DeleteAttachments [uuids: %v]: %v", delAttachmentUUIDs, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -228,7 +229,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea | |||||||
| 			updateAttachmentsList = append(updateAttachmentsList, k) | 			updateAttachmentsList = append(updateAttachmentsList, k) | ||||||
| 		} | 		} | ||||||
| 		// Check attachments | 		// Check attachments | ||||||
| 		attachments, err := models.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) | 		attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", updateAttachmentsList, err) | 			return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", updateAttachmentsList, err) | ||||||
| 		} | 		} | ||||||
| @@ -240,7 +241,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea | |||||||
|  |  | ||||||
| 		for uuid, newName := range editAttachments { | 		for uuid, newName := range editAttachments { | ||||||
| 			if !deletedUUIDsMap[uuid] { | 			if !deletedUUIDsMap[uuid] { | ||||||
| 				if err = models.UpdateAttachmentByUUID(ctx, &models.Attachment{ | 				if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ | ||||||
| 					UUID: uuid, | 					UUID: uuid, | ||||||
| 					Name: newName, | 					Name: newName, | ||||||
| 				}, "name"); err != nil { | 				}, "name"); err != nil { | ||||||
| @@ -255,7 +256,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, uuid := range delAttachmentUUIDs { | 	for _, uuid := range delAttachmentUUIDs { | ||||||
| 		if err := storage.Attachments.Delete(models.AttachmentRelativePath(uuid)); err != nil { | 		if err := storage.Attachments.Delete(repo_model.AttachmentRelativePath(uuid)); err != nil { | ||||||
| 			// Even delete files failed, but the attachments has been removed from database, so we | 			// Even delete files failed, but the attachments has been removed from database, so we | ||||||
| 			// should not return error but only record the error on logs. | 			// should not return error but only record the error on logs. | ||||||
| 			// users have to delete this attachments manually or we should have a | 			// users have to delete this attachments manually or we should have a | ||||||
| @@ -321,7 +322,7 @@ func DeleteReleaseByID(id int64, doer *models.User, delTag bool) error { | |||||||
| 		return fmt.Errorf("LoadAttributes: %v", err) | 		return fmt.Errorf("LoadAttributes: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.DeleteAttachmentsByRelease(rel.ID); err != nil { | 	if err := repo_model.DeleteAttachmentsByRelease(rel.ID); err != nil { | ||||||
| 		return fmt.Errorf("DeleteAttachments: %v", err) | 		return fmt.Errorf("DeleteAttachments: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/services/attachment" | 	"code.gitea.io/gitea/services/attachment" | ||||||
| @@ -103,7 +104,7 @@ func TestRelease_Create(t *testing.T) { | |||||||
| 		IsTag:        false, | 		IsTag:        false, | ||||||
| 	}, nil, "")) | 	}, nil, "")) | ||||||
|  |  | ||||||
| 	attach, err := attachment.NewAttachment(&models.Attachment{ | 	attach, err := attachment.NewAttachment(&repo_model.Attachment{ | ||||||
| 		RepoID:     repo.ID, | 		RepoID:     repo.ID, | ||||||
| 		UploaderID: user.ID, | 		UploaderID: user.ID, | ||||||
| 		Name:       "test.txt", | 		Name:       "test.txt", | ||||||
| @@ -236,7 +237,7 @@ func TestRelease_Update(t *testing.T) { | |||||||
| 	assert.Equal(t, tagName, release.TagName) | 	assert.Equal(t, tagName, release.TagName) | ||||||
|  |  | ||||||
| 	// Add new attachments | 	// Add new attachments | ||||||
| 	attach, err := attachment.NewAttachment(&models.Attachment{ | 	attach, err := attachment.NewAttachment(&repo_model.Attachment{ | ||||||
| 		RepoID:     repo.ID, | 		RepoID:     repo.ID, | ||||||
| 		UploaderID: user.ID, | 		UploaderID: user.ID, | ||||||
| 		Name:       "test.txt", | 		Name:       "test.txt", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user