60 lines
1.9 KiB
Rust
60 lines
1.9 KiB
Rust
use crate::city::House;
|
|
use rusqlite::{Connection, NO_PARAMS, params, Result, Transaction};
|
|
use std::collections::HashMap;
|
|
|
|
pub struct LayoutDB {
|
|
connection: Connection,
|
|
layouts: Vec<SavedLayout>
|
|
}
|
|
|
|
pub struct SavedLayout {
|
|
id: usize,
|
|
houses: Vec<House>
|
|
}
|
|
|
|
impl LayoutDB {
|
|
pub fn from_file(filename: &str) -> Result<Self> {
|
|
let connection = Connection::open(filename)?;
|
|
let mut layouts: HashMap<u32, Vec<(u32, u32)>> = HashMap::new();
|
|
|
|
// We need to dispose the statement so we can move the connection later
|
|
{
|
|
let mut stmt = connection.prepare("SELECT layout_id, x, y FROM houses")?;
|
|
let mut rows = stmt.query(NO_PARAMS)?;
|
|
|
|
while let Some(row) = rows.next()? {
|
|
let id: u32 = row.get(0)?;
|
|
let x: u32 = row.get(1)?;
|
|
let y: u32 = row.get(2)?;
|
|
layouts.entry(id).or_default().push((x, y));
|
|
}
|
|
}
|
|
|
|
let layouts = layouts.into_iter().map(|(id, xy_pairs)|
|
|
SavedLayout
|
|
{
|
|
id: id as usize,
|
|
houses: xy_pairs.into_iter().map(|(x, y)| House { x: x as usize, y: y as usize }).collect(),
|
|
}
|
|
).collect();
|
|
|
|
Ok(LayoutDB { connection, layouts })
|
|
}
|
|
|
|
pub fn layouts(&self) -> &Vec<SavedLayout> {
|
|
&self.layouts
|
|
}
|
|
|
|
pub fn add_layout(&mut self, houses: &Vec<House>, fully_optimized: bool) -> Result<()> {
|
|
let transaction = self.connection.transaction()?;
|
|
transaction.execute("INSERT INTO layouts (is_fully_optimized) VALUES (?1)",
|
|
params![fully_optimized])?;
|
|
let layout_id = transaction.last_insert_rowid();
|
|
for house in houses {
|
|
transaction.execute("INSERT INTO houses (layout_id, x, y) VALUES (?1, ?2, ?3)",
|
|
params![layout_id, house.x as u32, house.y as u32])?;
|
|
}
|
|
transaction.commit()?;
|
|
Ok(())
|
|
}
|
|
}
|