From 4bc6ad4979ae0fa19783dac92fb35517c7b99a4a Mon Sep 17 00:00:00 2001 From: Dan Whitacre Date: Sat, 18 May 2024 21:35:08 -0400 Subject: [PATCH] move lb to the db --- api/.dockerignore | 1 - api/Dockerfile | 1 - api/domain/leaderboard.go | 77 +++++++++++++++++++++++++++-------- api/leaderboard/standings | 16 -------- db/007_create_leaderboard.sql | 17 ++++++++ db/008_seed_leaderboard.sql | 15 +++++++ 6 files changed, 93 insertions(+), 34 deletions(-) delete mode 100644 api/leaderboard/standings create mode 100644 db/007_create_leaderboard.sql create mode 100644 db/008_seed_leaderboard.sql diff --git a/api/.dockerignore b/api/.dockerignore index 7cba30e..a35ef00 100644 --- a/api/.dockerignore +++ b/api/.dockerignore @@ -1,7 +1,6 @@ * .* -!leaderboard !player !go.mod !go.sum diff --git a/api/Dockerfile b/api/Dockerfile index 907b028..345ea37 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -14,7 +14,6 @@ FROM gcr.io/distroless/base-debian12 WORKDIR / COPY --from=build /hdstmevents-api /hdstmevents-api -COPY ./leaderboard /leaderboard COPY ./player /player EXPOSE 8080 diff --git a/api/domain/leaderboard.go b/api/domain/leaderboard.go index 2a755d3..9fb2a3e 100644 --- a/api/domain/leaderboard.go +++ b/api/domain/leaderboard.go @@ -1,11 +1,12 @@ package domain import ( - "encoding/json" + "context" "errors" - "os" "slices" "strings" + + "github.com/jackc/pgx/v5" ) type Leaderboard struct { @@ -26,43 +27,87 @@ type Top struct { Position int `json:"position"` } -func LeaderboardGet(leaderboard *Leaderboard) error { - if leaderboard.LeaderboardId == "" { - return errors.New("LeaderboardGet: missing leaderboardId, nothing to gets") - } +type LeaderboardData struct { + LeaderboardId string + LastModified string + WeeklyId string +} - file, err := os.Open("leaderboard/" + leaderboard.LeaderboardId) +func getLeaderboardData(leaderboardId string) ([]LeaderboardData, error) { + var leaderboardData []LeaderboardData + rows, err := db.Query( + context.Background(), + `select l.LeaderboardId, l.LastModified, lw.WeeklyId + from Leaderboard l + join LeaderboardWeekly lw on l.leaderboardId = lw.LeaderboardId + where l.LeaderboardId=$1`, + leaderboardId, + ) if err != nil { - return err + return leaderboardData, err } - defer file.Close() - jsonParser := json.NewDecoder(file) - if err = jsonParser.Decode(leaderboard); err != nil { - return err + leaderboardData, err = pgx.CollectRows(rows, pgx.RowToStructByName[LeaderboardData]) + if err != nil { + return leaderboardData, err + } + + return leaderboardData, nil +} + +func toLeaderboard(leaderboardData []LeaderboardData, leaderboard *Leaderboard) error { + if len(leaderboardData) < 1 { + return errors.New("LeaderboardGet: no leaderboardData to create leaderboard from") } - for i := 0; i < len(leaderboard.Weeklies); i++ { - err = WeeklyGet(leaderboard.Weeklies[i].Weekly) + leaderboard.LeaderboardId = leaderboardData[0].LeaderboardId + leaderboard.LastModified = leaderboardData[0].LastModified + + for i := 0; i < len(leaderboardData); i++ { + var weekly Weekly + weekly.WeeklyId = leaderboardData[i].WeeklyId + err := WeeklyGet(&weekly) if err != nil { return err } + var leaderboardWeekly LeaderboardWeekly + leaderboardWeekly.Weekly = &weekly + leaderboard.Weeklies = append(leaderboard.Weeklies, &leaderboardWeekly) + for j := 0; j < len(leaderboard.Weeklies[i].Weekly.Results); j++ { idx := slices.IndexFunc(leaderboard.Tops, func (top *Top) bool { return top.Player.AccountId == leaderboard.Weeklies[i].Weekly.Results[j].Player.AccountId }) if idx == -1 { - top := &Top{} + var top Top top.Player = leaderboard.Weeklies[i].Weekly.Results[j].Player idx = len(leaderboard.Tops) - leaderboard.Tops = append(leaderboard.Tops, top) + leaderboard.Tops = append(leaderboard.Tops, &top) } leaderboard.Tops[idx].Score += leaderboard.Weeklies[i].Weekly.Results[j].Score } } + return nil +} + +func LeaderboardGet(leaderboard *Leaderboard) error { + if leaderboard.LeaderboardId == "" { + return errors.New("LeaderboardGet: missing leaderboardId, nothing to gets") + } + + leaderboardData, err := getLeaderboardData(leaderboard.LeaderboardId) + if err != nil { + return err + } + + err = toLeaderboard(leaderboardData, leaderboard) + if err != nil { + return err + } + slices.SortFunc(leaderboard.Tops, func (topA *Top, topB *Top) int { if topB.Score == topA.Score { return strings.Compare(strings.ToLower(topA.Player.Name), strings.ToLower(topB.Player.Name)) diff --git a/api/leaderboard/standings b/api/leaderboard/standings deleted file mode 100644 index 9142693..0000000 --- a/api/leaderboard/standings +++ /dev/null @@ -1,16 +0,0 @@ -{ - "leaderboardId": "standings", - "weeklies": [{ - "weekly": { "weeklyId": "2024-04-27" } - }, - { - "weekly": { "weeklyId": "2024-05-04" } - }, - { - "weekly": { "weeklyId": "2024-05-11" } - }, - { - "weekly": { "weeklyId": "2024-05-17" } - }], - "lastModified": "2024-05-17T01:10:00+00:00" -} \ No newline at end of file diff --git a/db/007_create_leaderboard.sql b/db/007_create_leaderboard.sql new file mode 100644 index 0000000..bbcf8c2 --- /dev/null +++ b/db/007_create_leaderboard.sql @@ -0,0 +1,17 @@ +create table Leaderboard( + LeaderboardId varchar not null primary key, + LastModified varchar not null default '' +); + +create table LeaderboardWeekly( + LeaderboardWeeklyId serial primary key, + LeaderboardId varchar not null, + WeeklyId varchar not null, + foreign key(LeaderboardId) references Leaderboard(LeaderboardId), + foreign key(WeeklyId) references Weekly(WeeklyId) +); + +---- create above / drop below ---- + +drop table LeaderboardWeekly; +drop table Leaderboard; diff --git a/db/008_seed_leaderboard.sql b/db/008_seed_leaderboard.sql new file mode 100644 index 0000000..7ce3447 --- /dev/null +++ b/db/008_seed_leaderboard.sql @@ -0,0 +1,15 @@ +insert into Leaderboard (LeaderboardId, LastModified) +values + ('standings', '2024-05-17T01:10:00+00:00'); + +insert into LeaderboardWeekly (LeaderboardId, WeeklyId) +values + ('standings', '2024-04-27'), + ('standings', '2024-05-04'), + ('standings', '2024-05-11'), + ('standings', '2024-05-17'); + +---- create above / drop below ---- + +delete from LeaderboardWeekly; +delete from Leaderboard;