github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/api/util/order.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "strings" 8 ) 9 10 var ( 11 // OrderASC defines the ascending order keyword 12 OrderASC = "asc" 13 // OrderDESC defines the descending order keyword 14 OrderDESC = "desc" 15 ) 16 17 // OrderBy represents ordering information 18 type OrderBy []Order 19 20 // Order represents ordering information for a single key 21 type Order struct { 22 Key string 23 Direction string 24 } 25 26 // NewOrder constructs a basic order struct 27 func NewOrder(key, orderDirection string) Order { 28 if orderDirection != OrderASC && orderDirection != OrderDESC { 29 orderDirection = OrderDESC 30 } 31 return Order{ 32 Key: key, 33 Direction: orderDirection, 34 } 35 } 36 37 // String implements the stringer interface for OrderBy 38 func (o OrderBy) String() string { 39 var b strings.Builder 40 for i, oi := range o { 41 if i > 0 { 42 b.WriteString(",") 43 } 44 b.WriteString(oi.String()) 45 } 46 return b.String() 47 } 48 49 // String implements the stringer interface for Order 50 func (o Order) String() string { 51 return fmt.Sprintf("%s,%s", o.Key, o.Direction) 52 } 53 54 // SetQueryParams adds order by info to a url as query parameters 55 func (o OrderBy) SetQueryParams(u *url.URL) *url.URL { 56 q := u.Query() 57 if len(o) > 0 { 58 q.Set("orderBy", o.String()) 59 } 60 61 u.RawQuery = q.Encode() 62 return u 63 } 64 65 // OrderByFromRequest extracts orderBy params from an http request 66 func OrderByFromRequest(r *http.Request) OrderBy { 67 orderBy := r.FormValue("orderBy") 68 return NewOrderByFromString(orderBy, nil) 69 } 70 71 // OrderByFromRequestWithKeys extracts orderBy params from an 72 // http request and only takes the specified keys 73 func OrderByFromRequestWithKeys(r *http.Request, validKeys []string) OrderBy { 74 orderBy := r.FormValue("orderBy") 75 return NewOrderByFromString(orderBy, validKeys) 76 } 77 78 // NewOrderByFromString converts a commaa delimited string to an OrderBy struct 79 func NewOrderByFromString(orderBy string, validKeys []string) OrderBy { 80 orderComponents := strings.Split(orderBy, ",") 81 if orderBy == "" || len(orderComponents) == 0 || (len(orderComponents) != 1 && len(orderComponents)%2 == 1) { 82 return []Order{} 83 } 84 res := []Order{} 85 if len(orderComponents) == 1 { 86 res = append(res, NewOrder(strings.TrimSpace(orderComponents[0]), OrderDESC)) 87 return res 88 } 89 for i := 0; i <= len(orderComponents)/2; i += 2 { 90 orderDirection := "" 91 if strings.ToLower(orderComponents[i+1]) == OrderASC { 92 orderDirection = OrderASC 93 } else { 94 orderDirection = OrderDESC 95 } 96 orderKey := strings.TrimSpace(orderComponents[i]) 97 if validKeys != nil { 98 for _, vkey := range validKeys { 99 if vkey == orderKey { 100 res = append(res, NewOrder(orderKey, orderDirection)) 101 break 102 } 103 } 104 } else { 105 res = append(res, NewOrder(orderKey, orderDirection)) 106 } 107 } 108 109 return res 110 }