aboutsummaryrefslogtreecommitdiff
path: root/src/db/mod.rs
blob: 2cac0d2f37f0877bc5f0eb4dfa51931e55e434bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use anyhow::Result;
use rusqlite::{params, Connection};
use rusqlite_migration::{Migrations, M};
use uuid::Uuid;

use crate::model::event::Event;

pub fn init() -> Result<Connection> {
    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(conn: &Connection) -> Result<Vec<Event>> {
    let mut stmt = conn.prepare("SELECT id, date, start, end, name, repeated FROM events")?;

    let iter = stmt.query_map([], |row| {
        let uuid: String = row.get(0)?;
        let repetition: Option<String> = 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())
}