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.

pushmirror.go 4.2KB

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