Skip to content

Commit b3d8e2d

Browse files
authored
Update topics repo count when deleting repository (#10051)
* Update topics repo count when deleting repository * Add migration to fix incorrect data * Optimize to use single update to recalculate values
1 parent 159732d commit b3d8e2d

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

models/migrations/migrations.go

+2
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ var migrations = []Migration{
306306
NewMigration("Add columns to user and repository", addUserRepoMissingColumns),
307307
// v125 -> v126
308308
NewMigration("Add some columns on review for migration", addReviewMigrateInfo),
309+
// v126 -> v127
310+
NewMigration("Fix topic repository count", fixTopicRepositoryCount),
309311
}
310312

311313
// Migrate database to current version

models/migrations/v126.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2020 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+
"xorm.io/builder"
9+
"xorm.io/xorm"
10+
)
11+
12+
func fixTopicRepositoryCount(x *xorm.Engine) error {
13+
_, err := x.Exec(builder.Delete(builder.NotIn("`repo_id`", builder.Select("`id`").From("`repository`"))).From("`repo_topic`"))
14+
if err != nil {
15+
return err
16+
}
17+
18+
_, err = x.Exec(builder.Update(
19+
builder.Eq{
20+
"`repo_count`": builder.Select("count(*)").From("`repo_topic`").Where(builder.Eq{
21+
"`repo_topic`.`topic_id`": builder.Expr("`topic`.`id`"),
22+
}),
23+
}).From("`topic`").Where(builder.Eq{"'1'": "1"}))
24+
return err
25+
}

models/repo.go

+6
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,12 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
15711571
return err
15721572
}
15731573

1574+
if len(repo.Topics) > 0 {
1575+
if err = removeTopicsFromRepo(sess, repo.ID); err != nil {
1576+
return err
1577+
}
1578+
}
1579+
15741580
// FIXME: Remove repository files should be executed after transaction succeed.
15751581
repoPath := repo.RepoPath()
15761582
removeAllWithNotice(sess, "Delete repository files", repoPath)

models/topic.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func addTopicByNameToRepo(e Engine, repoID int64, topicName string) (*Topic, err
129129
}
130130

131131
// removeTopicFromRepo remove a topic from a repo and decrements the topic repo count
132-
func removeTopicFromRepo(repoID int64, topic *Topic, e Engine) error {
132+
func removeTopicFromRepo(e Engine, repoID int64, topic *Topic) error {
133133
topic.RepoCount--
134134
if _, err := e.ID(topic.ID).Cols("repo_count").Update(topic); err != nil {
135135
return err
@@ -145,6 +145,24 @@ func removeTopicFromRepo(repoID int64, topic *Topic, e Engine) error {
145145
return nil
146146
}
147147

148+
// removeTopicsFromRepo remove all topics from the repo and decrements respective topics repo count
149+
func removeTopicsFromRepo(e Engine, repoID int64) error {
150+
_, err := e.Where(
151+
builder.In("id",
152+
builder.Select("topic_id").From("repo_topic").Where(builder.Eq{"repo_id": repoID}),
153+
),
154+
).Cols("repo_count").SetExpr("repo_count", "repo_count-1").Update(&Topic{})
155+
if err != nil {
156+
return err
157+
}
158+
159+
if _, err = e.Delete(&RepoTopic{RepoID: repoID}); err != nil {
160+
return err
161+
}
162+
163+
return nil
164+
}
165+
148166
// FindTopicOptions represents the options when fdin topics
149167
type FindTopicOptions struct {
150168
ListOptions
@@ -216,7 +234,7 @@ func DeleteTopic(repoID int64, topicName string) (*Topic, error) {
216234
return nil, nil
217235
}
218236

219-
err = removeTopicFromRepo(repoID, topic, x)
237+
err = removeTopicFromRepo(x, repoID, topic)
220238

221239
return topic, err
222240
}
@@ -277,7 +295,7 @@ func SaveTopics(repoID int64, topicNames ...string) error {
277295
}
278296

279297
for _, topic := range removeTopics {
280-
err := removeTopicFromRepo(repoID, topic, sess)
298+
err := removeTopicFromRepo(sess, repoID, topic)
281299
if err != nil {
282300
return err
283301
}

0 commit comments

Comments
 (0)