aboutsummaryrefslogtreecommitdiff
path: root/planetwars-server/src/db/matches.rs
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-01-02 16:14:03 +0100
committerIlion Beyst <ilion.beyst@gmail.com>2022-01-02 16:14:03 +0100
commit85dcf3ba2fd0cf907610625399db691b274118bb (patch)
tree3fd041b1de19a9d3130be2045a7f9b9bd3a85fe0 /planetwars-server/src/db/matches.rs
parentbdb77f97d6af5a59e80d2b2552cd6994754cbf29 (diff)
downloadplanetwars.dev-85dcf3ba2fd0cf907610625399db691b274118bb.tar.xz
planetwars.dev-85dcf3ba2fd0cf907610625399db691b274118bb.zip
store matches in database
Diffstat (limited to 'planetwars-server/src/db/matches.rs')
-rw-r--r--planetwars-server/src/db/matches.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/planetwars-server/src/db/matches.rs b/planetwars-server/src/db/matches.rs
new file mode 100644
index 0000000..85f0631
--- /dev/null
+++ b/planetwars-server/src/db/matches.rs
@@ -0,0 +1,97 @@
+use chrono::NaiveDateTime;
+use diesel::{BelongingToDsl, RunQueryDsl};
+use diesel::{Connection, GroupedBy, PgConnection, QueryResult};
+
+use crate::schema::{match_players, matches};
+
+#[derive(Insertable)]
+#[table_name = "matches"]
+pub struct NewMatch<'a> {
+ pub log_path: &'a str,
+}
+
+#[derive(Insertable)]
+#[table_name = "match_players"]
+pub struct NewMatchPlayer {
+ /// id of the match this player is in
+ pub match_id: i32,
+ /// id of the bot behind this player
+ pub bot_id: i32,
+ /// player id within the match
+ pub player_id: i32,
+}
+
+#[derive(Queryable, Identifiable)]
+#[table_name = "matches"]
+pub struct MatchBase {
+ pub id: i32,
+ pub log_path: String,
+ pub created_at: NaiveDateTime,
+}
+
+#[derive(Queryable, Identifiable, Associations)]
+#[primary_key(match_id, player_id)]
+#[belongs_to(MatchBase, foreign_key = "match_id")]
+pub struct MatchPlayer {
+ pub match_id: i32,
+ pub bot_id: i32,
+ pub player_id: i32,
+}
+
+pub struct MatchPlayerData {
+ pub bot_id: i32,
+}
+
+pub fn create_match(
+ match_data: &NewMatch,
+ match_players: &[MatchPlayerData],
+ conn: &PgConnection,
+) -> QueryResult<i32> {
+ conn.transaction(|| {
+ let match_base = diesel::insert_into(matches::table)
+ .values(match_data)
+ .get_result::<MatchBase>(conn)?;
+
+ let match_players = match_players
+ .iter()
+ .enumerate()
+ .map(|(num, player_data)| NewMatchPlayer {
+ match_id: match_base.id,
+ bot_id: player_data.bot_id,
+ player_id: num as i32,
+ })
+ .collect::<Vec<_>>();
+
+ diesel::insert_into(match_players::table)
+ .values(&match_players)
+ .execute(conn)?;
+
+ Ok(match_base.id)
+ })
+}
+
+pub struct MatchData {
+ pub base: MatchBase,
+ pub match_players: Vec<MatchPlayer>,
+}
+
+pub fn list_matches(conn: &PgConnection) -> QueryResult<Vec<MatchData>> {
+ conn.transaction(|| {
+ let matches = matches::table.get_results::<MatchBase>(conn)?;
+
+ let match_players = MatchPlayer::belonging_to(&matches)
+ .load::<MatchPlayer>(conn)?
+ .grouped_by(&matches);
+
+ let res = matches
+ .into_iter()
+ .zip(match_players.into_iter())
+ .map(|(base, players)| MatchData {
+ base,
+ match_players: players.into_iter().collect(),
+ })
+ .collect();
+
+ Ok(res)
+ })
+}