2016-08-31 02:18:33 +03:00
// Copyright 2016 The Gogs Authors. All rights reserved.
2018-09-07 05:06:09 +03:00
// Copyright 2018 The Gitea Authors. All rights reserved.
2016-08-31 02:18:33 +03:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-12-10 04:27:50 +03:00
package repo
2016-08-31 02:18:33 +03:00
import (
2021-12-10 04:27:50 +03:00
"errors"
"fmt"
2016-08-31 02:18:33 +03:00
"time"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/log"
2019-08-15 17:46:21 +03:00
"code.gitea.io/gitea/modules/timeutil"
2017-12-04 04:48:03 +03:00
2019-10-17 12:26:49 +03:00
"xorm.io/xorm"
2016-08-31 02:18:33 +03:00
)
2021-12-10 04:27:50 +03:00
var (
// ErrMirrorNotExist mirror does not exist error
ErrMirrorNotExist = errors . New ( "Mirror does not exist" )
)
2021-06-14 20:20:43 +03:00
// RemoteMirrorer defines base methods for pull/push mirrors.
type RemoteMirrorer interface {
GetRepository ( ) * Repository
GetRemoteName ( ) string
}
2016-08-31 02:18:33 +03:00
// Mirror represents mirror information of a repository.
type Mirror struct {
2017-01-06 18:14:33 +03:00
ID int64 ` xorm:"pk autoincr" `
RepoID int64 ` xorm:"INDEX" `
2016-08-31 02:18:33 +03:00
Repo * Repository ` xorm:"-" `
2017-04-08 18:27:26 +03:00
Interval time . Duration
EnablePrune bool ` xorm:"NOT NULL DEFAULT true" `
2016-08-31 02:18:33 +03:00
2019-08-15 17:46:21 +03:00
UpdatedUnix timeutil . TimeStamp ` xorm:"INDEX" `
NextUpdateUnix timeutil . TimeStamp ` xorm:"INDEX" `
2016-08-31 02:18:33 +03:00
2021-04-09 01:25:57 +03:00
LFS bool ` xorm:"lfs_enabled NOT NULL DEFAULT false" `
LFSEndpoint string ` xorm:"lfs_endpoint TEXT" `
2019-10-01 16:40:17 +03:00
Address string ` xorm:"-" `
2016-08-31 02:18:33 +03:00
}
2021-09-19 14:49:59 +03:00
func init ( ) {
db . RegisterModel ( new ( Mirror ) )
}
2016-11-26 03:30:21 +03:00
// BeforeInsert will be invoked by XORM before inserting a record
2016-08-31 02:18:33 +03:00
func ( m * Mirror ) BeforeInsert ( ) {
2017-09-13 08:18:22 +03:00
if m != nil {
2019-08-15 17:46:21 +03:00
m . UpdatedUnix = timeutil . TimeStampNow ( )
m . NextUpdateUnix = timeutil . TimeStampNow ( )
2017-09-13 08:18:22 +03:00
}
2016-08-31 02:18:33 +03:00
}
2017-10-01 19:52:35 +03:00
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func ( m * Mirror ) AfterLoad ( session * xorm . Session ) {
2017-09-13 08:18:22 +03:00
if m == nil {
return
}
2016-08-31 02:18:33 +03:00
var err error
2017-10-01 19:52:35 +03:00
m . Repo , err = getRepositoryByID ( session , m . RepoID )
if err != nil {
2019-04-02 10:48:31 +03:00
log . Error ( "getRepositoryByID[%d]: %v" , m . ID , err )
2016-08-31 02:18:33 +03:00
}
}
2021-06-14 20:20:43 +03:00
// 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"
}
2016-08-31 02:18:33 +03:00
// ScheduleNextUpdate calculates and sets next update time.
func ( m * Mirror ) ScheduleNextUpdate ( ) {
2018-11-09 02:58:02 +03:00
if m . Interval != 0 {
2019-08-15 17:46:21 +03:00
m . NextUpdateUnix = timeutil . TimeStampNow ( ) . AddDuration ( m . Interval )
2018-11-09 02:58:02 +03:00
} else {
m . NextUpdateUnix = 0
}
2016-08-31 02:18:33 +03:00
}
2021-09-19 14:49:59 +03:00
func getMirrorByRepoID ( e db . Engine , repoID int64 ) ( * Mirror , error ) {
2016-08-31 02:18:33 +03:00
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 ) {
2021-09-23 18:45:36 +03:00
return getMirrorByRepoID ( db . GetEngine ( db . DefaultContext ) , repoID )
2016-08-31 02:18:33 +03:00
}
2021-09-19 14:49:59 +03:00
func updateMirror ( e db . Engine , m * Mirror ) error {
2017-10-05 07:43:04 +03:00
_ , err := e . ID ( m . ID ) . AllCols ( ) . Update ( m )
2016-08-31 02:18:33 +03:00
return err
}
2016-11-26 03:30:21 +03:00
// UpdateMirror updates the mirror
2016-08-31 02:18:33 +03:00
func UpdateMirror ( m * Mirror ) error {
2021-09-23 18:45:36 +03:00
return updateMirror ( db . GetEngine ( db . DefaultContext ) , m )
2016-08-31 02:18:33 +03:00
}
2016-11-26 03:30:21 +03:00
// DeleteMirrorByRepoID deletes a mirror by repoID
2016-08-31 02:18:33 +03:00
func DeleteMirrorByRepoID ( repoID int64 ) error {
2021-09-23 18:45:36 +03:00
_ , err := db . GetEngine ( db . DefaultContext ) . Delete ( & Mirror { RepoID : repoID } )
2016-08-31 02:18:33 +03:00
return err
}
2019-10-01 16:40:17 +03:00
// MirrorsIterate iterates all mirror repositories.
func MirrorsIterate ( f func ( idx int , bean interface { } ) error ) error {
2021-09-23 18:45:36 +03:00
return db . GetEngine ( db . DefaultContext ) .
2016-11-10 18:16:32 +03:00
Where ( "next_update_unix<=?" , time . Now ( ) . Unix ( ) ) .
2018-11-09 02:58:02 +03:00
And ( "next_update_unix!=0" ) .
2021-11-23 06:09:35 +03:00
OrderBy ( "updated_unix ASC" ) .
2019-10-01 16:40:17 +03:00
Iterate ( new ( Mirror ) , f )
2016-08-31 02:18:33 +03:00
}
2019-12-14 20:30:01 +03:00
// InsertMirror inserts a mirror to database
func InsertMirror ( mirror * Mirror ) error {
2021-09-23 18:45:36 +03:00
_ , err := db . GetEngine ( db . DefaultContext ) . Insert ( mirror )
2019-12-14 20:30:01 +03:00
return err
}
2021-12-10 04:27:50 +03:00
// 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 ) )
}