54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
package handlers
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"building-mgmt/internal/repository"
|
||
)
|
||
|
||
// Пагинация списков: одинаковые параметры limit/offset/sort/order
|
||
// у всех GET-списков, поэтому разбор вынесен отдельно.
|
||
// Словари сортировок приходят из repository — того же источника,
|
||
// что и ORDER BY в SQL: валидация и запрос не могут разъехаться.
|
||
|
||
// parsePage разбирает параметры страницы. Возвращает ok=false после
|
||
// ответа 400 — вызывающий хендлер обязан сразу вернуться.
|
||
func parsePage(c *gin.Context, sorts map[string]repository.SortSpec) (repository.Page, bool) {
|
||
page := repository.Page{
|
||
Limit: repository.DefaultLimit,
|
||
Sort: c.Query("sort"),
|
||
Order: c.Query("order"),
|
||
}
|
||
|
||
if v := c.Query("limit"); v != "" {
|
||
n, err := strconv.Atoi(v)
|
||
if err != nil || n < 1 || n > repository.MaxLimit {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid limit"})
|
||
return page, false
|
||
}
|
||
page.Limit = n
|
||
}
|
||
if v := c.Query("offset"); v != "" {
|
||
n, err := strconv.Atoi(v)
|
||
if err != nil || n < 0 {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid offset"})
|
||
return page, false
|
||
}
|
||
page.Offset = n
|
||
}
|
||
if page.Order != "" && page.Order != "asc" && page.Order != "desc" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid order"})
|
||
return page, false
|
||
}
|
||
if page.Sort != "" {
|
||
if _, ok := sorts[page.Sort]; !ok {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid sort"})
|
||
return page, false
|
||
}
|
||
}
|
||
return page, true
|
||
}
|