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.
This commit is contained in:
Ellie Huxtable 2021-02-14 16:53:18 +00:00 committed by GitHub
parent 46b5dc3761
commit 8af0034ae0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 18 deletions

View file

@ -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(())
}
}
}
}

View file

@ -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())
}
}