use crate::schema::{DatabaseError, DbConn}; use serde::{Deserialize, Serialize}; use diesel::{QueryDsl, RunQueryDsl, Connection, ExpressionMethods}; use uuid::Uuid; table! { gamenight (id) { id -> diesel::sql_types::Uuid, name -> VarChar, datetime -> VarChar, owner_id -> Uuid, } } table! { known_games (id) { id -> diesel::sql_types::Uuid, name -> VarChar, } } table! { gamenight_gamelist(gamenight_id, game_id) { gamenight_id -> diesel::sql_types::Uuid, game_id -> diesel::sql_types::Uuid, } } table! { gamenight_participants(gamenight_id, user_id) { gamenight_id -> diesel::sql_types::Uuid, user_id -> diesel::sql_types::Uuid, } } #[derive(Serialize, Deserialize, Debug, Queryable, Clone, Insertable)] #[table_name = "known_games"] pub struct Game { pub id: Uuid, pub name: String, } #[derive(Serialize, Deserialize, Debug, Queryable, Insertable)] #[table_name = "gamenight"] pub struct GameNight { pub id: Uuid, pub name: String, pub datetime: String, pub owner_id: Uuid, } #[derive(Serialize, Deserialize, Debug, Queryable, Insertable)] #[table_name="gamenight_gamelist"] pub struct GamenightGameListEntry { pub gamenight_id: Uuid, pub game_id: Uuid } #[derive(Serialize, Deserialize, Debug, Queryable, Insertable, Identifiable)] #[table_name="gamenight_participants"] #[primary_key(gamenight_id, user_id)] pub struct GamenightParticipantsEntry { pub gamenight_id: Uuid, pub user_id: Uuid } #[derive(Serialize, Deserialize, Debug, Queryable)] pub struct DeleteGameNight { pub game_id: Uuid, } pub async fn get_all_gamenights(conn: DbConn) -> Result, DatabaseError> { Ok(conn.run(|c| gamenight::table.load::(c) ).await?) } pub async fn insert_gamenight(conn: DbConn, new_gamenight: GameNight, game_list: Vec) -> Result { Ok(conn.run(move |c| c.transaction(|| { diesel::insert_into(gamenight::table) .values(&new_gamenight) .execute(c)?; let entries: Vec = game_list.iter().map( |g| GamenightGameListEntry { gamenight_id: new_gamenight.id.clone(), game_id: g.id.clone() } ).collect(); diesel::insert_into(gamenight_gamelist::table) .values(entries) .execute(c) }) ).await?) } pub async fn get_gamenight(conn: &DbConn, game_id: Uuid) -> Result { Ok(conn.run(move |c| gamenight::table.find(game_id).first(c) ).await?) } pub async fn delete_gamenight(conn: &DbConn, game_id: Uuid) -> Result { Ok(conn.run(move |c| diesel::delete( gamenight::table.filter( gamenight::id.eq(game_id) ) ).execute(c) ).await?) } pub async fn get_all_known_games(conn: &DbConn) -> Result, DatabaseError> { Ok(conn.run(|c| known_games::table.load::(c) ).await?) } pub async fn add_game(conn: &DbConn, game: Game) -> Result { Ok(conn.run(|c| diesel::insert_into(known_games::table) .values(game) .execute(c) ).await?) } pub async fn add_unknown_games(conn: &DbConn, games: &mut Vec) -> Result<(), DatabaseError> { let all_games = get_all_known_games(conn).await?; for game in games.iter_mut() { if !all_games.iter().any(|g| g.name == game.name) { game.id = Uuid::new_v4(); add_game(conn, game.clone()).await?; } } Ok(()) } pub async fn insert_participant(conn: &DbConn, participant: GamenightParticipantsEntry) -> Result { Ok(conn.run(move |c| diesel::insert_into(gamenight_participants::table) .values(&participant) .execute(c) ).await?) } impl From for (Uuid, Uuid) { fn from(entry: GamenightParticipantsEntry) -> Self { (entry.gamenight_id, entry.user_id) } } pub async fn remove_participant(conn: &DbConn, participant: GamenightParticipantsEntry) -> Result { Ok(conn.run(move |c| diesel::delete(&participant) .execute(c) ).await?) }