diff options
Diffstat (limited to 'models/repo/mirror.go')
-rw-r--r-- | models/repo/mirror.go | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/models/repo/mirror.go b/models/repo/mirror.go new file mode 100644 index 0000000000..bdb449af3a --- /dev/null +++ b/models/repo/mirror.go @@ -0,0 +1,177 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2018 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "errors" + "fmt" + "time" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +var ( + // ErrMirrorNotExist mirror does not exist error + ErrMirrorNotExist = errors.New("Mirror does not exist") +) + +// RemoteMirrorer defines base methods for pull/push mirrors. +type RemoteMirrorer interface { + GetRepository() *Repository + GetRemoteName() string +} + +// Mirror represents mirror information of a repository. +type Mirror struct { + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"INDEX"` + Repo *Repository `xorm:"-"` + Interval time.Duration + EnablePrune bool `xorm:"NOT NULL DEFAULT true"` + + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX"` + NextUpdateUnix timeutil.TimeStamp `xorm:"INDEX"` + + LFS bool `xorm:"lfs_enabled NOT NULL DEFAULT false"` + LFSEndpoint string `xorm:"lfs_endpoint TEXT"` + + Address string `xorm:"-"` +} + +func init() { + db.RegisterModel(new(Mirror)) +} + +// BeforeInsert will be invoked by XORM before inserting a record +func (m *Mirror) BeforeInsert() { + if m != nil { + m.UpdatedUnix = timeutil.TimeStampNow() + m.NextUpdateUnix = timeutil.TimeStampNow() + } +} + +// AfterLoad is invoked from XORM after setting the values of all fields of this object. +func (m *Mirror) AfterLoad(session *xorm.Session) { + if m == nil { + return + } + + var err error + m.Repo, err = getRepositoryByID(session, m.RepoID) + if err != nil { + log.Error("getRepositoryByID[%d]: %v", m.ID, err) + } +} + +// GetRepository returns the repository. +func (m *Mirror) GetRepository() *Repository { + return m.Repo +} + +// GetRemoteName returns the name of the remote. +func (m *Mirror) GetRemoteName() string { + return "origin" +} + +// ScheduleNextUpdate calculates and sets next update time. +func (m *Mirror) ScheduleNextUpdate() { + if m.Interval != 0 { + m.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(m.Interval) + } else { + m.NextUpdateUnix = 0 + } +} + +func getMirrorByRepoID(e db.Engine, repoID int64) (*Mirror, error) { + m := &Mirror{RepoID: repoID} + has, err := e.Get(m) + if err != nil { + return nil, err + } else if !has { + return nil, ErrMirrorNotExist + } + return m, nil +} + +// GetMirrorByRepoID returns mirror information of a repository. +func GetMirrorByRepoID(repoID int64) (*Mirror, error) { + return getMirrorByRepoID(db.GetEngine(db.DefaultContext), repoID) +} + +func updateMirror(e db.Engine, m *Mirror) error { + _, err := e.ID(m.ID).AllCols().Update(m) + return err +} + +// UpdateMirror updates the mirror +func UpdateMirror(m *Mirror) error { + return updateMirror(db.GetEngine(db.DefaultContext), m) +} + +// DeleteMirrorByRepoID deletes a mirror by repoID +func DeleteMirrorByRepoID(repoID int64) error { + _, err := db.GetEngine(db.DefaultContext).Delete(&Mirror{RepoID: repoID}) + return err +} + +// MirrorsIterate iterates all mirror repositories. +func MirrorsIterate(f func(idx int, bean interface{}) error) error { + return db.GetEngine(db.DefaultContext). + Where("next_update_unix<=?", time.Now().Unix()). + And("next_update_unix!=0"). + OrderBy("updated_unix ASC"). + Iterate(new(Mirror), f) +} + +// InsertMirror inserts a mirror to database +func InsertMirror(mirror *Mirror) error { + _, err := db.GetEngine(db.DefaultContext).Insert(mirror) + return err +} + +// MirrorRepositoryList contains the mirror repositories +type MirrorRepositoryList []*Repository + +func (repos MirrorRepositoryList) loadAttributes(e db.Engine) error { + if len(repos) == 0 { + return nil + } + + // Load mirrors. + repoIDs := make([]int64, 0, len(repos)) + for i := range repos { + if !repos[i].IsMirror { + continue + } + + repoIDs = append(repoIDs, repos[i].ID) + } + mirrors := make([]*Mirror, 0, len(repoIDs)) + if err := e. + Where("id > 0"). + In("repo_id", repoIDs). + Find(&mirrors); err != nil { + return fmt.Errorf("find mirrors: %v", err) + } + + set := make(map[int64]*Mirror) + for i := range mirrors { + set[mirrors[i].RepoID] = mirrors[i] + } + for i := range repos { + repos[i].Mirror = set[repos[i].ID] + } + return nil +} + +// LoadAttributes loads the attributes for the given MirrorRepositoryList +func (repos MirrorRepositoryList) LoadAttributes() error { + return repos.loadAttributes(db.GetEngine(db.DefaultContext)) +} |