diff --git a/src/cmd/import.rs b/src/cmd/import.rs index ac0777a..66a1207 100644 --- a/src/cmd/import.rs +++ b/src/cmd/import.rs @@ -40,7 +40,7 @@ fn import_autojump(db: &mut Database, buffer: &str) -> Result<()> { // take a while to normalize. rank = sigmoid(rank); - db.add_unchecked(path, rank, 0); + db.add_unchecked_merge(path, rank, 0); } if db.dirty() { @@ -65,7 +65,7 @@ fn import_z(db: &mut Database, buffer: &str) -> Result<()> { let path = split.next().with_context(|| format!("invalid entry: {line}"))?; - db.add_unchecked(path, rank, last_accessed); + db.add_unchecked_merge(path, rank, last_accessed); } if db.dirty() { @@ -107,12 +107,12 @@ mod tests { println!("got: {:?}", &db.dirs()); let exp = [ - Dir { path: "/baz".into(), rank: sigmoid(7.0), last_accessed: 0 }, - Dir { path: "/corge/grault/garply".into(), rank: 6.0, last_accessed: 600 }, - Dir { path: "/foo/bar".into(), rank: 9.0 + sigmoid(2.0), last_accessed: 900 }, Dir { path: "/quux/quuz".into(), rank: 1.0 + sigmoid(5.0), last_accessed: 100 }, + Dir { path: "/corge/grault/garply".into(), rank: 6.0, last_accessed: 600 }, Dir { path: "/waldo/fred/plugh".into(), rank: 3.0, last_accessed: 300 }, Dir { path: "/xyzzy/thud".into(), rank: 8.0, last_accessed: 800 }, + Dir { path: "/foo/bar".into(), rank: 9.0 + sigmoid(2.0), last_accessed: 900 }, + Dir { path: "/baz".into(), rank: sigmoid(7.0), last_accessed: 0 }, ]; println!("exp: {exp:?}"); @@ -148,12 +148,12 @@ mod tests { println!("got: {:?}", &db.dirs()); let exp = [ - Dir { path: "/baz".into(), rank: 7.0, last_accessed: 700 }, - Dir { path: "/corge/grault/garply".into(), rank: 6.0, last_accessed: 600 }, - Dir { path: "/foo/bar".into(), rank: 11.0, last_accessed: 900 }, Dir { path: "/quux/quuz".into(), rank: 10.0, last_accessed: 500 }, + Dir { path: "/corge/grault/garply".into(), rank: 6.0, last_accessed: 600 }, Dir { path: "/waldo/fred/plugh".into(), rank: 3.0, last_accessed: 300 }, Dir { path: "/xyzzy/thud".into(), rank: 8.0, last_accessed: 800 }, + Dir { path: "/foo/bar".into(), rank: 11.0, last_accessed: 900 }, + Dir { path: "/baz".into(), rank: 7.0, last_accessed: 700 }, ]; println!("exp: {exp:?}"); diff --git a/src/db/mod.rs b/src/db/mod.rs index e0d31a6..d3982fb 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -100,6 +100,7 @@ impl Database { /// directory is already in the database, it is expected that the user /// either does a check before calling this, or calls `dedup()` /// afterward. + #[cfg(test)] pub fn add_unchecked(&mut self, path: impl AsRef + Into, rank: Rank, now: Epoch) { let path_s: String = path.into(); let _ = self.conn.execute( @@ -109,6 +110,20 @@ impl Database { self.dirty = true; } + /// choose the max `now` + /// sum `rank` + pub fn add_unchecked_merge(&mut self, path: impl AsRef + Into, rank: Rank, now: Epoch) { + let path_s: String = path.into(); + let _ = self.conn.execute( + "INSERT INTO dirs (path, rank, last_accessed) VALUES (?1, ?2, ?3) + ON CONFLICT(path) DO UPDATE SET + rank = dirs.rank + excluded.rank, + last_accessed = MAX(dirs.last_accessed, excluded.last_accessed)", + params![&path_s, rank, now], + ); + self.dirty = true; + } + /// Increments the rank and updates the last_accessed of a directory, or /// creates it if it does not exist. pub fn add_update(&mut self, path: impl AsRef + Into, by: Rank, now: Epoch) { @@ -215,6 +230,7 @@ impl Database { // Using path as PRIMARY KEY ensures uniqueness, nothing to do here. } + #[cfg(test)] pub fn sort_by_path(&mut self) { // Sorting is done at query time in the sqlite-backed implementation. }