Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

96 linhas
2.4 KiB

  1. package controller
  2. import (
  3. "context"
  4. "log/slog"
  5. "net/http"
  6. "strconv"
  7. "time"
  8. "github.com/AFASystems/presence/internal/pkg/api/response"
  9. "github.com/AFASystems/presence/internal/pkg/model"
  10. "github.com/gorilla/mux"
  11. "gorm.io/gorm"
  12. )
  13. func TracksListController(db *gorm.DB, context context.Context) http.HandlerFunc {
  14. return func(w http.ResponseWriter, r *http.Request) {
  15. id := mux.Vars(r)["id"]
  16. var tracks []model.Tracks
  17. query := r.URL.Query()
  18. lStr := query.Get("limit")
  19. parseTime := func(key string, defaultTime time.Time) time.Time {
  20. t, err := time.Parse(time.RFC3339, query.Get(key))
  21. if err != nil {
  22. return defaultTime
  23. }
  24. return t
  25. }
  26. limit, _ := strconv.Atoi(lStr)
  27. if limit == 0 {
  28. limit = 10
  29. }
  30. from := parseTime("from", time.Now().AddDate(0, 0, -1))
  31. to := parseTime("to", time.Now())
  32. if err := db.WithContext(context).Where("uuid = ? AND timestamp BETWEEN ? AND ?", id, from, to).Order("timestamp DESC").Limit(limit).Find(&tracks).Error; err != nil {
  33. response.InternalError(w, "failed to list tracks", err)
  34. return
  35. }
  36. response.JSON(w, http.StatusOK, tracks)
  37. }
  38. }
  39. func TracksListAllController(db *gorm.DB, context context.Context) http.HandlerFunc {
  40. return func(w http.ResponseWriter, r *http.Request) {
  41. query := r.URL.Query()
  42. lStr := query.Get("limit")
  43. if lStr == "" {
  44. lStr = "100"
  45. }
  46. limit, err := strconv.Atoi(lStr)
  47. if err != nil {
  48. slog.Error("Error in converting limit string to integer value")
  49. response.InternalError(w, "internal server error", err)
  50. return
  51. }
  52. offsetStr := query.Get("offset")
  53. if offsetStr == "" {
  54. offsetStr = "0"
  55. }
  56. offset, err := strconv.Atoi(offsetStr)
  57. if err != nil {
  58. slog.Error("Error in converting offset string to integer value")
  59. response.InternalError(w, "internal server error", err)
  60. return
  61. }
  62. var tracks []model.Tracks
  63. // Subquery to get the latest timestamp per tracker
  64. subQuery := db.Model(&model.Tracks{}).
  65. Select("tracker, MAX(timestamp) AS max_timestamp").
  66. Group("tracker")
  67. if err := db.WithContext(context).
  68. Table("tracks").
  69. Select("tracks.*").
  70. Joins("JOIN (?) AS latest ON tracks.tracker = latest.tracker AND tracks.timestamp = latest.max_timestamp", subQuery).
  71. Order("tracks.timestamp DESC").
  72. Limit(limit).
  73. Offset(offset).
  74. Find(&tracks).Error; err != nil {
  75. response.InternalError(w, "failed to list tracks", err)
  76. return
  77. }
  78. response.JSON(w, http.StatusOK, tracks)
  79. }
  80. }