add paging implementation

pull/10616/head
zhulongcheng 2018-12-08 21:14:57 +08:00
parent df0b084543
commit 08c3d0916e
2 changed files with 147 additions and 0 deletions

109
http/paging.go Normal file
View File

@ -0,0 +1,109 @@
package http
import (
"context"
"net/http"
"net/url"
"strconv"
"github.com/influxdata/platform"
)
// decodeFindOptions returns a FindOptions decoded from http request.
func decodeFindOptions(ctx context.Context, r *http.Request) (*platform.FindOptions, error) {
opts := &platform.FindOptions{}
qp := r.URL.Query()
if offset := qp.Get("offset"); offset != "" {
o, err := strconv.Atoi(offset)
if err != nil {
return nil, err
}
opts.Offset = o
}
if limit := qp.Get("limit"); limit != "" {
l, err := strconv.Atoi(limit)
if err != nil {
return nil, err
}
opts.Limit = l
}
if sortBy := qp.Get("sortBy"); sortBy != "" {
opts.SortBy = sortBy
}
if descending := qp.Get("descending"); descending != "" {
desc, err := strconv.ParseBool(descending)
if err != nil {
return nil, err
}
opts.Descending = desc
}
return opts, nil
}
// newPagingLinks returns a PagingLinks.
// num is the number of returned results.
func newPagingLinks(basePath string, opts platform.FindOptions, f platform.PagingFilter, num int) *platform.PagingLinks {
u := url.URL{
Path: basePath,
}
values := url.Values{}
for k, vs := range f.QueryParams() {
for _, v := range vs {
if v != "" {
values.Add(k, v)
}
}
}
var self, next, prev string
for k, vs := range opts.QueryParams() {
for _, v := range vs {
if v != "" {
values.Add(k, v)
}
}
}
u.RawQuery = values.Encode()
self = u.String()
if num >= opts.Limit {
nextOffset := opts.Offset + opts.Limit
values.Set("offset", strconv.Itoa(nextOffset))
u.RawQuery = values.Encode()
next = u.String()
}
if opts.Offset > 0 {
prevOffset := opts.Offset - opts.Limit
if prevOffset < 0 {
prevOffset = 0
}
values.Set("offset", strconv.Itoa(prevOffset))
u.RawQuery = values.Encode()
prev = u.String()
}
links := &platform.PagingLinks{
Self: map[string]string{
"self": self,
},
Prev: map[string]string{
"prev": prev,
},
Next: map[string]string{
"next": next,
},
}
return links
}

38
paging.go Normal file
View File

@ -0,0 +1,38 @@
package platform
import (
"strconv"
)
// PagingFilter represents a filter containing url query params.
type PagingFilter interface {
// QueryParams returns a map containing url query params.
QueryParams() map[string][]string
}
// PagingLinks represents paging links.
type PagingLinks struct {
Prev map[string]string `json:"prev"`
Self map[string]string `json:"self"`
Next map[string]string `json:"next"`
}
// FindOptions represents options passed to all find methods with multiple results.
type FindOptions struct {
Limit int
Offset int
SortBy string
Descending bool
}
// QueryParams returns a map containing url query params.
func (f FindOptions) QueryParams() map[string][]string {
qp := map[string][]string{
"limit": []string{strconv.Itoa(f.Limit)},
"offset": []string{strconv.Itoa(f.Offset)},
"sortBy": []string{f.SortBy},
"descending": []string{strconv.FormatBool(f.Descending)},
}
return qp
}