package controller import ( "context" "log/slog" "net/http" "strconv" "time" "github.com/AFASystems/presence/internal/pkg/api/response" "github.com/AFASystems/presence/internal/pkg/model" "github.com/gorilla/mux" "gorm.io/gorm" ) func TracksListController(db *gorm.DB, context context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] var tracks []model.Tracks query := r.URL.Query() lStr := query.Get("limit") parseTime := func(key string, defaultTime time.Time) time.Time { t, err := time.Parse(time.RFC3339, query.Get(key)) if err != nil { return defaultTime } return t } limit, _ := strconv.Atoi(lStr) if limit == 0 { limit = 10 } from := parseTime("from", time.Now().AddDate(0, 0, -1)) to := parseTime("to", time.Now()) if err := db.WithContext(context).Where("uuid = ? AND timestamp BETWEEN ? AND ?", id, from, to).Order("timestamp DESC").Limit(limit).Find(&tracks).Error; err != nil { response.InternalError(w, "failed to list tracks", err) return } response.JSON(w, http.StatusOK, tracks) } } func TracksListAllController(db *gorm.DB, context context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() lStr := query.Get("limit") if lStr == "" { lStr = "100" } limit, err := strconv.Atoi(lStr) if err != nil { slog.Error("Error in converting limit string to integer value") response.InternalError(w, "internal server error", err) return } offsetStr := query.Get("offset") if offsetStr == "" { offsetStr = "0" } offset, err := strconv.Atoi(offsetStr) if err != nil { slog.Error("Error in converting offset string to integer value") response.InternalError(w, "internal server error", err) return } var tracks []model.Tracks // Subquery to get the latest timestamp per tracker subQuery := db.Model(&model.Tracks{}). Select("tracker, MAX(timestamp) AS max_timestamp"). Group("tracker") if err := db.WithContext(context). Table("tracks"). Select("tracks.*"). Joins("JOIN (?) AS latest ON tracks.tracker = latest.tracker AND tracks.timestamp = latest.max_timestamp", subQuery). Order("tracks.timestamp DESC"). Limit(limit). Offset(offset). Find(&tracks).Error; err != nil { response.InternalError(w, "failed to list tracks", err) return } response.JSON(w, http.StatusOK, tracks) } }