diff --git a/src/db.rs b/src/db.rs index 84f3cff..0e9c4a8 100644 --- a/src/db.rs +++ b/src/db.rs @@ -70,11 +70,11 @@ impl DB { Ok(()) } - pub fn migrate>(&mut self, path: P) -> Result<()> { - if !self.dirs.is_empty() { + pub fn migrate>(&mut self, path: P, merge: bool) -> Result<()> { + if !self.dirs.is_empty() && !merge { bail!( - "To prevent conflicts, you can only migrate from z with an empty \ - zoxide database!" + "To prevent conflicts, you can only migrate from z with an empty zoxide database! +If you wish to merge the two, specify the `--merge` flag." ); } @@ -87,7 +87,10 @@ impl DB { let line = if let Ok(line) = read_line { line } else { - eprintln!("could not read line {}: {:?}", line_number, read_line); + eprintln!( + "could not read entry at line {}: {:?}", + line_number, read_line + ); continue; }; @@ -131,6 +134,17 @@ impl DB { } }; + if merge { + // If the path exists in the database, add the ranks and set the epoch to + // the largest of the parsed epoch and the already present epoch. + if let Some(dir) = self.dirs.iter_mut().find(|dir| dir.path == path_str) { + dir.rank += rank; + dir.last_accessed = Epoch::max(epoch, dir.last_accessed); + + continue; + }; + } + // FIXME: When we switch to PathBuf for storing directories inside Dir, just // pass `PathBuf::from(path_str)` self.dirs.push(Dir { diff --git a/src/subcommand/migrate.rs b/src/subcommand/migrate.rs index 3ffd017..c3e67ec 100644 --- a/src/subcommand/migrate.rs +++ b/src/subcommand/migrate.rs @@ -7,10 +7,13 @@ use structopt::StructOpt; #[structopt(about = "Migrate from z database")] pub struct Migrate { path: String, + + #[structopt(long, help = "Merge entries into existing database")] + merge: bool, } impl Migrate { pub fn run(&self, env: &Env) -> Result<()> { - util::get_db(env)?.migrate(&self.path) + util::get_db(env)?.migrate(&self.path, self.merge) } }