add paging implementation
parent
df0b084543
commit
08c3d0916e
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue