From 70c4aad8e1cbc46b049b015dcd6f2e5be5a69e72 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 15 Jan 2024 10:19:25 +0800 Subject: [PATCH] Move more functions to db.Find (#28419) Following #28220 This PR move more functions to use `db.Find`. --------- Co-authored-by: delvh --- cmd/admin.go | 4 +- models/asymkey/gpg_key.go | 55 +++++++---------- models/asymkey/gpg_key_commit_verification.go | 23 ++++++- models/asymkey/gpg_key_list.go | 38 ++++++++++++ models/asymkey/ssh_key.go | 4 +- models/asymkey/ssh_key_principals.go | 23 ------- models/auth/webauthn.go | 3 +- models/db/list.go | 61 ++++++++++--------- models/db/paginator/paginator_test.go | 3 - models/issues/comment.go | 3 +- models/issues/tracked_time.go | 20 ++++-- models/repo/archiver.go | 13 +--- models/repo/collaboration.go | 55 ++++++++--------- models/repo/collaboration_test.go | 12 +++- models/repo/fork.go | 11 ++-- models/repo/release.go | 42 +++---------- modules/context/repo.go | 6 +- modules/repository/repo.go | 3 +- routers/api/v1/repo/collaborators.go | 5 +- routers/api/v1/repo/pull.go | 26 +++----- routers/api/v1/repo/release.go | 6 +- routers/api/v1/user/gpg_key.go | 27 +++++--- routers/web/feed/release.go | 4 +- routers/web/repo/release.go | 6 +- routers/web/repo/release_test.go | 4 +- routers/web/repo/repo.go | 5 +- routers/web/user/home.go | 5 +- routers/web/user/setting/keys.go | 15 ++++- services/asymkey/sign.go | 20 ++++-- services/convert/repository.go | 7 ++- services/migrations/gitea_uploader_test.go | 6 +- services/repository/archiver/archiver.go | 2 +- services/repository/push.go | 7 ++- services/user/delete.go | 4 +- tests/integration/mirror_pull_test.go | 12 ++-- tests/integration/repo_tag_test.go | 3 +- 36 files changed, 305 insertions(+), 238 deletions(-) create mode 100644 models/asymkey/gpg_key_list.go diff --git a/cmd/admin.go b/cmd/admin.go index b5903cd4fd..74bfa5a6c6 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -157,10 +157,10 @@ func runRepoSyncReleases(_ *cli.Context) error { } func getReleaseCount(ctx context.Context, id int64) (int64, error) { - return repo_model.GetReleaseCountByRepoID( + return db.Count[repo_model.Release]( ctx, - id, repo_model.FindReleasesOptions{ + RepoID: id, IncludeTags: true, }, ) diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index 421f24d4de..5236b2d450 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -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) diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index 8ac4364404..83fbab5d36 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -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{ diff --git a/models/asymkey/gpg_key_list.go b/models/asymkey/gpg_key_list.go new file mode 100644 index 0000000000..89548e495e --- /dev/null +++ b/models/asymkey/gpg_key_list.go @@ -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 +} diff --git a/models/asymkey/ssh_key.go b/models/asymkey/ssh_key.go index 116d6351b0..a409d8e841 100644 --- a/models/asymkey/ssh_key.go +++ b/models/asymkey/ssh_key.go @@ -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}) diff --git a/models/asymkey/ssh_key_principals.go b/models/asymkey/ssh_key_principals.go index 92789e26f8..4e7dee2c91 100644 --- a/models/asymkey/ssh_key_principals.go +++ b/models/asymkey/ssh_key_principals.go @@ -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) -} diff --git a/models/auth/webauthn.go b/models/auth/webauthn.go index d12713bd37..a65d2e1e34 100644 --- a/models/auth/webauthn.go +++ b/models/auth/webauthn.go @@ -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) } diff --git a/models/db/list.go b/models/db/list.go index b2f932e89b..4aeaf3e084 100644 --- a/models/db/list.go +++ b/models/db/list.go @@ -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 diff --git a/models/db/paginator/paginator_test.go b/models/db/paginator/paginator_test.go index a1117fc7a4..20602212d9 100644 --- a/models/db/paginator/paginator_test.go +++ b/models/db/paginator/paginator_test.go @@ -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) } } diff --git a/models/issues/comment.go b/models/issues/comment.go index 7b068d4983..a1698d4824 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -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) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index 795bddeb34..884a445d26 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -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") } diff --git a/models/repo/archiver.go b/models/repo/archiver.go index 1fccb29499..d9520c670c 100644 --- a/models/repo/archiver.go +++ b/models/repo/archiver.go @@ -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 diff --git a/models/repo/collaboration.go b/models/repo/collaboration.go index 2018ae2a7d..7288082614 100644 --- a/models/repo/collaboration.go +++ b/models/repo/collaboration.go @@ -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. diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 38114c307f..21a99dd557 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -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) } diff --git a/models/repo/fork.go b/models/repo/fork.go index 6be6ebc3f5..07cd31c269 100644 --- a/models/repo/fork.go +++ b/models/repo/fork.go @@ -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}) } diff --git a/models/repo/release.go b/models/repo/release.go index 4514a034ed..72a73f8e80 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -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 diff --git a/modules/context/repo.go b/modules/context/repo.go index 882a406731..8d82be1990 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -536,18 +536,20 @@ func RepoAssignment(ctx *Context) context.CancelFunc { ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL } - ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ + ctx.Data["NumTags"], err = db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{ IncludeDrafts: true, IncludeTags: true, HasSha1: util.OptionalBoolTrue, // only draft releases which are created with existing tags + RepoID: ctx.Repo.Repository.ID, }) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) return nil } - ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ + ctx.Data["NumReleases"], err = db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{ // only show draft releases for users who can write, read-only users shouldn't see draft releases. IncludeDrafts: ctx.Repo.CanWrite(unit_model.TypeReleases), + RepoID: ctx.Repo.Repository.ID, }) if err != nil { ctx.ServerError("GetReleaseCountByRepoID", err) diff --git a/modules/repository/repo.go b/modules/repository/repo.go index a9a2773501..33363e4689 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -299,10 +299,11 @@ func SyncReleasesWithTags(ctx context.Context, repo *repo_model.Repository, gitR IncludeDrafts: true, IncludeTags: true, ListOptions: db.ListOptions{PageSize: 50}, + RepoID: repo.ID, } for page := 1; ; page++ { opts.Page = page - rels, err := repo_model.GetReleasesByRepoID(gitRepo.Ctx, repo.ID, opts) + rels, err := db.Find[repo_model.Release](gitRepo.Ctx, opts) if err != nil { return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) } diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index 2538bcdbc6..a222e50a5e 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -8,6 +8,7 @@ import ( "errors" "net/http" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -53,7 +54,9 @@ func ListCollaborators(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - count, err := repo_model.CountCollaborators(ctx, ctx.Repo.Repository.ID) + count, err := db.Count[repo_model.Collaboration](ctx, repo_model.FindCollaborationOptions{ + RepoID: ctx.Repo.Repository.ID, + }) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index d6b9dddd9d..34129ad595 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1329,17 +1329,16 @@ func GetPullRequestCommits(ctx *context.APIContext) { userCache := make(map[string]*user_model.User) - start, end := listOptions.GetStartEnd() + start, limit := listOptions.GetSkipTake() - if end > totalNumberOfCommits { - end = totalNumberOfCommits - } + limit = min(limit, totalNumberOfCommits-start) + limit = max(limit, 0) verification := ctx.FormString("verification") == "" || ctx.FormBool("verification") files := ctx.FormString("files") == "" || ctx.FormBool("files") - apiCommits := make([]*api.Commit, 0, end-start) - for i := start; i < end; i++ { + apiCommits := make([]*api.Commit, 0, limit) + for i := start; i < start+limit; i++ { apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, baseGitRepo, commits[i], userCache, convert.ToCommitOptions{ Stat: true, @@ -1477,19 +1476,14 @@ func GetPullRequestFiles(ctx *context.APIContext) { totalNumberOfFiles := diff.NumFiles totalNumberOfPages := int(math.Ceil(float64(totalNumberOfFiles) / float64(listOptions.PageSize))) - start, end := listOptions.GetStartEnd() + start, limit := listOptions.GetSkipTake() - if end > totalNumberOfFiles { - end = totalNumberOfFiles - } + limit = min(limit, totalNumberOfFiles-start) - lenFiles := end - start - if lenFiles < 0 { - lenFiles = 0 - } + limit = max(limit, 0) - apiFiles := make([]*api.ChangedFile, 0, lenFiles) - for i := start; i < end; i++ { + apiFiles := make([]*api.ChangedFile, 0, limit) + for i := start; i < start+limit; i++ { apiFiles = append(apiFiles, convert.ToChangedFile(diff.Files[i], pr.HeadRepo, endCommitID)) } diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index b1d3b5f457..a41c5ba7d8 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -7,6 +7,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -154,9 +155,10 @@ func ListReleases(ctx *context.APIContext) { IncludeTags: false, IsDraft: ctx.FormOptionalBool("draft"), IsPreRelease: ctx.FormOptionalBool("pre-release"), + RepoID: ctx.Repo.Repository.ID, } - releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts) + releases, err := db.Find[repo_model.Release](ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) return @@ -170,7 +172,7 @@ func ListReleases(ctx *context.APIContext) { rels[i] = convert.ToAPIRelease(ctx, ctx.Repo.Repository, release) } - filteredCount, err := repo_model.CountReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts) + filteredCount, err := db.Count[repo_model.Release](ctx, opts) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index 4f8bcaca3e..234da5dfdc 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -18,23 +18,25 @@ import ( ) func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) { - keys, err := asymkey_model.ListGPGKeys(ctx, uid, listOptions) + keys, total, err := db.FindAndCount[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + ListOptions: listOptions, + OwnerID: uid, + }) if err != nil { ctx.Error(http.StatusInternalServerError, "ListGPGKeys", err) return } + if err := asymkey_model.GPGKeyList(keys).LoadSubKeys(ctx); err != nil { + ctx.Error(http.StatusInternalServerError, "ListGPGKeys", err) + return + } + apiKeys := make([]*api.GPGKey, len(keys)) for i := range keys { apiKeys[i] = convert.ToGPGKey(keys[i]) } - total, err := asymkey_model.CountUserGPGKeys(ctx, uid) - if err != nil { - ctx.InternalServerError(err) - return - } - ctx.SetTotalCountHeader(total) ctx.JSON(http.StatusOK, &apiKeys) } @@ -121,6 +123,10 @@ func GetGPGKey(ctx *context.APIContext) { } return } + if err := key.LoadSubKeys(ctx); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadSubKeys", err) + return + } ctx.JSON(http.StatusOK, convert.ToGPGKey(key)) } @@ -198,7 +204,10 @@ func VerifyUserGPGKey(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "VerifyUserGPGKey", err) } - key, err := asymkey_model.GetGPGKeysByKeyID(ctx, form.KeyID) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + KeyID: form.KeyID, + IncludeSubKeys: true, + }) if err != nil { if asymkey_model.IsErrGPGKeyNotExist(err) { ctx.NotFound() @@ -207,7 +216,7 @@ func VerifyUserGPGKey(ctx *context.APIContext) { } return } - ctx.JSON(http.StatusOK, convert.ToGPGKey(key[0])) + ctx.JSON(http.StatusOK, convert.ToGPGKey(keys[0])) } // swagger:parameters userCurrentPostGPGKey diff --git a/routers/web/feed/release.go b/routers/web/feed/release.go index fbfa11c63e..57b0c92766 100644 --- a/routers/web/feed/release.go +++ b/routers/web/feed/release.go @@ -6,6 +6,7 @@ package feed import ( "time" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" @@ -14,8 +15,9 @@ import ( // shows tags and/or releases on the repo as RSS / Atom feed func ShowReleaseFeed(ctx *context.Context, repo *repo_model.Repository, isReleasesOnly bool, formatType string) { - releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ + releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ IncludeTags: !isReleasesOnly, + RepoID: ctx.Repo.Repository.ID, }) if err != nil { ctx.ServerError("GetReleasesByRepoID", err) diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 595d599fe1..86cb93e49b 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -95,9 +95,10 @@ func Releases(ctx *context.Context) { ListOptions: listOptions, // only show draft releases for users who can write, read-only users shouldn't see draft releases. IncludeDrafts: writeAccess, + RepoID: ctx.Repo.Repository.ID, } - releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts) + releases, err := db.Find[repo_model.Release](ctx, opts) if err != nil { ctx.ServerError("GetReleasesByRepoID", err) return @@ -194,9 +195,10 @@ func TagsList(ctx *context.Context) { IncludeDrafts: true, IncludeTags: true, HasSha1: util.OptionalBoolTrue, + RepoID: ctx.Repo.Repository.ID, } - releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, opts) + releases, err := db.Find[repo_model.Release](ctx, opts) if err != nil { ctx.ServerError("GetReleasesByRepoID", err) return diff --git a/routers/web/repo/release_test.go b/routers/web/repo/release_test.go index a5a923d464..c4a2c1904e 100644 --- a/routers/web/repo/release_test.go +++ b/routers/web/repo/release_test.go @@ -6,6 +6,7 @@ package repo import ( "testing" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" @@ -74,8 +75,9 @@ func TestCalReleaseNumCommitsBehind(t *testing.T) { contexttest.LoadGitRepo(t, ctx) t.Cleanup(func() { ctx.Repo.GitRepo.Close() }) - releases, err := repo_model.GetReleasesByRepoID(ctx, ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ + releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ IncludeDrafts: ctx.Repo.CanWrite(unit.TypeReleases), + RepoID: ctx.Repo.Repository.ID, }) assert.NoError(t, err) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index b16e283836..cd5eac057e 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -379,7 +379,10 @@ func RedirectDownload(ctx *context.Context) { ) tagNames := []string{vTag} curRepo := ctx.Repo.Repository - releases, err := repo_model.GetReleasesByRepoIDAndNames(ctx, curRepo.ID, tagNames) + releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ + RepoID: curRepo.ID, + TagNames: tagNames, + }) if err != nil { ctx.ServerError("RedirectDownload", err) return diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 204d4adbd4..debbb9753c 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -663,7 +663,10 @@ func ShowSSHKeys(ctx *context.Context) { // ShowGPGKeys output all the public GPG keys of user by uid func ShowGPGKeys(ctx *context.Context) { - keys, err := asymkey_model.ListGPGKeys(ctx, ctx.ContextUser.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + ListOptions: db.ListOptionsAll, + OwnerID: ctx.ContextUser.ID, + }) if err != nil { ctx.ServerError("ListGPGKeys", err) return diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 0dfb506fa9..16410d06ff 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -277,18 +277,29 @@ func loadKeysData(ctx *context.Context) { } ctx.Data["ExternalKeys"] = externalKeys - gpgkeys, err := asymkey_model.ListGPGKeys(ctx, ctx.Doer.ID, db.ListOptions{}) + gpgkeys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + ListOptions: db.ListOptionsAll, + OwnerID: ctx.Doer.ID, + }) if err != nil { ctx.ServerError("ListGPGKeys", err) return } + if err := asymkey_model.GPGKeyList(gpgkeys).LoadSubKeys(ctx); err != nil { + ctx.ServerError("LoadSubKeys", err) + return + } ctx.Data["GPGKeys"] = gpgkeys tokenToSign := asymkey_model.VerificationToken(ctx.Doer, 1) // generate a new aes cipher using the csrfToken ctx.Data["TokenToSign"] = tokenToSign - principals, err := asymkey_model.ListPrincipalKeys(ctx, ctx.Doer.ID, db.ListOptions{}) + principals, err := db.Find[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{ + ListOptions: db.ListOptionsAll, + OwnerID: ctx.Doer.ID, + KeyTypes: []asymkey_model.KeyType{asymkey_model.KeyTypePrincipal}, + }) if err != nil { ctx.ServerError("ListPrincipalKeys", err) return diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go index 1598f32165..0c4aac8156 100644 --- a/services/asymkey/sign.go +++ b/services/asymkey/sign.go @@ -143,7 +143,10 @@ Loop: case always: break Loop case pubkey: - keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: u.ID, + IncludeSubKeys: true, + }) if err != nil { return false, "", nil, err } @@ -179,7 +182,10 @@ Loop: case always: break Loop case pubkey: - keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: u.ID, + IncludeSubKeys: true, + }) if err != nil { return false, "", nil, err } @@ -232,7 +238,10 @@ Loop: case always: break Loop case pubkey: - keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: u.ID, + IncludeSubKeys: true, + }) if err != nil { return false, "", nil, err } @@ -294,7 +303,10 @@ Loop: case always: break Loop case pubkey: - keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: u.ID, + IncludeSubKeys: true, + }) if err != nil { return false, "", nil, err } diff --git a/services/convert/repository.go b/services/convert/repository.go index 71038cd062..c16180c0af 100644 --- a/services/convert/repository.go +++ b/services/convert/repository.go @@ -8,6 +8,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -133,7 +134,11 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR return nil } - numReleases, _ := repo_model.GetReleaseCountByRepoID(ctx, repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false}) + numReleases, _ := db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{ + IncludeDrafts: false, + IncludeTags: false, + RepoID: repo.ID, + }) mirrorInterval := "" var mirrorUpdated time.Time diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 3dec3a26fc..4ec0361dfb 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -83,22 +83,24 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, labels, 12) - releases, err := repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{ + releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, }, IncludeTags: true, + RepoID: repo.ID, }) assert.NoError(t, err) assert.Len(t, releases, 8) - releases, err = repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{ + releases, err = db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, }, IncludeTags: false, + RepoID: repo.ID, }) assert.NoError(t, err) assert.Len(t, releases, 1) diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index b73d0eed48..c2ad4d484a 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -324,7 +324,7 @@ func DeleteOldRepositoryArchives(ctx context.Context, olderThan time.Duration) e log.Trace("Doing: ArchiveCleanup") for { - archivers, err := repo_model.FindRepoArchives(ctx, repo_model.FindRepoArchiversOption{ + archivers, err := db.Find[repo_model.RepoArchiver](ctx, repo_model.FindRepoArchiversOption{ ListOptions: db.ListOptions{ PageSize: 100, Page: 1, diff --git a/services/repository/push.go b/services/repository/push.go index 3bc7a78cb9..e86eebde81 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -327,9 +327,12 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo lowerTags = append(lowerTags, strings.ToLower(tag)) } - releases, err := repo_model.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags) + releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ + RepoID: repo.ID, + TagNames: lowerTags, + }) if err != nil { - return fmt.Errorf("GetReleasesByRepoIDAndNames: %w", err) + return fmt.Errorf("db.Find[repo_model.Release]: %w", err) } relMap := make(map[string]*repo_model.Release) for _, rel := range releases { diff --git a/services/user/delete.go b/services/user/delete.go index 748f5c2d1e..0e9c866171 100644 --- a/services/user/delete.go +++ b/services/user/delete.go @@ -159,7 +159,9 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) // ***** END: PublicKey ***** // ***** START: GPGPublicKey ***** - keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{}) + keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: u.ID, + }) if err != nil { return fmt.Errorf("ListGPGKeys: %w", err) } diff --git a/tests/integration/mirror_pull_test.go b/tests/integration/mirror_pull_test.go index c02e16bfc0..1e0edd9a2d 100644 --- a/tests/integration/mirror_pull_test.go +++ b/tests/integration/mirror_pull_test.go @@ -58,8 +58,12 @@ func TestMirrorPull(t *testing.T) { assert.NoError(t, err) defer gitRepo.Close() - findOptions := repo_model.FindReleasesOptions{IncludeDrafts: true, IncludeTags: true} - initCount, err := repo_model.GetReleaseCountByRepoID(db.DefaultContext, mirror.ID, findOptions) + findOptions := repo_model.FindReleasesOptions{ + IncludeDrafts: true, + IncludeTags: true, + RepoID: mirror.ID, + } + initCount, err := db.Count[repo_model.Release](db.DefaultContext, findOptions) assert.NoError(t, err) assert.NoError(t, release_service.CreateRelease(gitRepo, &repo_model.Release{ @@ -82,7 +86,7 @@ func TestMirrorPull(t *testing.T) { ok := mirror_service.SyncPullMirror(ctx, mirror.ID) assert.True(t, ok) - count, err := repo_model.GetReleaseCountByRepoID(db.DefaultContext, mirror.ID, findOptions) + count, err := db.Count[repo_model.Release](db.DefaultContext, findOptions) assert.NoError(t, err) assert.EqualValues(t, initCount+1, count) @@ -93,7 +97,7 @@ func TestMirrorPull(t *testing.T) { ok = mirror_service.SyncPullMirror(ctx, mirror.ID) assert.True(t, ok) - count, err = repo_model.GetReleaseCountByRepoID(db.DefaultContext, mirror.ID, findOptions) + count, err = db.Count[repo_model.Release](db.DefaultContext, findOptions) assert.NoError(t, err) assert.EqualValues(t, initCount, count) } diff --git a/tests/integration/repo_tag_test.go b/tests/integration/repo_tag_test.go index e588097994..7e77906473 100644 --- a/tests/integration/repo_tag_test.go +++ b/tests/integration/repo_tag_test.go @@ -74,9 +74,10 @@ func TestCreateNewTagProtected(t *testing.T) { }) // Cleanup - releases, err := repo_model.GetReleasesByRepoID(db.DefaultContext, repo.ID, repo_model.FindReleasesOptions{ + releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ IncludeTags: true, TagNames: []string{"v-1", "v-1.1"}, + RepoID: repo.ID, }) assert.NoError(t, err)