diff --git a/Cargo.lock b/Cargo.lock index 93390c7..f4859c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,6 +111,7 @@ dependencies = [ "chrono", "chrono-english", "cli-table", + "config", "directories", "eyre", "hostname", @@ -237,7 +238,7 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", - "num-traits", + "num-traits 0.2.14", "time", "winapi", ] @@ -290,6 +291,22 @@ dependencies = [ "syn 1.0.60", ] +[[package]] +name = "config" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9107d78ed62b3fa5a86e7d18e647abed48cfd8f8fab6c72f4cdb982d196f7e6" +dependencies = [ + "lazy_static 1.4.0", + "nom", + "rust-ini", + "serde 1.0.123", + "serde-hjson", + "serde_json", + "toml", + "yaml-rust", +] + [[package]] name = "console" version = "0.14.0" @@ -297,7 +314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa" dependencies = [ "encode_unicode", - "lazy_static", + "lazy_static 1.4.0", "libc", "regex", "terminal_size", @@ -335,7 +352,7 @@ checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" dependencies = [ "autocfg", "cfg-if 1.0.0", - "lazy_static", + "lazy_static 1.4.0", ] [[package]] @@ -658,17 +675,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" dependencies = [ "console", - "lazy_static", + "lazy_static 1.4.0", "number_prefix", "regex", ] +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + [[package]] name = "language-tags" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" + [[package]] name = "lazy_static" version = "1.4.0" @@ -692,6 +721,22 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" +dependencies = [ + "serde 0.8.23", + "serde_test", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + [[package]] name = "log" version = "0.3.9" @@ -737,6 +782,16 @@ dependencies = [ "log 0.3.9", ] +[[package]] +name = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +dependencies = [ + "memchr", + "version_check 0.1.5", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -744,7 +799,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", - "num-traits", + "num-traits 0.2.14", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.14", ] [[package]] @@ -1091,6 +1155,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rust-ini" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "safemem" version = "0.3.3" @@ -1103,12 +1179,51 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "088c5d71572124929ea7549a8ce98e1a6fd33d0a38367b09027b382e67c033db" +[[package]] +name = "serde" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" + [[package]] name = "serde" version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +[[package]] +name = "serde-hjson" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153" +dependencies = [ + "lazy_static 0.2.11", + "linked-hash-map 0.3.0", + "num-traits 0.1.43", + "regex", + "serde 0.8.23", +] + +[[package]] +name = "serde_json" +version = "1.0.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" +dependencies = [ + "itoa", + "ryu", + "serde 1.0.123", +] + +[[package]] +name = "serde_test" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" +dependencies = [ + "serde 0.8.23", +] + [[package]] name = "sha2" version = "0.8.2" @@ -1155,7 +1270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" dependencies = [ "clap", - "lazy_static", + "lazy_static 1.4.0", "structopt-derive", ] @@ -1274,7 +1389,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" dependencies = [ - "serde", + "serde 1.0.123", ] [[package]] @@ -1443,6 +1558,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map 0.5.4", +] + [[package]] name = "yansi" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 4a443a1..d29c3ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ hostname = "0.3.1" rocket = "0.4.7" chrono-english = "0.1.4" cli-table = "0.4" +config = "0.9" [dependencies.rusqlite] version = "0.24" diff --git a/src/command/history.rs b/src/command/history.rs index 5d2a805..09dd436 100644 --- a/src/command/history.rs +++ b/src/command/history.rs @@ -3,7 +3,7 @@ use std::env; use eyre::Result; use structopt::StructOpt; -use crate::local::database::Database; +use crate::local::database::{Database, QueryParam}; use crate::local::history::History; #[derive(StructOpt)] @@ -29,8 +29,11 @@ pub enum Cmd { aliases=&["l", "li", "lis"], )] List { - #[structopt(long)] - distinct: bool, + #[structopt(long, short)] + dir: bool, + + #[structopt(long, short)] + session: bool, }, } @@ -74,8 +77,27 @@ impl Cmd { Ok(()) } - Self::List { .. } => { - let history = db.list()?; + Self::List { session, dir, .. } => { + const QUERY_SESSION: &str = "select * from history where session = ?;"; + const QUERY_DIR: &str = "select * from history where cwd = ?;"; + const QUERY_SESSION_DIR: &str = + "select * from history where cwd = ?1 and session = ?2;"; + + let params = (session, dir); + + let cwd = env::current_dir()?.display().to_string(); + let session = env::var("ATUIN_SESSION")?; + + let history = match params { + (false, false) => db.list()?, + (true, false) => db.query(QUERY_SESSION, &[QueryParam::Text(session)])?, + (false, true) => db.query(QUERY_DIR, &[QueryParam::Text(cwd)])?, + (true, true) => db.query( + QUERY_SESSION_DIR, + &[QueryParam::Text(cwd), QueryParam::Text(session)], + )?, + }; + print_list(&history); Ok(()) diff --git a/src/local/database.rs b/src/local/database.rs index 5b98bb3..3133578 100644 --- a/src/local/database.rs +++ b/src/local/database.rs @@ -8,6 +8,10 @@ use rusqlite::{Transaction, NO_PARAMS}; use super::history::History; +pub enum QueryParam { + Text(String), +} + pub trait Database { fn save(&mut self, h: &History) -> Result<()>; fn save_bulk(&mut self, h: &[History]) -> Result<()>; @@ -16,6 +20,7 @@ pub trait Database { fn range(&self, from: chrono::DateTime, to: chrono::DateTime) -> Result>; fn update(&self, h: &History) -> Result<()>; + fn query(&self, query: &str, params: &[QueryParam]) -> Result>; } // Intended for use on a developer machine and not a sync server. @@ -95,6 +100,16 @@ impl Sqlite { } } +impl rusqlite::ToSql for QueryParam { + fn to_sql(&self) -> Result, rusqlite::Error> { + use rusqlite::types::{ToSqlOutput, Value}; + + match self { + QueryParam::Text(s) => Ok(ToSqlOutput::Owned(Value::Text(s.clone()))), + } + } +} + impl Database for Sqlite { fn save(&mut self, h: &History) -> Result<()> { debug!("saving history to sqlite"); @@ -176,6 +191,14 @@ impl Database for Sqlite { Ok(history_iter.filter_map(Result::ok).collect()) } + + fn query(&self, query: &str, params: &[QueryParam]) -> Result> { + let mut stmt = self.conn.prepare(query)?; + + let history_iter = stmt.query_map(params, |row| history_from_sqlite_row(None, row))?; + + Ok(history_iter.filter_map(Result::ok).collect()) + } } fn history_from_sqlite_row(