1
0
mirror of https://github.com/rancher/norman.git synced 2025-09-03 16:25:09 +00:00
Files
norman/handler/parse_collection.go
Darren Shepherd c06696a1e4 Initial
2017-10-15 19:23:15 -07:00

131 lines
2.4 KiB
Go

package handler
import (
"net/http"
"strconv"
"strings"
"github.com/rancher/go-rancher/v3"
"github.com/rancher/norman/query"
)
var (
ASC = SortOrder("asc")
DESC = SortOrder("desc")
defaultLimit = 100
maxLimit = 3000
)
type SortOrder string
type Pagination struct {
Limit int
Marker string
}
type CollectionAttributes struct {
Sort string
Order SortOrder
Pagination *Pagination
Conditions []*query.Condition
}
func ParseCollectionAttributes(req *http.Request, schema client.Schema) *CollectionAttributes {
if req.Method != http.MethodGet {
return nil
}
result := &CollectionAttributes{}
result.Order = parseOrder(req)
result.Sort = parseSort(schema, req)
result.Pagination = parsePagination(req)
result.Conditions = parseFilters(schema, req)
return result
}
func parseOrder(req *http.Request) SortOrder {
order := req.URL.Query().Get("order")
if SortOrder(order) == DESC {
return DESC
}
return ASC
}
func parseSort(schema client.Schema, req *http.Request) string {
sort := req.URL.Query().Get("sort")
if _, ok := schema.CollectionFilters[sort]; ok {
return sort
}
return ""
}
func parsePagination(req *http.Request) *Pagination {
q := req.URL.Query()
limit := q.Get("limit")
marker := q.Get("marker")
result := &Pagination{
Limit: defaultLimit,
Marker: marker,
}
if limit != "" {
limitInt, err := strconv.Atoi(limit)
if err != nil {
return result
}
if limitInt > maxLimit {
result.Limit = maxLimit
} else if limitInt > 0 {
result.Limit = limitInt
}
}
return result
}
func parseNameAndOp(value string) (string, string) {
name := value
op := "eq"
idx := strings.LastIndex(value, "_")
if idx > 0 {
op = value[idx+1:]
name = value[0:idx]
}
return name, op
}
func parseFilters(schema client.Schema, req *http.Request) []*query.Condition {
conditions := []*query.Condition{}
q := req.URL.Query()
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 || !query.ValidMod(op) {
continue
}
genericValues := []interface{}{}
for _, value := range values {
genericValues = append(genericValues, value)
}
conditions = append(conditions, query.NewCondition(query.ConditionType(mod), genericValues))
}
}
return conditions
}