move sorting to the database
All checks were successful
pedestrian-simulator / build (push) Successful in 1m2s

This commit is contained in:
2026-01-11 21:40:48 -07:00
parent 89816a5a8c
commit eaea2c4edb
3 changed files with 150 additions and 46 deletions

View File

@@ -222,55 +222,43 @@ func HandleKMLList(w http.ResponseWriter, r *http.Request) {
return
}
// Parse pagination parameters
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
if limit <= 0 {
limit = 10
// Parse parameters for My Files
myLimit, _ := strconv.Atoi(r.URL.Query().Get("my_limit"))
if myLimit <= 0 {
myLimit = 10
}
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
if page <= 0 {
page = 1
myPage, _ := strconv.Atoi(r.URL.Query().Get("my_page"))
if myPage <= 0 {
myPage = 1
}
offset := (page - 1) * limit
sortBy := r.URL.Query().Get("sort_by")
order := r.URL.Query().Get("order")
if order != "ASC" {
order = "DESC"
mySortBy := r.URL.Query().Get("my_sort_by")
if mySortBy == "" {
mySortBy = "date"
}
// 1. Get my files
myFiles, err := queryKMLMetadata(`
SELECT m.filename, m.user_id, u.display_name, m.distance, m.is_public, m.uploaded_at,
(SELECT COALESCE(SUM(v.vote_value), 0) FROM kml_votes v WHERE v.kml_id = m.id) as votes
FROM kml_metadata m
JOIN users u ON m.user_id = u.fitbit_user_id
WHERE m.user_id = ?
ORDER BY m.uploaded_at DESC
`, userID)
// Parse parameters for Public Files
publicLimit, _ := strconv.Atoi(r.URL.Query().Get("public_limit"))
if publicLimit <= 0 {
publicLimit = 10
}
publicPage, _ := strconv.Atoi(r.URL.Query().Get("public_page"))
if publicPage <= 0 {
publicPage = 1
}
publicSortBy := r.URL.Query().Get("public_sort_by")
if publicSortBy == "" {
publicSortBy = "votes"
}
// 1. Get My Files
myFiles, myTotal, err := fetchKMLList(userID, true, myPage, myLimit, mySortBy)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 2. Get public files (with pagination and sorting)
sortClause := "votes"
switch sortBy {
case "date":
sortClause = "m.uploaded_at"
case "distance":
sortClause = "m.distance"
}
publicFiles, err := queryKMLMetadata(fmt.Sprintf(`
SELECT m.filename, m.user_id, u.display_name, m.distance, m.is_public, m.uploaded_at,
(SELECT COALESCE(SUM(v.vote_value), 0) FROM kml_votes v WHERE v.kml_id = m.id) as votes
FROM kml_metadata m
JOIN users u ON m.user_id = u.fitbit_user_id
WHERE m.is_public = 1
ORDER BY %s %s
LIMIT ? OFFSET ?
`, sortClause, order), limit, offset)
// 2. Get Public Files
publicFiles, publicTotal, err := fetchKMLList(userID, false, publicPage, publicLimit, publicSortBy)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -279,12 +267,63 @@ func HandleKMLList(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"my_files": myFiles,
"my_total": myTotal,
"my_page": myPage,
"public_files": publicFiles,
"page": page,
"limit": limit,
"public_total": publicTotal,
"public_page": publicPage,
"limit": 10, // Default limit reference for UI
})
}
func fetchKMLList(userID string, mineOnly bool, page, limit int, sortBy string) ([]KMLMetadata, int, error) {
offset := (page - 1) * limit
var whereClause string
var args []interface{}
if mineOnly {
whereClause = "WHERE m.user_id = ?"
args = append(args, userID)
} else {
whereClause = "WHERE m.is_public = 1"
}
// Get total count first
var total int
err := db.QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM kml_metadata m %s", whereClause), args...).Scan(&total)
if err != nil {
return nil, 0, err
}
sortClause := "votes"
order := "DESC"
switch sortBy {
case "date":
sortClause = "m.uploaded_at"
case "distance":
sortClause = "m.distance"
case "votes":
sortClause = "votes"
case "filename":
sortClause = "m.filename"
order = "ASC"
}
query := fmt.Sprintf(`
SELECT m.filename, m.user_id, u.display_name, m.distance, m.is_public, m.uploaded_at,
(SELECT COALESCE(SUM(v.vote_value), 0) FROM kml_votes v WHERE v.kml_id = m.id) as votes
FROM kml_metadata m
JOIN users u ON m.user_id = u.fitbit_user_id
%s
ORDER BY %s %s
LIMIT ? OFFSET ?
`, whereClause, sortClause, order)
args = append(args, limit, offset)
files, err := queryKMLMetadata(query, args...)
return files, total, err
}
func queryKMLMetadata(query string, args ...interface{}) ([]KMLMetadata, error) {
rows, err := db.Query(query, args...)
if err != nil {