diff options
Diffstat (limited to 'src/db/events.rs')
-rw-r--r-- | src/db/events.rs | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/db/events.rs b/src/db/events.rs new file mode 100644 index 0000000..86206bb --- /dev/null +++ b/src/db/events.rs @@ -0,0 +1,139 @@ +use anyhow::Result; +use chrono::{NaiveDate, NaiveTime}; +use rusqlite::{params, Connection}; +use uuid::Uuid; + +use crate::model::event::Event; + +pub fn insert(conn: &Connection, event: &Event) -> Result<()> { + let repetition = match &event.repetition { + Some(r) => Some(serde_json::to_string(&r)?), + None => None, + }; + + let category = event.category.map(|id| id.to_hyphenated().to_string()); + + conn.execute( + "INSERT INTO events (id, date, start, end, name, repetition, category, created, updated) VALUES (?, ?, ?, ?, ?, ?, ?, datetime(), datetime())", + params![event.id.to_hyphenated().to_string(), event.date, event.start, event.end, event.name, repetition, category] + )?; + + Ok(()) +} + +pub fn update(conn: &Connection, event: &Event) -> Result<()> { + let repetition = match &event.repetition { + Some(r) => Some(serde_json::to_string(&r)?), + None => None, + }; + + let category = event.category.map(|id| id.to_hyphenated().to_string()); + + conn.execute( + "UPDATE events SET date = ?, start = ?, end = ?, name = ?, repetition = ?, category = ?, updated = datetime() WHERE id = ?", + params![event.date, event.start, event.end, event.name, repetition, category, 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(()) +} + +pub fn list_recurring(conn: &Connection) -> Result<Vec<Event>> { + let mut stmt = conn.prepare( + " + SELECT id, date, start, end, name, repetition, category + FROM events + WHERE repetition IS NOT NULL", + )?; + + 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<Vec<Event>> { + 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<NaiveTime>, + end: Option<NaiveTime>, + name: String, + repetition: Option<String>, + category: Option<String>, +) -> Result<Event> { + 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, + }) +} |