mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
a12ff24068
* leaderboards * [leaderboard] add basic leaderboards - will probably have to clean up later but data is collected now
30 lines
1.5 KiB
SQL
30 lines
1.5 KiB
SQL
-- A room's leaderboards: each player's value on each of a room's stat channels. Owned by
|
|
-- the `leaderboard` worker, which is the only reader and the only writer —
|
|
-- `POST /leaderboard/CheckAndSetStat` writes a row and the three reads
|
|
-- (`GetRanks`, `GetNearbyScores`, `GetPlayerRank`) rank them. Generated from
|
|
-- src/leaderboard-db.ts (SCHEMA_DDL) — keep in sync.
|
|
--
|
|
-- One row per (player, room, channel). A row is created the first time a player posts a
|
|
-- stat for that channel of the room; a player with no row is simply not on that board,
|
|
-- which the reads answer as an empty slice / the unranked sentinel rather than by
|
|
-- inserting on a read.
|
|
--
|
|
-- `stat_channel` is the client's `StatChannel` — which of the room's tracked stats this
|
|
-- is (a room keeps one board per channel) — and `stat_value` is what it posts as
|
|
-- `StatValue`. What a channel counts (wins, laps, a time) is the room's business; the
|
|
-- server only orders on it, highest first unless the client asks for ascending, ties
|
|
-- broken on the lower `player_id` so a rank is stable between two reads.
|
|
|
|
CREATE TABLE IF NOT EXISTS leaderboard (
|
|
player_id INTEGER NOT NULL,
|
|
room_id INTEGER NOT NULL,
|
|
stat_channel INTEGER NOT NULL,
|
|
stat_value INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (player_id, room_id, stat_channel)
|
|
);
|
|
|
|
-- The reads walk one board (room + channel) ordered by value; the primary key serves the
|
|
-- point lookup but not that scan.
|
|
CREATE INDEX IF NOT EXISTS leaderboard_board_value
|
|
ON leaderboard (room_id, stat_channel, stat_value DESC, player_id);
|