move sorting to the database
All checks were successful
pedestrian-simulator / build (push) Successful in 1m2s
All checks were successful
pedestrian-simulator / build (push) Successful in 1m2s
This commit is contained in:
123
server/kml.go
123
server/kml.go
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user