code.gitea.io/gitea@v1.21.7/models/repo/repo_indexer.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "context" 8 "fmt" 9 10 "code.gitea.io/gitea/models/db" 11 12 "xorm.io/builder" 13 ) 14 15 // RepoIndexerType specifies the repository indexer type 16 type RepoIndexerType int //revive:disable-line:exported 17 18 const ( 19 // RepoIndexerTypeCode code indexer 20 RepoIndexerTypeCode RepoIndexerType = iota // 0 21 // RepoIndexerTypeStats repository stats indexer 22 RepoIndexerTypeStats // 1 23 ) 24 25 // RepoIndexerStatus status of a repo's entry in the repo indexer 26 // For now, implicitly refers to default branch 27 type RepoIndexerStatus struct { //revive:disable-line:exported 28 ID int64 `xorm:"pk autoincr"` 29 RepoID int64 `xorm:"INDEX(s)"` 30 CommitSha string `xorm:"VARCHAR(40)"` 31 IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"` 32 } 33 34 func init() { 35 db.RegisterModel(new(RepoIndexerStatus)) 36 } 37 38 // GetUnindexedRepos returns repos which do not have an indexer status 39 func GetUnindexedRepos(indexerType RepoIndexerType, maxRepoID int64, page, pageSize int) ([]int64, error) { 40 ids := make([]int64, 0, 50) 41 cond := builder.Cond(builder.IsNull{ 42 "repo_indexer_status.id", 43 }).And(builder.Eq{ 44 "repository.is_empty": false, 45 }) 46 sess := db.GetEngine(db.DefaultContext).Table("repository").Join("LEFT OUTER", "repo_indexer_status", "repository.id = repo_indexer_status.repo_id AND repo_indexer_status.indexer_type = ?", indexerType) 47 if maxRepoID > 0 { 48 cond = builder.And(cond, builder.Lte{ 49 "repository.id": maxRepoID, 50 }) 51 } 52 if page >= 0 && pageSize > 0 { 53 start := 0 54 if page > 0 { 55 start = (page - 1) * pageSize 56 } 57 sess.Limit(pageSize, start) 58 } 59 60 sess.Where(cond).Cols("repository.id").Desc("repository.id") 61 err := sess.Find(&ids) 62 return ids, err 63 } 64 65 // GetIndexerStatus loads repo codes indxer status 66 func GetIndexerStatus(ctx context.Context, repo *Repository, indexerType RepoIndexerType) (*RepoIndexerStatus, error) { 67 switch indexerType { 68 case RepoIndexerTypeCode: 69 if repo.CodeIndexerStatus != nil { 70 return repo.CodeIndexerStatus, nil 71 } 72 case RepoIndexerTypeStats: 73 if repo.StatsIndexerStatus != nil { 74 return repo.StatsIndexerStatus, nil 75 } 76 } 77 status := &RepoIndexerStatus{RepoID: repo.ID} 78 if has, err := db.GetEngine(ctx).Where("`indexer_type` = ?", indexerType).Get(status); err != nil { 79 return nil, err 80 } else if !has { 81 status.IndexerType = indexerType 82 status.CommitSha = "" 83 } 84 switch indexerType { 85 case RepoIndexerTypeCode: 86 repo.CodeIndexerStatus = status 87 case RepoIndexerTypeStats: 88 repo.StatsIndexerStatus = status 89 } 90 return status, nil 91 } 92 93 // UpdateIndexerStatus updates indexer status 94 func UpdateIndexerStatus(ctx context.Context, repo *Repository, indexerType RepoIndexerType, sha string) error { 95 status, err := GetIndexerStatus(ctx, repo, indexerType) 96 if err != nil { 97 return fmt.Errorf("UpdateIndexerStatus: Unable to getIndexerStatus for repo: %s Error: %w", repo.FullName(), err) 98 } 99 100 if len(status.CommitSha) == 0 { 101 status.CommitSha = sha 102 if err := db.Insert(ctx, status); err != nil { 103 return fmt.Errorf("UpdateIndexerStatus: Unable to insert repoIndexerStatus for repo: %s Sha: %s Error: %w", repo.FullName(), sha, err) 104 } 105 return nil 106 } 107 status.CommitSha = sha 108 _, err = db.GetEngine(ctx).ID(status.ID).Cols("commit_sha"). 109 Update(status) 110 if err != nil { 111 return fmt.Errorf("UpdateIndexerStatus: Unable to update repoIndexerStatus for repo: %s Sha: %s Error: %w", repo.FullName(), sha, err) 112 } 113 return nil 114 }