code.gitea.io/gitea@v1.21.7/models/repo/pushmirror.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repo
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	"code.gitea.io/gitea/modules/log"
    12  	"code.gitea.io/gitea/modules/timeutil"
    13  	"code.gitea.io/gitea/modules/util"
    14  
    15  	"xorm.io/builder"
    16  )
    17  
    18  // ErrPushMirrorNotExist mirror does not exist error
    19  var ErrPushMirrorNotExist = util.NewNotExistErrorf("PushMirror does not exist")
    20  
    21  // PushMirror represents mirror information of a repository.
    22  type PushMirror struct {
    23  	ID            int64       `xorm:"pk autoincr"`
    24  	RepoID        int64       `xorm:"INDEX"`
    25  	Repo          *Repository `xorm:"-"`
    26  	RemoteName    string
    27  	RemoteAddress string `xorm:"VARCHAR(2048)"`
    28  
    29  	SyncOnCommit   bool `xorm:"NOT NULL DEFAULT true"`
    30  	Interval       time.Duration
    31  	CreatedUnix    timeutil.TimeStamp `xorm:"created"`
    32  	LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
    33  	LastError      string             `xorm:"text"`
    34  }
    35  
    36  type PushMirrorOptions struct {
    37  	ID         int64
    38  	RepoID     int64
    39  	RemoteName string
    40  }
    41  
    42  func (opts *PushMirrorOptions) toConds() builder.Cond {
    43  	cond := builder.NewCond()
    44  	if opts.RepoID > 0 {
    45  		cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
    46  	}
    47  	if opts.RemoteName != "" {
    48  		cond = cond.And(builder.Eq{"remote_name": opts.RemoteName})
    49  	}
    50  	if opts.ID > 0 {
    51  		cond = cond.And(builder.Eq{"id": opts.ID})
    52  	}
    53  	return cond
    54  }
    55  
    56  func init() {
    57  	db.RegisterModel(new(PushMirror))
    58  }
    59  
    60  // GetRepository returns the path of the repository.
    61  func (m *PushMirror) GetRepository() *Repository {
    62  	if m.Repo != nil {
    63  		return m.Repo
    64  	}
    65  	var err error
    66  	m.Repo, err = GetRepositoryByID(db.DefaultContext, m.RepoID)
    67  	if err != nil {
    68  		log.Error("getRepositoryByID[%d]: %v", m.ID, err)
    69  	}
    70  	return m.Repo
    71  }
    72  
    73  // GetRemoteName returns the name of the remote.
    74  func (m *PushMirror) GetRemoteName() string {
    75  	return m.RemoteName
    76  }
    77  
    78  // InsertPushMirror inserts a push-mirror to database
    79  func InsertPushMirror(ctx context.Context, m *PushMirror) error {
    80  	_, err := db.GetEngine(ctx).Insert(m)
    81  	return err
    82  }
    83  
    84  // UpdatePushMirror updates the push-mirror
    85  func UpdatePushMirror(ctx context.Context, m *PushMirror) error {
    86  	_, err := db.GetEngine(ctx).ID(m.ID).AllCols().Update(m)
    87  	return err
    88  }
    89  
    90  // UpdatePushMirrorInterval updates the push-mirror
    91  func UpdatePushMirrorInterval(ctx context.Context, m *PushMirror) error {
    92  	_, err := db.GetEngine(ctx).ID(m.ID).Cols("interval").Update(m)
    93  	return err
    94  }
    95  
    96  func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error {
    97  	if opts.RepoID > 0 {
    98  		_, err := db.GetEngine(ctx).Where(opts.toConds()).Delete(&PushMirror{})
    99  		return err
   100  	}
   101  	return util.NewInvalidArgumentErrorf("repoID required and must be set")
   102  }
   103  
   104  func GetPushMirror(ctx context.Context, opts PushMirrorOptions) (*PushMirror, error) {
   105  	mirror := &PushMirror{}
   106  	exist, err := db.GetEngine(ctx).Where(opts.toConds()).Get(mirror)
   107  	if err != nil {
   108  		return nil, err
   109  	} else if !exist {
   110  		return nil, ErrPushMirrorNotExist
   111  	}
   112  	return mirror, nil
   113  }
   114  
   115  // GetPushMirrorsByRepoID returns push-mirror information of a repository.
   116  func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) {
   117  	sess := db.GetEngine(ctx).Where("repo_id = ?", repoID)
   118  	if listOptions.Page != 0 {
   119  		sess = db.SetSessionPagination(sess, &listOptions)
   120  		mirrors := make([]*PushMirror, 0, listOptions.PageSize)
   121  		count, err := sess.FindAndCount(&mirrors)
   122  		return mirrors, count, err
   123  	}
   124  	mirrors := make([]*PushMirror, 0, 10)
   125  	count, err := sess.FindAndCount(&mirrors)
   126  	return mirrors, count, err
   127  }
   128  
   129  // GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
   130  func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) {
   131  	mirrors := make([]*PushMirror, 0, 10)
   132  	return mirrors, db.GetEngine(ctx).
   133  		Where("repo_id = ? AND sync_on_commit = ?", repoID, true).
   134  		Find(&mirrors)
   135  }
   136  
   137  // PushMirrorsIterate iterates all push-mirror repositories.
   138  func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any) error) error {
   139  	sess := db.GetEngine(ctx).
   140  		Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()).
   141  		And("`interval` != 0").
   142  		OrderBy("last_update ASC")
   143  	if limit > 0 {
   144  		sess = sess.Limit(limit)
   145  	}
   146  	return sess.Iterate(new(PushMirror), f)
   147  }