use crate::project::Project; use rusqlite::{Connection, Result}; pub struct Database { conn: Connection, } impl Database { pub fn new(path: &str) -> Result { let conn = Connection::open(path)?; conn.execute_batch(include_str!("schema.sql"))?; Ok(Self { conn }) } pub fn create_project(&self, title: String) -> Result { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64; self.conn.execute( "INSERT INTO projects (title, created_time, last_modified_time, percentage_completed, archived) VALUES (?1, ?2, ?3, ?4, ?5)", (&title, now, now, 0, 0), )?; Ok(self.conn.last_insert_rowid()) } pub fn update_project_progress(&self, id: i64, percentage: i32) -> Result<()> { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64; self.conn.execute( "UPDATE projects SET percentage_completed = ?1, last_modified_time = ?2 WHERE id = ?3", (percentage, now, id), )?; Ok(()) } pub fn archive_project(&self, id: i64) -> Result<()> { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64; self.conn.execute( "UPDATE projects SET archived = 1, last_modified_time = ?1 WHERE id = ?2", (now, id), )?; Ok(()) } pub fn unarchive_project(&self, id: i64) -> Result<()> { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64; self.conn.execute( "UPDATE projects SET archived = 0, last_modified_time = ?1 WHERE id = ?2", (now, id), )?; Ok(()) } pub fn list_all_projects(&self) -> Result> { let mut stmt = self.conn.prepare( "SELECT id, title, created_time, last_modified_time, percentage_completed, archived FROM projects ORDER BY last_modified_time DESC", )?; let projects = stmt .query_map([], |row| { Ok(Project { id: row.get(0)?, title: row.get(1)?, created_time: row.get(2)?, last_modified_time: row.get(3)?, percentage_completed: row.get(4)?, archived: row.get::<_, i32>(5)? != 0, }) })? .collect::>>()?; Ok(projects) } }