Skip to content

Commit a3a6513

Browse files
authored
Delete Labels & IssueLabels on Repo Delete too (#15039)
* Doctor: find IssueLabels without existing label * on Repo Delete: delete labels & issue_labels too * performance nits * Add Migration: Delete orphaned IssueLabels * Migration v174: use Sync2 * USE sess !!! * better func name * code format & comment * RAW SQL * Update models/migrations/v176.go * next try?
1 parent dace0ce commit a3a6513

File tree

7 files changed

+116
-9
lines changed

7 files changed

+116
-9
lines changed

models/consistency.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,23 @@ func DeleteOrphanedLabels() error {
224224
return nil
225225
}
226226

227+
// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore
228+
func CountOrphanedIssueLabels() (int64, error) {
229+
return x.Table("issue_label").
230+
Join("LEFT", "label", "issue_label.label_id = label.id").
231+
Where(builder.IsNull{"label.id"}).Count()
232+
}
233+
234+
// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore
235+
func DeleteOrphanedIssueLabels() error {
236+
_, err := x.In("id", builder.Select("issue_label.id").From("issue_label").
237+
Join("LEFT", "label", "issue_label.label_id = label.id").
238+
Where(builder.IsNull{"label.id"})).
239+
Delete(IssueLabel{})
240+
241+
return err
242+
}
243+
227244
// CountOrphanedIssues count issues without a repo
228245
func CountOrphanedIssues() (int64, error) {
229246
return x.Table("issue").

models/issue_label.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,3 +780,15 @@ func DeleteIssueLabel(issue *Issue, label *Label, doer *User) (err error) {
780780

781781
return sess.Commit()
782782
}
783+
784+
func deleteLabelsByRepoID(sess Engine, repoID int64) error {
785+
deleteCond := builder.Select("id").From("label").Where(builder.Eq{"label.repo_id": repoID})
786+
787+
if _, err := sess.In("label_id", deleteCond).
788+
Delete(&IssueLabel{}); err != nil {
789+
return err
790+
}
791+
792+
_, err := sess.Delete(&Label{RepoID: repoID})
793+
return err
794+
}

models/migrations/migrations.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,13 @@ var migrations = []Migration{
295295
// v173 -> v174
296296
NewMigration("Add time_id column to Comment", addTimeIDCommentColumn),
297297
// v174 -> v175
298-
NewMigration("create repo transfer table", addRepoTransfer),
298+
NewMigration("Create repo transfer table", addRepoTransfer),
299299
// v175 -> v176
300300
NewMigration("Fix Postgres ID Sequences broken by recreate-table", fixPostgresIDSequences),
301301
// v176 -> v177
302302
NewMigration("Remove invalid labels from comments", removeInvalidLabels),
303+
// v177 -> v178
304+
NewMigration("Delete orphaned IssueLabels", deleteOrphanedIssueLabels),
303305
}
304306

305307
// GetCurrentDBVersion returns the current db version

models/migrations/v174.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package migrations
66

77
import (
8+
"fmt"
9+
810
"xorm.io/xorm"
911
)
1012

@@ -19,5 +21,15 @@ func addRepoTransfer(x *xorm.Engine) error {
1921
UpdatedUnix int64 `xorm:"INDEX NOT NULL updated"`
2022
}
2123

22-
return x.Sync(new(RepoTransfer))
24+
sess := x.NewSession()
25+
defer sess.Close()
26+
if err := sess.Begin(); err != nil {
27+
return err
28+
}
29+
30+
if err := sess.Sync2(new(RepoTransfer)); err != nil {
31+
return fmt.Errorf("Sync2: %v", err)
32+
}
33+
34+
return sess.Commit()
2335
}

models/migrations/v177.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"fmt"
9+
10+
"xorm.io/xorm"
11+
)
12+
13+
func deleteOrphanedIssueLabels(x *xorm.Engine) error {
14+
type IssueLabel struct {
15+
ID int64 `xorm:"pk autoincr"`
16+
IssueID int64 `xorm:"UNIQUE(s)"`
17+
LabelID int64 `xorm:"UNIQUE(s)"`
18+
}
19+
20+
sess := x.NewSession()
21+
defer sess.Close()
22+
if err := sess.Begin(); err != nil {
23+
return err
24+
}
25+
26+
if err := sess.Sync2(new(IssueLabel)); err != nil {
27+
return fmt.Errorf("Sync2: %v", err)
28+
}
29+
30+
if _, err := sess.Exec(`DELETE FROM issue_label WHERE issue_label.id IN (
31+
SELECT ill.id FROM (
32+
SELECT il.id
33+
FROM issue_label AS il
34+
LEFT JOIN label ON il.label_id = label.id
35+
WHERE
36+
label.id IS NULL
37+
) AS ill)`); err != nil {
38+
return err
39+
}
40+
41+
return sess.Commit()
42+
}

models/repo.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,11 +1447,11 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
14471447
releaseAttachments = append(releaseAttachments, attachments[i].RelativePath())
14481448
}
14491449

1450-
if _, err = sess.Exec("UPDATE `user` SET num_stars=num_stars-1 WHERE id IN (SELECT `uid` FROM `star` WHERE repo_id = ?)", repo.ID); err != nil {
1450+
if _, err := sess.Exec("UPDATE `user` SET num_stars=num_stars-1 WHERE id IN (SELECT `uid` FROM `star` WHERE repo_id = ?)", repo.ID); err != nil {
14511451
return err
14521452
}
14531453

1454-
if err = deleteBeans(sess,
1454+
if err := deleteBeans(sess,
14551455
&Access{RepoID: repo.ID},
14561456
&Action{RepoID: repo.ID},
14571457
&Watch{RepoID: repoID},
@@ -1475,28 +1475,33 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
14751475
return fmt.Errorf("deleteBeans: %v", err)
14761476
}
14771477

1478+
// Delete Labels and related objects
1479+
if err := deleteLabelsByRepoID(sess, repoID); err != nil {
1480+
return err
1481+
}
1482+
14781483
// Delete Issues and related objects
14791484
var attachmentPaths []string
14801485
if attachmentPaths, err = deleteIssuesByRepoID(sess, repoID); err != nil {
14811486
return err
14821487
}
14831488

1484-
if _, err = sess.Where("repo_id = ?", repoID).Delete(new(RepoUnit)); err != nil {
1489+
if _, err := sess.Where("repo_id = ?", repoID).Delete(new(RepoUnit)); err != nil {
14851490
return err
14861491
}
14871492

14881493
if repo.IsFork {
1489-
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkID); err != nil {
1494+
if _, err := sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkID); err != nil {
14901495
return fmt.Errorf("decrease fork count: %v", err)
14911496
}
14921497
}
14931498

1494-
if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", uid); err != nil {
1499+
if _, err := sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", uid); err != nil {
14951500
return err
14961501
}
14971502

14981503
if len(repo.Topics) > 0 {
1499-
if err = removeTopicsFromRepo(sess, repo.ID); err != nil {
1504+
if err := removeTopicsFromRepo(sess, repo.ID); err != nil {
15001505
return err
15011506
}
15021507
}

modules/doctor/dbconsistency.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ func checkDBConsistency(logger log.Logger, autofix bool) error {
2626
logger.Critical("Error: %v whilst counting orphaned labels")
2727
return err
2828
}
29-
3029
if count > 0 {
3130
if autofix {
3231
if err = models.DeleteOrphanedLabels(); err != nil {
@@ -39,6 +38,24 @@ func checkDBConsistency(logger log.Logger, autofix bool) error {
3938
}
4039
}
4140

41+
// find IssueLabels without existing label
42+
count, err = models.CountOrphanedIssueLabels()
43+
if err != nil {
44+
logger.Critical("Error: %v whilst counting orphaned issue_labels")
45+
return err
46+
}
47+
if count > 0 {
48+
if autofix {
49+
if err = models.DeleteOrphanedIssueLabels(); err != nil {
50+
logger.Critical("Error: %v whilst deleting orphaned issue_labels")
51+
return err
52+
}
53+
logger.Info("%d issue_labels without existing label deleted", count)
54+
} else {
55+
logger.Warn("%d issue_labels without existing label", count)
56+
}
57+
}
58+
4259
// find issues without existing repository
4360
count, err = models.CountOrphanedIssues()
4461
if err != nil {

0 commit comments

Comments
 (0)