1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Move more functions to db.Find (#28419)

Following #28220

This PR move more functions to use `db.Find`.

---------

Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
Lunny Xiao
2024-01-15 10:19:25 +08:00
committed by GitHub
parent e5313248a8
commit 70c4aad8e1
36 changed files with 305 additions and 238 deletions

View File

@@ -11,21 +11,13 @@ import (
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"github.com/keybase/go-crypto/openpgp"
"github.com/keybase/go-crypto/openpgp/packet"
"xorm.io/xorm"
"xorm.io/builder"
)
// __________________ ________ ____ __.
// / _____/\______ \/ _____/ | |/ _|____ ___.__.
// / \ ___ | ___/ \ ___ | <_/ __ < | |
// \ \_\ \| | \ \_\ \ | | \ ___/\___ |
// \______ /|____| \______ / |____|__ \___ > ____|
// \/ \/ \/ \/\/
// GPGKey represents a GPG key.
type GPGKey struct {
ID int64 `xorm:"pk autoincr"`
@@ -54,12 +46,11 @@ func (key *GPGKey) BeforeInsert() {
key.AddedUnix = timeutil.TimeStampNow()
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (key *GPGKey) AfterLoad(session *xorm.Session) {
err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey)
if err != nil {
log.Error("Find Sub GPGkeys[%s]: %v", key.KeyID, err)
func (key *GPGKey) LoadSubKeys(ctx context.Context) error {
if err := db.GetEngine(ctx).Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey); err != nil {
return fmt.Errorf("find Sub GPGkeys[%s]: %v", key.KeyID, err)
}
return nil
}
// PaddedKeyID show KeyID padded to 16 characters
@@ -76,20 +67,26 @@ func PaddedKeyID(keyID string) string {
return zeros[0:16-len(keyID)] + keyID
}
// ListGPGKeys returns a list of public keys belongs to given user.
func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
keys := make([]*GPGKey, 0, 2)
return keys, sess.Find(&keys)
type FindGPGKeyOptions struct {
db.ListOptions
OwnerID int64
KeyID string
IncludeSubKeys bool
}
// CountUserGPGKeys return number of gpg keys a user own
func CountUserGPGKeys(ctx context.Context, userID int64) (int64, error) {
return db.GetEngine(ctx).Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{})
func (opts FindGPGKeyOptions) ToConds() builder.Cond {
cond := builder.NewCond()
if !opts.IncludeSubKeys {
cond = cond.And(builder.Eq{"primary_key_id": ""})
}
if opts.OwnerID > 0 {
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
}
if opts.KeyID != "" {
cond = cond.And(builder.Eq{"key_id": opts.KeyID})
}
return cond
}
func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, error) {
@@ -103,12 +100,6 @@ func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, e
return key, nil
}
// GetGPGKeysByKeyID returns public key by given ID.
func GetGPGKeysByKeyID(ctx context.Context, keyID string) ([]*GPGKey, error) {
keys := make([]*GPGKey, 0, 1)
return keys, db.GetEngine(ctx).Where("key_id=?", keyID).Find(&keys)
}
// GPGKeyToEntity retrieve the imported key and the traducted entity
func GPGKeyToEntity(ctx context.Context, k *GPGKey) (*openpgp.Entity, error) {
impKey, err := GetGPGImportByKeyID(ctx, k.KeyID)

View File

@@ -166,7 +166,9 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
// Now try to associate the signature with the committer, if present
if committer.ID != 0 {
keys, err := ListGPGKeys(ctx, committer.ID, db.ListOptions{})
keys, err := db.Find[GPGKey](ctx, FindGPGKeyOptions{
OwnerID: committer.ID,
})
if err != nil { // Skipping failed to get gpg keys of user
log.Error("ListGPGKeys: %v", err)
return &CommitVerification{
@@ -176,6 +178,15 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
}
}
if err := GPGKeyList(keys).LoadSubKeys(ctx); err != nil {
log.Error("LoadSubKeys: %v", err)
return &CommitVerification{
CommittingUser: committer,
Verified: false,
Reason: "gpg.error.failed_retrieval_gpg_keys",
}
}
committerEmailAddresses, _ := user_model.GetEmailAddresses(ctx, committer.ID)
activated := false
for _, e := range committerEmailAddresses {
@@ -392,7 +403,10 @@ func hashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
if keyID == "" {
return nil
}
keys, err := GetGPGKeysByKeyID(ctx, keyID)
keys, err := db.Find[GPGKey](ctx, FindGPGKeyOptions{
KeyID: keyID,
IncludeSubKeys: true,
})
if err != nil {
log.Error("GetGPGKeysByKeyID: %v", err)
return &CommitVerification{
@@ -407,7 +421,10 @@ func hashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
for _, key := range keys {
var primaryKeys []*GPGKey
if key.PrimaryKeyID != "" {
primaryKeys, err = GetGPGKeysByKeyID(ctx, key.PrimaryKeyID)
primaryKeys, err = db.Find[GPGKey](ctx, FindGPGKeyOptions{
KeyID: key.PrimaryKeyID,
IncludeSubKeys: true,
})
if err != nil {
log.Error("GetGPGKeysByKeyID: %v", err)
return &CommitVerification{

View File

@@ -0,0 +1,38 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package asymkey
import (
"context"
"code.gitea.io/gitea/models/db"
)
type GPGKeyList []*GPGKey
func (keys GPGKeyList) keyIDs() []string {
ids := make([]string, len(keys))
for i, key := range keys {
ids[i] = key.KeyID
}
return ids
}
func (keys GPGKeyList) LoadSubKeys(ctx context.Context) error {
subKeys := make([]*GPGKey, 0, len(keys))
if err := db.GetEngine(ctx).In("primary_key_id", keys.keyIDs()).Find(&subKeys); err != nil {
return err
}
subKeysMap := make(map[string][]*GPGKey, len(subKeys))
for _, key := range subKeys {
subKeysMap[key.PrimaryKeyID] = append(subKeysMap[key.PrimaryKeyID], key)
}
for _, key := range keys {
if subKeys, ok := subKeysMap[key.KeyID]; ok {
key.SubsKey = subKeys
}
}
return nil
}

View File

@@ -197,10 +197,10 @@ func (opts FindPublicKeyOptions) ToConds() builder.Cond {
cond = cond.And(builder.Eq{"fingerprint": opts.Fingerprint})
}
if len(opts.KeyTypes) > 0 {
cond = cond.And(builder.In("type", opts.KeyTypes))
cond = cond.And(builder.In("`type`", opts.KeyTypes))
}
if opts.NotKeytype > 0 {
cond = cond.And(builder.Neq{"type": opts.NotKeytype})
cond = cond.And(builder.Neq{"`type`": opts.NotKeytype})
}
if opts.LoginSourceID > 0 {
cond = cond.And(builder.Eq{"login_source_id": opts.LoginSourceID})

View File

@@ -15,15 +15,6 @@ import (
"code.gitea.io/gitea/modules/util"
)
// __________ .__ .__ .__
// \______ _______|__| ____ ____ |_____________ | | ______
// | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
// | | | | \| | | \ \___| | |_> / __ \| |__\___ \
// |____| |__| |__|___| /\___ |__| __(____ |____/____ >
// \/ \/ |__| \/ \/
//
// This file contains functions related to principals
// AddPrincipalKey adds new principal to database and authorized_principals file.
func AddPrincipalKey(ctx context.Context, ownerID int64, content string, authSourceID int64) (*PublicKey, error) {
dbCtx, committer, err := db.TxContext(ctx)
@@ -103,17 +94,3 @@ func CheckPrincipalKeyString(ctx context.Context, user *user_model.User, content
return "", fmt.Errorf("didn't match allowed principals: %s", setting.SSH.AuthorizedPrincipalsAllow)
}
// ListPrincipalKeys returns a list of principals belongs to given user.
func ListPrincipalKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*PublicKey, error) {
sess := db.GetEngine(ctx).Where("owner_id = ? AND type = ?", uid, KeyTypePrincipal)
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
keys := make([]*PublicKey, 0, listOptions.PageSize)
return keys, sess.Find(&keys)
}
keys := make([]*PublicKey, 0, 5)
return keys, sess.Find(&keys)
}

View File

@@ -13,7 +13,6 @@ import (
"code.gitea.io/gitea/modules/util"
"github.com/go-webauthn/webauthn/webauthn"
"xorm.io/xorm"
)
// ErrWebAuthnCredentialNotExist represents a "ErrWebAuthnCRedentialNotExist" kind of error.
@@ -83,7 +82,7 @@ func (cred *WebAuthnCredential) BeforeUpdate() {
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (cred *WebAuthnCredential) AfterLoad(session *xorm.Session) {
func (cred *WebAuthnCredential) AfterLoad() {
cred.LowerName = strings.ToLower(cred.Name)
}

View File

@@ -21,17 +21,9 @@ const (
// Paginator is the base for different ListOptions types
type Paginator interface {
GetSkipTake() (skip, take int)
GetStartEnd() (start, end int)
IsListAll() bool
}
// GetPaginatedSession creates a paginated database session
func GetPaginatedSession(p Paginator) *xorm.Session {
skip, take := p.GetSkipTake()
return x.Limit(take, skip)
}
// SetSessionPagination sets pagination for a database session
func SetSessionPagination(sess Engine, p Paginator) *xorm.Session {
skip, take := p.GetSkipTake()
@@ -39,13 +31,6 @@ func SetSessionPagination(sess Engine, p Paginator) *xorm.Session {
return sess.Limit(take, skip)
}
// SetEnginePagination sets pagination for a database engine
func SetEnginePagination(e Engine, p Paginator) Engine {
skip, take := p.GetSkipTake()
return e.Limit(take, skip)
}
// ListOptions options to paginate results
type ListOptions struct {
PageSize int
@@ -66,13 +51,6 @@ func (opts *ListOptions) GetSkipTake() (skip, take int) {
return (opts.Page - 1) * opts.PageSize, opts.PageSize
}
// GetStartEnd returns the start and end of the ListOptions
func (opts *ListOptions) GetStartEnd() (start, end int) {
start, take := opts.GetSkipTake()
end = start + take
return start, end
}
func (opts ListOptions) GetPage() int {
return opts.Page
}
@@ -135,11 +113,6 @@ func (opts *AbsoluteListOptions) GetSkipTake() (skip, take int) {
return opts.skip, opts.take
}
// GetStartEnd returns the start and end values
func (opts *AbsoluteListOptions) GetStartEnd() (start, end int) {
return opts.skip, opts.skip + opts.take
}
// FindOptions represents a find options
type FindOptions interface {
GetPage() int
@@ -148,15 +121,34 @@ type FindOptions interface {
ToConds() builder.Cond
}
type JoinFunc func(sess Engine) error
type FindOptionsJoin interface {
ToJoins() []JoinFunc
}
type FindOptionsOrder interface {
ToOrders() string
}
// Find represents a common find function which accept an options interface
func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
sess := GetEngine(ctx).Where(opts.ToConds())
sess := GetEngine(ctx)
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return nil, err
}
}
}
sess = sess.Where(opts.ToConds())
page, pageSize := opts.GetPage(), opts.GetPageSize()
if !opts.IsListAll() && pageSize > 0 && page >= 1 {
if !opts.IsListAll() && pageSize > 0 {
if page == 0 {
page = 1
}
sess.Limit(pageSize, (page-1)*pageSize)
}
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" {
@@ -176,8 +168,17 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
// Count represents a common count function which accept an options interface
func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
sess := GetEngine(ctx)
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return 0, err
}
}
}
var object T
return GetEngine(ctx).Where(opts.ToConds()).Count(&object)
return sess.Where(opts.ToConds()).Count(&object)
}
// FindAndCount represents a common findandcount function which accept an options interface

View File

@@ -52,11 +52,8 @@ func TestPaginator(t *testing.T) {
for _, c := range cases {
skip, take := c.Paginator.GetSkipTake()
start, end := c.Paginator.GetStartEnd()
assert.Equal(t, c.Skip, skip)
assert.Equal(t, c.Take, take)
assert.Equal(t, c.Start, start)
assert.Equal(t, c.End, end)
}
}

View File

@@ -28,7 +28,6 @@ import (
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
)
// ErrCommentNotExist represents a "CommentNotExist" kind of error.
@@ -338,7 +337,7 @@ func (c *Comment) BeforeUpdate() {
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (c *Comment) AfterLoad(session *xorm.Session) {
func (c *Comment) AfterLoad() {
c.Patch = c.PatchQuoted
if len(c.PatchQuoted) > 0 && c.PatchQuoted[0] == '"' {
unquoted, err := strconv.Unquote(c.PatchQuoted)

View File

@@ -94,7 +94,7 @@ type FindTrackedTimesOptions struct {
}
// toCond will convert each condition into a xorm-Cond
func (opts *FindTrackedTimesOptions) toCond() builder.Cond {
func (opts *FindTrackedTimesOptions) ToConds() builder.Cond {
cond := builder.NewCond().And(builder.Eq{"tracked_time.deleted": false})
if opts.IssueID != 0 {
cond = cond.And(builder.Eq{"issue_id": opts.IssueID})
@@ -117,6 +117,18 @@ func (opts *FindTrackedTimesOptions) toCond() builder.Cond {
return cond
}
func (opts *FindTrackedTimesOptions) ToJoins() []db.JoinFunc {
if opts.RepositoryID > 0 || opts.MilestoneID > 0 {
return []db.JoinFunc{
func(e db.Engine) error {
e.Join("INNER", "issue", "issue.id = tracked_time.issue_id")
return nil
},
}
}
return nil
}
// toSession will convert the given options to a xorm Session by using the conditions from toCond and joining with issue table if required
func (opts *FindTrackedTimesOptions) toSession(e db.Engine) db.Engine {
sess := e
@@ -124,10 +136,10 @@ func (opts *FindTrackedTimesOptions) toSession(e db.Engine) db.Engine {
sess = e.Join("INNER", "issue", "issue.id = tracked_time.issue_id")
}
sess = sess.Where(opts.toCond())
sess = sess.Where(opts.ToConds())
if opts.Page != 0 {
sess = db.SetEnginePagination(sess, opts)
sess = db.SetSessionPagination(sess, opts)
}
return sess
@@ -141,7 +153,7 @@ func GetTrackedTimes(ctx context.Context, options *FindTrackedTimesOptions) (tra
// CountTrackedTimes returns count of tracked times that fit to the given options.
func CountTrackedTimes(ctx context.Context, opts *FindTrackedTimesOptions) (int64, error) {
sess := db.GetEngine(ctx).Where(opts.toCond())
sess := db.GetEngine(ctx).Where(opts.ToConds())
if opts.RepositoryID > 0 || opts.MilestoneID > 0 {
sess = sess.Join("INNER", "issue", "issue.id = tracked_time.issue_id")
}

View File

@@ -111,7 +111,7 @@ type FindRepoArchiversOption struct {
OlderThan time.Duration
}
func (opts FindRepoArchiversOption) toConds() builder.Cond {
func (opts FindRepoArchiversOption) ToConds() builder.Cond {
cond := builder.NewCond()
if opts.OlderThan > 0 {
cond = cond.And(builder.Lt{"created_unix": time.Now().Add(-opts.OlderThan).Unix()})
@@ -119,15 +119,8 @@ func (opts FindRepoArchiversOption) toConds() builder.Cond {
return cond
}
// FindRepoArchives find repo archivers
func FindRepoArchives(ctx context.Context, opts FindRepoArchiversOption) ([]*RepoArchiver, error) {
archivers := make([]*RepoArchiver, 0, opts.PageSize)
start, limit := opts.GetSkipTake()
err := db.GetEngine(ctx).Where(opts.toConds()).
Asc("created_unix").
Limit(limit, start).
Find(&archivers)
return archivers, err
func (opts FindRepoArchiversOption) ToOrders() string {
return "created_unix ASC"
}
// SetArchiveRepoState sets if a repo is archived

View File

@@ -11,8 +11,9 @@ import (
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
)
// Collaboration represent the relation between an individual and a repository.
@@ -37,35 +38,38 @@ type Collaborator struct {
// GetCollaborators returns the collaborators for a repository
func GetCollaborators(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) {
collaborations, err := getCollaborations(ctx, repoID, listOptions)
collaborations, err := db.Find[Collaboration](ctx, FindCollaborationOptions{
ListOptions: listOptions,
RepoID: repoID,
})
if err != nil {
return nil, fmt.Errorf("getCollaborations: %w", err)
return nil, fmt.Errorf("db.Find[Collaboration]: %w", err)
}
collaborators := make([]*Collaborator, 0, len(collaborations))
userIDs := make([]int64, 0, len(collaborations))
for _, c := range collaborations {
user, err := user_model.GetUserByID(ctx, c.UserID)
if err != nil {
if user_model.IsErrUserNotExist(err) {
log.Warn("Inconsistent DB: User: %d is listed as collaborator of %-v but does not exist", c.UserID, repoID)
user = user_model.NewGhostUser()
} else {
return nil, err
}
userIDs = append(userIDs, c.UserID)
}
usersMap := make(map[int64]*user_model.User)
if err := db.GetEngine(ctx).In("id", userIDs).Find(&usersMap); err != nil {
return nil, fmt.Errorf("Find users map by user ids: %w", err)
}
for _, c := range collaborations {
u := usersMap[c.UserID]
if u == nil {
u = user_model.NewGhostUser()
}
collaborators = append(collaborators, &Collaborator{
User: user,
User: u,
Collaboration: c,
})
}
return collaborators, nil
}
// CountCollaborators returns total number of collaborators for a repository
func CountCollaborators(ctx context.Context, repoID int64) (int64, error) {
return db.GetEngine(ctx).Where("repo_id = ? ", repoID).Count(&Collaboration{})
}
// GetCollaboration get collaboration for a repository id with a user id
func GetCollaboration(ctx context.Context, repoID, uid int64) (*Collaboration, error) {
collaboration := &Collaboration{
@@ -84,18 +88,13 @@ func IsCollaborator(ctx context.Context, repoID, userID int64) (bool, error) {
return db.GetEngine(ctx).Get(&Collaboration{RepoID: repoID, UserID: userID})
}
func getCollaborations(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*Collaboration, error) {
if listOptions.Page == 0 {
collaborations := make([]*Collaboration, 0, 8)
return collaborations, db.GetEngine(ctx).Find(&collaborations, &Collaboration{RepoID: repoID})
}
type FindCollaborationOptions struct {
db.ListOptions
RepoID int64
}
e := db.GetEngine(ctx)
e = db.SetEnginePagination(e, &listOptions)
collaborations := make([]*Collaboration, 0, listOptions.PageSize)
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID})
func (opts FindCollaborationOptions) ToConds() builder.Cond {
return builder.And(builder.Eq{"repo_id": opts.RepoID})
}
// ChangeCollaborationAccessMode sets new access mode for the collaboration.

View File

@@ -89,17 +89,23 @@ func TestRepository_CountCollaborators(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
count, err := repo_model.CountCollaborators(db.DefaultContext, repo1.ID)
count, err := db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: repo1.ID,
})
assert.NoError(t, err)
assert.EqualValues(t, 2, count)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
count, err = repo_model.CountCollaborators(db.DefaultContext, repo2.ID)
count, err = db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: repo2.ID,
})
assert.NoError(t, err)
assert.EqualValues(t, 2, count)
// Non-existent repository.
count, err = repo_model.CountCollaborators(db.DefaultContext, unittest.NonexistentID)
count, err = db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: unittest.NonexistentID,
})
assert.NoError(t, err)
assert.EqualValues(t, 0, count)
}

View File

@@ -56,13 +56,16 @@ func GetUserFork(ctx context.Context, repoID, userID int64) (*Repository, error)
// GetForks returns all the forks of the repository
func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions) ([]*Repository, error) {
sess := db.GetEngine(ctx)
var forks []*Repository
if listOptions.Page == 0 {
forks := make([]*Repository, 0, repo.NumForks)
return forks, db.GetEngine(ctx).Find(&forks, &Repository{ForkID: repo.ID})
forks = make([]*Repository, 0, repo.NumForks)
} else {
forks = make([]*Repository, 0, listOptions.PageSize)
sess = db.SetSessionPagination(sess, &listOptions)
}
sess := db.GetPaginatedSession(&listOptions)
forks := make([]*Repository, 0, listOptions.PageSize)
return forks, sess.Find(&forks, &Repository{ForkID: repo.ID})
}

View File

@@ -225,6 +225,7 @@ func GetReleaseForRepoByID(ctx context.Context, repoID, id int64) (*Release, err
// FindReleasesOptions describes the conditions to Find releases
type FindReleasesOptions struct {
db.ListOptions
RepoID int64
IncludeDrafts bool
IncludeTags bool
IsPreRelease util.OptionalBool
@@ -233,9 +234,8 @@ type FindReleasesOptions struct {
HasSha1 util.OptionalBool // useful to find draft releases which are created with existing tags
}
func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
cond := builder.NewCond()
cond = cond.And(builder.Eq{"repo_id": repoID})
func (opts FindReleasesOptions) ToConds() builder.Cond {
var cond builder.Cond = builder.Eq{"repo_id": opts.RepoID}
if !opts.IncludeDrafts {
cond = cond.And(builder.Eq{"is_draft": false})
@@ -262,18 +262,8 @@ func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
return cond
}
// GetReleasesByRepoID returns a list of releases of repository.
func GetReleasesByRepoID(ctx context.Context, repoID int64, opts FindReleasesOptions) ([]*Release, error) {
sess := db.GetEngine(ctx).
Desc("created_unix", "id").
Where(opts.toConds(repoID))
if opts.PageSize != 0 {
sess = db.SetSessionPagination(sess, &opts.ListOptions)
}
rels := make([]*Release, 0, opts.PageSize)
return rels, sess.Find(&rels)
func (opts FindReleasesOptions) ToOrders() string {
return "created_unix DESC, id DESC"
}
// GetTagNamesByRepoID returns a list of release tag names of repository.
@@ -286,23 +276,19 @@ func GetTagNamesByRepoID(ctx context.Context, repoID int64) ([]string, error) {
IncludeDrafts: true,
IncludeTags: true,
HasSha1: util.OptionalBoolTrue,
RepoID: repoID,
}
tags := make([]string, 0)
sess := db.GetEngine(ctx).
Table("release").
Desc("created_unix", "id").
Where(opts.toConds(repoID)).
Where(opts.ToConds()).
Cols("tag_name")
return tags, sess.Find(&tags)
}
// CountReleasesByRepoID returns a number of releases matching FindReleaseOptions and RepoID.
func CountReleasesByRepoID(ctx context.Context, repoID int64, opts FindReleasesOptions) (int64, error) {
return db.GetEngine(ctx).Where(opts.toConds(repoID)).Count(new(Release))
}
// GetLatestReleaseByRepoID returns the latest release for a repository
func GetLatestReleaseByRepoID(ctx context.Context, repoID int64) (*Release, error) {
cond := builder.NewCond().
@@ -325,20 +311,6 @@ func GetLatestReleaseByRepoID(ctx context.Context, repoID int64) (*Release, erro
return rel, nil
}
// GetReleasesByRepoIDAndNames returns a list of releases of repository according repoID and tagNames.
func GetReleasesByRepoIDAndNames(ctx context.Context, repoID int64, tagNames []string) (rels []*Release, err error) {
err = db.GetEngine(ctx).
In("tag_name", tagNames).
Desc("created_unix").
Find(&rels, Release{RepoID: repoID})
return rels, err
}
// GetReleaseCountByRepoID returns the count of releases of repository
func GetReleaseCountByRepoID(ctx context.Context, repoID int64, opts FindReleasesOptions) (int64, error) {
return db.GetEngine(ctx).Where(opts.toConds(repoID)).Count(&Release{})
}
type releaseMetaSearch struct {
ID []int64
Rel []*Release