diff options
| author | Ellie Huxtable <e@elm.sh> | 2020-10-05 00:59:28 +0100 |
|---|---|---|
| committer | Ellie Huxtable <e@elm.sh> | 2020-10-05 00:59:28 +0100 |
| commit | 27b9a9430518c071a2a7de7f46dfd8aac3cead80 (patch) | |
| tree | 0551a4979606d7bf351149df10cf08f47dc9e665 /src/local/database.rs | |
| download | atuin-27b9a9430518c071a2a7de7f46dfd8aac3cead80.zip | |
Initial commit
Currently writing shell history to a sqlite db :)
Could do with:
1) store exit code
2) store duration
3) tidy up main
4) ...remote stuff
Diffstat (limited to 'src/local/database.rs')
| -rw-r--r-- | src/local/database.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/local/database.rs b/src/local/database.rs new file mode 100644 index 00000000..b84bf99c --- /dev/null +++ b/src/local/database.rs @@ -0,0 +1,93 @@ +use std::path::Path; + +use eyre::Result; +use shellexpand; + +use rusqlite::{params, Connection}; +use rusqlite::NO_PARAMS; + +use super::history::History; + +pub trait Database { + fn save(&self, h: History) -> Result<()>; + fn list(&self) -> Result<()>; +} + +// Intended for use on a developer machine and not a sync server. +// TODO: implement IntoIterator +pub struct SqliteDatabase { + conn: Connection, +} + +impl SqliteDatabase{ + pub fn new(path: &str) -> Result<SqliteDatabase> { + let path = shellexpand::full(path)?; + let path = path.as_ref(); + + debug!("opening sqlite database at {:?}", path); + + let create = !Path::new(path).exists(); + let conn = Connection::open(path)?; + + if create { + Self::setup_db(&conn)?; + } + + Ok(SqliteDatabase{ + conn: conn, + }) + } + + fn setup_db(conn: &Connection) -> Result<()> { + debug!("running sqlite database setup"); + + conn.execute( + "create table if not exists history ( + id integer primary key, + timestamp integer not null, + command text not null, + cwd text not null + )", + NO_PARAMS, + )?; + + Ok(()) + } +} + +impl Database for SqliteDatabase { + fn save(&self, h: History) -> Result<()> { + debug!("saving history to sqlite"); + + self.conn.execute( + "insert into history ( + timestamp, + command, + cwd + ) values (?1, ?2, ?3)", + params![h.timestamp, h.command, h.cwd])?; + + Ok(()) + } + + fn list(&self) -> Result<()> { + debug!("listing history"); + + let mut stmt = self.conn.prepare("SELECT timestamp, command, cwd FROM history")?; + let history_iter = stmt.query_map(params![], |row| { + Ok(History { + timestamp: row.get(0)?, + command: row.get(1)?, + cwd: row.get(2)?, + }) + })?; + + for h in history_iter { + let h = h.unwrap(); + + println!("{}:{}:{}", h.timestamp, h.cwd, h.command); + } + + Ok(()) + } +} |
