use std::collections::HashSet; 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::Zone; impl Db { /// Save a zone to the database. pub fn save_zone(&self, zone: &Zone) -> RudeResult<()> { let mut statement = try_log!( self.0.prepare( "insert into zones (id, parent, name, users_visible) values (?, ?, ?, ?) on conflict(id) do update set id=?, parent=?, name=?, users_visible=?;" ), "Unable to prepare sql statement" ); let _ = try_log!( statement.execute(params![ zone.id, zone.parent, zone.name, zone.users_visible, zone.id, zone.parent, zone.name, zone.users_visible, ]), "Unable to perform query" ); Ok(()) } /// Load a zone from the database. pub fn load_zone(&self, id: Id) -> RudeResult> { let mut statement = try_log!( self.0 .prepare("select id, parent, name, users_visible from zones where id = ?"), "Unable to prepare sql statement" ); let mut rows = try_log!(statement.query(params![id]), "Unable to perform query"); let mut zone = if let Some(row) = try_log!(rows.next(), "Unable to retrieve row") { try_log!(Zone::try_from(row), "Unable to get Zone from Row") } else { return Ok(None); }; zone.areas = { let mut a = HashSet::new(); let mut statement = try_log!( self.0.prepare("select id from zones where parent = ?;"), "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 new_id = try_log!(row.get(0), "Unable to retrieve field"); if new_id != id { a.insert(new_id); } } let mut statement = try_log!( self.0.prepare("select id from rooms where zone = ?;"), "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") { a.insert(try_log!(row.get(0), "Unable to retrieve field")); } a }; Ok(Some(zone)) } }