From fc3d0826096943b979717ed46c9a4cfd86e06106 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 19 Nov 2021 21:39:57 +0800 Subject: [PATCH] Move attachment into models/repo/ (#17650) * Move attachment into models/repo/ * Fix test * Fix bug --- cmd/migrate_storage.go | 3 +- integrations/attachment_test.go | 4 +- models/error.go | 25 +---- models/issue.go | 116 ++++++++++++---------- models/issue_assignees.go | 21 ++-- models/issue_comment.go | 70 +++++++------ models/issue_comment_list.go | 11 +- models/issue_dependency.go | 23 +++-- models/issue_label.go | 40 ++++---- models/issue_list.go | 7 +- models/issue_lock.go | 12 +-- models/issue_milestone.go | 23 +++-- models/issue_stopwatch.go | 39 ++++---- models/issue_tracked_time.go | 36 +++---- models/issue_xref.go | 16 +-- models/issue_xref_test.go | 27 +++-- models/notification.go | 16 +-- models/project_issue.go | 24 ++--- models/pull.go | 23 +++-- models/release.go | 25 ++--- models/repo.go | 31 +++++- models/{ => repo}/attachment.go | 79 ++++++++------- models/{ => repo}/attachment_test.go | 30 +----- models/repo/main_test.go | 18 ++++ models/repo_test.go | 28 ++++++ models/review.go | 57 ++++++----- models/statistic.go | 3 +- modules/convert/release.go | 3 +- modules/doctor/dbconsistency.go | 5 +- modules/doctor/storage.go | 4 +- routers/api/v1/repo/release_attachment.go | 11 +- routers/web/repo/attachment.go | 11 +- routers/web/repo/issue.go | 11 +- routers/web/repo/repo.go | 5 +- services/attachment/attachment.go | 8 +- services/attachment/attachment_test.go | 5 +- services/migrations/gitea_uploader.go | 3 +- services/release/release.go | 13 +-- services/release/release_test.go | 5 +- 39 files changed, 477 insertions(+), 414 deletions(-) rename models/{ => repo}/attachment.go (80%) rename models/{ => repo}/attachment_test.go (78%) create mode 100644 models/repo/main_test.go diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index 1829ad00ba..9f1d9057f9 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "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/setting" "code.gitea.io/gitea/modules/storage" @@ -79,7 +80,7 @@ var CmdMigrateStorage = cli.Command{ } 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()) return err }) diff --git a/integrations/attachment_test.go b/integrations/attachment_test.go index 052f27605a..481104d73f 100644 --- a/integrations/attachment_test.go +++ b/integrations/attachment_test.go @@ -14,7 +14,7 @@ import ( "strings" "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/test" @@ -122,7 +122,7 @@ func TestGetAttachment(t *testing.T) { t.Run(tc.name, func(t *testing.T) { //Write empty file to be available for response 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) } //Actual test diff --git a/models/error.go b/models/error.go index 7d9b2ae65b..862b5633ec 100644 --- a/models/error.go +++ b/models/error.go @@ -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) } -// _____ __ __ .__ __ -// / _ \_/ |__/ |______ ____ | |__ _____ ____ _____/ |_ -// / /_\ \ __\ __\__ \ _/ ___\| | \ / \_/ __ \ / \ __\ -// / | \ | | | / __ \\ \___| 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. func IsErrUploadNotExist(err error) bool { - _, ok := err.(ErrAttachmentNotExist) + _, ok := err.(ErrUploadNotExist) return ok } diff --git a/models/issue.go b/models/issue.go index ef31f416ad..1b9d35d1e3 100644 --- a/models/issue.go +++ b/models/issue.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" @@ -60,11 +61,11 @@ type Issue struct { UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` ClosedUnix timeutil.TimeStamp `xorm:"INDEX"` - Attachments []*Attachment `xorm:"-"` - Comments []*Comment `xorm:"-"` - Reactions ReactionList `xorm:"-"` - TotalTrackedTime int64 `xorm:"-"` - Assignees []*User `xorm:"-"` + Attachments []*repo_model.Attachment `xorm:"-"` + Comments []*Comment `xorm:"-"` + Reactions ReactionList `xorm:"-"` + TotalTrackedTime int64 `xorm:"-"` + Assignees []*User `xorm:"-"` // IsLocked limits commenting abilities to users on an issue // with write access @@ -273,7 +274,8 @@ func (issue *Issue) loadMilestone(e db.Engine) (err error) { return nil } -func (issue *Issue) loadAttributes(e db.Engine) (err error) { +func (issue *Issue) loadAttributes(ctx context.Context) (err error) { + e := db.GetEngine(ctx) if err = issue.loadRepo(e); err != nil { return } @@ -304,7 +306,7 @@ func (issue *Issue) loadAttributes(e db.Engine) (err error) { } if issue.Attachments == nil { - issue.Attachments, err = getAttachmentsByIssueID(e, issue.ID) + issue.Attachments, err = repo_model.GetAttachmentsByIssueIDCtx(ctx, issue.ID) if err != nil { return fmt.Errorf("getAttachmentsByIssueID [%d]: %v", issue.ID, err) } @@ -328,7 +330,7 @@ func (issue *Issue) loadAttributes(e db.Engine) (err error) { // LoadAttributes loads the attribute of this issue. func (issue *Issue) LoadAttributes() error { - return issue.loadAttributes(db.GetEngine(db.DefaultContext)) + return issue.loadAttributes(db.DefaultContext) } // LoadMilestone load milestone of this issue. @@ -426,12 +428,12 @@ func (issue *Issue) HasLabel(labelID int64) bool { return issue.hasLabel(db.GetEngine(db.DefaultContext), labelID) } -func (issue *Issue) addLabel(e db.Engine, label *Label, doer *User) error { - return newIssueLabel(e, issue, label, doer) +func (issue *Issue) addLabel(ctx context.Context, label *Label, doer *User) error { + return newIssueLabel(ctx, issue, label, doer) } -func (issue *Issue) addLabels(e db.Engine, labels []*Label, doer *User) error { - return newIssueLabels(e, issue, labels, doer) +func (issue *Issue) addLabels(ctx context.Context, labels []*Label, doer *User) error { + return newIssueLabels(ctx, issue, labels, doer) } func (issue *Issue) getLabels(e db.Engine) (err error) { @@ -446,17 +448,17 @@ func (issue *Issue) getLabels(e db.Engine) (err error) { return nil } -func (issue *Issue) removeLabel(e db.Engine, doer *User, label *Label) error { - return deleteIssueLabel(e, issue, label, doer) +func (issue *Issue) removeLabel(ctx context.Context, doer *User, label *Label) error { + return deleteIssueLabel(ctx, issue, label, doer) } -func (issue *Issue) clearLabels(e db.Engine, doer *User) (err error) { - if err = issue.getLabels(e); err != nil { +func (issue *Issue) clearLabels(ctx context.Context, doer *User) (err error) { + if err = issue.getLabels(db.GetEngine(ctx)); err != nil { return fmt.Errorf("getLabels: %v", err) } for i := range issue.Labels { - if err = issue.removeLabel(e, doer, issue.Labels[i]); err != nil { + if err = issue.removeLabel(ctx, doer, issue.Labels[i]); err != nil { return fmt.Errorf("removeLabel: %v", err) } } @@ -487,7 +489,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) { return ErrRepoLabelNotExist{} } - if err = issue.clearLabels(db.GetEngine(ctx), doer); err != nil { + if err = issue.clearLabels(ctx, doer); err != nil { return err } @@ -561,13 +563,13 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) { toRemove = append(toRemove, issue.Labels[removeIndex:]...) if len(toAdd) > 0 { - if err = issue.addLabels(db.GetEngine(ctx), toAdd, doer); err != nil { + if err = issue.addLabels(ctx, toAdd, doer); err != nil { return fmt.Errorf("addLabels: %v", err) } } for _, l := range toRemove { - if err = issue.removeLabel(db.GetEngine(ctx), doer, l); err != nil { + if err = issue.removeLabel(ctx, doer, l); err != nil { return fmt.Errorf("removeLabel: %v", err) } } @@ -596,9 +598,9 @@ func updateIssueCols(e db.Engine, issue *Issue, cols ...string) error { return nil } -func (issue *Issue) changeStatus(e db.Engine, doer *User, isClosed, isMergePull bool) (*Comment, error) { +func (issue *Issue) changeStatus(ctx context.Context, doer *User, isClosed, isMergePull bool) (*Comment, error) { // Reload the issue - currentIssue, err := getIssueByID(e, issue.ID) + currentIssue, err := getIssueByID(db.GetEngine(ctx), issue.ID) if err != nil { return nil, err } @@ -616,10 +618,11 @@ func (issue *Issue) changeStatus(e db.Engine, doer *User, isClosed, isMergePull } issue.IsClosed = isClosed - return issue.doChangeStatus(e, doer, isMergePull) + return issue.doChangeStatus(ctx, doer, isMergePull) } -func (issue *Issue) doChangeStatus(e db.Engine, doer *User, isMergePull bool) (*Comment, error) { +func (issue *Issue) doChangeStatus(ctx context.Context, doer *User, isMergePull bool) (*Comment, error) { + e := db.GetEngine(ctx) // Check for open dependencies if issue.IsClosed && issue.Repo.isDependenciesEnabled(e) { // only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies @@ -672,7 +675,7 @@ func (issue *Issue) doChangeStatus(e db.Engine, doer *User, isMergePull bool) (* cmtType = CommentTypeMergePull } - return createComment(e, &CreateCommentOptions{ + return createComment(ctx, &CreateCommentOptions{ Type: cmtType, Doer: doer, Repo: issue.Repo, @@ -695,7 +698,7 @@ func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (*Comment, error) { return nil, err } - comment, err := issue.changeStatus(db.GetEngine(ctx), doer, isClosed, false) + comment, err := issue.changeStatus(ctx, doer, isClosed, false) if err != nil { return nil, err } @@ -731,10 +734,10 @@ func (issue *Issue) ChangeTitle(doer *User, oldTitle string) (err error) { OldTitle: oldTitle, NewTitle: issue.Title, } - if _, err = createComment(db.GetEngine(ctx), opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } - if err = issue.addCrossReferences(db.GetEngine(ctx), doer, true); err != nil { + if err = issue.addCrossReferences(ctx, doer, true); err != nil { return err } @@ -767,7 +770,7 @@ func (issue *Issue) ChangeRef(doer *User, oldRef string) (err error) { OldRef: oldRefFriendly, NewRef: newRefFriendly, } - if _, err = createComment(db.GetEngine(ctx), opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } @@ -792,7 +795,7 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc Issue: issue, OldRef: branchName, } - if _, err = createComment(db.GetEngine(ctx), opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return err } @@ -806,13 +809,13 @@ func (issue *Issue) UpdateAttachments(uuids []string) (err error) { return err } defer committer.Close() - attachments, err := getAttachmentsByUUIDs(db.GetEngine(ctx), uuids) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids) if err != nil { return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) } for i := 0; i < len(attachments); i++ { attachments[i].IssueID = issue.ID - if err := updateAttachment(db.GetEngine(ctx), attachments[i]); err != nil { + if err := repo_model.UpdateAttachmentCtx(ctx, attachments[i]); err != nil { return fmt.Errorf("update attachment [id: %d]: %v", attachments[i].ID, err) } } @@ -838,7 +841,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) { return fmt.Errorf("SaveIssueContentHistory: %v", err) } - if err = issue.addCrossReferences(ctx.Engine(), doer, true); err != nil { + if err = issue.addCrossReferences(ctx, doer, true); err != nil { return fmt.Errorf("addCrossReferences: %v", err) } @@ -908,7 +911,8 @@ type NewIssueOptions struct { IsPull bool } -func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { +func newIssue(ctx context.Context, doer *User, opts NewIssueOptions) (err error) { + e := db.GetEngine(ctx) opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) if opts.Issue.MilestoneID > 0 { @@ -949,7 +953,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { OldMilestoneID: 0, MilestoneID: opts.Issue.MilestoneID, } - if _, err = createComment(e, opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return err } } @@ -981,7 +985,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { continue } - if err = opts.Issue.addLabel(e, label, opts.Issue.Poster); err != nil { + if err = opts.Issue.addLabel(ctx, label, opts.Issue.Poster); err != nil { return fmt.Errorf("addLabel [id: %d]: %v", label.ID, err) } } @@ -992,7 +996,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { } if len(opts.Attachments) > 0 { - attachments, err := getAttachmentsByUUIDs(e, opts.Attachments) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments) if err != nil { return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) } @@ -1004,7 +1008,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { } } } - if err = opts.Issue.loadAttributes(e); err != nil { + if err = opts.Issue.loadAttributes(ctx); err != nil { return err } @@ -1013,7 +1017,7 @@ func newIssue(e db.Engine, doer *User, opts NewIssueOptions) (err error) { return err } - return opts.Issue.addCrossReferences(e, doer, false) + return opts.Issue.addCrossReferences(ctx, doer, false) } // RecalculateIssueIndexForRepo create issue_index for repo if not exist and @@ -1056,7 +1060,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) } defer committer.Close() - if err = newIssue(db.GetEngine(ctx), issue.Poster, NewIssueOptions{ + if err = newIssue(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, @@ -1119,7 +1123,7 @@ func GetIssueWithAttrsByID(id int64) (*Issue, error) { if err != nil { return nil, err } - return issue, issue.loadAttributes(db.GetEngine(db.DefaultContext)) + return issue, issue.loadAttributes(db.DefaultContext) } // GetIssueByID returns an issue by given ID. @@ -1838,11 +1842,12 @@ func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int6 // If the issue status is changed a statusChangeComment is returned // similarly if the title is changed the titleChanged bool is set to true func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, titleChanged bool, err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, false, err } + defer committer.Close() + sess := db.GetEngine(ctx) if err := issue.loadRepo(sess); err != nil { return nil, false, fmt.Errorf("loadRepo: %v", err) @@ -1871,23 +1876,23 @@ func UpdateIssueByAPI(issue *Issue, doer *User) (statusChangeComment *Comment, t OldTitle: currentIssue.Title, NewTitle: issue.Title, } - _, err := createComment(sess, opts) + _, err := createComment(ctx, opts) if err != nil { return nil, false, fmt.Errorf("createComment: %v", err) } } if currentIssue.IsClosed != issue.IsClosed { - statusChangeComment, err = issue.doChangeStatus(sess, doer, false) + statusChangeComment, err = issue.doChangeStatus(ctx, doer, false) if err != nil { return nil, false, err } } - if err := issue.addCrossReferences(sess, doer, true); err != nil { + if err := issue.addCrossReferences(ctx, doer, true); err != nil { return nil, false, err } - return statusChangeComment, titleChanged, sess.Commit() + return statusChangeComment, titleChanged, committer.Commit() } // UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it. @@ -1897,11 +1902,12 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us return nil } - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) // Update the deadline if err = updateIssueCols(sess, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil { @@ -1909,11 +1915,11 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us } // Make the comment - if _, err = createDeadlineComment(sess, doer, issue, deadlineUnix); err != nil { + if _, err = createDeadlineComment(ctx, doer, issue, deadlineUnix); err != nil { return fmt.Errorf("createRemovedDueDateComment: %v", err) } - return sess.Commit() + return committer.Commit() } // DependencyInfo represents high level information about an issue which is a dependency of another issue. @@ -2244,7 +2250,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin return } - var attachments []*Attachment + var attachments []*repo_model.Attachment if err = sess.In("issue_id", deleteCond). Find(&attachments); err != nil { return @@ -2255,7 +2261,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin } if _, err = sess.In("issue_id", deleteCond). - Delete(&Attachment{}); err != nil { + Delete(&repo_model.Attachment{}); err != nil { return } diff --git a/models/issue_assignees.go b/models/issue_assignees.go index 0f7ba2d702..996a3a8563 100644 --- a/models/issue_assignees.go +++ b/models/issue_assignees.go @@ -5,12 +5,11 @@ package models import ( + "context" "fmt" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/util" - - "xorm.io/xorm" ) // 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. func (issue *Issue) ToggleAssignee(doer *User, assigneeID int64) (removed bool, comment *Comment, err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return 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 { return false, nil, err } - if err := sess.Commit(); err != nil { + if err := committer.Commit(); err != nil { return false, nil, err } 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) if err != nil { 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, } // Comment - comment, err = createComment(sess, opts) + comment, err = createComment(ctx, opts) if err != nil { 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 -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 assignee, err := getUserByID(e, assigneeID) if err != nil { diff --git a/models/issue_comment.go b/models/issue_comment.go index 1936695732..fccc139cd0 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -7,6 +7,7 @@ package models import ( + "context" "fmt" "regexp" "strconv" @@ -15,6 +16,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -198,8 +200,8 @@ type Comment struct { // Reference issue in commit message CommitSHA string `xorm:"VARCHAR(40)"` - Attachments []*Attachment `xorm:"-"` - Reactions ReactionList `xorm:"-"` + Attachments []*repo_model.Attachment `xorm:"-"` + Reactions ReactionList `xorm:"-"` // For view issue page. ShowRole RoleDescriptor `xorm:"-"` @@ -300,7 +302,7 @@ func (c *Comment) AfterDelete() { return } - _, err := DeleteAttachmentsByComment(c.ID, true) + _, err := repo_model.DeleteAttachmentsByComment(c.ID, true) if err != nil { 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 - c.Attachments, err = getAttachmentsByCommentID(db.GetEngine(db.DefaultContext), c.ID) + c.Attachments, err = repo_model.GetAttachmentsByCommentIDCtx(db.DefaultContext, c.ID) if err != nil { 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 func (c *Comment) UpdateAttachments(uuids []string) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } - attachments, err := getAttachmentsByUUIDs(sess, uuids) + defer committer.Close() + + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids) if err != nil { return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", uuids, err) } for i := 0; i < len(attachments); i++ { attachments[i].IssueID = c.IssueID 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 sess.Commit() + return committer.Commit() } // LoadAssigneeUserAndTeam if comment.Type is CommentTypeAssignees, then load assignees @@ -715,7 +718,8 @@ func (c *Comment) LoadPushCommits() (err error) { 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 if opts.Label != nil { LabelID = opts.Label.ID @@ -763,18 +767,19 @@ func createComment(e db.Engine, opts *CreateCommentOptions) (_ *Comment, err err return nil, err } - if err = updateCommentInfos(e, opts, comment); err != nil { + if err = updateCommentInfos(ctx, opts, comment); err != nil { 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 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. switch opts.Type { case CommentTypeCode: @@ -797,7 +802,7 @@ func updateCommentInfos(e db.Engine, opts *CreateCommentOptions, comment *Commen } // Check attachments - attachments, err := getAttachmentsByUUIDs(e, opts.Attachments) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments) if err != nil { return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) } @@ -819,7 +824,7 @@ func updateCommentInfos(e db.Engine, opts *CreateCommentOptions, comment *Commen 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 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") } - if err := issue.loadRepo(e); err != nil { + if err := issue.loadRepo(db.GetEngine(ctx)); err != nil { return nil, err } @@ -848,7 +853,7 @@ func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlin Issue: issue, Content: content, } - comment, err := createComment(e, opts) + comment, err := createComment(ctx, opts) if err != nil { return nil, err } @@ -856,12 +861,12 @@ func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlin } // 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 if !add { cType = CommentTypeRemoveDependency } - if err = issue.loadRepo(e); err != nil { + if err = issue.loadRepo(db.GetEngine(ctx)); err != nil { return } @@ -873,7 +878,7 @@ func createIssueDependencyComment(e *xorm.Session, doer *User, issue, dependentI Issue: issue, DependentIssueID: dependentIssue.ID, } - if _, err = createComment(e, opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return } @@ -884,7 +889,7 @@ func createIssueDependencyComment(e *xorm.Session, doer *User, issue, dependentI Issue: dependentIssue, DependentIssueID: issue.ID, } - _, err = createComment(e, opts) + _, err = createComment(ctx, opts) return } @@ -928,18 +933,18 @@ type CreateCommentOptions struct { // CreateComment creates comment of issue or commit. func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() - comment, err = createComment(sess, opts) + comment, err = createComment(ctx, opts) if err != nil { return nil, err } - if err = sess.Commit(); err != nil { + if err = committer.Commit(); err != nil { return nil, err } @@ -1068,11 +1073,12 @@ func CountComments(opts *FindCommentsOptions) (int64, error) { // UpdateComment updates information of comment. func UpdateComment(c *Comment, doer *User) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) if _, err := sess.ID(c.ID).AllCols().Update(c); err != nil { return err @@ -1080,10 +1086,10 @@ func UpdateComment(c *Comment, doer *User) error { if err := c.loadIssue(sess); err != nil { return err } - if err := c.addCrossReferences(sess, doer, true); err != nil { + if err := c.addCrossReferences(ctx, doer, true); err != nil { return err } - if err := sess.Commit(); err != nil { + if err := committer.Commit(); err != nil { return fmt.Errorf("Commit: %v", err) } diff --git a/models/issue_comment_list.go b/models/issue_comment_list.go index bd1b48f8e5..3c587fc8f7 100644 --- a/models/issue_comment_list.go +++ b/models/issue_comment_list.go @@ -4,7 +4,10 @@ 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 type CommentList []*Comment @@ -393,7 +396,7 @@ func (comments CommentList) loadAttachments(e db.Engine) (err error) { return nil } - attachments := make(map[int64][]*Attachment, len(comments)) + attachments := make(map[int64][]*repo_model.Attachment, len(comments)) commentsIDs := comments.getCommentIDs() left := len(commentsIDs) for left > 0 { @@ -404,13 +407,13 @@ func (comments CommentList) loadAttachments(e db.Engine) (err error) { rows, err := e.Table("attachment"). Join("INNER", "comment", "comment.id = attachment.comment_id"). In("comment.id", commentsIDs[:limit]). - Rows(new(Attachment)) + Rows(new(repo_model.Attachment)) if err != nil { return err } for rows.Next() { - var attachment Attachment + var attachment repo_model.Attachment err = rows.Scan(&attachment) if err != nil { _ = rows.Close() diff --git a/models/issue_dependency.go b/models/issue_dependency.go index f58bb3da0a..ee984fbe3e 100644 --- a/models/issue_dependency.go +++ b/models/issue_dependency.go @@ -37,11 +37,12 @@ const ( // CreateIssueDependency creates a new dependency for an issue func CreateIssueDependency(user *User, issue, dep *Issue) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) // Check if it aleready exists 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 - if err = createIssueDependencyComment(sess, user, issue, dep, true); err != nil { + if err = createIssueDependencyComment(ctx, user, issue, dep, true); err != nil { return err } - return sess.Commit() + return committer.Commit() } // RemoveIssueDependency removes a dependency from an issue func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType) (err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() var issueDepToDelete IssueDependency @@ -95,7 +96,7 @@ func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType return ErrUnknownDependencyType{depType} } - affected, err := sess.Delete(&issueDepToDelete) + affected, err := db.GetEngine(ctx).Delete(&issueDepToDelete) if err != nil { return err } @@ -106,10 +107,10 @@ func RemoveIssueDependency(user *User, issue, dep *Issue, depType DependencyType } // 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 sess.Commit() + return committer.Commit() } // Check if the dependency already exists diff --git a/models/issue_label.go b/models/issue_label.go index 293b7140f7..492e298600 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -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 // 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{ IssueID: issue.ID, LabelID: label.ID, @@ -683,7 +684,7 @@ func newIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err err Label: label, Content: "1", } - if _, err = createComment(e, opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return err } @@ -696,11 +697,12 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { return nil } - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) if err = issue.loadRepo(sess); err != nil { return err @@ -711,7 +713,7 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { return nil } - if err = newIssueLabel(sess, issue, label, doer); err != nil { + if err = newIssueLabel(ctx, issue, label, doer); err != nil { return err } @@ -720,11 +722,12 @@ func NewIssueLabel(issue *Issue, label *Label, doer *User) (err error) { 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 -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 { return err } @@ -735,7 +738,7 @@ func newIssueLabels(e db.Engine, issue *Issue, labels []*Label, doer *User) (err 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) } } @@ -751,7 +754,7 @@ func NewIssueLabels(issue *Issue, labels []*Label, doer *User) (err error) { } 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 } @@ -763,7 +766,8 @@ func NewIssueLabels(issue *Issue, labels []*Label, doer *User) (err error) { 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{ IssueID: issue.ID, LabelID: label.ID, @@ -784,7 +788,7 @@ func deleteIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err Issue: issue, Label: label, } - if _, err = createComment(e, opts); err != nil { + if _, err = createComment(ctx, opts); err != nil { return err } @@ -793,22 +797,22 @@ func deleteIssueLabel(e db.Engine, issue *Issue, label *Label, doer *User) (err // DeleteIssueLabel deletes issue-label relation. func DeleteIssueLabel(issue *Issue, label *Label, doer *User) (err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() - if err = deleteIssueLabel(sess, issue, label, doer); err != nil { + if err = deleteIssueLabel(ctx, issue, label, doer); err != nil { return err } issue.Labels = nil - if err = issue.loadLabels(sess); err != nil { + if err = issue.loadLabels(db.GetEngine(ctx)); err != nil { return err } - return sess.Commit() + return committer.Commit() } func deleteLabelsByRepoID(sess db.Engine, repoID int64) error { diff --git a/models/issue_list.go b/models/issue_list.go index 04dcc58422..6eeb2a961a 100644 --- a/models/issue_list.go +++ b/models/issue_list.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" "xorm.io/builder" ) @@ -322,7 +323,7 @@ func (issues IssueList) loadAttachments(e db.Engine) (err error) { return nil } - attachments := make(map[int64][]*Attachment, len(issues)) + attachments := make(map[int64][]*repo_model.Attachment, len(issues)) issuesIDs := issues.getIssueIDs() left := len(issuesIDs) for left > 0 { @@ -333,13 +334,13 @@ func (issues IssueList) loadAttachments(e db.Engine) (err error) { rows, err := e.Table("attachment"). Join("INNER", "issue", "issue.id = attachment.issue_id"). In("issue.id", issuesIDs[:limit]). - Rows(new(Attachment)) + Rows(new(repo_model.Attachment)) if err != nil { return err } for rows.Next() { - var attachment Attachment + var attachment repo_model.Attachment err = rows.Scan(&attachment) if err != nil { if err1 := rows.Close(); err1 != nil { diff --git a/models/issue_lock.go b/models/issue_lock.go index d8e3b4c0ab..d0b9c660c2 100644 --- a/models/issue_lock.go +++ b/models/issue_lock.go @@ -37,13 +37,13 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { commentType = CommentTypeUnlock } - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() - if err := updateIssueCols(sess, opts.Issue, "is_locked"); err != nil { + if err := updateIssueCols(db.GetEngine(ctx), opts.Issue, "is_locked"); err != nil { return err } @@ -54,9 +54,9 @@ func updateIssueLock(opts *IssueLockOptions, lock bool) error { Type: commentType, Content: opts.Reason, } - if _, err := createComment(sess, opt); err != nil { + if _, err := createComment(ctx, opt); err != nil { return err } - return sess.Commit() + return committer.Commit() } diff --git a/models/issue_milestone.go b/models/issue_milestone.go index 3898e5b397..fd5d052cbd 100644 --- a/models/issue_milestone.go +++ b/models/issue_milestone.go @@ -5,6 +5,7 @@ package models import ( + "context" "fmt" "strings" "time" @@ -15,7 +16,6 @@ import ( "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" - "xorm.io/xorm" ) // 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) } -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 { return err } @@ -293,7 +294,7 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto OldMilestoneID: oldMilestoneID, MilestoneID: issue.MilestoneID, } - if _, err := createComment(e, opts); err != nil { + if _, err := createComment(ctx, opts); err != nil { return err } } @@ -303,17 +304,17 @@ func changeMilestoneAssign(e *xorm.Session, doer *User, issue *Issue, oldMilesto // ChangeMilestoneAssign changes assignment of milestone for issue. func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err = changeMilestoneAssign(ctx, doer, issue, oldMilestoneID); err != nil { return err } - if err = changeMilestoneAssign(sess, doer, issue, oldMilestoneID); err != nil { - return err - } - - if err = sess.Commit(); err != nil { + if err = committer.Commit(); err != nil { return fmt.Errorf("Commit: %v", err) } return nil diff --git a/models/issue_stopwatch.go b/models/issue_stopwatch.go index e8f19dd738..e9c38b9165 100644 --- a/models/issue_stopwatch.go +++ b/models/issue_stopwatch.go @@ -5,13 +5,12 @@ package models import ( + "context" "fmt" "time" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/timeutil" - - "xorm.io/xorm" ) // 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. func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } - if err := createOrStopIssueStopwatch(sess, user, issue); err != nil { + defer committer.Close() + if err := createOrStopIssueStopwatch(ctx, user, issue); err != nil { 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) if err != nil { return err @@ -122,7 +122,7 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error return err } - if _, err := createComment(e, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, Repo: issue.Repo, @@ -146,7 +146,7 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error if err != nil { return err } - if err := createOrStopIssueStopwatch(e, user, issue); err != nil { + if err := createOrStopIssueStopwatch(ctx, user, issue); err != nil { return err } } @@ -157,11 +157,11 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error IssueID: issue.ID, } - if _, err := e.Insert(sw); err != nil { + if err := db.Insert(ctx, sw); err != nil { return err } - if _, err := createComment(e, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, 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. func CancelStopwatch(user *User, issue *Issue) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } - if err := cancelStopwatch(sess, user, issue); err != nil { + defer committer.Close() + if err := cancelStopwatch(ctx, user, issue); err != nil { 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) if err != nil { return err @@ -201,7 +202,7 @@ func cancelStopwatch(e *xorm.Session, user *User, issue *Issue) error { return err } - if _, err := createComment(e, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Doer: user, Issue: issue, Repo: issue.Repo, diff --git a/models/issue_tracked_time.go b/models/issue_tracked_time.go index 79de891019..55d585a55c 100644 --- a/models/issue_tracked_time.go +++ b/models/issue_tracked_time.go @@ -154,12 +154,12 @@ func GetTrackedSeconds(opts FindTrackedTimesOptions) (int64, error) { // AddTime will add the given time (in seconds) to the issue func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) t, err := addTime(sess, user, issue, amount, created) if err != nil { @@ -170,7 +170,7 @@ func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*Tracke return nil, err } - if _, err := createComment(sess, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, @@ -181,7 +181,7 @@ func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*Tracke 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) { @@ -230,12 +230,12 @@ func TotalTimes(options *FindTrackedTimesOptions) (map[*User]string, error) { // DeleteIssueUserTimes deletes times for issue func DeleteIssueUserTimes(issue *Issue, user *User) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) opts := FindTrackedTimesOptions{ IssueID: issue.ID, @@ -253,7 +253,7 @@ func DeleteIssueUserTimes(issue *Issue, user *User) error { if err := issue.loadRepo(sess); err != nil { return err } - if _, err := createComment(sess, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, @@ -263,17 +263,17 @@ func DeleteIssueUserTimes(issue *Issue, user *User) error { return err } - return sess.Commit() + return committer.Commit() } // DeleteTime delete a specific Time func DeleteTime(t *TrackedTime) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() + sess := db.GetEngine(ctx) if err := t.loadAttributes(sess); err != nil { return err @@ -283,7 +283,7 @@ func DeleteTime(t *TrackedTime) error { return err } - if _, err := createComment(sess, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Issue: t.Issue, Repo: t.Issue.Repo, Doer: t.User, @@ -293,7 +293,7 @@ func DeleteTime(t *TrackedTime) error { return err } - return sess.Commit() + return committer.Commit() } func deleteTimes(e db.Engine, opts FindTrackedTimesOptions) (removedTime int64, err error) { diff --git a/models/issue_xref.go b/models/issue_xref.go index 4630f4d3a4..55483ce57b 100644 --- a/models/issue_xref.go +++ b/models/issue_xref.go @@ -5,6 +5,7 @@ package models import ( + "context" "fmt" "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 if issue.IsPull { commentType = CommentTypePullRef @@ -72,10 +73,11 @@ func (issue *Issue) addCrossReferences(e db.Engine, doer *User, removeOld bool) OrigIssue: issue, 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) if err != nil { return err @@ -125,7 +127,7 @@ func (issue *Issue) createCrossReferences(e db.Engine, ctx *crossReferencesConte RefAction: xref.Action, RefIsPull: ctx.OrigIssue.IsPull, } - _, err := createComment(e, opts) + _, err := createComment(stdCtx, opts) if err != nil { 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 { return nil } - if err := comment.loadIssue(e); err != nil { + if err := comment.loadIssue(db.GetEngine(stdCtx)); err != nil { return err } ctx := &crossReferencesContext{ @@ -254,7 +256,7 @@ func (comment *Comment) addCrossReferences(e db.Engine, doer *User, removeOld bo OrigComment: comment, 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 { diff --git a/models/issue_xref_test.go b/models/issue_xref_test.go index 551c29dcba..c40e545fa8 100644 --- a/models/issue_xref_test.go +++ b/models/issue_xref_test.go @@ -140,19 +140,18 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu Index: idx, } - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - - assert.NoError(t, sess.Begin()) - err = newIssue(sess, d, NewIssueOptions{ + ctx, committer, err := db.TxContext() + assert.NoError(t, err) + defer committer.Close() + err = newIssue(ctx, d, NewIssueOptions{ Repo: r, Issue: i, }) 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, i.addCrossReferences(sess, d, false)) - assert.NoError(t, sess.Commit()) + assert.NoError(t, i.addCrossReferences(ctx, d, false)) + assert.NoError(t, committer.Commit()) 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) c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - assert.NoError(t, sess.Begin()) - _, err := sess.Insert(c) + ctx, committer, err := db.TxContext() assert.NoError(t, err) - assert.NoError(t, c.addCrossReferences(sess, d, false)) - assert.NoError(t, sess.Commit()) + defer committer.Close() + err = db.Insert(ctx, c) + assert.NoError(t, err) + assert.NoError(t, c.addCrossReferences(ctx, d, false)) + assert.NoError(t, committer.Commit()) return c } diff --git a/models/notification.go b/models/notification.go index 1e18073618..3c252d123d 100644 --- a/models/notification.go +++ b/models/notification.go @@ -5,6 +5,7 @@ package models import ( + "context" "fmt" "net/url" "strconv" @@ -391,14 +392,15 @@ func countUnread(e db.Engine, userID int64) int64 { // LoadAttributes load Repo Issue User and Comment if not loaded 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 { return } - if err = n.loadIssue(e); err != nil { + if err = n.loadIssue(ctx); err != nil { return } if err = n.loadUser(e); err != nil { @@ -420,13 +422,13 @@ func (n *Notification) loadRepo(e db.Engine) (err error) { 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 { - n.Issue, err = getIssueByID(e, n.IssueID) + n.Issue, err = getIssueByID(db.GetEngine(ctx), n.IssueID) if err != nil { return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) } - return n.Issue.loadAttributes(e) + return n.Issue.loadAttributes(ctx) } return nil } @@ -464,7 +466,7 @@ func (n *Notification) GetRepo() (*Repository, error) { // GetIssue returns the issue of the notification 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 diff --git a/models/project_issue.go b/models/project_issue.go index 4e3bc0039d..75e74295b5 100644 --- a/models/project_issue.go +++ b/models/project_issue.go @@ -5,11 +5,10 @@ package models import ( + "context" "fmt" "code.gitea.io/gitea/models/db" - - "xorm.io/xorm" ) // 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 func ChangeProjectAssign(issue *Issue, doer *User, newProjectID int64) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := addUpdateIssueProject(ctx, issue, doer, newProjectID); err != nil { return err } - if err := addUpdateIssueProject(sess, issue, doer, newProjectID); err != nil { - return err - } - - return sess.Commit() + return committer.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) 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 _, err := createComment(e, &CreateCommentOptions{ + if _, err := createComment(ctx, &CreateCommentOptions{ Type: CommentTypeProject, Doer: doer, Repo: issue.Repo, diff --git a/models/pull.go b/models/pull.go index 6bcc30e901..3bfebee118 100644 --- a/models/pull.go +++ b/models/pull.go @@ -394,11 +394,12 @@ func (pr *PullRequest) SetMerged() (bool, error) { pr.HasMerged = true - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { 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 { return false, err @@ -432,7 +433,7 @@ func (pr *PullRequest) SetMerged() (bool, error) { 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) } @@ -441,7 +442,7 @@ func (pr *PullRequest) SetMerged() (bool, error) { 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 true, nil @@ -456,13 +457,13 @@ func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []st issue.Index = idx - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err = sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } + defer committer.Close() - if err = newIssue(sess, issue.Poster, NewIssueOptions{ + if err = newIssue(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, @@ -478,11 +479,11 @@ func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []st pr.Index = issue.Index pr.BaseRepo = repo 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) } - if err = sess.Commit(); err != nil { + if err = committer.Commit(); err != nil { return fmt.Errorf("Commit: %v", err) } diff --git a/models/release.go b/models/release.go index f7bd67b8ca..69d2ceda5e 100644 --- a/models/release.go +++ b/models/release.go @@ -14,6 +14,7 @@ import ( "strings" "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/timeutil" "code.gitea.io/gitea/modules/util" @@ -36,14 +37,14 @@ type Release struct { Title string Sha1 string `xorm:"VARCHAR(40)"` NumCommits int64 - NumCommitsBehind int64 `xorm:"-"` - Note string `xorm:"TEXT"` - RenderedNote string `xorm:"-"` - IsDraft bool `xorm:"NOT NULL DEFAULT false"` - IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` - IsTag bool `xorm:"NOT NULL DEFAULT false"` - Attachments []*Attachment `xorm:"-"` - CreatedUnix timeutil.TimeStamp `xorm:"INDEX"` + NumCommitsBehind int64 `xorm:"-"` + Note string `xorm:"TEXT"` + RenderedNote string `xorm:"-"` + IsDraft bool `xorm:"NOT NULL DEFAULT false"` + IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` + IsTag bool `xorm:"NOT NULL DEFAULT false"` + Attachments []*repo_model.Attachment `xorm:"-"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX"` } func init() { @@ -126,7 +127,7 @@ func UpdateRelease(ctx context.Context, rel *Release) error { // AddReleaseAttachments adds a release attachments func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { // Check attachments - attachments, err := getAttachmentsByUUIDs(db.GetEngine(ctx), attachmentUUIDs) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, attachmentUUIDs) if err != nil { return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) } @@ -295,9 +296,9 @@ func getReleaseAttachments(e db.Engine, rels ...*Release) (err error) { // Sort 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 { - element.Attachments = []*Attachment{} + element.Attachments = []*repo_model.Attachment{} sortedRels.ID[index] = element.ID sortedRels.Rel[index] = element } @@ -307,7 +308,7 @@ func getReleaseAttachments(e db.Engine, rels ...*Release) (err error) { err = e. Asc("release_id", "name"). In("release_id", sortedRels.ID). - Find(&attachments, Attachment{}) + Find(&attachments, repo_model.Attachment{}) if err != nil { return err } diff --git a/models/repo.go b/models/repo.go index 3877502926..5921441afa 100644 --- a/models/repo.go +++ b/models/repo.go @@ -25,6 +25,7 @@ import ( admin_model "code.gitea.io/gitea/models/admin" "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/webhook" "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"). Where("`release`.repo_id = ?", repoID). 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 - var newAttachments []*Attachment + var newAttachments []*repo_model.Attachment if err := sess.Where(builder.Eq{ "repo_id": repo.ID, "issue_id": 0, @@ -1634,7 +1635,7 @@ func DeleteRepository(doer *User, uid, repoID int64) error { 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 } @@ -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 +} diff --git a/models/attachment.go b/models/repo/attachment.go similarity index 80% rename from models/attachment.go rename to models/repo/attachment.go index 34edc676cf..3fb331a202 100644 --- a/models/attachment.go +++ b/models/repo/attachment.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package repo import ( "context" @@ -11,12 +11,9 @@ import ( "path" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/timeutil" - - "xorm.io/xorm" ) // 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) } -// 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 func GetAttachmentByID(id int64) (*Attachment, error) { 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) { attach := &Attachment{} 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) } -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) - 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. 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. 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) - 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: @@ -229,7 +227,7 @@ func DeleteAttachmentsByComment(commentID int64, remove bool) (int, error) { // UpdateAttachment updates the given attachment in database func UpdateAttachment(atta *Attachment) error { - return updateAttachment(db.GetEngine(db.DefaultContext), atta) + return UpdateAttachmentCtx(db.DefaultContext, atta) } // UpdateAttachmentByUUID Updates attachment via uuid @@ -241,15 +239,16 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str return err } -func updateAttachment(e db.Engine, atta *Attachment) error { - var sess *xorm.Session +// UpdateAttachmentCtx updates the given attachment in database +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 == "" { - sess = e.ID(atta.ID) + sess = sess.ID(atta.ID) } else { // 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 } diff --git a/models/attachment_test.go b/models/repo/attachment_test.go similarity index 78% rename from models/attachment_test.go rename to models/repo/attachment_test.go index 4081811d19..53c28d5324 100644 --- a/models/attachment_test.go +++ b/models/repo/attachment_test.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package repo import ( "testing" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" "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(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) - }) - } -} diff --git a/models/repo/main_test.go b/models/repo/main_test.go new file mode 100644 index 0000000000..ac62df9d9c --- /dev/null +++ b/models/repo/main_test.go @@ -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", + ) +} diff --git a/models/repo_test.go b/models/repo_test.go index ec1bcc0487..5cc396eb76 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -13,6 +13,7 @@ import ( "testing" "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/unittest" "code.gitea.io/gitea/modules/markup" @@ -224,3 +225,30 @@ func TestRepoGetReviewerTeams(t *testing.T) { assert.NoError(t, err) 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) + }) + } +} diff --git a/models/review.go b/models/review.go index ab275ecb26..62172bac01 100644 --- a/models/review.go +++ b/models/review.go @@ -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 func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, commitID string, stale bool, attachmentUUIDs []string) (*Review, *Comment, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) 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, Doer: doer, Content: review.Content, @@ -464,7 +465,7 @@ func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content, comm } 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 @@ -631,11 +632,12 @@ func InsertReviews(reviews []*Review) error { // AddReviewRequest add a review request from one reviewer func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) if err != nil && !IsErrReviewNotExist(err) { @@ -667,7 +669,7 @@ func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { return nil, err } - comment, err := createComment(sess, &CreateCommentOptions{ + comment, err := createComment(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -680,16 +682,17 @@ func AddReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { return nil, err } - return comment, sess.Commit() + return comment, committer.Commit() } // RemoveReviewRequest remove a review request from one reviewer func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) review, err := getReviewByIssueIDAndUserID(sess, issue.ID, reviewer.ID) 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, Doer: doer, Repo: issue.Repo, @@ -733,16 +736,17 @@ func RemoveReviewRequest(issue *Issue, reviewer, doer *User) (*Comment, error) { return nil, err } - return comment, sess.Commit() + return comment, committer.Commit() } // AddTeamReviewRequest add a review request from one team func AddTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) 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, Doer: doer, 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 comment, sess.Commit() + return comment, committer.Commit() } // RemoveTeamReviewRequest remove a review request from one team func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment, error) { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return nil, err } + defer committer.Close() + sess := db.GetEngine(ctx) review, err := getTeamReviewerByIssueIDAndTeamID(sess, issue.ID, reviewer.ID) if err != nil && !IsErrReviewNotExist(err) { @@ -836,10 +841,10 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment } if doer == nil { - return nil, sess.Commit() + return nil, committer.Commit() } - comment, err := createComment(sess, &CreateCommentOptions{ + comment, err := createComment(ctx, &CreateCommentOptions{ Type: CommentTypeReviewRequest, Doer: doer, Repo: issue.Repo, @@ -851,7 +856,7 @@ func RemoveTeamReviewRequest(issue *Issue, reviewer *Team, doer *User) (*Comment 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 diff --git a/models/statistic.go b/models/statistic.go index 1849497cd9..cb300c1a87 100644 --- a/models/statistic.go +++ b/models/statistic.go @@ -7,6 +7,7 @@ package models import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/setting" @@ -102,7 +103,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.Label, _ = e.Count(new(Label)) stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) 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.ProjectBoard, _ = e.Count(new(ProjectBoard)) return diff --git a/modules/convert/release.go b/modules/convert/release.go index 70f0d6e764..955d3ff05f 100644 --- a/modules/convert/release.go +++ b/modules/convert/release.go @@ -6,6 +6,7 @@ package convert import ( "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" 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 -func ToReleaseAttachment(a *models.Attachment) *api.Attachment { +func ToReleaseAttachment(a *repo_model.Attachment) *api.Attachment { return &api.Attachment{ ID: a.ID, Name: a.Name, diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index 040f73abcd..e5f0c5678d 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "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/setting" ) @@ -110,8 +111,8 @@ func checkDBConsistency(logger log.Logger, autofix bool) error { // find attachments without existing issues or releases { Name: "Orphaned Attachments without existing issues or releases", - Counter: models.CountOrphanedAttachments, - Fixer: asFixer(models.DeleteOrphanedAttachments), + Counter: repo_model.CountOrphanedAttachments, + Fixer: asFixer(repo_model.DeleteOrphanedAttachments), }, // find null archived repositories { diff --git a/modules/doctor/storage.go b/modules/doctor/storage.go index cb06d66204..d2b7f5ee13 100644 --- a/modules/doctor/storage.go +++ b/modules/doctor/storage.go @@ -5,7 +5,7 @@ package doctor 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/storage" ) @@ -21,7 +21,7 @@ func checkAttachmentStorageFiles(logger log.Logger, autofix bool) error { if err != nil { return err } - exist, err := models.ExistAttachmentsByUUID(stat.Name()) + exist, err := repo_model.ExistAttachmentsByUUID(stat.Name()) if err != nil { return err } diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index d1533e2b5a..fe82915a94 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" @@ -54,7 +55,7 @@ func GetReleaseAttachment(ctx *context.APIContext) { releaseID := ctx.ParamsInt64(":id") attachID := ctx.ParamsInt64(":asset") - attach, err := models.GetAttachmentByID(attachID) + attach, err := repo_model.GetAttachmentByID(attachID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return @@ -241,7 +242,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") attachID := ctx.ParamsInt64(":asset") - attach, err := models.GetAttachmentByID(attachID) + attach, err := repo_model.GetAttachmentByID(attachID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return @@ -256,7 +257,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { 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.JSON(http.StatusCreated, convert.ToReleaseAttachment(attach)) @@ -299,7 +300,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") attachID := ctx.ParamsInt64(":asset") - attach, err := models.GetAttachmentByID(attachID) + attach, err := repo_model.GetAttachmentByID(attachID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) 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 - if err := models.DeleteAttachment(attach, true); err != nil { + if err := repo_model.DeleteAttachment(attach, true); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) return } diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index 3968d27652..303eee24d1 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -9,6 +9,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "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 func DeleteAttachment(ctx *context.Context) { file := ctx.FormString("file") - attach, err := models.GetAttachmentByUUID(file) + attach, err := repo_model.GetAttachmentByUUID(file) if err != nil { ctx.Error(http.StatusBadRequest, err.Error()) return @@ -71,7 +72,7 @@ func DeleteAttachment(ctx *context.Context) { ctx.Error(http.StatusForbidden) return } - err = models.DeleteAttachment(attach, true) + err = repo_model.DeleteAttachment(attach, true) if err != nil { ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteAttachment: %v", err)) return @@ -83,9 +84,9 @@ func DeleteAttachment(ctx *context.Context) { // GetAttachment serve attachements func GetAttachment(ctx *context.Context) { - attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid")) + attach, err := repo_model.GetAttachmentByUUID(ctx.Params(":uuid")) if err != nil { - if models.IsErrAttachmentNotExist(err) { + if repo_model.IsErrAttachmentNotExist(err) { ctx.Error(http.StatusNotFound) } else { ctx.ServerError("GetAttachmentByUUID", err) @@ -93,7 +94,7 @@ func GetAttachment(ctx *context.Context) { return } - repository, unitType, err := attach.LinkedRepository() + repository, unitType, err := models.LinkedRepository(attach) if err != nil { ctx.ServerError("LinkedRepository", err) return diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 129287b96a..6cc9419763 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -2516,7 +2517,7 @@ func GetCommentAttachments(ctx *context.Context) { } func updateAttachments(item interface{}, files []string) error { - var attachments []*models.Attachment + var attachments []*repo_model.Attachment switch content := item.(type) { case *models.Issue: attachments = content.Attachments @@ -2529,7 +2530,7 @@ func updateAttachments(item interface{}, files []string) error { if util.IsStringInSlice(attachments[i].UUID, files) { continue } - if err := models.DeleteAttachment(attachments[i], true); err != nil { + if err := repo_model.DeleteAttachment(attachments[i], true); err != nil { return err } } @@ -2549,16 +2550,16 @@ func updateAttachments(item interface{}, files []string) error { } switch content := item.(type) { case *models.Issue: - content.Attachments, err = models.GetAttachmentsByIssueID(content.ID) + content.Attachments, err = repo_model.GetAttachmentsByIssueID(content.ID) case *models.Comment: - content.Attachments, err = models.GetAttachmentsByCommentID(content.ID) + content.Attachments, err = repo_model.GetAttachmentsByCommentID(content.ID) default: return fmt.Errorf("Unknown Type: %T", content) } 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{}{ "ctx": ctx.Data, "Attachments": attachments, diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 2d6189824d..e8fdb99ff4 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -346,7 +347,7 @@ func RedirectDownload(ctx *context.Context) { curRepo := ctx.Repo.Repository releases, err := models.GetReleasesByRepoIDAndNames(db.DefaultContext, curRepo.ID, tagNames) if err != nil { - if models.IsErrAttachmentNotExist(err) { + if repo_model.IsErrAttachmentNotExist(err) { ctx.Error(http.StatusNotFound) return } @@ -355,7 +356,7 @@ func RedirectDownload(ctx *context.Context) { } if len(releases) == 1 { release := releases[0] - att, err := models.GetAttachmentByReleaseIDFileName(release.ID, fileName) + att, err := repo_model.GetAttachmentByReleaseIDFileName(release.ID, fileName) if err != nil { ctx.Error(http.StatusNotFound) return diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go index f747ccec3e..e3b65a239b 100644 --- a/services/attachment/attachment.go +++ b/services/attachment/attachment.go @@ -10,8 +10,8 @@ import ( "fmt" "io" - "code.gitea.io/gitea/models" "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/upload" "code.gitea.io/gitea/modules/util" @@ -20,7 +20,7 @@ import ( ) // 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 { 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 -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) n, _ := util.ReadAtMost(file, buf) buf = buf[:n] @@ -49,7 +49,7 @@ func UploadAttachment(file io.Reader, actorID, repoID, releaseID int64, fileName return nil, err } - return NewAttachment(&models.Attachment{ + return NewAttachment(&repo_model.Attachment{ RepoID: repoID, UploaderID: actorID, ReleaseID: releaseID, diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go index 5bb5db11ec..a992fbf151 100644 --- a/services/attachment/attachment_test.go +++ b/services/attachment/attachment_test.go @@ -10,6 +10,7 @@ import ( "testing" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -29,14 +30,14 @@ func TestUploadAttachment(t *testing.T) { assert.NoError(t, err) defer f.Close() - attach, err := NewAttachment(&models.Attachment{ + attach, err := NewAttachment(&repo_model.Attachment{ RepoID: 1, UploaderID: user.ID, Name: filepath.Base(fPath), }, f) assert.NoError(t, err) - attachment, err := models.GetAttachmentByUUID(attach.UUID) + attachment, err := repo_model.GetAttachmentByUUID(attach.UUID) assert.NoError(t, err) assert.EqualValues(t, user.ID, attachment.UploaderID) assert.Equal(t, int64(0), attachment.DownloadCount) diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 0f215e05d6..2394c63d76 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models" "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/log" base "code.gitea.io/gitea/modules/migration" @@ -295,7 +296,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { asset.Created = release.Created } } - var attach = models.Attachment{ + var attach = repo_model.Attachment{ UUID: gouuid.New().String(), Name: asset.Name, DownloadCount: int64(*asset.DownloadCount), diff --git a/services/release/release.go b/services/release/release.go index f6f456e8fa..30274f93ef 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" "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/log" "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) if len(delAttachmentUUIDs) > 0 { // Check attachments - attachments, err := models.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) if err != nil { 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 } - 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) } } @@ -228,7 +229,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea updateAttachmentsList = append(updateAttachmentsList, k) } // Check attachments - attachments, err := models.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) if err != nil { 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 { if !deletedUUIDsMap[uuid] { - if err = models.UpdateAttachmentByUUID(ctx, &models.Attachment{ + if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ UUID: uuid, Name: newName, }, "name"); err != nil { @@ -255,7 +256,7 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea } 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 // should not return error but only record the error on logs. // 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) } - if err := models.DeleteAttachmentsByRelease(rel.ID); err != nil { + if err := repo_model.DeleteAttachmentsByRelease(rel.ID); err != nil { return fmt.Errorf("DeleteAttachments: %v", err) } diff --git a/services/release/release_test.go b/services/release/release_test.go index d720bf996b..92eb128f71 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/services/attachment" @@ -103,7 +104,7 @@ func TestRelease_Create(t *testing.T) { IsTag: false, }, nil, "")) - attach, err := attachment.NewAttachment(&models.Attachment{ + attach, err := attachment.NewAttachment(&repo_model.Attachment{ RepoID: repo.ID, UploaderID: user.ID, Name: "test.txt", @@ -236,7 +237,7 @@ func TestRelease_Update(t *testing.T) { assert.Equal(t, tagName, release.TagName) // Add new attachments - attach, err := attachment.NewAttachment(&models.Attachment{ + attach, err := attachment.NewAttachment(&repo_model.Attachment{ RepoID: repo.ID, UploaderID: user.ID, Name: "test.txt",