From 24323b7b342b883e92f348c3668a19e3561c7814 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Fri, 15 Dec 2023 17:20:04 -0800 Subject: [PATCH] Provide cumulative statistics --- pkg/server/database.go | 60 ++++++++++++++++++++++++++++++++- pkg/server/database_disabled.go | 6 +++- pkg/server/server.go | 21 ++++++++++-- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/pkg/server/database.go b/pkg/server/database.go index ba7793e..67ed689 100644 --- a/pkg/server/database.go +++ b/pkg/server/database.go @@ -406,7 +406,7 @@ func recordGameResult(g *bgammon.Game, winType int, account1 int, account2 int) return err } -func serverStats(tz *time.Location) (*serverStatsResult, error) { +func dailyStats(tz *time.Location) (*serverStatsResult, error) { tx, err := begin() if err != nil { return nil, err @@ -461,6 +461,64 @@ func serverStats(tz *time.Location) (*serverStatsResult, error) { return result, nil } +func cumulativeStats(tz *time.Location) (*serverStatsResult, error) { + tx, err := begin() + if err != nil { + return nil, err + } + defer tx.Commit(context.Background()) + + var earliestGame int64 + rows, err := tx.Query(context.Background(), "SELECT started FROM game ORDER BY started ASC LIMIT 1") + if err != nil { + return nil, err + } + for rows.Next() { + if err != nil { + continue + } + err = rows.Scan(&earliestGame) + } + if err != nil { + return nil, err + } + + result := &serverStatsResult{} + earliest := midnight(time.Unix(earliestGame, 0).In(tz)) + rangeStart, rangeEnd := earliest.Unix(), earliest.AddDate(0, 0, 1).Unix() + var count int + var total int + for { + rows, err := tx.Query(context.Background(), "SELECT COUNT(*) FROM game WHERE started >= $1 AND started < $2", rangeStart, rangeEnd) + if err != nil { + return nil, err + } + for rows.Next() { + if err != nil { + continue + } + err = rows.Scan(&count) + } + if err != nil { + return nil, err + } + + total += count + + result.History = append(result.History, &serverStatsEntry{ + Date: earliest.Format("2006-01-02"), + Games: total, + }) + + earliest = earliest.AddDate(0, 0, 1) + rangeStart, rangeEnd = rangeEnd, earliest.AddDate(0, 0, 1).Unix() + if rangeStart >= time.Now().Unix() { + break + } + } + return result, nil +} + func botStats(name string, tz *time.Location) (*botStatsResult, error) { tx, err := begin() if err != nil { diff --git a/pkg/server/database_disabled.go b/pkg/server/database_disabled.go index af21cc3..104baa0 100644 --- a/pkg/server/database_disabled.go +++ b/pkg/server/database_disabled.go @@ -47,7 +47,11 @@ func recordGameResult(g *bgammon.Game, winType int, account1 int, account2 int) return nil } -func serverStats(tz *time.Location) (*serverStatsResult, error) { +func dailyStats(tz *time.Location) (*serverStatsResult, error) { + return &serverStatsResult{}, nil +} + +func cumulativeStats(tz *time.Location) (*serverStatsResult, error) { return &serverStatsResult{}, nil } diff --git a/pkg/server/server.go b/pkg/server/server.go index cc4a3a8..d3e51f6 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -166,10 +166,24 @@ func (s *server) handleListMatches(w http.ResponseWriter, r *http.Request) { w.Write(s.cachedMatches()) } -func (s *server) handlePrintStats(w http.ResponseWriter, r *http.Request) { +func (s *server) handlePrintDailyStats(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - stats, err := serverStats(s.tz) + stats, err := dailyStats(s.tz) + if err != nil { + log.Fatalf("failed to fetch server statistics: %s", err) + } + buf, err := json.Marshal(stats) + if err != nil { + log.Fatalf("failed to fetch serialize server statistics: %s", err) + } + w.Write(buf) +} + +func (s *server) handlePrintCumulativeStats(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + stats, err := cumulativeStats(s.tz) if err != nil { log.Fatalf("failed to fetch server statistics: %s", err) } @@ -237,7 +251,8 @@ func (s *server) listenWebSocket(address string) { m := mux.NewRouter() m.HandleFunc("/reset/{id:[0-9]+}/{key:[A-Za-z0-9]+}", s.handleResetPassword) m.HandleFunc("/matches", s.handleListMatches) - m.HandleFunc("/stats", s.handlePrintStats) + m.HandleFunc("/stats", s.handlePrintDailyStats) + m.HandleFunc("/stats-total", s.handlePrintCumulativeStats) m.HandleFunc("/stats-tabula", s.handlePrintTabulaStats) m.HandleFunc("/stats-wildbg", s.handlePrintWildBGStats) m.HandleFunc("/", s.handleWebSocket)