@ -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 . LoadAtt ribute s( ctx ) ; err != nil {
return err
if err := issue . LoadAtt achment s( 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
}