Skip to content

Commit 696fbe6

Browse files
lunnywxiaoguang
andauthored
Refactor push mirror find and add check for updating push mirror (#32539)
Co-authored-by: wxiaoguang <[email protected]>
1 parent 8a20fba commit 696fbe6

File tree

8 files changed

+142
-108
lines changed

8 files changed

+142
-108
lines changed

models/db/collation.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ func CheckCollations(x *xorm.Engine) (*CheckCollationsResult, error) {
6868

6969
var candidateCollations []string
7070
if x.Dialect().URI().DBType == schemas.MYSQL {
71-
if _, err = x.SQL("SELECT @@collation_database").Get(&res.DatabaseCollation); err != nil {
71+
_, err = x.SQL("SELECT DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", setting.Database.Name).Get(&res.DatabaseCollation)
72+
if err != nil {
7273
return nil, err
7374
}
7475
res.IsCollationCaseSensitive = func(s string) bool {

models/repo/pushmirror.go

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ import (
99

1010
"code.gitea.io/gitea/models/db"
1111
"code.gitea.io/gitea/modules/log"
12+
"code.gitea.io/gitea/modules/optional"
1213
"code.gitea.io/gitea/modules/timeutil"
1314
"code.gitea.io/gitea/modules/util"
1415

1516
"xorm.io/builder"
1617
)
1718

18-
// ErrPushMirrorNotExist mirror does not exist error
19-
var ErrPushMirrorNotExist = util.NewNotExistErrorf("PushMirror does not exist")
20-
2119
// PushMirror represents mirror information of a repository.
2220
type PushMirror struct {
2321
ID int64 `xorm:"pk autoincr"`
@@ -96,26 +94,46 @@ func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error {
9694
return util.NewInvalidArgumentErrorf("repoID required and must be set")
9795
}
9896

97+
type findPushMirrorOptions struct {
98+
db.ListOptions
99+
RepoID int64
100+
SyncOnCommit optional.Option[bool]
101+
}
102+
103+
func (opts findPushMirrorOptions) ToConds() builder.Cond {
104+
cond := builder.NewCond()
105+
if opts.RepoID > 0 {
106+
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
107+
}
108+
if opts.SyncOnCommit.Has() {
109+
cond = cond.And(builder.Eq{"sync_on_commit": opts.SyncOnCommit.Value()})
110+
}
111+
return cond
112+
}
113+
99114
// GetPushMirrorsByRepoID returns push-mirror information of a repository.
100115
func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) {
101-
sess := db.GetEngine(ctx).Where("repo_id = ?", repoID)
102-
if listOptions.Page != 0 {
103-
sess = db.SetSessionPagination(sess, &listOptions)
104-
mirrors := make([]*PushMirror, 0, listOptions.PageSize)
105-
count, err := sess.FindAndCount(&mirrors)
106-
return mirrors, count, err
116+
return db.FindAndCount[PushMirror](ctx, findPushMirrorOptions{
117+
ListOptions: listOptions,
118+
RepoID: repoID,
119+
})
120+
}
121+
122+
func GetPushMirrorByIDAndRepoID(ctx context.Context, id, repoID int64) (*PushMirror, bool, error) {
123+
var pushMirror PushMirror
124+
has, err := db.GetEngine(ctx).Where("id = ?", id).And("repo_id = ?", repoID).Get(&pushMirror)
125+
if !has || err != nil {
126+
return nil, has, err
107127
}
108-
mirrors := make([]*PushMirror, 0, 10)
109-
count, err := sess.FindAndCount(&mirrors)
110-
return mirrors, count, err
128+
return &pushMirror, true, nil
111129
}
112130

113131
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
114132
func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) {
115-
mirrors := make([]*PushMirror, 0, 10)
116-
return mirrors, db.GetEngine(ctx).
117-
Where("repo_id = ? AND sync_on_commit = ?", repoID, true).
118-
Find(&mirrors)
133+
return db.Find[PushMirror](ctx, findPushMirrorOptions{
134+
RepoID: repoID,
135+
SyncOnCommit: optional.Some(true),
136+
})
119137
}
120138

121139
// PushMirrorsIterate iterates all push-mirror repositories.

routers/web/repo/setting/setting.go

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"errors"
99
"fmt"
1010
"net/http"
11-
"strconv"
1211
"strings"
1312
"time"
1413

@@ -290,8 +289,8 @@ func SettingsPost(ctx *context.Context) {
290289
return
291290
}
292291

293-
m, err := selectPushMirrorByForm(ctx, form, repo)
294-
if err != nil {
292+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
293+
if m == nil {
295294
ctx.NotFound("", nil)
296295
return
297296
}
@@ -317,15 +316,13 @@ func SettingsPost(ctx *context.Context) {
317316
return
318317
}
319318

320-
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
321-
if err != nil {
322-
ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err)
319+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
320+
if m == nil {
321+
ctx.NotFound("", nil)
323322
return
324323
}
325-
m := &repo_model.PushMirror{
326-
ID: id,
327-
Interval: interval,
328-
}
324+
325+
m.Interval = interval
329326
if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil {
330327
ctx.ServerError("UpdatePushMirrorInterval", err)
331328
return
@@ -334,7 +331,10 @@ func SettingsPost(ctx *context.Context) {
334331
// If we observed its implementation in the context of `push-mirror-sync` where it
335332
// is evident that pushing to the queue is necessary for updates.
336333
// So, there are updates within the given interval, it is necessary to update the queue accordingly.
337-
mirror_service.AddPushMirrorToQueue(m.ID)
334+
if !ctx.FormBool("push_mirror_defer_sync") {
335+
// push_mirror_defer_sync is mainly for testing purpose, we do not really want to sync the push mirror immediately
336+
mirror_service.AddPushMirrorToQueue(m.ID)
337+
}
338338
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
339339
ctx.Redirect(repo.Link() + "/settings")
340340

@@ -348,18 +348,18 @@ func SettingsPost(ctx *context.Context) {
348348
// as an error on the UI for this action
349349
ctx.Data["Err_RepoName"] = nil
350350

351-
m, err := selectPushMirrorByForm(ctx, form, repo)
352-
if err != nil {
351+
m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID)
352+
if m == nil {
353353
ctx.NotFound("", nil)
354354
return
355355
}
356356

357-
if err = mirror_service.RemovePushMirrorRemote(ctx, m); err != nil {
357+
if err := mirror_service.RemovePushMirrorRemote(ctx, m); err != nil {
358358
ctx.ServerError("RemovePushMirrorRemote", err)
359359
return
360360
}
361361

362-
if err = repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
362+
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
363363
ctx.ServerError("DeletePushMirrorByID", err)
364364
return
365365
}
@@ -995,24 +995,3 @@ func handleSettingRemoteAddrError(ctx *context.Context, err error, form *forms.R
995995
}
996996
ctx.RenderWithErr(ctx.Tr("repo.mirror_address_url_invalid"), tplSettingsOptions, form)
997997
}
998-
999-
func selectPushMirrorByForm(ctx *context.Context, form *forms.RepoSettingForm, repo *repo_model.Repository) (*repo_model.PushMirror, error) {
1000-
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
1001-
if err != nil {
1002-
return nil, err
1003-
}
1004-
1005-
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
1006-
if err != nil {
1007-
return nil, err
1008-
}
1009-
1010-
for _, m := range pushMirrors {
1011-
if m.ID == id {
1012-
m.Repo = repo
1013-
return m, nil
1014-
}
1015-
}
1016-
1017-
return nil, fmt.Errorf("PushMirror[%v] not associated to repository %v", id, repo)
1018-
}

services/forms/repo_form.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ type RepoSettingForm struct {
122122
MirrorPassword string
123123
LFS bool `form:"mirror_lfs"`
124124
LFSEndpoint string `form:"mirror_lfs_endpoint"`
125-
PushMirrorID string
125+
PushMirrorID int64
126126
PushMirrorAddress string
127127
PushMirrorUsername string
128128
PushMirrorPassword string

services/mirror/mirror.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99

1010
repo_model "code.gitea.io/gitea/models/repo"
11-
"code.gitea.io/gitea/modules/graceful"
1211
"code.gitea.io/gitea/modules/log"
1312
"code.gitea.io/gitea/modules/queue"
1413
"code.gitea.io/gitea/modules/setting"
@@ -119,14 +118,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
119118
return nil
120119
}
121120

122-
func queueHandler(items ...*SyncRequest) []*SyncRequest {
123-
for _, req := range items {
124-
doMirrorSync(graceful.GetManager().ShutdownContext(), req)
125-
}
126-
return nil
127-
}
128-
129121
// InitSyncMirrors initializes a go routine to sync the mirrors
130122
func InitSyncMirrors() {
131-
StartSyncMirrors(queueHandler)
123+
StartSyncMirrors()
132124
}

services/mirror/queue.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ type SyncRequest struct {
2828
ReferenceID int64 // RepoID for pull mirror, MirrorID for push mirror
2929
}
3030

31+
func queueHandler(items ...*SyncRequest) []*SyncRequest {
32+
for _, req := range items {
33+
doMirrorSync(graceful.GetManager().ShutdownContext(), req)
34+
}
35+
return nil
36+
}
37+
3138
// StartSyncMirrors starts a go routine to sync the mirrors
32-
func StartSyncMirrors(queueHandle func(data ...*SyncRequest) []*SyncRequest) {
39+
func StartSyncMirrors() {
3340
if !setting.Mirror.Enabled {
3441
return
3542
}
36-
mirrorQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "mirror", queueHandle)
43+
mirrorQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "mirror", queueHandler)
3744
if mirrorQueue == nil {
3845
log.Fatal("Unable to create mirror queue")
3946
}

tests/integration/db_collation_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ func TestDatabaseCollation(t *testing.T) {
7373

7474
t.Run("Convert tables to utf8mb4_bin", func(t *testing.T) {
7575
defer test.MockVariableValue(&setting.Database.CharsetCollation, "utf8mb4_bin")()
76-
assert.NoError(t, db.ConvertDatabaseTable())
7776
r, err := db.CheckCollations(x)
7877
assert.NoError(t, err)
78+
assert.EqualValues(t, "utf8mb4_bin", r.ExpectedCollation)
79+
assert.NoError(t, db.ConvertDatabaseTable())
80+
r, err = db.CheckCollations(x)
81+
assert.NoError(t, err)
7982
assert.Equal(t, "utf8mb4_bin", r.DatabaseCollation)
8083
assert.True(t, r.CollationEquals(r.ExpectedCollation, r.DatabaseCollation))
8184
assert.Empty(t, r.InconsistentCollationColumns)

0 commit comments

Comments
 (0)