mirror of https://github.com/go-gitea/gitea.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.3 KiB
152 lines
4.3 KiB
// Copyright 2021 The Gitea Authors. All rights reserved. |
|
// SPDX-License-Identifier: MIT |
|
|
|
package repo |
|
|
|
import ( |
|
"context" |
|
"time" |
|
|
|
"code.gitea.io/gitea/models/db" |
|
"code.gitea.io/gitea/modules/log" |
|
"code.gitea.io/gitea/modules/optional" |
|
"code.gitea.io/gitea/modules/timeutil" |
|
"code.gitea.io/gitea/modules/util" |
|
|
|
"xorm.io/builder" |
|
) |
|
|
|
// PushMirror represents mirror information of a repository. |
|
type PushMirror struct { |
|
ID int64 `xorm:"pk autoincr"` |
|
RepoID int64 `xorm:"INDEX"` |
|
Repo *Repository `xorm:"-"` |
|
RemoteName string |
|
RemoteAddress string `xorm:"VARCHAR(2048)"` |
|
|
|
SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"` |
|
Interval time.Duration |
|
CreatedUnix timeutil.TimeStamp `xorm:"created"` |
|
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"` |
|
LastError string `xorm:"text"` |
|
} |
|
|
|
type PushMirrorOptions struct { |
|
db.ListOptions |
|
ID int64 |
|
RepoID int64 |
|
RemoteName string |
|
} |
|
|
|
func (opts PushMirrorOptions) ToConds() builder.Cond { |
|
cond := builder.NewCond() |
|
if opts.RepoID > 0 { |
|
cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) |
|
} |
|
if opts.RemoteName != "" { |
|
cond = cond.And(builder.Eq{"remote_name": opts.RemoteName}) |
|
} |
|
if opts.ID > 0 { |
|
cond = cond.And(builder.Eq{"id": opts.ID}) |
|
} |
|
return cond |
|
} |
|
|
|
func init() { |
|
db.RegisterModel(new(PushMirror)) |
|
} |
|
|
|
// GetRepository returns the path of the repository. |
|
func (m *PushMirror) GetRepository(ctx context.Context) *Repository { |
|
if m.Repo != nil { |
|
return m.Repo |
|
} |
|
var err error |
|
m.Repo, err = GetRepositoryByID(ctx, m.RepoID) |
|
if err != nil { |
|
log.Error("getRepositoryByID[%d]: %v", m.ID, err) |
|
} |
|
return m.Repo |
|
} |
|
|
|
// GetRemoteName returns the name of the remote. |
|
func (m *PushMirror) GetRemoteName() string { |
|
return m.RemoteName |
|
} |
|
|
|
// UpdatePushMirror updates the push-mirror |
|
func UpdatePushMirror(ctx context.Context, m *PushMirror) error { |
|
_, err := db.GetEngine(ctx).ID(m.ID).AllCols().Update(m) |
|
return err |
|
} |
|
|
|
// UpdatePushMirrorInterval updates the push-mirror |
|
func UpdatePushMirrorInterval(ctx context.Context, m *PushMirror) error { |
|
_, err := db.GetEngine(ctx).ID(m.ID).Cols("interval").Update(m) |
|
return err |
|
} |
|
|
|
func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error { |
|
if opts.RepoID > 0 { |
|
_, err := db.Delete[PushMirror](ctx, opts) |
|
return err |
|
} |
|
return util.NewInvalidArgumentErrorf("repoID required and must be set") |
|
} |
|
|
|
type findPushMirrorOptions struct { |
|
db.ListOptions |
|
RepoID int64 |
|
SyncOnCommit optional.Option[bool] |
|
} |
|
|
|
func (opts findPushMirrorOptions) ToConds() builder.Cond { |
|
cond := builder.NewCond() |
|
if opts.RepoID > 0 { |
|
cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) |
|
} |
|
if opts.SyncOnCommit.Has() { |
|
cond = cond.And(builder.Eq{"sync_on_commit": opts.SyncOnCommit.Value()}) |
|
} |
|
return cond |
|
} |
|
|
|
// GetPushMirrorsByRepoID returns push-mirror information of a repository. |
|
func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) { |
|
return db.FindAndCount[PushMirror](ctx, findPushMirrorOptions{ |
|
ListOptions: listOptions, |
|
RepoID: repoID, |
|
}) |
|
} |
|
|
|
func GetPushMirrorByIDAndRepoID(ctx context.Context, id, repoID int64) (*PushMirror, bool, error) { |
|
var pushMirror PushMirror |
|
has, err := db.GetEngine(ctx).Where("id = ?", id).And("repo_id = ?", repoID).Get(&pushMirror) |
|
if !has || err != nil { |
|
return nil, has, err |
|
} |
|
return &pushMirror, true, nil |
|
} |
|
|
|
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits |
|
func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) { |
|
return db.Find[PushMirror](ctx, findPushMirrorOptions{ |
|
RepoID: repoID, |
|
SyncOnCommit: optional.Some(true), |
|
}) |
|
} |
|
|
|
// PushMirrorsIterate iterates all push-mirror repositories. |
|
func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any) error) error { |
|
sess := db.GetEngine(ctx). |
|
Table("push_mirror"). |
|
Join("INNER", "`repository`", "`repository`.id = `push_mirror`.repo_id"). |
|
Where("`push_mirror`.last_update + (`push_mirror`.`interval` / ?) <= ?", time.Second, time.Now().Unix()). |
|
And("`push_mirror`.`interval` != 0"). |
|
And("`repository`.is_archived = ?", false). |
|
OrderBy("last_update ASC") |
|
if limit > 0 { |
|
sess = sess.Limit(limit) |
|
} |
|
return sess.Iterate(new(PushMirror), f) |
|
}
|
|
|