OSDN Git Service

rename (#465)
[bytom/vapor.git] / toolbar / server / pagination.go
1 package server
2
3 import (
4         "fmt"
5         "reflect"
6         "strconv"
7
8         "github.com/gin-gonic/gin"
9
10         "github.com/bytom/vapor/errors"
11 )
12
13 const (
14         defaultSatrtStr = "0"
15         defaultLimitStr = "10"
16         maxPageLimit    = 1000
17 )
18
19 var (
20         errParsePaginationStart = fmt.Errorf("parse pagination start")
21         errParsePaginationLimit = fmt.Errorf("parse pagination limit")
22 )
23
24 type PaginationQuery struct {
25         Start uint64 `json:"start"`
26         Limit uint64 `json:"limit"`
27 }
28
29 // parsePagination request meets the standard on https://developer.atlassian.com/server/confluence/pagination-in-the-rest-api/
30 func parsePagination(c *gin.Context) (*PaginationQuery, error) {
31         startStr := c.DefaultQuery("start", defaultSatrtStr)
32         limitStr := c.DefaultQuery("limit", defaultLimitStr)
33
34         start, err := strconv.ParseUint(startStr, 10, 64)
35         if err != nil {
36                 return nil, errors.Wrap(err, errParsePaginationStart)
37         }
38
39         limit, err := strconv.ParseUint(limitStr, 10, 64)
40         if err != nil {
41                 return nil, errors.Wrap(err, errParsePaginationLimit)
42         }
43
44         if limit > maxPageLimit {
45                 limit = maxPageLimit
46         }
47
48         return &PaginationQuery{
49                 Start: start,
50                 Limit: limit,
51         }, nil
52 }
53
54 type PaginationInfo struct {
55         Start   uint64
56         Limit   uint64
57         HasNext bool
58 }
59
60 func processPaginationIfPresent(fun handlerFun, args []interface{}, result []interface{}, context *gin.Context) bool {
61         ft := reflect.TypeOf(fun)
62         if ft.NumIn() != 3 {
63                 return false
64         }
65
66         list := result[0]
67         size := reflect.ValueOf(list).Len()
68         query := args[2].(*PaginationQuery)
69
70         paginationInfo := &PaginationInfo{Start: query.Start, Limit: query.Limit, HasNext: size == int(query.Limit)}
71         respondSuccessPaginationResp(context, list, paginationInfo)
72         return true
73 }