aboutsummaryrefslogtreecommitdiffstats
path: root/src/local/database.rs
diff options
context:
space:
mode:
authorConrad Ludgate <conradludgate@gmail.com>2021-02-14 17:18:02 +0000
committerGitHub <noreply@github.com>2021-02-14 17:18:02 +0000
commit72c5ea79147f7bd486839cfeb4aab62a98a0bdd2 (patch)
treeb9bfffc47dc3a8ad457bb8bd414a215eea26504e /src/local/database.rs
parentNeaten the history listing code (#5) (diff)
downloadatuin-72c5ea79147f7bd486839cfeb4aab62a98a0bdd2.zip
tidy some stuff (#6)
Diffstat (limited to 'src/local/database.rs')
-rw-r--r--src/local/database.rs133
1 files changed, 66 insertions, 67 deletions
diff --git a/src/local/database.rs b/src/local/database.rs
index 43b17e50..e2df9ba5 100644
--- a/src/local/database.rs
+++ b/src/local/database.rs
@@ -3,18 +3,18 @@ use std::path::Path;
use eyre::{eyre, Result};
-use rusqlite::NO_PARAMS;
use rusqlite::{params, Connection};
+use rusqlite::{Transaction, NO_PARAMS};
-use crate::History;
+use super::history::History;
pub trait Database {
- fn save(&mut self, h: History) -> Result<()>;
+ 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) -> Result<Vec<History>>;
fn since(&self, date: chrono::DateTime<Utc>) -> Result<Vec<History>>;
- fn update(&self, h: History) -> Result<()>;
+ fn update(&self, h: &History) -> Result<()>;
}
// Intended for use on a developer machine and not a sync server.
@@ -65,46 +65,53 @@ impl Sqlite {
Ok(())
}
+
+ fn save_raw(tx: &Transaction, h: &History) -> Result<()> {
+ tx.execute(
+ "insert or ignore into history (
+ id,
+ timestamp,
+ duration,
+ exit,
+ command,
+ cwd,
+ session,
+ hostname
+ ) values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)",
+ params![
+ h.id,
+ h.timestamp,
+ h.duration,
+ h.exit,
+ h.command,
+ h.cwd,
+ h.session,
+ h.hostname
+ ],
+ )?;
+
+ Ok(())
+ }
}
impl Database for Sqlite {
- fn save(&mut self, h: History) -> Result<()> {
+ fn save(&mut self, h: &History) -> Result<()> {
debug!("saving history to sqlite");
- let v = vec![h];
- self.save_bulk(&v)
+ let tx = self.conn.transaction()?;
+ Self::save_raw(&tx, h)?;
+ tx.commit()?;
+
+ Ok(())
}
fn save_bulk(&mut self, h: &[History]) -> Result<()> {
debug!("saving history to sqlite");
let tx = self.conn.transaction()?;
-
for i in h {
- tx.execute(
- "insert or ignore into history (
- id,
- timestamp,
- duration,
- exit,
- command,
- cwd,
- session,
- hostname
- ) values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)",
- params![
- i.id,
- i.timestamp,
- i.duration,
- i.exit,
- i.command,
- i.cwd,
- i.session,
- i.hostname
- ],
- )?;
+ Self::save_raw(&tx, i)?
}
-
tx.commit()?;
Ok(())
@@ -119,16 +126,7 @@ impl Database for Sqlite {
)?;
let mut iter = stmt.query_map(params![id], |row| {
- Ok(History {
- id: String::from(id),
- 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)?,
- })
+ history_from_sqlite_row(Some(id.to_string()), row)
})?;
let history = iter.next().unwrap();
@@ -139,7 +137,7 @@ impl Database for Sqlite {
}
}
- fn update(&self, h: History) -> Result<()> {
+ fn update(&self, h: &History) -> Result<()> {
debug!("updating sqlite history");
self.conn.execute(
@@ -159,42 +157,43 @@ impl Database for Sqlite {
.conn
.prepare("SELECT * FROM history order by timestamp asc")?;
- let history_iter = stmt.query_map(params![], |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)?,
- })
- })?;
+ let history_iter = stmt.query_map(params![], |row| history_from_sqlite_row(None, row))?;
- Ok(history_iter.filter_map(|x| x.ok()).collect())
+ Ok(history_iter.filter_map(Result::ok).collect())
}
fn since(&self, date: chrono::DateTime<Utc>) -> Result<Vec<History>> {
- debug!("listing history");
+ debug!("listing history since {:?}", date);
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)?,
- })
+ history_from_sqlite_row(None, row)
})?;
- Ok(history_iter.filter_map(|x| x.ok()).collect())
+ Ok(history_iter.filter_map(Result::ok).collect())
}
}
+
+fn history_from_sqlite_row(
+ id: Option<String>,
+ row: &rusqlite::Row,
+) -> Result<History, rusqlite::Error> {
+ let id = match id {
+ Some(id) => id,
+ None => row.get(0)?,
+ };
+
+ Ok(History {
+ id,
+ 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)?,
+ })
+}