2017-11-11 04:44:02 +00:00
|
|
|
package parse
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/rancher/norman/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2017-11-21 20:46:30 +00:00
|
|
|
defaultLimit = int64(1000)
|
2017-11-11 04:44:02 +00:00
|
|
|
maxLimit = int64(3000)
|
|
|
|
)
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
func QueryOptions(apiContext *types.APIContext, schema *types.Schema) types.QueryOptions {
|
|
|
|
req := apiContext.Request
|
2017-11-11 04:44:02 +00:00
|
|
|
if req.Method != http.MethodGet {
|
2017-11-21 20:46:30 +00:00
|
|
|
return types.QueryOptions{}
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
result := &types.QueryOptions{}
|
|
|
|
|
|
|
|
result.Sort = parseSort(schema, req)
|
|
|
|
result.Pagination = parsePagination(req)
|
|
|
|
result.Conditions = parseFilters(schema, req)
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
return *result
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func parseOrder(req *http.Request) types.SortOrder {
|
|
|
|
order := req.URL.Query().Get("order")
|
|
|
|
if types.SortOrder(order) == types.DESC {
|
|
|
|
return types.DESC
|
|
|
|
}
|
|
|
|
return types.ASC
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseSort(schema *types.Schema, req *http.Request) types.Sort {
|
|
|
|
sortField := req.URL.Query().Get("sort")
|
|
|
|
if _, ok := schema.CollectionFilters[sortField]; !ok {
|
|
|
|
sortField = ""
|
|
|
|
}
|
|
|
|
return types.Sort{
|
|
|
|
Order: parseOrder(req),
|
|
|
|
Name: sortField,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func parsePagination(req *http.Request) *types.Pagination {
|
|
|
|
q := req.URL.Query()
|
|
|
|
limit := q.Get("limit")
|
|
|
|
marker := q.Get("marker")
|
|
|
|
|
|
|
|
result := &types.Pagination{
|
|
|
|
Limit: &defaultLimit,
|
|
|
|
Marker: marker,
|
|
|
|
}
|
|
|
|
|
|
|
|
if limit != "" {
|
|
|
|
limitInt, err := strconv.ParseInt(limit, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
if limitInt > maxLimit {
|
|
|
|
result.Limit = &maxLimit
|
2017-11-21 20:46:30 +00:00
|
|
|
} else if limitInt >= 0 {
|
2017-11-11 04:44:02 +00:00
|
|
|
result.Limit = &limitInt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
func parseNameAndOp(value string) (string, types.ModifierType) {
|
2017-11-11 04:44:02 +00:00
|
|
|
name := value
|
|
|
|
op := "eq"
|
|
|
|
|
|
|
|
idx := strings.LastIndex(value, "_")
|
|
|
|
if idx > 0 {
|
|
|
|
op = value[idx+1:]
|
|
|
|
name = value[0:idx]
|
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
return name, types.ModifierType(op)
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func parseFilters(schema *types.Schema, req *http.Request) []*types.QueryCondition {
|
2017-11-21 20:46:30 +00:00
|
|
|
var conditions []*types.QueryCondition
|
2017-11-11 04:44:02 +00:00
|
|
|
for key, values := range req.URL.Query() {
|
|
|
|
name, op := parseNameAndOp(key)
|
|
|
|
filter, ok := schema.CollectionFilters[name]
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, mod := range filter.Modifiers {
|
|
|
|
if op != mod || !types.ValidMod(op) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
conditions = append(conditions, types.NewConditionFromString(name, mod, values...))
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return conditions
|
|
|
|
}
|