9
9
"strings"
10
10
11
11
"code.gitea.io/gitea/models/db"
12
+ "code.gitea.io/gitea/modules/util"
12
13
13
14
"xorm.io/builder"
14
- "xorm.io/xorm"
15
15
)
16
16
17
17
// Badge represents a user badge
@@ -29,6 +29,50 @@ type UserBadge struct { //nolint:revive
29
29
UserID int64 `xorm:"INDEX"`
30
30
}
31
31
32
+ // ErrBadgeAlreadyExist represents a "badge already exists" error.
33
+ type ErrBadgeAlreadyExist struct {
34
+ Slug string
35
+ }
36
+
37
+ // IsErrBadgeAlreadyExist checks if an error is a ErrBadgeAlreadyExist.
38
+ func IsErrBadgeAlreadyExist (err error ) bool {
39
+ _ , ok := err .(ErrBadgeAlreadyExist )
40
+ return ok
41
+ }
42
+
43
+ func (err ErrBadgeAlreadyExist ) Error () string {
44
+ return fmt .Sprintf ("badge already exists [slug: %s]" , err .Slug )
45
+ }
46
+
47
+ // Unwrap unwraps this error as a ErrExist error
48
+ func (err ErrBadgeAlreadyExist ) Unwrap () error {
49
+ return util .ErrAlreadyExist
50
+ }
51
+
52
+ // ErrBadgeNotExist represents a "BadgeNotExist" kind of error.
53
+ type ErrBadgeNotExist struct {
54
+ Slug string
55
+ ID int64
56
+ }
57
+
58
+ func (err ErrBadgeNotExist ) Error () string {
59
+ if err .ID > 0 {
60
+ return fmt .Sprintf ("badge does not exist [id: %d]" , err .ID )
61
+ }
62
+ return fmt .Sprintf ("badge does not exist [slug: %s]" , err .Slug )
63
+ }
64
+
65
+ // IsErrBadgeNotExist checks if an error is a ErrBadgeNotExist.
66
+ func IsErrBadgeNotExist (err error ) bool {
67
+ _ , ok := err .(ErrBadgeNotExist )
68
+ return ok
69
+ }
70
+
71
+ // Unwrap unwraps this error as a ErrNotExist error
72
+ func (err ErrBadgeNotExist ) Unwrap () error {
73
+ return util .ErrNotExist
74
+ }
75
+
32
76
func init () {
33
77
db .RegisterModel (new (Badge ))
34
78
db .RegisterModel (new (UserBadge ))
@@ -73,7 +117,6 @@ func GetBadgeUsers(ctx context.Context, opts *GetBadgeUsersOptions) ([]*User, in
73
117
func CreateBadge (ctx context.Context , badge * Badge ) error {
74
118
// this will fail if the badge already exists due to the UNIQUE constraint
75
119
_ , err := db .GetEngine (ctx ).Insert (badge )
76
-
77
120
return err
78
121
}
79
122
@@ -151,11 +194,14 @@ func RemoveUserBadges(ctx context.Context, u *User, badges []*Badge) error {
151
194
slugs [i ] = badge .Slug
152
195
}
153
196
197
+ var badgeIDs []int64
198
+ if err := db .GetEngine (ctx ).Table ("badge" ).In ("slug" , slugs ).Cols ("id" ).Find (& badgeIDs ); err != nil {
199
+ return err
200
+ }
201
+
154
202
if _ , err := db .GetEngine (ctx ).
155
- Table ("user_badge" ).
156
- Join ("INNER" , "badge" , "`user_badge`.badge_id = badge.id" ).
157
- Where ("`user_badge`.user_id = ?" , u .ID ).
158
- And (builder .In ("badge.slug" , slugs )).
203
+ Where ("user_id = ?" , u .ID ).
204
+ In ("badge_id" , badgeIDs ).
159
205
Delete (& UserBadge {}); err != nil {
160
206
return err
161
207
}
@@ -184,66 +230,29 @@ func (opts *SearchBadgeOptions) ToConds() builder.Cond {
184
230
cond := builder .NewCond ()
185
231
186
232
if opts .Keyword != "" {
187
- cond = cond .And (builder.Like {"badge.slug" , opts .Keyword })
188
- }
189
-
190
- return cond
191
- }
192
-
193
- func (opts * SearchBadgeOptions ) ToOrders () string {
194
- orderBy := "badge.slug"
195
- return orderBy
196
- }
197
-
198
- func SearchBadges (ctx context.Context , opts * SearchBadgeOptions ) (badges []* Badge , _ int64 , _ error ) {
199
- sessCount := opts .toSearchQueryBase (ctx )
200
- count , err := sessCount .Count (new (Badge ))
201
- if err != nil {
202
- return nil , 0 , fmt .Errorf ("count: %w" , err )
203
- }
204
- sessCount .Close ()
205
-
206
- if len (opts .OrderBy ) == 0 {
207
- opts .OrderBy = db .SearchOrderByID
208
- }
209
-
210
- sessQuery := opts .toSearchQueryBase (ctx ).OrderBy (opts .OrderBy .String ())
211
- defer sessQuery .Close ()
212
- if opts .Page != 0 {
213
- sessQuery = db .SetSessionPagination (sessQuery , opts )
214
- }
215
-
216
- // the sql may contain JOIN, so we must only select Badge related columns
217
- sessQuery = sessQuery .Select ("`badge`.*" )
218
- badges = make ([]* Badge , 0 , opts .PageSize )
219
- return badges , count , sessQuery .Find (& badges )
220
- }
221
-
222
- func (opts * SearchBadgeOptions ) toSearchQueryBase (ctx context.Context ) * xorm.Session {
223
- var cond builder.Cond
224
- cond = builder.Neq {"id" : - 1 }
225
-
226
- if len (opts .Keyword ) > 0 {
227
233
lowerKeyword := strings .ToLower (opts .Keyword )
228
234
keywordCond := builder .Or (
229
- builder.Like {"slug" , lowerKeyword },
230
- builder.Like {"description" , lowerKeyword },
231
- builder.Like {"id" , lowerKeyword },
235
+ builder.Like {"badge. slug" , lowerKeyword },
236
+ builder.Like {"badge. description" , lowerKeyword },
237
+ builder.Like {"badge. id" , lowerKeyword },
232
238
)
233
239
cond = cond .And (keywordCond )
234
240
}
235
241
236
242
if opts .ID > 0 {
237
- cond = cond .And (builder.Eq {"id" : opts .ID })
243
+ cond = cond .And (builder.Eq {"badge. id" : opts .ID })
238
244
}
239
245
240
246
if len (opts .Slug ) > 0 {
241
- cond = cond .And (builder.Eq {"slug" : opts .Slug })
247
+ cond = cond .And (builder.Eq {"badge. slug" : opts .Slug })
242
248
}
243
249
244
- e := db .GetEngine (ctx )
250
+ return cond
251
+ }
245
252
246
- return e .Where (cond )
253
+ // SearchBadges returns badges based on the provided SearchBadgeOptions options
254
+ func SearchBadges (ctx context.Context , opts * SearchBadgeOptions ) ([]* Badge , int64 , error ) {
255
+ return db .FindAndCount [Badge ](ctx , opts )
247
256
}
248
257
249
258
// GetBadgeByID returns a specific badge by ID
0 commit comments