aboutsummaryrefslogtreecommitdiffstats
path: root/services/issue
diff options
context:
space:
mode:
Diffstat (limited to 'services/issue')
-rw-r--r--services/issue/assignee.go2
-rw-r--r--services/issue/issue.go92
-rw-r--r--services/issue/issue_test.go6
3 files changed, 83 insertions, 17 deletions
diff --git a/services/issue/assignee.go b/services/issue/assignee.go
index c7e2495568..a9494b7ab4 100644
--- a/services/issue/assignee.go
+++ b/services/issue/assignee.go
@@ -54,6 +54,8 @@ func ToggleAssigneeWithNotify(ctx context.Context, issue *issues_model.Issue, do
if err != nil {
return false, nil, err
}
+ issue.AssigneeID = assigneeID
+ issue.Assignee = assignee
notify_service.IssueChangeAssignee(ctx, doer, issue, assignee, removed, comment)
diff --git a/services/issue/issue.go b/services/issue/issue.go
index 455a1ec297..2cb5f2801d 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -190,9 +190,13 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi
}
// delete entries in database
- if err := deleteIssue(ctx, issue); err != nil {
+ attachmentPaths, err := deleteIssue(ctx, issue)
+ if err != nil {
return err
}
+ for _, attachmentPath := range attachmentPaths {
+ system_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachmentPath)
+ }
// delete pull request related git data
if issue.IsPull && gitRepo != nil {
@@ -256,45 +260,45 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i
}
// deleteIssue deletes the issue
-func deleteIssue(ctx context.Context, issue *issues_model.Issue) error {
+func deleteIssue(ctx context.Context, issue *issues_model.Issue) ([]string, error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
- return err
+ return nil, err
}
defer committer.Close()
- e := db.GetEngine(ctx)
- if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
- return err
+ if _, err := db.GetEngine(ctx).ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
+ return nil, err
}
// update the total issue numbers
if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil {
- return err
+ return nil, err
}
// if the issue is closed, update the closed issue numbers
if issue.IsClosed {
if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil {
- return err
+ return nil, err
}
}
if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
- return fmt.Errorf("error updating counters for milestone id %d: %w",
+ return nil, fmt.Errorf("error updating counters for milestone id %d: %w",
issue.MilestoneID, err)
}
if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil {
- return err
+ return nil, err
}
// find attachments related to this issue and remove them
- if err := issue.LoadAttributes(ctx); err != nil {
- return err
+ if err := issue.LoadAttachments(ctx); err != nil {
+ return nil, err
}
+ var attachmentPaths []string
for i := range issue.Attachments {
- system_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", issue.Attachments[i].RelativePath())
+ attachmentPaths = append(attachmentPaths, issue.Attachments[i].RelativePath())
}
// delete all database data still assigned to this issue
@@ -318,8 +322,68 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error {
&issues_model.Comment{DependentIssueID: issue.ID},
&issues_model.IssuePin{IssueID: issue.ID},
); err != nil {
+ return nil, err
+ }
+
+ if err := committer.Commit(); err != nil {
+ return nil, err
+ }
+ return attachmentPaths, nil
+}
+
+// DeleteOrphanedIssues delete issues without a repo
+func DeleteOrphanedIssues(ctx context.Context) error {
+ var attachmentPaths []string
+ err := db.WithTx(ctx, func(ctx context.Context) error {
+ repoIDs, err := issues_model.GetOrphanedIssueRepoIDs(ctx)
+ if err != nil {
+ return err
+ }
+ for i := range repoIDs {
+ paths, err := DeleteIssuesByRepoID(ctx, repoIDs[i])
+ if err != nil {
+ return err
+ }
+ attachmentPaths = append(attachmentPaths, paths...)
+ }
+ return nil
+ })
+ if err != nil {
return err
}
- return committer.Commit()
+ // Remove issue attachment files.
+ for i := range attachmentPaths {
+ system_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachmentPaths[i])
+ }
+ return nil
+}
+
+// DeleteIssuesByRepoID deletes issues by repositories id
+func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) {
+ for {
+ issues := make([]*issues_model.Issue, 0, db.DefaultMaxInSize)
+ if err := db.GetEngine(ctx).
+ Where("repo_id = ?", repoID).
+ OrderBy("id").
+ Limit(db.DefaultMaxInSize).
+ Find(&issues); err != nil {
+ return nil, err
+ }
+
+ if len(issues) == 0 {
+ break
+ }
+
+ for _, issue := range issues {
+ issueAttachPaths, err := deleteIssue(ctx, issue)
+ if err != nil {
+ return nil, fmt.Errorf("deleteIssue [issue_id: %d]: %w", issue.ID, err)
+ }
+
+ attachmentPaths = append(attachmentPaths, issueAttachPaths...)
+ }
+ }
+
+ return attachmentPaths, err
}
diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go
index b3df8191e1..bad0d65d1e 100644
--- a/services/issue/issue_test.go
+++ b/services/issue/issue_test.go
@@ -44,7 +44,7 @@ func TestIssue_DeleteIssue(t *testing.T) {
ID: issueIDs[2],
}
- err = deleteIssue(db.DefaultContext, issue)
+ _, err = deleteIssue(db.DefaultContext, issue)
assert.NoError(t, err)
issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1)
assert.NoError(t, err)
@@ -55,7 +55,7 @@ func TestIssue_DeleteIssue(t *testing.T) {
assert.NoError(t, err)
issue, err = issues_model.GetIssueByID(db.DefaultContext, 4)
assert.NoError(t, err)
- err = deleteIssue(db.DefaultContext, issue)
+ _, err = deleteIssue(db.DefaultContext, issue)
assert.NoError(t, err)
assert.Len(t, attachments, 2)
for i := range attachments {
@@ -78,7 +78,7 @@ func TestIssue_DeleteIssue(t *testing.T) {
assert.NoError(t, err)
assert.False(t, left)
- err = deleteIssue(db.DefaultContext, issue2)
+ _, err = deleteIssue(db.DefaultContext, issue2)
assert.NoError(t, err)
left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
assert.NoError(t, err)