* Move attachment into models/repo/ * Fix test * Fix bugtags/v1.16.0-rc1
@@ -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 | |||
}) |
@@ -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 |
@@ -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 | |||
} | |||
@@ -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 | |||
} | |||
@@ -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 { |
@@ -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) | |||
} | |||
@@ -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() |
@@ -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 |
@@ -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 { |
@@ -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 { |
@@ -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() | |||
} |
@@ -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(sess, doer, issue, oldMilestoneID); err != nil { | |||
if err = changeMilestoneAssign(ctx, 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 |
@@ -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, |
@@ -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) { |
@@ -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 { |
@@ -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) | |||
defer committer.Close() | |||
err = db.Insert(ctx, c) | |||
assert.NoError(t, err) | |||
assert.NoError(t, c.addCrossReferences(sess, d, false)) | |||
assert.NoError(t, sess.Commit()) | |||
assert.NoError(t, c.addCrossReferences(ctx, d, false)) | |||
assert.NoError(t, committer.Commit()) | |||
return c | |||
} |
@@ -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 |
@@ -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(sess, issue, doer, newProjectID); err != nil { | |||
if err := addUpdateIssueProject(ctx, 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, |
@@ -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) | |||
} | |||
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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 | |||
} | |||
@@ -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) | |||
}) | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
// Copyright 2020 The Gitea Authors. All rights reserved. | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repo | |||
import ( | |||
"path/filepath" | |||
"testing" | |||
"code.gitea.io/gitea/models/unittest" | |||
) | |||
func TestMain(m *testing.M) { | |||
unittest.MainTest(m, filepath.Join("..", ".."), | |||
"attachment.yml", | |||
) | |||
} |
@@ -13,6 +13,7 @@ import ( | |||
"testing" | |||
"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) | |||
}) | |||
} | |||
} |
@@ -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 |
@@ -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 |
@@ -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, |
@@ -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 | |||
{ |
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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 |
@@ -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, |
@@ -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 |
@@ -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, |
@@ -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) |
@@ -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), |
@@ -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) | |||
} | |||
@@ -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", |