From b2331d7fb00604a3e6592d310579a5c64a736468 Mon Sep 17 00:00:00 2001 From: Tait Hoyem Date: Sun, 2 Apr 2023 13:44:15 -0600 Subject: [PATCH] team_players -> game_players; help from ChatGPT to simplify some queries using conditional aggragation --- migrations/20230324221302_add_leagues.up.sql | 4 +- migrations/20230325035659_add_leagues.up.sql | 4 +- ...0230327024927_create_team_players.down.sql | 2 - ...l => 20230327025710_create_games.down.sql} | 0 ...sql => 20230327025710_create_games.up.sql} | 2 + ....sql => 20230327025711_add_games.down.sql} | 0 migrations/20230327025711_add_games.up.sql | 39 + ...=> 20230327025712_create_periods.down.sql} | 0 ...l => 20230327025712_create_periods.up.sql} | 0 .../20230327025718_add_game_players.down.sql | 2 + ...=> 20230327025718_add_game_players.up.sql} | 10 +- ... 20230327025719_add_game_players.down.sql} | 2 +- .../20230327025719_add_game_players.up.sql | 816 ++++++++++++++++++ .../20230327025719_add_team_players.up.sql | 178 ---- migrations/20230327030604_add_games.up.sql | 31 - migrations/20230327224840_create_shots.up.sql | 17 +- migrations/20230327235843_add_shots.up.sql | 514 +++++------ src/db.rs | 2 +- src/main.rs | 16 +- src/model.rs | 32 +- src/views.rs | 359 ++++---- templates/division_list.html | 2 +- templates/game_list.html | 2 +- 23 files changed, 1268 insertions(+), 766 deletions(-) delete mode 100644 migrations/20230327024927_create_team_players.down.sql rename migrations/{20230324230201_create_games.down.sql => 20230327025710_create_games.down.sql} (100%) rename migrations/{20230324230201_create_games.up.sql => 20230327025710_create_games.up.sql} (93%) rename migrations/{20230327030604_add_games.down.sql => 20230327025711_add_games.down.sql} (100%) create mode 100644 migrations/20230327025711_add_games.up.sql rename migrations/{20230327021923_create_periods.down.sql => 20230327025712_create_periods.down.sql} (100%) rename migrations/{20230327021923_create_periods.up.sql => 20230327025712_create_periods.up.sql} (100%) create mode 100644 migrations/20230327025718_add_game_players.down.sql rename migrations/{20230327024927_create_team_players.up.sql => 20230327025718_add_game_players.up.sql} (68%) rename migrations/{20230327025719_add_team_players.down.sql => 20230327025719_add_game_players.down.sql} (56%) create mode 100644 migrations/20230327025719_add_game_players.up.sql delete mode 100644 migrations/20230327025719_add_team_players.up.sql delete mode 100644 migrations/20230327030604_add_games.up.sql diff --git a/migrations/20230324221302_add_leagues.up.sql b/migrations/20230324221302_add_leagues.up.sql index 7b98765..9648527 100644 --- a/migrations/20230324221302_add_leagues.up.sql +++ b/migrations/20230324221302_add_leagues.up.sql @@ -1,7 +1,5 @@ -- Add up migration script here CREATE TABLE IF NOT EXISTS leagues ( id SERIAL PRIMARY KEY NOT NULL, - name VARCHAR(255) NOT NULL, - start_date TIMESTAMPTZ NOT NULL, - end_date TIMESTAMPTZ + name VARCHAR(255) NOT NULL ); diff --git a/migrations/20230325035659_add_leagues.up.sql b/migrations/20230325035659_add_leagues.up.sql index e51c111..a1239b1 100644 --- a/migrations/20230325035659_add_leagues.up.sql +++ b/migrations/20230325035659_add_leagues.up.sql @@ -1,5 +1,5 @@ -- Add up migration script here INSERT INTO leagues - (id, name, start_date, end_date) + (id, name) VALUES - (1, '2022 Canadian National Blind Hockey Tournament', '2022-03-24', '2022-03-26'); + (1, '2022 Canadian National Blind Hockey Tournament'); diff --git a/migrations/20230327024927_create_team_players.down.sql b/migrations/20230327024927_create_team_players.down.sql deleted file mode 100644 index a99de3f..0000000 --- a/migrations/20230327024927_create_team_players.down.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Add down migration script here -DROP TABLE IF EXISTS team_players; diff --git a/migrations/20230324230201_create_games.down.sql b/migrations/20230327025710_create_games.down.sql similarity index 100% rename from migrations/20230324230201_create_games.down.sql rename to migrations/20230327025710_create_games.down.sql diff --git a/migrations/20230324230201_create_games.up.sql b/migrations/20230327025710_create_games.up.sql similarity index 93% rename from migrations/20230324230201_create_games.up.sql rename to migrations/20230327025710_create_games.up.sql index c07ab51..c854573 100644 --- a/migrations/20230324230201_create_games.up.sql +++ b/migrations/20230327025710_create_games.up.sql @@ -8,6 +8,8 @@ CREATE TABLE IF NOT EXISTS games ( division INTEGER NOT NULL, team_home INTEGER NOT NULL, team_away INTEGER NOT NULL, + start_at TIMESTAMPTZ NOT NULL, + end_at TIMESTAMPTZ NOT NULL, -- home and away teams need to actually be teams CONSTRAINT team_home_fk FOREIGN KEY(team_home) diff --git a/migrations/20230327030604_add_games.down.sql b/migrations/20230327025711_add_games.down.sql similarity index 100% rename from migrations/20230327030604_add_games.down.sql rename to migrations/20230327025711_add_games.down.sql diff --git a/migrations/20230327025711_add_games.up.sql b/migrations/20230327025711_add_games.up.sql new file mode 100644 index 0000000..4d83d58 --- /dev/null +++ b/migrations/20230327025711_add_games.up.sql @@ -0,0 +1,39 @@ +INSERT INTO games + (id, name, division, team_home, team_away, start_at, end_at) +VALUES + ( + 1, + 'Game 1', + 1, -- LV/D + 1, -- Bullseye + 2, -- Seecats + '2022-03-25 17:00:00 America/Toronto', + '2022-03-25 18:30:00 America/Toronto' + ), + ( + 2, + 'Game 2', + 1, -- LV/D + 1, -- Bullseye + 2, -- Seecats + '2022-03-26 12:00:00 America/Toronto', + '2022-03-26 13:30:00 America/Toronto' + ), + ( + 3, + 'Game 3', + 1, -- LV/D + 1, -- Bullseye + 2, -- Seecats + '2022-03-26 17:30:00 America/Toronto', + '2022-03-26 19:00:00 America/Toronto' + ), + ( + 4, + 'Game 4', + 1, -- LV/D + 1, -- Bullseye + 2, -- Seecats + '2022-03-27 10:00:00 America/Toronto', + '2022-03-27 11:30:00 America/Toronto' + ); diff --git a/migrations/20230327021923_create_periods.down.sql b/migrations/20230327025712_create_periods.down.sql similarity index 100% rename from migrations/20230327021923_create_periods.down.sql rename to migrations/20230327025712_create_periods.down.sql diff --git a/migrations/20230327021923_create_periods.up.sql b/migrations/20230327025712_create_periods.up.sql similarity index 100% rename from migrations/20230327021923_create_periods.up.sql rename to migrations/20230327025712_create_periods.up.sql diff --git a/migrations/20230327025718_add_game_players.down.sql b/migrations/20230327025718_add_game_players.down.sql new file mode 100644 index 0000000..477ea88 --- /dev/null +++ b/migrations/20230327025718_add_game_players.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS game_players; diff --git a/migrations/20230327024927_create_team_players.up.sql b/migrations/20230327025718_add_game_players.up.sql similarity index 68% rename from migrations/20230327024927_create_team_players.up.sql rename to migrations/20230327025718_add_game_players.up.sql index f2e3bef..b1e3a98 100644 --- a/migrations/20230327024927_create_team_players.up.sql +++ b/migrations/20230327025718_add_game_players.up.sql @@ -1,15 +1,21 @@ -- Add up migration script here -CREATE TABLE IF NOT EXISTS team_players ( +CREATE TABLE IF NOT EXISTS game_players ( id SERIAL PRIMARY KEY NOT NULL, team INTEGER NOT NULL, + game INTEGER NOT NULL, player INTEGER NOT NULL, position INTEGER NOT NULL, - -- not a foreign key + -- the number of the player, usually a 1 or 2 digit number player_number INTEGER NOT NULL, + CONSTRAINT team_fk FOREIGN KEY(team) REFERENCES teams(id) ON DELETE RESTRICT, + CONSTRAINT game_fk + FOREIGN KEY(game) + REFERENCES games(id) + ON DELETE RESTRICT, CONSTRAINT player_fk FOREIGN KEY(player) REFERENCES players(id) diff --git a/migrations/20230327025719_add_team_players.down.sql b/migrations/20230327025719_add_game_players.down.sql similarity index 56% rename from migrations/20230327025719_add_team_players.down.sql rename to migrations/20230327025719_add_game_players.down.sql index 0fa63d9..fd09597 100644 --- a/migrations/20230327025719_add_team_players.down.sql +++ b/migrations/20230327025719_add_game_players.down.sql @@ -1,2 +1,2 @@ -- Add down migration script here -DELETE FROM team_players; +DELETE FROM game_players; diff --git a/migrations/20230327025719_add_game_players.up.sql b/migrations/20230327025719_add_game_players.up.sql new file mode 100644 index 0000000..58dd921 --- /dev/null +++ b/migrations/20230327025719_add_game_players.up.sql @@ -0,0 +1,816 @@ +-- Add up migration script here +INSERT INTO game_players + (team, player, position, player_number, game) +VALUES + ( + 1, + 31, + 1, + 11, + 1 + ), + ( + 1, + 1, + 3, + 3, + 1 + ), + ( + 1, + 2, + 4, + 8, + 1 + ), + ( + 1, + 3, + 5, + 1, + 1 + ), + ( + 1, + 4, + 2, + 14, + 1 + ), + ( + 1, + 5, + 4, + 91, + 1 + ), + ( + 1, + 7, + 1, + 15, + 1 + ), + ( + 1, + 8, + 4, + 10, + 1 + ), + ( + 1, + 9, + 3, + 13, + 1 + ), + ( + 1, + 10, + 1, + 10, + 1 + ), + ( + 1, + 11, + 2, + 84, + 1 + ), + ( + 2, + 12, + 5, + 35, + 1 + ), + ( + 2, + 13, + 5, + 30, + 1 + ), + ( + 2, + 14, + 1, + 15, + 1 + ), + ( + 2, + 15, + 2, + 17, + 1 + ), + ( + 2, + 16, + 1, + 3, + 1 + ), + ( + 2, + 17, + 2, + 9, + 1 + ), + ( + 2, + 18, + 4, + 16, + 1 + ), + ( + 2, + 19, + 4, + 4, + 1 + ), + ( + 2, + 21, + 4, + 14, + 1 + ), + ( + 2, + 22, + 4, + 12, + 1 + ), + ( + 2, + 23, + 2, + 10, + 1 + ), + ( + 2, + 24, + 7, + 0, + 1 + ), + ( + 2, + 25, + 7, + 0, + 1 + ), + ( + 2, + 26, + 7, + 0, + 1 + ), + ( + 1, + 27, + 7, + 0, + 1 + ), + ( + 1, + 28, + 7, + 0, + 1 + ), + ( + 1, + 29, + 7, + 0, + 1 + ), + ( + 1, + 30, + 7, + 0, + 1 + ), + ( + 1, + 31, + 1, + 11, + 2 + ), + ( + 1, + 1, + 3, + 3, + 2 + ), + ( + 1, + 2, + 4, + 8, + 2 + ), + ( + 1, + 3, + 5, + 1, + 2 + ), + ( + 1, + 4, + 2, + 14, + 2 + ), + ( + 1, + 5, + 4, + 91, + 2 + ), + ( + 1, + 7, + 1, + 15, + 2 + ), + ( + 1, + 8, + 4, + 10, + 2 + ), + ( + 1, + 9, + 3, + 13, + 2 + ), + ( + 1, + 10, + 1, + 10, + 2 + ), + ( + 1, + 11, + 2, + 84, + 2 + ), + ( + 2, + 12, + 5, + 35, + 2 + ), + ( + 2, + 13, + 5, + 30, + 2 + ), + ( + 2, + 14, + 1, + 15, + 2 + ), + ( + 2, + 15, + 2, + 17, + 2 + ), + ( + 2, + 16, + 1, + 3, + 2 + ), + ( + 2, + 17, + 2, + 9, + 2 + ), + ( + 2, + 18, + 4, + 16, + 2 + ), + ( + 2, + 19, + 4, + 4, + 2 + ), + ( + 2, + 21, + 4, + 14, + 2 + ), + ( + 2, + 22, + 4, + 12, + 2 + ), + ( + 2, + 23, + 2, + 10, + 2 + ), + ( + 2, + 24, + 7, + 0, + 2 + ), + ( + 2, + 25, + 7, + 0, + 2 + ), + ( + 2, + 26, + 7, + 0, + 2 + ), + ( + 1, + 27, + 7, + 0, + 2 + ), + ( + 1, + 28, + 7, + 0, + 2 + ), + ( + 1, + 29, + 7, + 0, + 2 + ), + ( + 1, + 30, + 7, + 0, + 2 + ), + ( + 1, + 31, + 1, + 11, + 3 + ), + ( + 1, + 1, + 3, + 3, + 3 + ), + ( + 1, + 2, + 4, + 8, + 3 + ), + ( + 1, + 3, + 5, + 1, + 3 + ), + ( + 1, + 4, + 2, + 14, + 3 + ), + ( + 1, + 5, + 4, + 91, + 3 + ), + ( + 1, + 7, + 1, + 15, + 3 + ), + ( + 1, + 8, + 4, + 10, + 3 + ), + ( + 1, + 9, + 3, + 13, + 3 + ), + ( + 1, + 10, + 1, + 10, + 3 + ), + ( + 1, + 11, + 2, + 84, + 3 + ), + ( + 2, + 12, + 5, + 35, + 3 + ), + ( + 2, + 13, + 5, + 30, + 3 + ), + ( + 2, + 14, + 1, + 15, + 3 + ), + ( + 2, + 15, + 2, + 17, + 3 + ), + ( + 2, + 16, + 1, + 3, + 3 + ), + ( + 2, + 17, + 2, + 9, + 3 + ), + ( + 2, + 18, + 4, + 16, + 3 + ), + ( + 2, + 19, + 4, + 4, + 3 + ), + ( + 2, + 21, + 4, + 14, + 3 + ), + ( + 2, + 22, + 4, + 12, + 3 + ), + ( + 2, + 23, + 2, + 10, + 3 + ), + ( + 2, + 24, + 7, + 0, + 3 + ), + ( + 2, + 25, + 7, + 0, + 3 + ), + ( + 2, + 26, + 7, + 0, + 3 + ), + ( + 1, + 27, + 7, + 0, + 3 + ), + ( + 1, + 28, + 7, + 0, + 3 + ), + ( + 1, + 29, + 7, + 0, + 3 + ), + ( + 1, + 30, + 7, + 0, + 3 + ), + ( + 1, + 31, + 1, + 11, + 4 + ), + ( + 1, + 1, + 3, + 3, + 4 + ), + ( + 1, + 2, + 4, + 8, + 4 + ), + ( + 1, + 3, + 5, + 1, + 4 + ), + ( + 1, + 4, + 2, + 14, + 4 + ), + ( + 1, + 5, + 4, + 91, + 4 + ), + ( + 1, + 7, + 1, + 15, + 4 + ), + ( + 1, + 8, + 4, + 10, + 4 + ), + ( + 1, + 9, + 3, + 13, + 4 + ), + ( + 1, + 10, + 1, + 10, + 4 + ), + ( + 1, + 11, + 2, + 84, + 4 + ), + ( + 2, + 12, + 5, + 35, + 4 + ), + ( + 2, + 13, + 5, + 30, + 4 + ), + ( + 2, + 14, + 1, + 15, + 4 + ), + ( + 2, + 15, + 2, + 17, + 4 + ), + ( + 2, + 16, + 1, + 3, + 4 + ), + ( + 2, + 17, + 2, + 9, + 4 + ), + ( + 2, + 18, + 4, + 16, + 4 + ), + ( + 2, + 19, + 4, + 4, + 4 + ), + ( + 2, + 21, + 4, + 14, + 4 + ), + ( + 2, + 22, + 4, + 12, + 4 + ), + ( + 2, + 23, + 2, + 10, + 4 + ), + ( + 2, + 24, + 7, + 0, + 4 + ), + ( + 2, + 25, + 7, + 0, + 4 + ), + ( + 2, + 26, + 7, + 0, + 4 + ), + ( + 1, + 27, + 7, + 0, + 4 + ), + ( + 1, + 28, + 7, + 0, + 4 + ), + ( + 1, + 29, + 7, + 0, + 4 + ), + ( + 1, + 30, + 7, + 0, + 4 + ); diff --git a/migrations/20230327025719_add_team_players.up.sql b/migrations/20230327025719_add_team_players.up.sql deleted file mode 100644 index a39eaf7..0000000 --- a/migrations/20230327025719_add_team_players.up.sql +++ /dev/null @@ -1,178 +0,0 @@ --- Add up migration script here -INSERT INTO team_players - (team, player, position, player_number) -VALUES - ( - 1, - 31, - 1, - 11 - ), - ( - 1, - 1, - 3, - 3 - ), - ( - 1, - 2, - 4, - 8 - ), - ( - 1, - 3, - 5, - 1 - ), - ( - 1, - 4, - 2, - 14 - ), - ( - 1, - 5, - 4, - 91 - ), - ( - 1, - 7, - 1, - 15 - ), - ( - 1, - 8, - 4, - 10 - ), - ( - 1, - 9, - 3, - 13 - ), - ( - 1, - 10, - 1, - 10 - ), - ( - 1, - 11, - 2, - 84 - ), - ( - 2, - 12, - 5, - 35 - ), - ( - 2, - 13, - 5, - 30 - ), - ( - 2, - 14, - 1, - 15 - ), - ( - 2, - 15, - 2, - 17 - ), - ( - 2, - 16, - 1, - 3 - ), - ( - 2, - 17, - 2, - 9 - ), - ( - 2, - 18, - 4, - 16 - ), - ( - 2, - 19, - 4, - 4 - ), - ( - 2, - 21, - 4, - 14 - ), - ( - 2, - 22, - 4, - 12 - ), - ( - 2, - 23, - 2, - 10 - ), - ( - 2, - 24, - 7, - 0 - ), - ( - 2, - 25, - 7, - 0 - ), - ( - 2, - 26, - 7, - 0 - ), - ( - 1, - 27, - 7, - 0 - ), - ( - 1, - 28, - 7, - 0 - ), - ( - 1, - 29, - 7, - 0 - ), - ( - 1, - 30, - 7, - 0 - ); diff --git a/migrations/20230327030604_add_games.up.sql b/migrations/20230327030604_add_games.up.sql deleted file mode 100644 index cbc6e94..0000000 --- a/migrations/20230327030604_add_games.up.sql +++ /dev/null @@ -1,31 +0,0 @@ -INSERT INTO games - (id, name, division, team_home, team_away) -VALUES - ( - 1, - 'Game 1', - 1, -- LV/D - 1, -- Bullseye - 2 -- Seecats - ), - ( - 2, - 'Game 2', - 1, -- LV/D - 1, -- Bullseye - 2 -- Seecats - ), - ( - 3, - 'Game 3', - 1, -- LV/D - 1, -- Bullseye - 2 -- Seecats - ), - ( - 4, - 'Game 4', - 1, -- LV/D - 1, -- Bullseye - 2 -- Seecats - ); diff --git a/migrations/20230327224840_create_shots.up.sql b/migrations/20230327224840_create_shots.up.sql index 46d2718..7a6e885 100644 --- a/migrations/20230327224840_create_shots.up.sql +++ b/migrations/20230327224840_create_shots.up.sql @@ -10,8 +10,6 @@ CREATE TABLE IF NOT EXISTS shots ( on_net BOOLEAN NOT NULL, -- did the puck go in? goal BOOLEAN NOT NULL, - -- what team was the shooter on - shooter_team INTEGER NOT NULL, -- which player is the shooter shooter INTEGER NOT NULL, -- which player was the goalie @@ -28,32 +26,27 @@ CREATE TABLE IF NOT EXISTS shots ( -- was the shooter a real player CONSTRAINT shooter_fk FOREIGN KEY(shooter) - REFERENCES players(id) + REFERENCES game_players(id) ON DELETE RESTRICT, -- was the assistant is a real player CONSTRAINT assistant_fk FOREIGN KEY(assistant) - REFERENCES players(id) + REFERENCES game_players(id) ON DELETE RESTRICT, -- was the second assistant a real player CONSTRAINT assistant_second_fk FOREIGN KEY(assistant_second) - REFERENCES players(id) + REFERENCES game_players(id) ON DELETE RESTRICT, -- was the goalie a real player CONSTRAINT goalie_fk FOREIGN KEY(goalie) - REFERENCES players(id) + REFERENCES game_players(id) ON DELETE RESTRICT, -- was the (optional) blocker a real player CONSTRAINT blocker_fk FOREIGN KEY(blocker) - REFERENCES players(id) - ON DELETE RESTRICT, - -- was the shooter's team a real team - CONSTRAINT shooter_team_fk - FOREIGN KEY(shooter_team) - REFERENCES teams(id) + REFERENCES game_players(id) ON DELETE RESTRICT, -- is the period references a real period CONSTRAINT period_fk diff --git a/migrations/20230327235843_add_shots.up.sql b/migrations/20230327235843_add_shots.up.sql index 9f2bae7..5d8e9ec 100644 --- a/migrations/20230327235843_add_shots.up.sql +++ b/migrations/20230327235843_add_shots.up.sql @@ -1,11 +1,10 @@ -- Add up migration script here INSERT INTO shots - (shooter_team, goalie, shooter, period, period_time, video_timestamp, assistant, assistant_second, on_net, goal) + (goalie, shooter, period, period_time, video_timestamp, assistant, assistant_second, on_net, goal) VALUES ( - 1, 12, - 1, + 2, 1, 1018, null, @@ -15,8 +14,7 @@ VALUES false ), ( - 2, - 3, + 4, 18, 1, 912, @@ -27,8 +25,7 @@ VALUES false ), ( - 2, - 3, + 4, 16, 1, 736, @@ -39,8 +36,7 @@ VALUES false ), ( - 2, - 3, + 4, 14, 1, 638, @@ -51,9 +47,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 1, 495, null, @@ -63,9 +58,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 1, 325, null, @@ -75,9 +69,8 @@ VALUES false ), ( - 2, - 3, - 21, + 4, + 20, 1, 221, null, @@ -87,9 +80,8 @@ VALUES false ), ( - 1, 12, - 1, + 2, 1, 171, null, @@ -99,7 +91,6 @@ VALUES false ), ( - 1, 12, 9, 1, @@ -111,8 +102,7 @@ VALUES false ), ( - 2, - 3, + 4, 16, 2, 742, @@ -123,9 +113,8 @@ VALUES false ), ( - 2, - 3, - 23, + 4, + 22, 2, 733, null, @@ -135,9 +124,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 2, 676, null, @@ -147,9 +135,8 @@ VALUES false ), ( - 1, 12, - 4, + 5, 2, 651, null, @@ -159,7 +146,6 @@ VALUES false ), ( - 1, 12, 10, 2, @@ -171,9 +157,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 2, 321, null, @@ -183,8 +168,7 @@ VALUES false ), ( - 2, - 3, + 4, 14, 2, 243, @@ -195,9 +179,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 2, 174, null, @@ -207,9 +190,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 2, 160, null, @@ -219,8 +201,7 @@ VALUES false ), ( - 2, - 3, + 4, 16, 3, 517, @@ -231,8 +212,7 @@ VALUES false ), ( - 2, - 3, + 4, 14, 3, 503, @@ -243,9 +223,8 @@ VALUES true ), ( - 1, 12, - 1, + 2, 3, 433, null, @@ -255,9 +234,8 @@ VALUES false ), ( - 2, - 3, - 22, + 4, + 21, 3, 297, null, @@ -267,9 +245,8 @@ VALUES false ), ( - 2, - 3, - 23, + 4, + 22, 3, 212, null, @@ -279,9 +256,8 @@ VALUES false ), ( - 1, 12, - 2, + 3, 3, 30, null, @@ -291,7 +267,6 @@ VALUES false ), ( - 1, 12, 7, 3, @@ -303,9 +278,8 @@ VALUES true ), ( - 2, - 3, - 22, + 33, + 50, 4, 1120, 329, @@ -315,9 +289,8 @@ VALUES false ), ( - 2, - 3, - 15, + 33, + 44, 4, 828, 621, @@ -327,9 +300,8 @@ VALUES false ), ( - 1, - 12, - 4, + 41, + 34, 4, 465, 985, @@ -339,9 +311,8 @@ VALUES false ), ( - 2, - 3, - 22, + 33, + 50, 4, 107, 1343, @@ -351,9 +322,8 @@ VALUES false ), ( - 1, - 12, - 9, + 41, + 38, 4, 47, 1402, @@ -363,21 +333,19 @@ VALUES false ), ( - 1, - 13, - 31, + 42, + 30, 5, 1186, 1649, - 2, + 32, null, true, true ), ( - 2, - 3, - 22, + 33, + 50, 5, 1082, 1754, @@ -387,9 +355,8 @@ VALUES false ), ( - 1, - 13, - 2, + 42, + 32, 5, 990, 1845, @@ -399,9 +366,8 @@ VALUES false ), ( - 1, - 13, - 11, + 42, + 40, 5, 870, 1966, @@ -411,9 +377,8 @@ VALUES false ), ( - 1, - 13, - 1, + 42, + 31, 5, 778, 2059, @@ -423,9 +388,8 @@ VALUES false ), ( - 1, - 13, - 7, + 42, + 36, 5, 632, 2203, @@ -435,9 +399,8 @@ VALUES false ), ( - 1, - 13, - 2, + 42, + 32, 5, 505, 2451, @@ -447,9 +410,8 @@ VALUES false ), ( - 2, - 3, - 14, + 33, + 43, 5, 300, 2536, @@ -459,9 +421,8 @@ VALUES false ), ( - 2, - 3, - 14, + 33, + 43, 5, 262, 2574, @@ -471,9 +432,8 @@ VALUES false ), ( - 1, - 13, - 7, + 42, + 36, 5, 168, 2668, @@ -483,9 +443,8 @@ VALUES false ), ( - 2, - 3, - 16, + 33, + 45, 5, 77, 2758, @@ -495,9 +454,8 @@ VALUES false ), ( - 2, - 3, - 16, + 33, + 45, 5, 74, 2761, @@ -507,9 +465,8 @@ VALUES false ), ( - 1, - 12, - 1, + 41, + 31, 6, 1144, 3101, @@ -519,9 +476,8 @@ VALUES false ), ( - 1, - 12, - 9, + 41, + 38, 6, 1048, 3197, @@ -531,9 +487,8 @@ VALUES false ), ( - 1, - 12, - 9, + 41, + 38, 6, 979, 3265, @@ -543,9 +498,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 875, 3369, @@ -555,9 +509,8 @@ VALUES false ), ( - 2, - 3, - 16, + 33, + 45, 6, 738, 3507, @@ -567,9 +520,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 673, 3572, @@ -579,9 +531,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 621, 3623, @@ -591,9 +542,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 591, 3654, @@ -603,9 +553,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 570, 3675, @@ -615,9 +564,8 @@ VALUES false ), ( - 1, - 12, - 2, + 41, + 32, 6, 552, 3693, @@ -627,9 +575,8 @@ VALUES false ), ( - 1, - 12, - 1, + 41, + 31, 6, 22, 4402, @@ -639,33 +586,30 @@ VALUES false ), ( - 2, - 3, - 22, + 62, + 79, 7, 657, 1268, - 21, + 78, null, true, true ), ( - 1, - 13, - 2, + 71, + 61, 7, 565, 1360, - 7, + 65, null, true, true ), ( - 1, - 13, - 2, + 71, + 61, 7, 385, 1539, @@ -675,9 +619,8 @@ VALUES false ), ( - 1, - 13, - 1, + 71, + 60, 7, 173, 1751, @@ -687,9 +630,8 @@ VALUES false ), ( - 1, - 13, - 7, + 71, + 65, 7, 99, 1825, @@ -699,9 +641,8 @@ VALUES false ), ( - 1, - 13, - 1, + 71, + 60, 7, 74, 1850, @@ -711,9 +652,8 @@ VALUES false ), ( - 1, - 13, - 2, + 71, + 61, 7, 70, 1853, @@ -723,9 +663,8 @@ VALUES false ), ( - 1, - 13, - 1, + 71, + 60, 7, 68, 1855, @@ -735,9 +674,8 @@ VALUES false ), ( - 2, - 3, - 16, + 62, + 74, 8, 675, 2120, @@ -747,9 +685,8 @@ VALUES false ), ( - 1, - 12, - 2, + 70, + 61, 8, 540, 2255, @@ -759,9 +696,8 @@ VALUES false ), ( - 1, - 12, - 2, + 70, + 61, 8, 512, 2282, @@ -771,9 +707,8 @@ VALUES false ), ( - 1, - 12, - 1, + 70, + 60, 8, 470, 2324, @@ -783,9 +718,8 @@ VALUES false ), ( - 1, - 12, - 2, + 70, + 61, 8, 412, 2382, @@ -795,9 +729,8 @@ VALUES false ), ( - 2, - 3, - 17, + 62, + 75, 8, 252, 2543, @@ -807,9 +740,8 @@ VALUES false ), ( - 1, - 12, - 2, + 70, + 61, 8, 162, 2677, @@ -819,9 +751,8 @@ VALUES false ), ( - 2, - 3, - 16, + 62, + 74, 8, 100, 2139, @@ -831,9 +762,8 @@ VALUES false ), ( - 2, - 3, - 21, + 62, + 78, 8, 1042, 3158, @@ -843,9 +773,8 @@ VALUES false ), ( - 2, - 3, - 21, + 62, + 78, 8, 832, 3367, @@ -855,9 +784,8 @@ VALUES false ), ( - 1, - 12, - 2, + 70, + 61, 9, 549, 3651, @@ -867,9 +795,8 @@ VALUES false ), ( - 1, - 12, - 1, + 70, + 60, 9, 282, 3918, @@ -879,9 +806,8 @@ VALUES true ), ( - 1, - 12, - 2, + 70, + 61, 9, 153, 4047, @@ -891,9 +817,8 @@ VALUES false ), ( - 2, - 3, - 22, + 91, + 108, 10, 1094, 259, @@ -903,9 +828,8 @@ VALUES false ), ( - 1, - 12, - 7, + 99, + 94, 10, 1027, 326, @@ -915,9 +839,8 @@ VALUES false ), ( - 1, - 12, - 2, + 99, + 90, 10, 888, 466, @@ -927,9 +850,8 @@ VALUES false ), ( - 1, - 12, - 2, + 99, + 90, 10, 879, 474, @@ -939,9 +861,8 @@ VALUES false ), ( - 1, - 12, - 2, + 99, + 90, 10, 873, 481, @@ -951,9 +872,8 @@ VALUES false ), ( - 1, - 12, - 7, + 99, + 94, 10, 836, 518, @@ -963,9 +883,8 @@ VALUES false ), ( - 1, - 12, - 9, + 99, + 96, 10, 794, 560, @@ -975,9 +894,8 @@ VALUES false ), ( - 2, - 12, - 22, + 99, + 108, 10, 754, 600, @@ -987,9 +905,8 @@ VALUES false ), ( - 2, - 3, - 18, + 91, + 105, 10, 691, 663, @@ -999,9 +916,8 @@ VALUES true ), ( - 1, - 12, - 9, + 99, + 96, 10, 164, 1190, @@ -1011,21 +927,19 @@ VALUES false ), ( - 1, - 12, - 2, + 99, + 90, 10, 106, 1247, - 31, + 88, null, true, true ), ( - 2, - 3, - 21, + 91, + 107, 10, 19, 1335, @@ -1035,9 +949,8 @@ VALUES false ), ( - 1, - 13, - 31, + 100, + 88, 11, 1081, 1663, @@ -1047,9 +960,8 @@ VALUES false ), ( - 1, - 13, - 1, + 100, + 89, 11, 953, 1792, @@ -1059,21 +971,19 @@ VALUES false ), ( - 1, - 13, - 2, + 100, + 90, 11, 883, 1862, - 7, + 94, null, true, true ), ( - 1, - 13, - 2, + 100, + 90, 11, 789, 1956, @@ -1083,9 +993,8 @@ VALUES false ), ( - 1, - 13, - 1, + 100, + 89, 11, 697, 2047, @@ -1095,9 +1004,8 @@ VALUES false ), ( - 1, - 13, - 4, + 100, + 92, 11, 696, 2048, @@ -1107,9 +1015,8 @@ VALUES false ), ( - 2, - 3, - 16, + 91, + 103, 11, 668, 2077, @@ -1119,9 +1026,8 @@ VALUES false ), ( - 1, - 13, - 2, + 100, + 90, 11, 619, 2126, @@ -1131,21 +1037,19 @@ VALUES false ), ( - 1, - 13, - 2, + 100, + 90, 11, 613, 2132, - 1, + 89, null, true, true ), ( - 1, - 13, - 31, + 100, + 88, 11, 515, 2230, @@ -1155,21 +1059,19 @@ VALUES false ), ( - 1, - 13, - 2, + 100, + 90, 11, 514, 2231, - 31, + 88, null, true, true ), ( - 2, - 3, - 16, + 91, + 103, 11, 425, 2320, @@ -1179,33 +1081,30 @@ VALUES false ), ( - 2, - 3, - 14, + 91, + 101, 12, 1193, 2934, - 16, + 103, null, true, true ), ( - 2, - 3, - 16, + 91, + 103, 12, 972, 3154, - 14, + 101, null, true, true ), ( - 1, - 12, - 1, + 99, + 89, 12, 892, 3234, @@ -1215,9 +1114,8 @@ VALUES false ), ( - 1, - 12, - 1, + 99, + 89, 12, 868, 3258, @@ -1227,9 +1125,8 @@ VALUES false ), ( - 2, - 3, - 14, + 91, + 101, 12, 780, 3346, @@ -1239,9 +1136,8 @@ VALUES false ), ( - 2, - 3, - 21, + 91, + 107, 12, 738, 3388, @@ -1251,9 +1147,8 @@ VALUES false ), ( - 1, - 12, - 2, + 99, + 90, 12, 352, 3774, @@ -1263,9 +1158,8 @@ VALUES false ), ( - 2, - 3, - 16, + 91, + 103, 12, 31, 4185, @@ -1275,9 +1169,8 @@ VALUES false ), ( - 2, - 3, - 14, + 91, + 101, 12, 28, 4188, @@ -1287,13 +1180,12 @@ VALUES false ), ( - 2, - 3, - 22, + 91, + 108, 12, 16, 4232, - 16, + 103, null, true, true diff --git a/src/db.rs b/src/db.rs index e93fb94..0ed89d8 100644 --- a/src/db.rs +++ b/src/db.rs @@ -4,6 +4,6 @@ use sqlx::postgres::PgPoolOptions; pub async fn connect() -> Pool { PgPoolOptions::new() .max_connections(8) - .connect("postgres://ibihf:ibihf@localhost/ibihf").await + .connect("postgres://ibihf2:ibihf@localhost/ibihf").await .unwrap() } diff --git a/src/main.rs b/src/main.rs index f8affa7..94471c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,14 +5,13 @@ mod filters; mod translations; use translations::{ - TranslatedKey, SupportedLanguage, }; use crate::model::{ League, Team, Division, - TeamPlayer, + GamePlayer, Player, Shot, Game, @@ -45,7 +44,6 @@ use axum::{ }, response::{ Json, - Html, IntoResponse, }, routing::get, @@ -233,7 +231,7 @@ async fn league_html(State(server_config): State, Path(lang): Path< (StatusCode::OK, leagues_template) } -async fn divisions_for_league_html(State(server_config): State, Path(league_id): Path, Path(lang): Path) -> impl IntoResponse { +async fn divisions_for_league_html(State(server_config): State, Path((lang,league_id)): Path<(SupportedLanguage, i32)>) -> impl IntoResponse { let league = League::get(&*server_config.db_pool, league_id) .await .unwrap(); @@ -248,7 +246,7 @@ async fn divisions_for_league_html(State(server_config): State, Pat (StatusCode::OK, html) } -async fn games_for_division_html(State(server_config): State, Path(division_id): Path, Path(lang): Path) -> impl IntoResponse { +async fn games_for_division_html(State(server_config): State, Path((lang,division_id)): Path<(SupportedLanguage,i32)>) -> impl IntoResponse { let division = Division::get(&*server_config.db_pool, division_id) .await .unwrap(); @@ -262,7 +260,7 @@ async fn games_for_division_html(State(server_config): State, Path( }; (StatusCode::OK, games_template) } -async fn score_for_game_html(State(server_config): State, Path(game_id): Path, Path(lang): Path) -> impl IntoResponse { +async fn score_for_game_html(State(server_config): State, Path((lang,game_id)): Path<(SupportedLanguage, i32)>) -> impl IntoResponse { let game = sqlx::query_as::<_, Game>( "SELECT * FROM games WHERE id = $1;" ) @@ -318,9 +316,9 @@ macro_rules! impl_all_query_types { } impl_all_query_types!( - TeamPlayer, - team_player_all, - team_player_id + GamePlayer, + game_player_all, + game_player_id ); impl_all_query_types!( Player, diff --git a/src/model.rs b/src/model.rs index 6782c2d..40444e1 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,6 +1,6 @@ use sqlx::FromRow; use sqlx::types::chrono::{DateTime, Utc}; -use chrono::serde::{ts_seconds, ts_seconds_option}; +use chrono::serde::ts_seconds; use serde::{Serialize, Deserialize}; pub trait TableName { @@ -20,19 +20,11 @@ pub struct League { #[ormx(default)] pub id: i32, pub name: String, - #[serde(with = "ts_seconds")] - pub start_date: DateTime, - #[serde(with = "ts_seconds_option")] - pub end_date: Option>, } #[derive(FromRow, Serialize, Deserialize, Debug, ormx::Patch)] #[ormx(table_name = "leagues", table = League, id = "id")] pub struct NewLeague { pub name: String, - #[serde(with = "ts_seconds")] - pub start_date: DateTime, - #[serde(with = "ts_seconds_option")] - pub end_date: Option>, } #[derive(FromRow, Serialize, Deserialize, Debug, ormx::Table)] @@ -102,7 +94,6 @@ pub struct NewPlayer { pub struct Shot { #[ormx(default)] pub id: i32, - pub shooter_team: i32, pub shooter: i32, pub goalie: i32, pub assistant: Option, @@ -118,13 +109,14 @@ pub struct Shot { } #[derive(FromRow, Deserialize, Serialize, Debug, ormx::Table)] -#[ormx(table = "team_players", id = id, insertable, deletable)] -pub struct TeamPlayer { +#[ormx(table = "game_players", id = id, insertable, deletable)] +pub struct GamePlayer { #[ormx(default)] pub id: i32, pub team: i32, pub player: i32, pub position: i32, + pub game: i32, } #[derive(FromRow, Deserialize, Serialize, Debug, ormx::Table)] @@ -139,19 +131,29 @@ pub struct Game { pub team_away: i32, } -impl_table_name!(TeamPlayer, "team_players"); +#[derive(FromRow, Deserialize, Serialize, Debug, ormx::Table)] +#[ormx(table = "periods", id = id, insertable, deletable)] +pub struct Period { + pub id: i32, + pub period_type: i32, + #[ormx(get_many(i32))] + pub game: i32, +} + +impl_table_name!(GamePlayer, "game_players"); impl_table_name!(Player, "players"); impl_table_name!(League, "leagues"); impl_table_name!(Division, "divisions"); impl_table_name!(Team, "teams"); impl_table_name!(Shot, "shots"); impl_table_name!(Game, "games"); +impl_table_name!(Period, "periods"); #[cfg(test)] mod tests { use std::env; use crate::model::{ - TeamPlayer, + GamePlayer, Player, League, Division, @@ -207,7 +209,7 @@ mod tests { } } } - generate_select_test!(TeamPlayer, select_team_player); + generate_select_test!(GamePlayer, selec_game_player); generate_select_test!(Player, select_player); generate_select_test!(League, select_league); generate_select_test!(Division, select_division); diff --git a/src/views.rs b/src/views.rs index 13fa728..49eb8ff 100644 --- a/src/views.rs +++ b/src/views.rs @@ -4,9 +4,43 @@ use crate::model::{ Player, Game, League, + Division, + Period, }; use serde::{Serialize, Deserialize}; +#[derive(FromRow, Serialize, Deserialize, Debug)] +pub struct IihfPoints { + pub team_id: i32, + pub team_name: String, + pub reg_wins: i64, + pub reg_losses: i64, + pub ot_wins: i64, + pub ot_losses: i64, + pub ties: i64, +} + +impl Division { + pub async fn team_iihf_points(&self, pool: &PgPool) -> Result, sqlx::Error> { + let games = Game::by_division(pool, self.id) + .await + .unwrap(); + let mut scores = Vec::new(); + for game in games { + let score = get_score_from_game(pool, &game) + .await + .unwrap(); + let periods_len = Period::by_game(pool, game.id) + .await + .unwrap() + .len(); + scores.push((periods_len, score)); + } + + todo!() + } +} + #[derive(FromRow, Deserialize, Serialize, Debug)] pub struct TeamStats { pub name: String, @@ -39,53 +73,45 @@ SELECT SELECT COUNT(shots.id) FROM shots JOIN periods ON periods.id=shots.period - WHERE shooter=players.id - AND goal=true - AND periods.game=$1 - ) AS goals, + WHERE shots.goal=true + AND (shots.shooter=game_players.id + OR shots.assistant=game_players.id + OR shots.assistant_second=game_players.id) + ) AS points, ( SELECT COUNT(shots.id) FROM shots JOIN periods ON periods.id=shots.period - WHERE (assistant=players.id - OR assistant_second=players.id) - AND goal=true - AND periods.game=$1 - ) AS assists, + WHERE shots.goal=true + AND shots.shooter=game_players.id + ) AS goals, ( SELECT COUNT(shots.id) FROM shots JOIN periods ON periods.id=shots.period - WHERE (assistant=players.id - OR assistant_second=players.id - OR shooter=players.id) - AND goal=true - AND periods.game=$1 - ) AS points, - players.name AS name -FROM players -JOIN shots ON shots.shooter=players.id OR shots.assistant=players.id -JOIN periods ON periods.id=shots.period -WHERE periods.game = $1 -GROUP BY players.id --- exclude players who do not have any points --- NOTE: we can NOT use the aliased column "points" here, so we need to recalculate it. --- This should not be a performance problem because the optimizer should deal with duplicate sub-queries. -HAVING + WHERE shots.goal=true + AND (shots.assistant=game_players.id + OR shots.assistant_second=game_players.id) + ) AS assists, ( + SELECT name + FROM players + WHERE id=game_players.player + ) AS name +FROM game_players +WHERE game_players.game=$1 + AND ( SELECT COUNT(shots.id) FROM shots JOIN periods ON periods.id=shots.period - WHERE (assistant=players.id - OR assistant_second=players.id - OR shooter=players.id) - AND goal=true - AND periods.game=$1 + WHERE shots.goal=true + AND (shots.shooter=game_players.id + OR shots.assistant=game_players.id + OR shots.assistant_second=game_players.id) ) > 0 ORDER BY points DESC, - goals DESC, - players.name; + goals DESC; "#; sqlx::query_as::<_, PlayerStats>(query) .bind(game.id) @@ -98,12 +124,13 @@ pub async fn get_latest_league_for_player(pool: &PgPool, player: &Player) -> Res r#" SELECT leagues.* FROM players -JOIN team_players ON team_players.player=players.id -JOIN teams ON teams.id=team_players.team +JOIN game_players ON game_players.player=players.id +JOIN games ON games.id=game_players.game +JOIN teams ON teams.id=game_players.team JOIN divisions ON divisions.id=teams.division JOIN leagues ON leagues.id=divisions.league WHERE players.id=$1 -ORDER BY leagues.end_date DESC +ORDER BY games.end_at DESC LIMIT 1; "#; sqlx::query_as::<_, League>(query) @@ -163,62 +190,41 @@ WHERE id=$1; } pub async fn get_latest_stats(pool: &PgPool, player: &Player) -> Result, sqlx::Error> { - let query = r#" + let query = +r#" SELECT - shots.shooter AS player_id, - shots.assistant AS first_assist_id, - shots.assistant_second AS second_assist_id, - ( - SELECT name - FROM players - WHERE id=shots.shooter - ) AS player_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant - ) AS first_assist_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant_second - ) AS second_assist_name, - ( - SELECT player_number - FROM team_players - WHERE player=shots.shooter - AND team=shots.shooter_team - ) AS player_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant - AND team=shots.shooter_team - ) AS first_assist_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant_second - AND team=shots.shooter_team - ) AS second_assist_number, + players.id AS player_id, + p_assist.id AS first_assist_id, + p_assist_second.id AS second_assist_id, + players.name AS player_name, + p_assist.name AS first_assist_name, + p_assist_second.name AS second_assist_name, + game_players.player_number AS player_number, + gp_assist.player_number AS first_assist_number, + gp_assist_second.player_number AS second_assist_number, teams.name AS team_name, teams.id AS team_id, - shots.shooter_team AS player_team, shots.period_time AS time_remaining, period_types.id AS period_id, period_types.short_name AS period_short_name FROM shots +JOIN game_players ON game_players.id=shots.shooter +JOIN players ON players.id=game_players.player +JOIN teams ON teams.id=game_players.team +LEFT JOIN game_players gp_assist ON gp_assist.id=shots.assistant +LEFT JOIN players p_assist ON p_assist.id=gp_assist.player +LEFT JOIN game_players gp_assist_second ON gp_assist_second.id=shots.assistant_second +LEFT JOIN players p_assist_second ON p_assist_second.id=gp_assist_second.id JOIN periods ON shots.period=periods.id -JOIN period_types ON periods.period_type=period_types.id -JOIN teams ON shots.shooter_team=teams.id -WHERE shots.shooter=$1 +JOIN period_types ON period_types.id=periods.period_type +WHERE players.id=$1 ORDER BY shots.created_at DESC, periods.period_type DESC, shots.period_time ASC LIMIT 5; "#; - sqlx::query_as::<_, GoalDetails>(query) + sqlx::query_as::<_, GoalDetails>(&query) .bind(player.id) .fetch_all(pool) .await @@ -227,30 +233,26 @@ LIMIT 5; pub async fn get_all_player_stats(pool: &PgPool, player: &Player) -> Result { let query =r#" SELECT - ( - SELECT COUNT(id) - FROM shots - WHERE shots.goal=true - AND shots.shooter=players.id - ) AS goals, - ( - SELECT COUNT(id) - FROM shots - WHERE shots.goal=true - AND (shots.assistant=players.id - OR shots.assistant_second=players.id) - ) AS assists, - ( - SELECT COUNT(id) - FROM shots - WHERE shots.goal=true - AND (shots.shooter=players.id - OR shots.assistant=players.id - OR shots.assistant_second=players.id) - ) AS points, + COUNT(goals) AS goals, + COUNT(assists) AS assists, + COUNT(points) AS points, players.name AS name FROM players -WHERE id=$1; +JOIN game_players ON game_players.player=players.id +LEFT JOIN shots points + ON (points.shooter=game_players.id + OR points.assistant=game_players.id + OR points.assistant_second=game_players.id) + AND points.goal=true +LEFT JOIN shots goals + ON goals.shooter=game_players.id + AND goals.goal=true +LEFT JOIN shots assists + ON (points.assistant=game_players.id + OR points.assistant_second=game_players.id) + AND points.goal=true +WHERE players.id=$1 +GROUP BY players.id; "#; sqlx::query_as::<_, PlayerStats>(query) .bind(player.id) @@ -266,6 +268,7 @@ pub struct GoalDetails { pub team_name: String, pub team_id: i32, pub time_remaining: i32, + pub period_id: i32, pub period_short_name: String, pub first_assist_name: Option, pub first_assist_number: Option, @@ -300,51 +303,30 @@ SELECT shots.shooter AS player_id, shots.assistant AS first_assist_id, shots.assistant_second AS second_assist_id, - ( - SELECT name - FROM players - WHERE id=shots.shooter - ) AS player_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant - ) AS first_assist_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant_second - ) AS second_assist_name, - ( - SELECT player_number - FROM team_players - WHERE player=shots.shooter - AND team=shots.shooter_team - ) AS player_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant - AND team=shots.shooter_team - ) AS first_assist_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant_second - AND team=shots.shooter_team - ) AS second_assist_number, + players.name AS player_name, + p_assist.name AS first_assist_name, + p_assist_second.name AS second_assist_name, + game_players.player_number AS player_number, + gp_assist.player_number AS first_assist_number, + gp_assist_second.player_number AS second_assist_number, teams.name AS team_name, teams.id AS team_id, - shots.shooter_team AS player_team, shots.period_time AS time_remaining, period_types.id AS period_id, period_types.short_name AS period_short_name FROM shots -JOIN periods ON shots.period=periods.id -JOIN period_types ON periods.period_type=period_types.id -JOIN teams ON shots.shooter_team=teams.id +JOIN game_players ON game_players.id=shots.shooter +JOIN players ON players.id=game_players.player +LEFT JOIN game_players gp_assist ON gp_assist.id=shots.assistant +LEFT JOIN players p_assist ON p_assist.id=gp_assist.player +LEFT JOIN game_players gp_assist_second ON gp_assist.id=shots.assistant_second +LEFT JOIN players p_assist_second ON p_assist.id=gp_assist_second.player +JOIN teams ON teams.id=game_players.team +JOIN periods ON periods.id=shots.period +JOIN period_types ON period_types.id=periods.period_type +JOIN games ON games.id=periods.game WHERE shots.goal=true - AND periods.game=$1 + AND games.id=$1 ORDER BY periods.period_type ASC, shots.period_time DESC; @@ -362,49 +344,27 @@ SELECT shots.assistant AS first_assist_id, shots.assistant_second AS second_assist_id, shots.goal AS is_goal, - ( - SELECT name - FROM players - WHERE id=shots.shooter - ) AS player_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant - ) AS first_assist_name, - ( - SELECT name - FROM players - WHERE id=shots.assistant_second - ) AS second_assist_name, - ( - SELECT player_number - FROM team_players - WHERE player=shots.shooter - AND team=shots.shooter_team - ) AS player_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant - AND team=shots.shooter_team - ) AS first_assist_number, - ( - SELECT player_number - FROM team_players - WHERE player=shots.assistant_second - AND team=shots.shooter_team - ) AS second_assist_number, + players.name AS player_name, + p_assistant.name AS first_assist_name, + p_assistant_second.name AS second_assist_name, + game_players.player_number AS player_number, + gp_assistant.player_number AS first_assist_number, + gp_assistant_second.player_number AS second_assist_number, teams.name AS team_name, teams.id AS team_id, - shots.shooter_team AS player_team, shots.period_time AS time_remaining, period_types.id AS period_id, period_types.short_name AS period_short_name FROM shots +JOIN game_players ON game_players.id=shots.shooter +JOIN players ON players.id=game_players.player +JOIN teams ON teams.id=game_players.team +LEFT JOIN game_players gp_assistant ON gp_assistant.id=shots.assistant +LEFT JOIN players p_assistant ON p_assistant.id=gp_assistant.player +LEFT JOIN game_players gp_assistant_second ON gp_assistant_second.id=shots.assistant_second +LEFT JOIN players p_assistant_second ON p_assistant_second.id=gp_assistant_second.player JOIN periods ON shots.period=periods.id JOIN period_types ON periods.period_type=period_types.id -JOIN teams ON shots.shooter_team=teams.id WHERE periods.game=$1 ORDER BY periods.period_type ASC, @@ -418,25 +378,16 @@ ORDER BY pub async fn get_score_from_game(pool: &PgPool, game: &Game) -> Result, sqlx::Error> { let query = r#" SELECT - ( - SELECT COUNT(shots.id) - FROM shots - JOIN periods ON periods.id=shots.period - WHERE periods.game=$1 - AND shots.goal=true - AND shots.shooter_team=teams.id - ) AS goals, - ( - SELECT COUNT(shots.id) - FROM shots - JOIN periods ON periods.id=shots.period - WHERE periods.game=$1 - AND shooter_team=teams.id - ) AS shots, + COUNT(CASE WHEN shots.goal = true THEN shots.id END) AS goals, + COUNT(shots.id) AS shots, teams.name AS name FROM games -JOIN teams ON teams.id=games.team_home OR teams.id=games.team_away -WHERE games.id=$1; +JOIN periods ON periods.game=games.id +JOIN shots ON shots.period=periods.id +JOIN game_players ON game_players.id=shots.shooter +JOIN teams ON teams.id=game_players.team +WHERE games.id=$1 +GROUP BY teams.id; "#; sqlx::query_as::<_, TeamStats>(query) .bind(game.id) @@ -480,6 +431,7 @@ ORDER BY #[cfg(test)] mod tests { use std::env; + use ormx::Table; use crate::model::{ Game, Player, @@ -495,14 +447,27 @@ mod tests { get_league_player_stats, get_all_player_stats, get_latest_stats, + get_play_by_play_from_game, }; + + #[test] + fn check_play_by_play() { + tokio_test::block_on(async move { + let pool = db_connect().await; + let game = Game::get(&pool, 3) + .await + .unwrap(); + let pbp = get_play_by_play_from_game(&pool, &game) + .await + .unwrap(); + }) + } #[test] fn get_latest_stats_of_player() { tokio_test::block_on(async move { let pool = db_connect().await; - let player = sqlx::query_as::<_, Player>("SELECT * FROM id=2;") - .fetch_one(&pool) + let player = Player::get(&pool, 2) .await .unwrap(); let latest = get_latest_stats(&pool, &player) @@ -561,7 +526,7 @@ mod tests { fn check_score_details_from_game() { tokio_test::block_on(async move { let pool = db_connect().await; - let game = sqlx::query_as::<_, Game>("SELECT * FROM games WHERE id=1;") + let game = sqlx::query_as::<_, Game>("SELECT * FROM games WHERE id=3;") .fetch_one(&pool) .await .unwrap(); @@ -629,17 +594,17 @@ SELECT teams.name AS scorer_team_name, players.name AS scorer_name, positions.name AS position, - team_players.player_number AS scorer_number, + game_players.player_number AS scorer_number, shots.period_time AS period_time_left, period_types.name AS period_name FROM shots -JOIN teams ON teams.id=shots.shooter_team -JOIN players ON players.id=shots.shooter -JOIN team_players ON team_players.player=players.id AND team_players.team=teams.id +JOIN game_players ON game_players.id=shots.shooter +JOIN players ON players.id=game_players.player +JOIN teams ON teams.id=game_players.team JOIN periods ON periods.id=shots.period JOIN period_types ON period_types.id=periods.period_type -JOIN positions ON positions.id=team_players.position; +JOIN positions ON positions.id=game_players.position; "#; let result = sqlx::query_as::<_, Notification>(query) .fetch_one(&pool) diff --git a/templates/division_list.html b/templates/division_list.html index 143fa8e..313acd1 100644 --- a/templates/division_list.html +++ b/templates/division_list.html @@ -1,6 +1,6 @@

Divisions for the {{ league.name }}

diff --git a/templates/game_list.html b/templates/game_list.html index 77c4cda..e447a85 100644 --- a/templates/game_list.html +++ b/templates/game_list.html @@ -2,7 +2,7 @@ {% if games.len() > 0 %}
    {% for game in games %} -
  1. {{ game.name }}
  2. +
  3. {{ game.name }}
  4. {% endfor %}
{% else %}