Skip to content

Commit 23179ec

Browse files
lunnydelvh
authored andcommitted
Move more functions to db.Find (go-gitea#28419)
Following go-gitea#28220 This PR move more functions to use `db.Find`. --------- Co-authored-by: delvh <[email protected]>
1 parent 3bd49ca commit 23179ec

36 files changed

+305
-238
lines changed

cmd/admin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ func runRepoSyncReleases(_ *cli.Context) error {
157157
}
158158

159159
func getReleaseCount(ctx context.Context, id int64) (int64, error) {
160-
return repo_model.GetReleaseCountByRepoID(
160+
return db.Count[repo_model.Release](
161161
ctx,
162-
id,
163162
repo_model.FindReleasesOptions{
163+
RepoID: id,
164164
IncludeTags: true,
165165
},
166166
)

models/asymkey/gpg_key.go

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,13 @@ import (
1111

1212
"code.gitea.io/gitea/models/db"
1313
user_model "code.gitea.io/gitea/models/user"
14-
"code.gitea.io/gitea/modules/log"
1514
"code.gitea.io/gitea/modules/timeutil"
1615

1716
"github.com/keybase/go-crypto/openpgp"
1817
"github.com/keybase/go-crypto/openpgp/packet"
19-
"xorm.io/xorm"
18+
"xorm.io/builder"
2019
)
2120

22-
// __________________ ________ ____ __.
23-
// / _____/\______ \/ _____/ | |/ _|____ ___.__.
24-
// / \ ___ | ___/ \ ___ | <_/ __ < | |
25-
// \ \_\ \| | \ \_\ \ | | \ ___/\___ |
26-
// \______ /|____| \______ / |____|__ \___ > ____|
27-
// \/ \/ \/ \/\/
28-
2921
// GPGKey represents a GPG key.
3022
type GPGKey struct {
3123
ID int64 `xorm:"pk autoincr"`
@@ -54,12 +46,11 @@ func (key *GPGKey) BeforeInsert() {
5446
key.AddedUnix = timeutil.TimeStampNow()
5547
}
5648

57-
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
58-
func (key *GPGKey) AfterLoad(session *xorm.Session) {
59-
err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey)
60-
if err != nil {
61-
log.Error("Find Sub GPGkeys[%s]: %v", key.KeyID, err)
49+
func (key *GPGKey) LoadSubKeys(ctx context.Context) error {
50+
if err := db.GetEngine(ctx).Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey); err != nil {
51+
return fmt.Errorf("find Sub GPGkeys[%s]: %v", key.KeyID, err)
6252
}
53+
return nil
6354
}
6455

6556
// PaddedKeyID show KeyID padded to 16 characters
@@ -76,20 +67,26 @@ func PaddedKeyID(keyID string) string {
7667
return zeros[0:16-len(keyID)] + keyID
7768
}
7869

79-
// ListGPGKeys returns a list of public keys belongs to given user.
80-
func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
81-
sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
82-
if listOptions.Page != 0 {
83-
sess = db.SetSessionPagination(sess, &listOptions)
84-
}
85-
86-
keys := make([]*GPGKey, 0, 2)
87-
return keys, sess.Find(&keys)
70+
type FindGPGKeyOptions struct {
71+
db.ListOptions
72+
OwnerID int64
73+
KeyID string
74+
IncludeSubKeys bool
8875
}
8976

90-
// CountUserGPGKeys return number of gpg keys a user own
91-
func CountUserGPGKeys(ctx context.Context, userID int64) (int64, error) {
92-
return db.GetEngine(ctx).Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{})
77+
func (opts FindGPGKeyOptions) ToConds() builder.Cond {
78+
cond := builder.NewCond()
79+
if !opts.IncludeSubKeys {
80+
cond = cond.And(builder.Eq{"primary_key_id": ""})
81+
}
82+
83+
if opts.OwnerID > 0 {
84+
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
85+
}
86+
if opts.KeyID != "" {
87+
cond = cond.And(builder.Eq{"key_id": opts.KeyID})
88+
}
89+
return cond
9390
}
9491

9592
func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, error) {
@@ -103,12 +100,6 @@ func GetGPGKeyForUserByID(ctx context.Context, ownerID, keyID int64) (*GPGKey, e
103100
return key, nil
104101
}
105102

106-
// GetGPGKeysByKeyID returns public key by given ID.
107-
func GetGPGKeysByKeyID(ctx context.Context, keyID string) ([]*GPGKey, error) {
108-
keys := make([]*GPGKey, 0, 1)
109-
return keys, db.GetEngine(ctx).Where("key_id=?", keyID).Find(&keys)
110-
}
111-
112103
// GPGKeyToEntity retrieve the imported key and the traducted entity
113104
func GPGKeyToEntity(ctx context.Context, k *GPGKey) (*openpgp.Entity, error) {
114105
impKey, err := GetGPGImportByKeyID(ctx, k.KeyID)

models/asymkey/gpg_key_commit_verification.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
166166

167167
// Now try to associate the signature with the committer, if present
168168
if committer.ID != 0 {
169-
keys, err := ListGPGKeys(ctx, committer.ID, db.ListOptions{})
169+
keys, err := db.Find[GPGKey](ctx, FindGPGKeyOptions{
170+
OwnerID: committer.ID,
171+
})
170172
if err != nil { // Skipping failed to get gpg keys of user
171173
log.Error("ListGPGKeys: %v", err)
172174
return &CommitVerification{
@@ -176,6 +178,15 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *CommitVerific
176178
}
177179
}
178180

181+
if err := GPGKeyList(keys).LoadSubKeys(ctx); err != nil {
182+
log.Error("LoadSubKeys: %v", err)
183+
return &CommitVerification{
184+
CommittingUser: committer,
185+
Verified: false,
186+
Reason: "gpg.error.failed_retrieval_gpg_keys",
187+
}
188+
}
189+
179190
committerEmailAddresses, _ := user_model.GetEmailAddresses(ctx, committer.ID)
180191
activated := false
181192
for _, e := range committerEmailAddresses {
@@ -392,7 +403,10 @@ func hashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
392403
if keyID == "" {
393404
return nil
394405
}
395-
keys, err := GetGPGKeysByKeyID(ctx, keyID)
406+
keys, err := db.Find[GPGKey](ctx, FindGPGKeyOptions{
407+
KeyID: keyID,
408+
IncludeSubKeys: true,
409+
})
396410
if err != nil {
397411
log.Error("GetGPGKeysByKeyID: %v", err)
398412
return &CommitVerification{
@@ -407,7 +421,10 @@ func hashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
407421
for _, key := range keys {
408422
var primaryKeys []*GPGKey
409423
if key.PrimaryKeyID != "" {
410-
primaryKeys, err = GetGPGKeysByKeyID(ctx, key.PrimaryKeyID)
424+
primaryKeys, err = db.Find[GPGKey](ctx, FindGPGKeyOptions{
425+
KeyID: key.PrimaryKeyID,
426+
IncludeSubKeys: true,
427+
})
411428
if err != nil {
412429
log.Error("GetGPGKeysByKeyID: %v", err)
413430
return &CommitVerification{

models/asymkey/gpg_key_list.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package asymkey
5+
6+
import (
7+
"context"
8+
9+
"code.gitea.io/gitea/models/db"
10+
)
11+
12+
type GPGKeyList []*GPGKey
13+
14+
func (keys GPGKeyList) keyIDs() []string {
15+
ids := make([]string, len(keys))
16+
for i, key := range keys {
17+
ids[i] = key.KeyID
18+
}
19+
return ids
20+
}
21+
22+
func (keys GPGKeyList) LoadSubKeys(ctx context.Context) error {
23+
subKeys := make([]*GPGKey, 0, len(keys))
24+
if err := db.GetEngine(ctx).In("primary_key_id", keys.keyIDs()).Find(&subKeys); err != nil {
25+
return err
26+
}
27+
subKeysMap := make(map[string][]*GPGKey, len(subKeys))
28+
for _, key := range subKeys {
29+
subKeysMap[key.PrimaryKeyID] = append(subKeysMap[key.PrimaryKeyID], key)
30+
}
31+
32+
for _, key := range keys {
33+
if subKeys, ok := subKeysMap[key.KeyID]; ok {
34+
key.SubsKey = subKeys
35+
}
36+
}
37+
return nil
38+
}

models/asymkey/ssh_key.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ func (opts FindPublicKeyOptions) ToConds() builder.Cond {
197197
cond = cond.And(builder.Eq{"fingerprint": opts.Fingerprint})
198198
}
199199
if len(opts.KeyTypes) > 0 {
200-
cond = cond.And(builder.In("type", opts.KeyTypes))
200+
cond = cond.And(builder.In("`type`", opts.KeyTypes))
201201
}
202202
if opts.NotKeytype > 0 {
203-
cond = cond.And(builder.Neq{"type": opts.NotKeytype})
203+
cond = cond.And(builder.Neq{"`type`": opts.NotKeytype})
204204
}
205205
if opts.LoginSourceID > 0 {
206206
cond = cond.And(builder.Eq{"login_source_id": opts.LoginSourceID})

models/asymkey/ssh_key_principals.go

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ import (
1515
"code.gitea.io/gitea/modules/util"
1616
)
1717

18-
// __________ .__ .__ .__
19-
// \______ _______|__| ____ ____ |_____________ | | ______
20-
// | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
21-
// | | | | \| | | \ \___| | |_> / __ \| |__\___ \
22-
// |____| |__| |__|___| /\___ |__| __(____ |____/____ >
23-
// \/ \/ |__| \/ \/
24-
//
25-
// This file contains functions related to principals
26-
2718
// AddPrincipalKey adds new principal to database and authorized_principals file.
2819
func AddPrincipalKey(ctx context.Context, ownerID int64, content string, authSourceID int64) (*PublicKey, error) {
2920
dbCtx, committer, err := db.TxContext(ctx)
@@ -103,17 +94,3 @@ func CheckPrincipalKeyString(ctx context.Context, user *user_model.User, content
10394

10495
return "", fmt.Errorf("didn't match allowed principals: %s", setting.SSH.AuthorizedPrincipalsAllow)
10596
}
106-
107-
// ListPrincipalKeys returns a list of principals belongs to given user.
108-
func ListPrincipalKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*PublicKey, error) {
109-
sess := db.GetEngine(ctx).Where("owner_id = ? AND type = ?", uid, KeyTypePrincipal)
110-
if listOptions.Page != 0 {
111-
sess = db.SetSessionPagination(sess, &listOptions)
112-
113-
keys := make([]*PublicKey, 0, listOptions.PageSize)
114-
return keys, sess.Find(&keys)
115-
}
116-
117-
keys := make([]*PublicKey, 0, 5)
118-
return keys, sess.Find(&keys)
119-
}

models/auth/webauthn.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"code.gitea.io/gitea/modules/util"
1414

1515
"github.com/go-webauthn/webauthn/webauthn"
16-
"xorm.io/xorm"
1716
)
1817

1918
// ErrWebAuthnCredentialNotExist represents a "ErrWebAuthnCRedentialNotExist" kind of error.
@@ -83,7 +82,7 @@ func (cred *WebAuthnCredential) BeforeUpdate() {
8382
}
8483

8584
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
86-
func (cred *WebAuthnCredential) AfterLoad(session *xorm.Session) {
85+
func (cred *WebAuthnCredential) AfterLoad() {
8786
cred.LowerName = strings.ToLower(cred.Name)
8887
}
8988

models/db/list.go

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,16 @@ const (
2121
// Paginator is the base for different ListOptions types
2222
type Paginator interface {
2323
GetSkipTake() (skip, take int)
24-
GetStartEnd() (start, end int)
2524
IsListAll() bool
2625
}
2726

28-
// GetPaginatedSession creates a paginated database session
29-
func GetPaginatedSession(p Paginator) *xorm.Session {
30-
skip, take := p.GetSkipTake()
31-
32-
return x.Limit(take, skip)
33-
}
34-
3527
// SetSessionPagination sets pagination for a database session
3628
func SetSessionPagination(sess Engine, p Paginator) *xorm.Session {
3729
skip, take := p.GetSkipTake()
3830

3931
return sess.Limit(take, skip)
4032
}
4133

42-
// SetEnginePagination sets pagination for a database engine
43-
func SetEnginePagination(e Engine, p Paginator) Engine {
44-
skip, take := p.GetSkipTake()
45-
46-
return e.Limit(take, skip)
47-
}
48-
4934
// ListOptions options to paginate results
5035
type ListOptions struct {
5136
PageSize int
@@ -66,13 +51,6 @@ func (opts *ListOptions) GetSkipTake() (skip, take int) {
6651
return (opts.Page - 1) * opts.PageSize, opts.PageSize
6752
}
6853

69-
// GetStartEnd returns the start and end of the ListOptions
70-
func (opts *ListOptions) GetStartEnd() (start, end int) {
71-
start, take := opts.GetSkipTake()
72-
end = start + take
73-
return start, end
74-
}
75-
7654
func (opts ListOptions) GetPage() int {
7755
return opts.Page
7856
}
@@ -135,11 +113,6 @@ func (opts *AbsoluteListOptions) GetSkipTake() (skip, take int) {
135113
return opts.skip, opts.take
136114
}
137115

138-
// GetStartEnd returns the start and end values
139-
func (opts *AbsoluteListOptions) GetStartEnd() (start, end int) {
140-
return opts.skip, opts.skip + opts.take
141-
}
142-
143116
// FindOptions represents a find options
144117
type FindOptions interface {
145118
GetPage() int
@@ -148,15 +121,34 @@ type FindOptions interface {
148121
ToConds() builder.Cond
149122
}
150123

124+
type JoinFunc func(sess Engine) error
125+
126+
type FindOptionsJoin interface {
127+
ToJoins() []JoinFunc
128+
}
129+
151130
type FindOptionsOrder interface {
152131
ToOrders() string
153132
}
154133

155134
// Find represents a common find function which accept an options interface
156135
func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
157-
sess := GetEngine(ctx).Where(opts.ToConds())
136+
sess := GetEngine(ctx)
137+
138+
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
139+
for _, joinFunc := range joinOpt.ToJoins() {
140+
if err := joinFunc(sess); err != nil {
141+
return nil, err
142+
}
143+
}
144+
}
145+
146+
sess = sess.Where(opts.ToConds())
158147
page, pageSize := opts.GetPage(), opts.GetPageSize()
159-
if !opts.IsListAll() && pageSize > 0 && page >= 1 {
148+
if !opts.IsListAll() && pageSize > 0 {
149+
if page == 0 {
150+
page = 1
151+
}
160152
sess.Limit(pageSize, (page-1)*pageSize)
161153
}
162154
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" {
@@ -176,8 +168,17 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
176168

177169
// Count represents a common count function which accept an options interface
178170
func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
171+
sess := GetEngine(ctx)
172+
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
173+
for _, joinFunc := range joinOpt.ToJoins() {
174+
if err := joinFunc(sess); err != nil {
175+
return 0, err
176+
}
177+
}
178+
}
179+
179180
var object T
180-
return GetEngine(ctx).Where(opts.ToConds()).Count(&object)
181+
return sess.Where(opts.ToConds()).Count(&object)
181182
}
182183

183184
// FindAndCount represents a common findandcount function which accept an options interface

models/db/paginator/paginator_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,8 @@ func TestPaginator(t *testing.T) {
5252

5353
for _, c := range cases {
5454
skip, take := c.Paginator.GetSkipTake()
55-
start, end := c.Paginator.GetStartEnd()
5655

5756
assert.Equal(t, c.Skip, skip)
5857
assert.Equal(t, c.Take, take)
59-
assert.Equal(t, c.Start, start)
60-
assert.Equal(t, c.End, end)
6158
}
6259
}

0 commit comments

Comments
 (0)