use std::collections::HashMap; use std::convert::TryFrom; use rusqlite::params; use crate::database::Db; use crate::id::Id; use crate::result::RudeResult; use crate::try_log; use crate::world::{Exit, Room}; impl Db { /// Save a room to the database. pub fn save_room(&self, room: &Room) -> RudeResult<()> { let mut statement = try_log!( self.0.prepare( "insert into rooms (id, zone, name, description, users_visible) values (?, ?, ?, ?, ?) on conflict(id) do update set id=?, zone=?, name=?, description=?, users_visible=?;" ), "Unable to prepare sql statement" ); let _ = try_log!( statement.execute(params![ room.id, room.zone, room.name, room.description.join("\n"), room.users_visible, room.id, room.zone, room.name, room.description.join("\n"), room.users_visible, ]), "Unable to perform query" ); for (direction, exit) in room.exits.iter() { let mut statement = try_log!( self.0 .prepare("insert into exits (room, target, direction) values (?, ?, ?);"), "Unable to prepare sql statement" ); let _ = try_log!( statement.execute(params![room.id, exit.target, exit.direction,]), "Unable to perform query" ); } Ok(()) } /// Load a room from the database. pub fn load_room(&self, id: Id) -> RudeResult> { let mut statement = try_log!( self.0.prepare( "select id, zone, name, description, users_visible from rooms where id = ?" ), "Unable to prepare sql statement" ); let mut rows = try_log!(statement.query(params![id]), "Unable to perform query"); let mut room = if let Some(row) = try_log!(rows.next(), "Unable to retrieve row") { try_log!(Room::try_from(row), "Unable to get Room from Row") } else { return Ok(None); }; room.exits = { let mut e = HashMap::new(); let mut statement = try_log!( self.0 .prepare("select room, target, direction from exits where room = ?"), "Unable to prepare sql statement" ); let mut rows = try_log!(statement.query(params![id]), "Unable to perform query"); while let Some(row) = try_log!(rows.next(), "Unable to retrieve row") { let exit = try_log!(Exit::try_from(row), "Unable to get Exit from Row"); e.insert(exit.direction, exit); } e }; Ok(Some(room)) } }