diff options
Diffstat (limited to 'src/db')
-rw-r--r-- | src/db/categories.rs | 25 | ||||
-rw-r--r-- | src/db/event-color.rs | 7 | ||||
-rw-r--r-- | src/db/event_color.rs | 14 | ||||
-rw-r--r-- | src/db/events.rs | 139 | ||||
-rw-r--r-- | src/db/migrations/2-categories.sql | 10 | ||||
-rw-r--r-- | src/db/migrations/3-event-color.sql | 5 | ||||
-rw-r--r-- | src/db/mod.rs | 137 |
7 files changed, 200 insertions, 137 deletions
diff --git a/src/db/categories.rs b/src/db/categories.rs new file mode 100644 index 0000000..ebefb6d --- /dev/null +++ b/src/db/categories.rs @@ -0,0 +1,25 @@ +use anyhow::Result; +use rusqlite::Connection; +use uuid::Uuid; + +use crate::model::category::Category; + +pub fn list(conn: &Connection) -> Result<Vec<Category>> { + let mut stmt = conn.prepare("SELECT id, name, color FROM categories")?; + + let iter = stmt.query_map([], |row| { + Ok(read_category(row.get(0)?, row.get(1)?, row.get(2)?)) + })?; + + let mut res = vec![]; + for category in iter { + res.push(category??) + } + Ok(res) +} + +fn read_category(id: String, name: String, color: String) -> Result<Category> { + let id = Uuid::parse_str(&id)?; + + Ok(Category { id, name, color }) +} diff --git a/src/db/event-color.rs b/src/db/event-color.rs new file mode 100644 index 0000000..18612e4 --- /dev/null +++ b/src/db/event-color.rs @@ -0,0 +1,7 @@ + + +pub fn get_default_color(conn: &Connection) -> Result<String> { +} + +// pub fn set_default_color(conon: &Connection, color: &str) -> Result<()> { +// } diff --git a/src/db/event_color.rs b/src/db/event_color.rs new file mode 100644 index 0000000..33d350b --- /dev/null +++ b/src/db/event_color.rs @@ -0,0 +1,14 @@ +use anyhow::Result; +use rusqlite::Connection; + +pub fn get_default_color(conn: &Connection) -> Result<String> { + let mut stmt = conn.prepare("SELECT * FROM event_color LIMIT 1")?; + + let iter = stmt.query_map([], |row| row.get(0))?; + + let mut res = vec![]; + for color in iter { + res.push(color?) + } + Ok(res.first().unwrap_or(&"blue".to_string()).clone()) +} 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, + }) +} diff --git a/src/db/migrations/2-categories.sql b/src/db/migrations/2-categories.sql index 27e9699..0b373d0 100644 --- a/src/db/migrations/2-categories.sql +++ b/src/db/migrations/2-categories.sql @@ -1,13 +1,11 @@ CREATE TABLE IF NOT EXISTS "categories" ( "id" TEXT PRIMARY KEY, /* UUID */ - "name" TEXT NOT NULL, - "color" TEXT NOT NULL, /* HEXA */ + "name" TEXT NOT NULL UNIQUE, + "color" TEXT NOT NULL, /* COLOR */ "created" TEXT NOT NULL, /* DATETIME */ "updated" TEXT NOT NULL /* DATETIME */ ); -INSERT INTO - "categories" ("id", "name", "color", "created", "updated") - VALUES ("b2253284-1572-43d5-96ec-bf6ad448f46a", "Perso", "#a8c2e0", datetime(), datetime()); - ALTER TABLE "events" ADD COLUMN "category" TEXT REFERENCES "categories" ("id"); /* UUID */ + +PRAGMA foreign_keys = ON diff --git a/src/db/migrations/3-event-color.sql b/src/db/migrations/3-event-color.sql new file mode 100644 index 0000000..ec589ea --- /dev/null +++ b/src/db/migrations/3-event-color.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS "event_color" ( + "color" TEXT NOT NULL /* COLOR */ +); + +INSERT INTO "event_color" ("color") VALUES ("#a8c2e0"); diff --git a/src/db/mod.rs b/src/db/mod.rs index 101c874..20e7f81 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,143 +1,18 @@ +pub mod categories; +pub mod event_color; +pub mod events; + use anyhow::Result; -use chrono::{NaiveDate, NaiveTime}; -use rusqlite::{params, Connection}; +use rusqlite::Connection; use rusqlite_migration::{Migrations, M}; -use uuid::Uuid; - -use crate::model::event::Event; pub fn init(db_path: &str) -> Result<Connection> { let mut conn = Connection::open(db_path)?; let migrations = Migrations::new(vec![ M::up(include_str!("migrations/1-init.sql")), M::up(include_str!("migrations/2-categories.sql")), + M::up(include_str!("migrations/3-event-color.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(()) -} - -pub fn list_recurring(conn: &Connection) -> Result<Vec<Event>> { - 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| { - Ok(read_recurring_event( - row.get(0)?, - row.get(1)?, - row.get(2)?, - row.get(3)?, - row.get(4)?, - row.get(5)?, - )) - })?; - - let mut res = vec![]; - for event in iter { - res.push(event??) - } - Ok(res) -} - -fn read_recurring_event( - uuid: String, - date: NaiveDate, - start: Option<NaiveTime>, - end: Option<NaiveTime>, - name: String, - repetition: Option<String>, -) -> Result<Event> { - let id = Uuid::parse_str(&uuid)?; - let repetition = match repetition { - Some(r) => Some(serde_json::from_str(&r)?), - None => None, - }; - - Ok(Event { - id, - date, - start, - end, - name, - repetition, - }) -} - -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 - FROM events - WHERE - repetition IS NULL - AND date >= ? - AND date <= ? - ", - )?; - - let iter = stmt.query_map([start, end], |row| { - let uuid: String = row.get(0)?; - let date = row.get(1)?; - let start = row.get(2)?; - let end = row.get(3)?; - let name = row.get(4)?; - Ok(Uuid::parse_str(&uuid).map(|id| Event { - id, - date, - start, - end, - name, - repetition: None, - })) - })?; - - let mut res = vec![]; - for event in iter { - res.push(event??) - } - Ok(res) -} |