use anyhow::Result; use chrono::{NaiveDate, NaiveTime}; use rusqlite::{named_params, Connection}; use uuid::Uuid; use crate::model::event::Event; pub fn insert(conn: &Connection, event: &Event) -> Result<()> { let query = r#" INSERT INTO events (id, date, start, end, name, repetition, category, created, updated) VALUES (:id, :date, :start, :end, :name, :repetition, :category, datetime(), datetime()) "#; let repetition = match &event.repetition { Some(r) => Some(serde_json::to_string(&r)?), None => None, }; let category = event.category.map(|id| id.hyphenated().to_string()); conn.execute( query, named_params![ ":id": event.id.hyphenated().to_string(), ":date": event.date, ":start": event.start, ":end": event.end, ":name": event.name, ":repetition": repetition, ":category": category ], )?; Ok(()) } pub fn update(conn: &Connection, event: &Event) -> Result<()> { let query = r#" UPDATE events SET date = :date, start = :start, end = :end, name = :name, repetition = :repetition, category = :category, updated = datetime() WHERE id = :id "#; let repetition = match &event.repetition { Some(r) => Some(serde_json::to_string(&r)?), None => None, }; let category = event.category.map(|id| id.hyphenated().to_string()); conn.execute( query, named_params![ ":date": event.date, ":start": event.start, ":end": event.end, ":name": event.name, ":repetition": repetition, ":category": category, ":id": event.id.hyphenated().to_string() ], )?; Ok(()) } pub fn delete(conn: &Connection, id: &Uuid) -> Result<()> { let query = r#"DELETE FROM events WHERE id = :id"#; conn.execute(query, named_params![":id": id.hyphenated().to_string()])?; Ok(()) } pub fn list_recurring(conn: &Connection) -> Result> { let query = r#" SELECT id, date, start, end, name, repetition, category FROM events WHERE repetition IS NOT NULL "#; let mut stmt = conn.prepare(query)?; let iter = stmt.query_map([], |row| { Ok(read_event( row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?, row.get(5)?, row.get(6)?, )) })?; let mut res = vec![]; for event in iter { res.push(event??) } Ok(res) } pub fn list_non_recurring_between( conn: &Connection, start: NaiveDate, end: NaiveDate, ) -> Result> { let mut stmt = conn.prepare( " SELECT id, date, start, end, name, category FROM events WHERE repetition IS NULL AND date >= ? AND date <= ? ", )?; let iter = stmt.query_map([start, end], |row| { Ok(read_event( row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?, None, row.get(5)?, )) })?; let mut res = vec![]; for event in iter { res.push(event??) } Ok(res) } fn read_event( id: String, date: NaiveDate, start: Option, end: Option, name: String, repetition: Option, category: Option, ) -> Result { let id = Uuid::parse_str(&id)?; let repetition = match repetition { Some(r) => Some(serde_json::from_str(&r)?), None => None, }; let category = match category { Some(c) => Some(Uuid::parse_str(&c)?), None => None, }; Ok(Event { id, date, start, end, name, repetition, category, }) }