summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEllie Huxtable <e@elm.sh>2021-02-14 16:53:18 +0000
committerGitHub <noreply@github.com>2021-02-14 16:53:18 +0000
commit8af0034ae0bb7a4067abd296f9f27f9aafd18a82 (patch)
tree69b56c5110fe80d335d082f2812dc8b6f07b1bf0
parent46b5dc376156966bcb9a316e18695a159d87b421 (diff)
Neaten the history listing code (#5)
I'd like to reduce the amount of SQL in the database code. Make it as generic as possible, and later on perhaps expose a generic "execute" function. This function can be used by analysis commands, and the SQL can live there - rather than database.rs being a huge bag of SQL.
-rw-r--r--src/command/history.rs13
-rw-r--r--src/local/database.rs56
2 files changed, 51 insertions, 18 deletions
diff --git a/src/command/history.rs b/src/command/history.rs
index 73be66fa..5959fc55 100644
--- a/src/command/history.rs
+++ b/src/command/history.rs
@@ -34,6 +34,12 @@ pub enum Cmd {
},
}
+fn print_list(h: &Vec<History>) {
+ for i in h {
+ println!("{}", i.command);
+ }
+}
+
impl Cmd {
pub fn run(&self, db: &mut Sqlite) -> Result<()> {
match self {
@@ -68,7 +74,12 @@ impl Cmd {
Ok(())
}
- Self::List { distinct } => db.list(*distinct),
+ Self::List { .. } => {
+ let history = db.list()?;
+ print_list(&history);
+
+ Ok(())
+ }
}
}
}
diff --git a/src/local/database.rs b/src/local/database.rs
index 4f99d8ac..43b17e50 100644
--- a/src/local/database.rs
+++ b/src/local/database.rs
@@ -1,3 +1,4 @@
+use chrono::Utc;
use std::path::Path;
use eyre::{eyre, Result};
@@ -11,7 +12,8 @@ pub trait Database {
fn save(&mut self, h: History) -> Result<()>;
fn save_bulk(&mut self, h: &[History]) -> Result<()>;
fn load(&self, id: &str) -> Result<History>;
- fn list(&self, distinct: bool) -> Result<()>;
+ fn list(&self) -> Result<Vec<History>>;
+ fn since(&self, date: chrono::DateTime<Utc>) -> Result<Vec<History>>;
fn update(&self, h: History) -> Result<()>;
}
@@ -150,29 +152,49 @@ impl Database for Sqlite {
Ok(())
}
- fn list(&self, distinct: bool) -> Result<()> {
+ fn list(&self) -> Result<Vec<History>> {
debug!("listing history");
- let mut stmt = if distinct {
- self.conn
- .prepare("SELECT command FROM history order by timestamp asc")?
- } else {
- self.conn
- .prepare("SELECT distinct command FROM history order by timestamp asc")?
- };
+ let mut stmt = self
+ .conn
+ .prepare("SELECT * FROM history order by timestamp asc")?;
let history_iter = stmt.query_map(params![], |row| {
- let command: String = row.get(0)?;
-
- Ok(command)
+ Ok(History {
+ id: row.get(0)?,
+ timestamp: row.get(1)?,
+ duration: row.get(2)?,
+ exit: row.get(3)?,
+ command: row.get(4)?,
+ cwd: row.get(5)?,
+ session: row.get(6)?,
+ hostname: row.get(7)?,
+ })
})?;
- for h in history_iter {
- let h = h.unwrap();
+ Ok(history_iter.filter_map(|x| x.ok()).collect())
+ }
- println!("{}", h);
- }
+ fn since(&self, date: chrono::DateTime<Utc>) -> Result<Vec<History>> {
+ debug!("listing history");
- Ok(())
+ let mut stmt = self.conn.prepare(
+ "SELECT distinct command FROM history where timestamp > ?1 order by timestamp asc",
+ )?;
+
+ let history_iter = stmt.query_map(params![date.timestamp_nanos()], |row| {
+ Ok(History {
+ id: row.get(0)?,
+ timestamp: row.get(1)?,
+ duration: row.get(2)?,
+ exit: row.get(3)?,
+ command: row.get(4)?,
+ cwd: row.get(5)?,
+ session: row.get(6)?,
+ hostname: row.get(7)?,
+ })
+ })?;
+
+ Ok(history_iter.filter_map(|x| x.ok()).collect())
}
}