@@ -19,6 +19,7 @@ import (
1919 "code.gitea.io/gitea/modules/git"
2020 "code.gitea.io/gitea/modules/log"
2121 "code.gitea.io/gitea/modules/storage"
22+ "code.gitea.io/gitea/modules/util"
2223 notify_service "code.gitea.io/gitea/services/notify"
2324)
2425
@@ -190,9 +191,11 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi
190191 }
191192
192193 // delete entries in database
193- if err := deleteIssue (ctx , issue , true ); err != nil {
194+ cleanup , err := deleteIssue (ctx , issue , true )
195+ if err != nil {
194196 return err
195197 }
198+ cleanup ()
196199
197200 // delete pull request related git data
198201 if issue .IsPull && gitRepo != nil {
@@ -256,8 +259,9 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i
256259}
257260
258261// deleteIssue deletes the issue
259- func deleteIssue (ctx context.Context , issue * issues_model.Issue , deleteAttachments bool ) error {
260- return db .WithTx (ctx , func (ctx context.Context ) error {
262+ func deleteIssue (ctx context.Context , issue * issues_model.Issue , deleteAttachments bool ) (util.CleanUpFunc , error ) {
263+ cleanup := util .NewCleanUpFunc ()
264+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
261265 if _ , err := db .GetEngine (ctx ).ID (issue .ID ).NoAutoCondition ().Delete (issue ); err != nil {
262266 return err
263267 }
@@ -302,7 +306,6 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue, deleteAttachmen
302306 & issues_model.Stopwatch {IssueID : issue .ID },
303307 & issues_model.TrackedTime {IssueID : issue .ID },
304308 & project_model.ProjectIssue {IssueID : issue .ID },
305- & repo_model.Attachment {IssueID : issue .ID },
306309 & issues_model.PullRequest {IssueID : issue .ID },
307310 & issues_model.Comment {RefIssueID : issue .ID },
308311 & issues_model.IssueDependency {DependencyID : issue .ID },
@@ -313,19 +316,32 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue, deleteAttachmen
313316 }
314317
315318 for _ , comment := range issue .Comments {
316- if _ , err := deleteComment (ctx , comment , deleteAttachments ); err != nil {
319+ _ , cleanupDeleteComment , err := deleteComment (ctx , comment , deleteAttachments )
320+ if err != nil {
317321 return fmt .Errorf ("deleteComment [comment_id: %d]: %w" , comment .ID , err )
318322 }
323+ cleanup = cleanup .Append (cleanupDeleteComment )
319324 }
320325
321326 if deleteAttachments {
322- // Remove issue attachment files.
323- for i := range issue .Attachments {
324- system_model .RemoveStorageWithNotice (ctx , storage .Attachments , "Delete issue attachment" , issue .Attachments [i ].RelativePath ())
327+ // delete issue attachments
328+ _ , err := db .GetEngine (ctx ).Where ("issue_id = ? AND comment_id = 0" , issue .ID ).NoAutoCondition ().Delete (& issues_model.Issue {})
329+ if err != nil {
330+ return err
325331 }
332+ // the storage cleanup function to remove attachments could be called after all transactions are committed
333+ cleanup = cleanup .Append (func () {
334+ // Remove issue attachment files.
335+ for i := range issue .Attachments {
336+ system_model .RemoveStorageWithNotice (ctx , storage .Attachments , "Delete issue attachment" , issue .Attachments [i ].RelativePath ())
337+ }
338+ })
326339 }
327340 return nil
328- })
341+ }); err != nil {
342+ return nil , err
343+ }
344+ return cleanup , nil
329345}
330346
331347// DeleteOrphanedIssues delete issues without a repo
@@ -361,9 +377,11 @@ func DeleteIssuesByRepoID(ctx context.Context, repoID int64, deleteAttachments b
361377 }
362378
363379 for _ , issue := range issues {
364- if err := deleteIssue (ctx , issue , deleteAttachments ); err != nil {
380+ cleanup , err := deleteIssue (ctx , issue , deleteAttachments )
381+ if err != nil {
365382 return fmt .Errorf ("deleteIssue [issue_id: %d]: %w" , issue .ID , err )
366383 }
384+ cleanup ()
367385 }
368386 }
369387
0 commit comments