Improve pagination #105

Merged
konrad merged 24 commits from feature/pagination into master 2019-10-23 21:11:41 +00:00
6 changed files with 45 additions and 16 deletions
Showing only changes of commit 806cc598b9 - Show all commits

View File

@ -130,9 +130,9 @@ func (l *Label) Delete() (err error) {
// @Success 200 {array} models.Label "The labels"
// @Failure 500 {object} models.Message "Internal error"
// @Router /labels [get]
func (l *Label) ReadAll(search string, a web.Auth, page int) (ls interface{}, err error) {
func (l *Label) ReadAll(a web.Auth, search string, page int, perPage int) (ls interface{}, resultCount int, numberOfPages int, err error) {
if _, is := a.(*LinkSharing); is {
return nil, ErrGenericForbidden{}
return nil, 0, 0, ErrGenericForbidden{}
}
u := &User{ID: a.GetID()}
@ -140,13 +140,15 @@ func (l *Label) ReadAll(search string, a web.Auth, page int) (ls interface{}, er
// Get all tasks
taskIDs, err := getUserTaskIDs(u)
if err != nil {
return nil, err
return nil, 0, 0, err
}
return getLabelsByTaskIDs(&LabelByTaskIDsOptions{
Search: search,
User: u,
TaskIDs: taskIDs,
Page: page,
PerPage: perPage,
GetUnusedLabels: true,
GroupByLabelIDsOnly: true,
})

View File

@ -107,15 +107,15 @@ func (lt *LabelTask) Create(a web.Auth) (err error) {
// @Success 200 {array} models.Label "The labels"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{task}/labels [get]
func (lt *LabelTask) ReadAll(search string, a web.Auth, page int) (labels interface{}, err error) {
func (lt *LabelTask) ReadAll(a web.Auth, search string, page int, perPage int) (labels interface{}, resultCount int, numberOfPages int, err error) {
// Check if the user has the right to see the task
task := Task{ID: lt.TaskID}
canRead, err := task.CanRead(a)
if err != nil {
return nil, err
return nil, 0, 0, err
}
if !canRead {
return nil, ErrNoRightToSeeTask{lt.TaskID, a.GetID()}
return nil, 0, 0, ErrNoRightToSeeTask{lt.TaskID, a.GetID()}
}
return getLabelsByTaskIDs(&LabelByTaskIDsOptions{
@ -137,6 +137,7 @@ type LabelByTaskIDsOptions struct {
User *User
Search string
Page int
PerPage int
TaskIDs []int64
GetUnusedLabels bool
GroupByLabelIDsOnly bool
@ -144,7 +145,7 @@ type LabelByTaskIDsOptions struct {
// Helper function to get all labels for a set of tasks
// Used when getting all labels for one task as well when getting all lables
func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err error) {
func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, resultCount int, numberOfPages int, err error) {
// Include unused labels. Needed to be able to show a list of all unused labels a user
// has access to.
var uidOrNil interface{}
@ -172,10 +173,10 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
Or(builder.In("label_task.task_id", opts.TaskIDs)).
And("labels.title LIKE ?", "%"+opts.Search+"%").
GroupBy(groupBy).
Limit(getLimitFromPageIndex(opts.Page)).
Limit(getLimitFromPageIndex(opts.Page, opts.PerPage)).
Find(&labels)
if err != nil {
return nil, err
return nil, 0, 0, err
}
// Get all created by users
@ -186,7 +187,7 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
users := make(map[int64]*User)
err = x.In("id", userids).Find(&users)
if err != nil {
return nil, err
return nil, 0, 0, err
}
// Obfuscate all user emails
@ -199,7 +200,19 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
labels[in].CreatedBy = users[l.CreatedByID]
}
return labels, err
// Get the total pages
totalEntries, err := x.Table("labels").
Join("LEFT", "label_task", "label_task.label_id = labels.id").
Where(requestOrNil, uidOrNil).
Or(builder.In("label_task.task_id", opts.TaskIDs)).
And("labels.title LIKE ?", "%"+opts.Search+"%").
GroupBy(groupBy).
Count(&Label{})
if err != nil {
return nil, 0, 0, err
}
return labels, len(labels), getTotalAvailablePagesForPageEntries(int(totalEntries), opts.PerPage), err
}
// Create or update a bunch of task labels

View File

@ -89,7 +89,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
CRUDable: tt.fields.CRUDable,
Rights: tt.fields.Rights,
}
gotLabels, err := l.ReadAll(tt.args.search, tt.args.a, tt.args.page)
gotLabels, _, _, err := l.ReadAll(tt.args.a, tt.args.search, tt.args.page, 0)
if (err != nil) != tt.wantErr {
t.Errorf("LabelTask.ReadAll() error = %v, wantErr %v", err, tt.wantErr)
return

View File

@ -117,7 +117,7 @@ func TestLabel_ReadAll(t *testing.T) {
CRUDable: tt.fields.CRUDable,
Rights: tt.fields.Rights,
}
gotLs, err := l.ReadAll(tt.args.search, tt.args.a, tt.args.page)
gotLs, _, _, err := l.ReadAll(tt.args.a, tt.args.search, tt.args.page, 0)
if (err != nil) != tt.wantErr {
t.Errorf("Label.ReadAll() error = %v, wantErr %v", err, tt.wantErr)
return

View File

@ -69,7 +69,7 @@ func SetEngine() (err error) {
return nil
}
func getLimitFromPageIndex(page int) (limit, start int) {
func getLimitFromPageIndex(page int, perPage ...int) (limit, start int) {
// Get everything when page index is -1
if page < 0 {
@ -77,10 +77,24 @@ func getLimitFromPageIndex(page int) (limit, start int) {
}
limit = config.ServicePageCount.GetInt()
if len(perPage) > 0 {
limit = perPage[0]
}
start = limit * (page - 1)
return
}
func getTotalAvailablePagesForPageEntries(numberOfPageEntries, perPage int) int {
if numberOfPageEntries == 0 {
return 0
}
if perPage == 0 {
return numberOfPageEntries / config.ServicePageCount.GetInt()
}
return numberOfPageEntries / perPage
}
// GetTotalCount returns the total amount of something
func GetTotalCount(counting interface{}) (count int64, err error) {
return x.Count(counting)

View File

@ -339,7 +339,7 @@ func GetTaskByID(listTaskID int64) (listTask Task, err error) {
}
// Get task labels
taskLabels, err := getLabelsByTaskIDs(&LabelByTaskIDsOptions{
taskLabels, _, _, err := getLabelsByTaskIDs(&LabelByTaskIDsOptions{
TaskIDs: []int64{listTaskID},
})
if err != nil {
@ -413,7 +413,7 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
}
// Get all labels for all the tasks
labels, err := getLabelsByTaskIDs(&LabelByTaskIDsOptions{
labels, _, _, err := getLabelsByTaskIDs(&LabelByTaskIDsOptions{
TaskIDs: taskIDs,
Page: -1,
})