use anyhow::Result; use chrono::NaiveDate; use rusqlite::{params, Connection}; use rusqlite_migration::{Migrations, M}; use uuid::Uuid; use crate::model::event::Event; pub fn init() -> Result { let mut conn = Connection::open("database.db")?; let migrations = Migrations::new(vec![M::up(include_str!("migrations/1-init.sql"))]); migrations.to_latest(&mut conn)?; Ok(conn) } pub fn insert(conn: &Connection, event: &Event) -> Result<()> { let repetition = match &event.repetition { Some(r) => Some(serde_json::to_string(&r)?), None => None, }; conn.execute( "INSERT INTO events (id, date, start, end, name, repetition, created, updated) VALUES (?, ?, ?, ?, ?, ?, datetime(), datetime())", params![event.id.to_hyphenated().to_string(), event.date, event.start, event.end, event.name, repetition] )?; Ok(()) } pub fn update(conn: &Connection, event: &Event) -> Result<()> { let repetition = match &event.repetition { Some(r) => Some(serde_json::to_string(&r)?), None => None, }; conn.execute( "UPDATE events SET date = ?, start = ?, end = ?, name = ?, repetition = ?, updated = datetime() where id = ?", params![event.date, event.start, event.end, event.name, repetition, event.id.to_hyphenated().to_string()] )?; Ok(()) } pub fn delete(conn: &Connection, id: &Uuid) -> Result<()> { conn.execute( "DELETE FROM events WHERE id = ?", params![id.to_hyphenated().to_string()], )?; Ok(()) } // TODO: Don’t use unwrap pub fn list_repeated(conn: &Connection) -> Result> { let mut stmt = conn.prepare( " SELECT id, date, start, end, name, repetition FROM events WHERE repetition IS NOT NULL", )?; let iter = stmt.query_map([], |row| { let uuid: String = row.get(0)?; let repetition: Option = row.get(5)?; Ok(Event { id: Uuid::parse_str(&uuid).unwrap(), date: row.get(1)?, start: row.get(2)?, end: row.get(3)?, name: row.get(4)?, repetition: repetition.and_then(|r: String| serde_json::from_str(&r).ok()), }) })?; Ok(iter.map(|r| r.unwrap()).collect()) } // TODO: Don’t use unwrap pub fn list_non_repeated_between( conn: &Connection, start: NaiveDate, end: NaiveDate, ) -> Result> { let mut stmt = conn.prepare( " SELECT id, date, start, end, name FROM events WHERE repetition IS NULL AND date >= ? AND date <= ? ", )?; let iter = stmt.query_map([start, end], |row| { let uuid: String = row.get(0)?; Ok(Event { id: Uuid::parse_str(&uuid).unwrap(), date: row.get(1)?, start: row.get(2)?, end: row.get(3)?, name: row.get(4)?, repetition: None, }) })?; Ok(iter.map(|r| r.unwrap()).collect()) }