Skip to content

Commit b0e0c70

Browse files
committed
paginate results
1 parent f8a6eb8 commit b0e0c70

File tree

151 files changed

+13018
-538
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+13018
-538
lines changed

cmd/admin.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,10 @@ func runRepoSyncReleases(c *cli.Context) error {
349349
log.Trace("Synchronizing repository releases (this may take a while)")
350350
for page := 1; ; page++ {
351351
repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
352-
Page: page,
353-
PageSize: models.RepositoryListDefaultPageSize,
352+
ListOptions: models.ListOptions{
353+
PageSize: models.RepositoryListDefaultPageSize,
354+
Page: page,
355+
},
354356
Private: true,
355357
})
356358
if err != nil {

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ require (
6868
github.com/mattn/go-sqlite3 v1.11.0
6969
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
7070
github.com/microcosm-cc/bluemonday v0.0.0-20161012083705-f77f16ffc87a
71+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
72+
github.com/modern-go/reflect2 v1.0.1 // indirect
7173
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
7274
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
7375
github.com/niklasfasching/go-org v0.1.8

models/access.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode
192192

193193
// refreshCollaboratorAccesses retrieves repository collaborations with their access modes.
194194
func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error {
195-
collaborations, err := repo.getCollaborations(e)
195+
collaborations, err := repo.getCollaborations(e, ListOptions{})
196196
if err != nil {
197197
return fmt.Errorf("getCollaborations: %v", err)
198198
}

models/gpg_key.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,14 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) {
6464
}
6565

6666
// ListGPGKeys returns a list of public keys belongs to given user.
67-
func ListGPGKeys(uid int64) ([]*GPGKey, error) {
68-
keys := make([]*GPGKey, 0, 5)
69-
return keys, x.Where("owner_id=? AND primary_key_id=''", uid).Find(&keys)
67+
func ListGPGKeys(uid int64, listOptions ListOptions) ([]*GPGKey, error) {
68+
sess := x.Where("owner_id=? AND primary_key_id=''", uid)
69+
if listOptions.Page != 0 {
70+
sess = listOptions.setSessionPagination(sess)
71+
}
72+
73+
var keys []*GPGKey
74+
return keys, sess.Find(&keys)
7075
}
7176

7277
// GetGPGKeyByID returns public key by given ID.
@@ -628,7 +633,7 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
628633

629634
// Now try to associate the signature with the committer, if present
630635
if committer.ID != 0 {
631-
keys, err := ListGPGKeys(committer.ID)
636+
keys, err := ListGPGKeys(committer.ID, ListOptions{})
632637
if err != nil { //Skipping failed to get gpg keys of user
633638
log.Error("ListGPGKeys: %v", err)
634639
return &CommitVerification{

models/issue.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,13 +1072,12 @@ func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) {
10721072

10731073
// IssuesOptions represents options of an issue.
10741074
type IssuesOptions struct {
1075+
ListOptions
10751076
RepoIDs []int64 // include all repos if empty
10761077
AssigneeID int64
10771078
PosterID int64
10781079
MentionedID int64
10791080
MilestoneID int64
1080-
Page int
1081-
PageSize int
10821081
IsClosed util.OptionalBool
10831082
IsPull util.OptionalBool
10841083
LabelIDs []int64

models/issue_comment.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,7 @@ func GetCommentByID(id int64) (*Comment, error) {
759759

760760
// FindCommentsOptions describes the conditions to Find comments
761761
type FindCommentsOptions struct {
762+
ListOptions
762763
RepoID int64
763764
IssueID int64
764765
ReviewID int64
@@ -792,6 +793,11 @@ func findComments(e Engine, opts FindCommentsOptions) ([]*Comment, error) {
792793
if opts.RepoID > 0 {
793794
sess.Join("INNER", "issue", "issue.id = comment.issue_id")
794795
}
796+
797+
if opts.Page != 0 {
798+
sess = opts.setSessionPagination(sess)
799+
}
800+
795801
return comments, sess.
796802
Asc("comment.created_unix").
797803
Asc("comment.id").

models/issue_label.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
298298
Find(&labels)
299299
}
300300

301-
func getLabelsByRepoID(e Engine, repoID int64, sortType string) ([]*Label, error) {
301+
func getLabelsByRepoID(e Engine, repoID int64, sortType string, listOptions ListOptions) ([]*Label, error) {
302302
labels := make([]*Label, 0, 10)
303303
sess := e.Where("repo_id = ?", repoID)
304304

@@ -313,12 +313,16 @@ func getLabelsByRepoID(e Engine, repoID int64, sortType string) ([]*Label, error
313313
sess.Asc("name")
314314
}
315315

316+
if listOptions.Page != 0 {
317+
sess = listOptions.setSessionPagination(sess)
318+
}
319+
316320
return labels, sess.Find(&labels)
317321
}
318322

319323
// GetLabelsByRepoID returns all labels that belong to given repository by ID.
320-
func GetLabelsByRepoID(repoID int64, sortType string) ([]*Label, error) {
321-
return getLabelsByRepoID(x, repoID, sortType)
324+
func GetLabelsByRepoID(repoID int64, sortType string, listOptions ListOptions) ([]*Label, error) {
325+
return getLabelsByRepoID(x, repoID, sortType, listOptions)
322326
}
323327

324328
func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {

models/issue_label_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func TestGetLabelsInRepoByIDs(t *testing.T) {
131131
func TestGetLabelsByRepoID(t *testing.T) {
132132
assert.NoError(t, PrepareTestDatabase())
133133
testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) {
134-
labels, err := GetLabelsByRepoID(repoID, sortType)
134+
labels, err := GetLabelsByRepoID(repoID, sortType, ListOptions{})
135135
assert.NoError(t, err)
136136
assert.Len(t, labels, len(expectedIssueIDs))
137137
for i, label := range labels {

models/issue_milestone.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func (milestones MilestoneList) getMilestoneIDs() []int64 {
219219
}
220220

221221
// GetMilestonesByRepoID returns all opened milestones of a repository.
222-
func GetMilestonesByRepoID(repoID int64, state api.StateType) (MilestoneList, error) {
222+
func GetMilestonesByRepoID(repoID int64, state api.StateType, listOptions ListOptions) (MilestoneList, error) {
223223
sess := x.Where("repo_id = ?", repoID)
224224

225225
switch state {
@@ -236,7 +236,11 @@ func GetMilestonesByRepoID(repoID int64, state api.StateType) (MilestoneList, er
236236
sess = sess.And("is_closed = ?", false)
237237
}
238238

239-
miles := make([]*Milestone, 0, 10)
239+
if listOptions.Page != 0 {
240+
sess = listOptions.setSessionPagination(sess)
241+
}
242+
243+
var miles []*Milestone
240244
return miles, sess.Asc("deadline_unix").Asc("id").Find(&miles)
241245
}
242246

models/issue_milestone_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
7171
assert.NoError(t, PrepareTestDatabase())
7272
test := func(repoID int64, state api.StateType) {
7373
repo := AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
74-
milestones, err := GetMilestonesByRepoID(repo.ID, state)
74+
milestones, err := GetMilestonesByRepoID(repo.ID, state, ListOptions{})
7575
assert.NoError(t, err)
7676

7777
var n int
@@ -105,7 +105,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
105105
test(3, api.StateClosed)
106106
test(3, api.StateAll)
107107

108-
milestones, err := GetMilestonesByRepoID(NonexistentID, api.StateOpen)
108+
milestones, err := GetMilestonesByRepoID(NonexistentID, api.StateOpen, ListOptions{})
109109
assert.NoError(t, err)
110110
assert.Len(t, milestones, 0)
111111
}

models/issue_reaction.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Reaction struct {
2828

2929
// FindReactionsOptions describes the conditions to Find reactions
3030
type FindReactionsOptions struct {
31+
ListOptions
3132
IssueID int64
3233
CommentID int64
3334
}
@@ -58,16 +59,21 @@ func FindCommentReactions(comment *Comment) (ReactionList, error) {
5859
}
5960

6061
// FindIssueReactions returns a ReactionList of all reactions from an issue
61-
func FindIssueReactions(issue *Issue) (ReactionList, error) {
62+
func FindIssueReactions(issue *Issue, listOptions ListOptions) (ReactionList, error) {
6263
return findReactions(x, FindReactionsOptions{
63-
IssueID: issue.ID,
64-
CommentID: -1,
64+
ListOptions: listOptions,
65+
IssueID: issue.ID,
66+
CommentID: -1,
6567
})
6668
}
6769

6870
func findReactions(e Engine, opts FindReactionsOptions) ([]*Reaction, error) {
69-
reactions := make([]*Reaction, 0, 10)
71+
var reactions []*Reaction
7072
sess := e.Where(opts.toConds())
73+
if opts.Page != 0 {
74+
sess = opts.setSessionPagination(sess)
75+
}
76+
7177
return reactions, sess.
7278
In("reaction.`type`", setting.UI.Reactions).
7379
Asc("reaction.issue_id", "reaction.comment_id", "reaction.created_unix", "reaction.id").

models/issue_stopwatch.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool,
3333
}
3434

3535
// GetUserStopwatches return list of all stopwatches of a user
36-
func GetUserStopwatches(userID int64) (sws *Stopwatches, err error) {
36+
func GetUserStopwatches(userID int64, listOptions ListOptions) (sws *Stopwatches, err error) {
3737
sws = new(Stopwatches)
38-
err = x.Where("stopwatch.user_id = ?", userID).Find(sws)
38+
sess := x.Where("stopwatch.user_id = ?", userID)
39+
if listOptions.Page != 0 {
40+
sess = listOptions.setSessionPagination(sess)
41+
}
42+
43+
err = sess.Find(sws)
3944
if err != nil {
4045
return nil, err
4146
}

models/issue_test.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,30 @@ func TestIssues(t *testing.T) {
139139
IssuesOptions{
140140
RepoIDs: []int64{1, 3},
141141
SortType: "oldest",
142-
Page: 1,
143-
PageSize: 4,
142+
ListOptions: ListOptions{
143+
Page: 1,
144+
PageSize: 4,
145+
},
144146
},
145147
[]int64{1, 2, 3, 5},
146148
},
147149
{
148150
IssuesOptions{
149151
LabelIDs: []int64{1},
150-
Page: 1,
151-
PageSize: 4,
152+
ListOptions: ListOptions{
153+
Page: 1,
154+
PageSize: 4,
155+
},
152156
},
153157
[]int64{2, 1},
154158
},
155159
{
156160
IssuesOptions{
157161
LabelIDs: []int64{1, 2},
158-
Page: 1,
159-
PageSize: 4,
162+
ListOptions: ListOptions{
163+
Page: 1,
164+
PageSize: 4,
165+
},
160166
},
161167
[]int64{}, // issues with **both** label 1 and 2, none of these issues matches, TODO: add more tests
162168
},

models/issue_tracked_time.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func (t *TrackedTime) APIFormat() *api.TrackedTime {
4242

4343
// FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored.
4444
type FindTrackedTimesOptions struct {
45+
ListOptions
4546
IssueID int64
4647
UserID int64
4748
RepositoryID int64
@@ -68,10 +69,24 @@ func (opts *FindTrackedTimesOptions) ToCond() builder.Cond {
6869

6970
// ToSession will convert the given options to a xorm Session by using the conditions from ToCond and joining with issue table if required
7071
func (opts *FindTrackedTimesOptions) ToSession(e Engine) *xorm.Session {
72+
var sess *xorm.Session
7173
if opts.RepositoryID > 0 || opts.MilestoneID > 0 {
72-
return e.Join("INNER", "issue", "issue.id = tracked_time.issue_id").Where(opts.ToCond())
74+
sess = e.Join("INNER", "issue", "issue.id = tracked_time.issue_id")
7375
}
74-
return x.Where(opts.ToCond())
76+
77+
if opts.Page != 0 {
78+
if sess == nil {
79+
sess = opts.getPaginatedSession()
80+
} else {
81+
sess = opts.setSessionPagination(sess)
82+
}
83+
}
84+
85+
if sess == nil {
86+
return e.Where(opts.ToCond())
87+
}
88+
89+
return sess.Where(opts.ToCond())
7590
}
7691

7792
// GetTrackedTimes returns all tracked times that fit to the given options.

models/issue_watch.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,22 @@ func GetIssueWatchersIDs(issueID int64) ([]int64, error) {
7474
}
7575

7676
// GetIssueWatchers returns watchers/unwatchers of a given issue
77-
func GetIssueWatchers(issueID int64) (IssueWatchList, error) {
78-
return getIssueWatchers(x, issueID)
77+
func GetIssueWatchers(issueID int64, listOptions ListOptions) (IssueWatchList, error) {
78+
return getIssueWatchers(x, issueID, listOptions)
7979
}
8080

81-
func getIssueWatchers(e Engine, issueID int64) (watches IssueWatchList, err error) {
82-
err = e.
81+
func getIssueWatchers(e Engine, issueID int64, listOptions ListOptions) (watches IssueWatchList, err error) {
82+
sess := e.
8383
Where("`issue_watch`.issue_id = ?", issueID).
8484
And("`issue_watch`.is_watching = ?", true).
8585
And("`user`.is_active = ?", true).
8686
And("`user`.prohibit_login = ?", false).
87-
Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id").
88-
Find(&watches)
87+
Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id")
88+
89+
if listOptions.Page == 0 {
90+
sess = listOptions.setSessionPagination(sess)
91+
}
92+
err = sess.Find(&watches)
8993
return
9094
}
9195

models/issue_watch_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ func TestGetIssueWatch(t *testing.T) {
4141
func TestGetIssueWatchers(t *testing.T) {
4242
assert.NoError(t, PrepareTestDatabase())
4343

44-
iws, err := GetIssueWatchers(1)
44+
iws, err := GetIssueWatchers(1, ListOptions{})
4545
assert.NoError(t, err)
4646
// Watcher is inactive, thus 0
4747
assert.Len(t, iws, 0)
4848

49-
iws, err = GetIssueWatchers(2)
49+
iws, err = GetIssueWatchers(2, ListOptions{})
5050
assert.NoError(t, err)
5151
// Watcher is explicit not watching
5252
assert.Len(t, iws, 0)
5353

54-
iws, err = GetIssueWatchers(5)
54+
iws, err = GetIssueWatchers(5, ListOptions{})
5555
assert.NoError(t, err)
5656
// Issue has no Watchers
5757
assert.Len(t, iws, 0)
5858

59-
iws, err = GetIssueWatchers(7)
59+
iws, err = GetIssueWatchers(7, ListOptions{})
6060
assert.NoError(t, err)
6161
// Issue has one watcher
6262
assert.Len(t, iws, 1)

models/list_options.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package models
2+
3+
import (
4+
"code.gitea.io/gitea/modules/setting"
5+
"xorm.io/xorm"
6+
)
7+
8+
// ListOptions options to paginate results
9+
type ListOptions struct {
10+
PageSize int
11+
Page int
12+
}
13+
14+
func (opts ListOptions) getPaginatedSession() *xorm.Session {
15+
opts.setDefaultValues()
16+
17+
return x.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
18+
}
19+
20+
func (opts ListOptions) setSessionPagination(sess *xorm.Session) *xorm.Session {
21+
opts.setDefaultValues()
22+
23+
return sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
24+
}
25+
26+
func (opts ListOptions) setDefaultValues() {
27+
if opts.PageSize <= 0 || opts.PageSize > setting.UI.ExplorePagingNum {
28+
opts.PageSize = setting.UI.ExplorePagingNum
29+
}
30+
if opts.Page <= 0 {
31+
opts.Page = 1
32+
}
33+
}

models/notification.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID int64, notificationAuth
7575
}
7676

7777
func createOrUpdateIssueNotifications(e Engine, issueID, commentID int64, notificationAuthorID int64) error {
78-
issueWatches, err := getIssueWatchers(e, issueID)
78+
issueWatches, err := getIssueWatchers(e, issueID, ListOptions{})
7979
if err != nil {
8080
return err
8181
}

0 commit comments

Comments
 (0)