diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/asymkey/gpg_key.go | 55 | ||||
-rw-r--r-- | models/asymkey/gpg_key_commit_verification.go | 23 | ||||
-rw-r--r-- | models/asymkey/gpg_key_list.go | 38 | ||||
-rw-r--r-- | models/asymkey/ssh_key.go | 4 | ||||
-rw-r--r-- | models/asymkey/ssh_key_principals.go | 23 | ||||
-rw-r--r-- | models/auth/webauthn.go | 3 | ||||
-rw-r--r-- | models/db/list.go | 61 | ||||
-rw-r--r-- | models/db/paginator/paginator_test.go | 3 | ||||
-rw-r--r-- | models/issues/comment.go | 3 | ||||
-rw-r--r-- | models/issues/tracked_time.go | 20 | ||||
-rw-r--r-- | models/repo/archiver.go | 13 | ||||
-rw-r--r-- | models/repo/collaboration.go | 55 | ||||
-rw-r--r-- | models/repo/collaboration_test.go | 12 | ||||
-rw-r--r-- | models/repo/fork.go | 11 | ||||
-rw-r--r-- | models/repo/release.go | 42 |
15 files changed, 185 insertions, 181 deletions
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}) - } - - e := db.GetEngine(ctx) - - e = db.SetEnginePagination(e, &listOptions) +type FindCollaborationOptions struct { + db.ListOptions + RepoID int64 +} - 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 |