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) -} | 
