aboutsummaryrefslogtreecommitdiffstats
path: root/models/issue.go
diff options
context:
space:
mode:
authorOtto Richter (fnetX) <git@fralix.ovh>2022-03-01 01:20:15 +0100
committerGitHub <noreply@github.com>2022-03-01 01:20:15 +0100
commit062fd4c217cc7302f56acf043d6214a9db46ee2f (patch)
tree4aaa51baaee1d7ddfab00a88a2d22f5911af1312 /models/issue.go
parent6859b6919800cbf2958dbfbe76fca42f4dcbb194 (diff)
downloadgitea-062fd4c217cc7302f56acf043d6214a9db46ee2f.tar.gz
gitea-062fd4c217cc7302f56acf043d6214a9db46ee2f.zip
[API] Allow removing issues (#18879)
Add new feature to delete issues and pulls via API Co-authored-by: fnetx <git@fralix.ovh> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Gusted <williamzijl7@hotmail.com> Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'models/issue.go')
-rw-r--r--models/issue.go114
1 files changed, 114 insertions, 0 deletions
diff --git a/models/issue.go b/models/issue.go
index 91d4df32d1..625374faaf 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -13,6 +13,7 @@ import (
"strconv"
"strings"
+ admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
@@ -24,6 +25,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
@@ -1990,6 +1992,118 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us
return committer.Commit()
}
+// DeleteIssue deletes the issue
+func DeleteIssue(issue *Issue) error {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ if err := deleteIssue(ctx, issue); err != nil {
+ return err
+ }
+
+ return committer.Commit()
+}
+
+func deleteInIssue(e db.Engine, issueID int64, beans ...interface{}) error {
+ for _, bean := range beans {
+ if _, err := e.In("issue_id", issueID).Delete(bean); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func deleteIssue(ctx context.Context, issue *Issue) error {
+ e := db.GetEngine(ctx)
+ if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
+ return err
+ }
+
+ if issue.IsPull {
+ if _, err := e.ID(issue.RepoID).Decr("num_pulls").Update(new(repo_model.Repository)); err != nil {
+ return err
+ }
+ if issue.IsClosed {
+ if _, err := e.ID(issue.RepoID).Decr("num_closed_pulls").Update(new(repo_model.Repository)); err != nil {
+ return err
+ }
+ }
+ } else {
+ if _, err := e.ID(issue.RepoID).Decr("num_issues").Update(new(repo_model.Repository)); err != nil {
+ return err
+ }
+ if issue.IsClosed {
+ if _, err := e.ID(issue.RepoID).Decr("num_closed_issues").Update(new(repo_model.Repository)); err != nil {
+ return err
+ }
+ }
+ }
+
+ // delete actions assigned to this issue
+ var comments []int64
+ if err := e.Table(new(Comment)).In("issue_id", issue.ID).Cols("id").Find(&comments); err != nil {
+ return err
+ }
+ for i := range comments {
+ if _, err := e.Where("comment_id = ?", comments[i]).Delete(&Action{}); err != nil {
+ return err
+ }
+ }
+ if _, err := e.Table("action").Where("repo_id = ?", issue.RepoID).In("op_type", ActionCreateIssue, ActionCreatePullRequest).
+ Where("content LIKE ?", strconv.FormatInt(issue.ID, 10)+"|%").Delete(&Action{}); err != nil {
+ return err
+ }
+
+ // find attachments related to this issue and remove them
+ var attachments []*repo_model.Attachment
+ if err := e.In("issue_id", issue.ID).Find(&attachments); err != nil {
+ return err
+ }
+
+ for i := range attachments {
+ admin_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachments[i].RelativePath())
+ }
+
+ // delete all database data still assigned to this issue
+ if err := deleteInIssue(e, issue.ID,
+ &issues.ContentHistory{},
+ &Comment{},
+ &IssueLabel{},
+ &IssueDependency{},
+ &IssueAssignees{},
+ &IssueUser{},
+ &Reaction{},
+ &IssueWatch{},
+ &Stopwatch{},
+ &TrackedTime{},
+ &ProjectIssue{},
+ &repo_model.Attachment{},
+ &PullRequest{},
+ ); err != nil {
+ return err
+ }
+
+ // References to this issue in other issues
+ if _, err := e.In("ref_issue_id", issue.ID).Delete(&Comment{}); err != nil {
+ return err
+ }
+
+ // Delete dependencies for issues in other repositories
+ if _, err := e.In("dependency_id", issue.ID).Delete(&IssueDependency{}); err != nil {
+ return err
+ }
+
+ // delete from dependent issues
+ if _, err := e.In("dependent_issue_id", issue.ID).Delete(&Comment{}); err != nil {
+ return err
+ }
+
+ return nil
+}
+
// DependencyInfo represents high level information about an issue which is a dependency of another issue.
type DependencyInfo struct {
Issue `xorm:"extends"`