Skip to content

Commit fd3cf7e

Browse files
committed
remove stale watches
1 parent ffc60ff commit fd3cf7e

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ var migrations = []Migration{
186186
NewMigration("add u2f", addU2FReg),
187187
// v66 -> v67
188188
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
189+
// v67 -> v68
190+
NewMigration("remove stale watches", removeStaleWatches),
189191
}
190192

191193
// Migrate database to current version

models/migrations/v67.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2018 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+
"code.gitea.io/gitea/modules/setting"
9+
10+
"github.com/go-xorm/xorm"
11+
)
12+
13+
func removeStaleWatches(x *xorm.Engine) error {
14+
type Watch struct {
15+
ID int64
16+
UserID int64
17+
RepoID int64
18+
}
19+
20+
type Repository struct {
21+
ID int64
22+
IsPrivate bool
23+
OwnerID int64
24+
}
25+
26+
type Access struct {
27+
UserID int64
28+
RepoID int64
29+
Mode int
30+
}
31+
32+
const (
33+
// AccessModeNone no access
34+
AccessModeNone int = iota // 0
35+
// AccessModeRead read access
36+
AccessModeRead // 1
37+
)
38+
39+
accessLevel := func(userID int64, repo *Repository) (int, error) {
40+
mode := AccessModeNone
41+
if !repo.IsPrivate {
42+
mode = AccessModeRead
43+
}
44+
45+
if userID == 0 {
46+
return mode, nil
47+
}
48+
49+
if userID == repo.OwnerID {
50+
return 4, nil
51+
}
52+
53+
a := &Access{UserID: userID, RepoID: repo.ID}
54+
if has, err := x.Get(a); !has || err != nil {
55+
return mode, err
56+
}
57+
return a.Mode, nil
58+
}
59+
60+
repoCache := make(map[int64]*Repository)
61+
return x.BufferSize(setting.IterateBufferSize).Iterate(new(Watch),
62+
func(idx int, bean interface{}) error {
63+
watch := bean.(*Watch)
64+
65+
repo := repoCache[watch.RepoID]
66+
if repo == nil {
67+
repo = &Repository{
68+
ID: watch.RepoID,
69+
}
70+
if _, err := x.Get(repo); err != nil {
71+
return err
72+
}
73+
}
74+
75+
// Remove watches from now unaccessible
76+
mode, err := accessLevel(watch.UserID, repo)
77+
if err != nil {
78+
return err
79+
}
80+
has := AccessModeRead <= mode
81+
if has {
82+
return nil
83+
}
84+
85+
sess := x.NewSession()
86+
if _, err = sess.Delete(&Watch{0, watch.UserID, repo.ID}); err != nil {
87+
return err
88+
}
89+
_, err = sess.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repo.ID)
90+
91+
return sess.Commit()
92+
})
93+
}

0 commit comments

Comments
 (0)