golift.io/starr@v1.0.0/paginate.go (about) 1 package starr 2 3 import ( 4 "fmt" 5 "net/url" 6 "strconv" 7 "strings" 8 ) 9 10 /* This file containers helper methods and types for page-able API calls. 11 * Like GetHistory() and GetQueue(). 12 */ 13 14 // PageReq is the input to search requests that have page-able responses. 15 // These are turned into HTTP parameters. 16 type PageReq struct { 17 PageSize int // 10 is default if not provided. 18 Page int // 1 is default if not provided. 19 SortKey string // date, timeleft, others? 20 SortDir Sorting // ascending, descending 21 Filter Filtering // enums for eventTypes. App specific. 22 url.Values // Additional values that may be set. 23 } 24 25 // Sorting is used as a request parameter value to sort lists, like History and Queue. 26 type Sorting string 27 28 const ( 29 // SortAsc is the default, and sorts lists in ascending order. 30 SortAscend Sorting = "ascending" 31 // SortDesc flips the sort order to descending. 32 SortDescend Sorting = "descending" 33 ) 34 35 // Filtering is used as a request parameter value to filter lists, like History and Queue. 36 // The filter values are different per-app, so find their values in their respective modules. 37 type Filtering int 38 39 // Set makes sure the sort direction is valid. 40 func (s *Sorting) Set(val string) { 41 switch Sorting(strings.ToLower(val)) { 42 default: 43 fallthrough 44 case SortAscend: 45 *s = SortAscend 46 case SortDescend: 47 *s = SortDescend 48 } 49 } 50 51 // Param returns the string value of a Filter eventType. 52 func (f Filtering) Param() string { 53 return fmt.Sprint(f) 54 } 55 56 // Params returns a brand new url.Values with all request parameters combined. 57 func (r *PageReq) Params() url.Values { 58 params := make(url.Values) 59 60 if r.Filter > 0 { 61 params.Set("eventType", r.Filter.Param()) 62 } 63 64 if r.Page > 0 { 65 params.Set("page", fmt.Sprint(r.Page)) 66 } else { 67 params.Set("page", "1") 68 } 69 70 if r.PageSize > 0 { 71 params.Set("pageSize", fmt.Sprint(r.PageSize)) 72 } else { 73 params.Set("pageSize", "10") 74 } 75 76 if r.SortKey != "" { 77 params.Set("sortKey", r.SortKey) 78 } else { 79 params.Set("sortKey", "date") // timeleft, title, id 80 } 81 82 if r.SortDir != "" { 83 params.Set("sortDirection", string(r.SortDir)) 84 } else { 85 params.Set("sortDirection", "ascending") // descending 86 } 87 88 for k, v := range r.Values { 89 for _, val := range v { 90 params.Set(k, val) 91 } 92 } 93 94 return params 95 } 96 97 // Encode turns our request parameters into a URI string. 98 func (r *PageReq) Encode() string { 99 return r.Params().Encode() 100 } 101 102 // CheckSet sets a request parameter if it's not already set. 103 func (r *PageReq) CheckSet(key, value string) { //nolint:cyclop 104 switch strings.ToLower(key) { 105 case "page": 106 if r.Page == 0 { 107 r.Page, _ = strconv.Atoi(value) 108 } 109 case "pagesize": 110 if r.PageSize == 0 { 111 r.PageSize, _ = strconv.Atoi(value) 112 } 113 case "sortkey": 114 if r.SortKey == "" { 115 r.SortKey = value 116 } 117 case "sortdirection": 118 if r.SortDir == "" { 119 r.SortDir.Set(value) 120 } 121 default: 122 if r.Values == nil { 123 r.Values = make(url.Values) 124 } 125 126 if r.Values.Get(key) == "" { 127 r.Values.Set(key, value) 128 } 129 } 130 } 131 132 // Set sets a request parameter. 133 func (r *PageReq) Set(key, value string) { 134 switch strings.ToLower(key) { 135 case "page": 136 r.Page, _ = strconv.Atoi(value) 137 case "pagesize": 138 r.PageSize, _ = strconv.Atoi(value) 139 case "sortkey": 140 r.SortKey = value 141 case "sortdirection": 142 r.SortDir.Set(value) 143 default: 144 if r.Values == nil { 145 r.Values = make(url.Values) 146 } 147 148 r.Values.Set(key, value) 149 } 150 } 151 152 // SetPerPage returns a proper perPage value that is not equal to zero, 153 // and not larger than the record count desired. If the count is zero, then 154 // perPage can be anything other than zero. 155 // This is used by paginated methods in the starr modules. 156 func SetPerPage(records, perPage int) int { 157 const perPageDefault = 500 158 159 if perPage <= 1 { 160 if records > perPageDefault || records == 0 { 161 perPage = perPageDefault 162 } else { 163 perPage = records 164 } 165 } else if perPage > records && records != 0 { 166 perPage = records 167 } 168 169 return perPage 170 } 171 172 // AdjustPerPage to make sure we don't go over, or ask for more records than exist. 173 // This is used by paginated methods in the starr modules. 174 // 'records' is the number requested, 'total' is the number in the app, 175 // 'collected' is how many we have so far, and 'perPage' is the current perPage setting. 176 func AdjustPerPage(records, total, collected, perPage int) int { 177 // Do not ask for more than was requested. 178 if d := records - collected; perPage > d && d > 0 { 179 perPage = d 180 } 181 182 // Ask for only the known total. 183 if d := total - collected; perPage > d { 184 perPage = d 185 } 186 187 return perPage 188 }