Skip to main content

storekit/
settings.rs

1use rusqlite::{Connection, OptionalExtension, params};
2
3pub const SETTINGS_TABLE_SQL: &str =
4    "CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT NOT NULL);";
5
6pub fn get(connection: &Connection, key: &str) -> rusqlite::Result<Option<String>> {
7    connection
8        .query_row(
9            "SELECT value FROM settings WHERE key = ?1",
10            params![key],
11            |row| row.get(0),
12        )
13        .optional()
14}
15
16pub fn set(connection: &Connection, key: &str, value: &str) -> rusqlite::Result<()> {
17    connection.execute(
18        "INSERT INTO settings(key, value) VALUES (?1, ?2)
19         ON CONFLICT(key) DO UPDATE SET value = excluded.value",
20        params![key, value],
21    )?;
22    Ok(())
23}
24
25pub fn clear(connection: &Connection, key: &str) -> rusqlite::Result<()> {
26    connection.execute("DELETE FROM settings WHERE key = ?1", params![key])?;
27    Ok(())
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn get_set_and_clear_share_one_table_contract() {
36        let connection = Connection::open_in_memory().unwrap();
37        connection.execute_batch(SETTINGS_TABLE_SQL).unwrap();
38        assert_eq!(get(&connection, "desk").unwrap(), None);
39        set(&connection, "desk", "paper").unwrap();
40        assert_eq!(get(&connection, "desk").unwrap().as_deref(), Some("paper"));
41        clear(&connection, "desk").unwrap();
42        assert_eq!(get(&connection, "desk").unwrap(), None);
43    }
44}