diff options
Diffstat (limited to 'src/database.rs')
| -rw-r--r-- | src/database.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 0000000..a1d0a18 --- /dev/null +++ b/src/database.rs @@ -0,0 +1,80 @@ +use anyhow::Result; +use rusqlite::{Connection, Transaction, config::DbConfig}; + +const DB_NAME: &str = "database.sqlite"; +const DB_VERSION: i64 = 0; + +struct Database { + conn: Connection, +} + +impl Database { + fn new() -> Result<Self> { + let mut init = false; + if !std::fs::exists(DB_NAME)? { + init = true; + } + + let mut db = Database { + conn: Connection::open(DB_NAME)?, + }; + if init { + db.initialize()?; + } + + db.conn.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY)?; + + Ok(db) + } + + fn initialize(&mut self) -> Result<()> { + let tx = self.conn.transaction()?; + let mut q = "CREATE TABLE version ( + version INTEGER NOT NULL, + UNIQUE (version))"; + tx.execute(q, ())?; + + q = "INSERT INTO version VALUES (?)"; + tx.execute(q, &[&DB_VERSION])?; + + q = "CREATE TABLE user ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + email TEXT NOT NULL, + UNIQUE (email))"; + tx.execute(q, ())?; + + q = "CREATE TABLE list ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + description TEXT, + UNIQUE (name))"; + tx.execute(q, ())?; + + q = "CREATE TABLE subscription ( + user_id INTEGER REFERENCES user (id), + list_id INTEGER REFERENCES list (id), + UNIQUE (user_id, list_id))"; + tx.execute(q, ())?; + + tx.commit()?; + Ok(()) + } + + fn execute<Ex>(&mut self, q: Ex) -> Result<QueryResult<Ex::T>> where Ex: DBExecutable { + let tx = self.conn.transaction()?; + let ris = q.execute(&tx)?; + tx.commit()?; + Ok(ris) + } +} + +pub trait DBExecutable { + type T; + fn execute(&self, tx: &Transaction) -> Result<QueryResult<Self::T>>; +} + +pub enum QueryResult<T> { + Empty, + Vec(Vec<T>) +} |
