From 49b003997d96da7742f97f3ee6e8537337c68272 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Apr 2025 09:54:43 -0700 Subject: [PATCH 1/2] Fix doctor deleting orphaned issues attachments --- models/issues/issue_update.go | 40 +++++++------------------------- services/doctor/dbconsistency.go | 3 ++- services/issue/issue.go | 29 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 746a59c6fdc5d..a05a84ddfce44 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -15,7 +15,6 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" - system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -817,36 +816,13 @@ func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths [] return attachmentPaths, err } -// DeleteOrphanedIssues delete issues without a repo -func DeleteOrphanedIssues(ctx context.Context) error { - var attachmentPaths []string - err := db.WithTx(ctx, func(ctx context.Context) error { - var ids []int64 - - if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). - Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). - Find(&ids); err != nil { - return err - } - - for i := range ids { - paths, err := DeleteIssuesByRepoID(ctx, ids[i]) - if err != nil { - return err - } - attachmentPaths = append(attachmentPaths, paths...) - } - - return nil - }) - if err != nil { - return err - } - - // Remove issue attachment files. - for i := range attachmentPaths { - system_model.RemoveAllWithNotice(ctx, "Delete issue attachment", attachmentPaths[i]) +func GetOrphanedIssueRepoIDs(ctx context.Context) ([]int64, error) { + var repoIDs []int64 + if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). + Join("LEFT", "repository", "issue.repo_id=repository.id"). + Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). + Find(&repoIDs); err != nil { + return nil, err } - return nil + return repoIDs, nil } diff --git a/services/doctor/dbconsistency.go b/services/doctor/dbconsistency.go index 62326ed07c865..d5a133d8b2527 100644 --- a/services/doctor/dbconsistency.go +++ b/services/doctor/dbconsistency.go @@ -15,6 +15,7 @@ import ( secret_model "code.gitea.io/gitea/models/secret" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + issue_service "code.gitea.io/gitea/services/issue" ) type consistencyCheck struct { @@ -93,7 +94,7 @@ func prepareDBConsistencyChecks() []consistencyCheck { // find issues without existing repository Name: "Orphaned Issues without existing repository", Counter: issues_model.CountOrphanedIssues, - Fixer: asFixer(issues_model.DeleteOrphanedIssues), + Fixer: asFixer(issue_service.DeleteOrphanedIssues), }, // find releases without existing repository genericOrphanCheck("Orphaned Releases without existing repository", diff --git a/services/issue/issue.go b/services/issue/issue.go index 455a1ec29781b..ecbbf1148182b 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -323,3 +323,32 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error { return committer.Commit() } + +// 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 := issues_model.DeleteIssuesByRepoID(ctx, repoIDs[i]) + if err != nil { + return err + } + attachmentPaths = append(attachmentPaths, paths...) + } + + return nil + }) + if err != nil { + return err + } + + // Remove issue attachment files. + for i := range attachmentPaths { + system_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachmentPaths[i]) + } + return nil +} From d4f5ee36ec286380a8265be580af3cc8c4769dec Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 9 Apr 2025 11:15:28 -0700 Subject: [PATCH 2/2] improve --- models/issues/issue_update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 1b179389e61d3..ec323f381bc04 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -819,7 +819,7 @@ func GetOrphanedIssueRepoIDs(ctx context.Context) ([]int64, error) { var repoIDs []int64 if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). + Where(builder.IsNull{"repository.id"}). Find(&repoIDs); err != nil { return nil, err }