influxdb/http/paging.go

134 lines
2.6 KiB
Go

package http
import (
"fmt"
"net/http"
"net/url"
"strconv"
platform "github.com/influxdata/influxdb"
)
// decodeFindOptions returns a FindOptions decoded from http request.
func decodeFindOptions(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, &platform.Error{
Code: platform.EInvalid,
Msg: "offset is invalid",
}
}
opts.Offset = o
}
if limit := qp.Get("limit"); limit != "" {
l, err := strconv.Atoi(limit)
if err != nil {
return nil, &platform.Error{
Code: platform.EInvalid,
Msg: "limit is invalid",
}
}
if l < 1 || l > platform.MaxPageSize {
return nil, &platform.Error{
Code: platform.EInvalid,
Msg: fmt.Sprintf("limit must be between 1 and %d", platform.MaxPageSize),
}
}
opts.Limit = l
} else {
opts.Limit = platform.DefaultPageSize
}
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, &platform.Error{
Code: platform.EInvalid,
Msg: "descending is invalid",
}
}
opts.Descending = desc
}
return opts, nil
}
func findOptionParams(opts ...platform.FindOptions) [][2]string {
var out [][2]string
for _, o := range opts {
for k, vals := range o.QueryParams() {
for _, v := range vals {
out = append(out, [2]string{k, v})
}
}
}
return out
}
// 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{
Prev: prev,
Self: self,
Next: next,
}
return links
}