Merge pull request #1260 from matthiasbeyer/imag-mv/fix-links

imag-mv: Fix links after moving entry
This commit is contained in:
Matthias Beyer 2018-02-07 01:57:11 +01:00 committed by GitHub
commit c7e1842000
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 1 deletions

View file

@ -26,4 +26,5 @@ log = "0.4.0"
libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" }
libimagstore = { version = "0.6.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.6.0", path = "../../../lib/core/libimagstore" }
libimagentrylink = { version = "0.6.0", path = "../../../lib/entry/libimagentrylink" }

View file

@ -38,6 +38,9 @@ extern crate clap;
extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagentrylink;
use std::process::exit;
mod ui; mod ui;
use ui::build_ui; use ui::build_ui;
@ -47,6 +50,10 @@ use std::path::PathBuf;
use libimagrt::setup::generate_runtime_setup; use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagentrylink::internal::InternalLinker;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
fn main() { fn main() {
let rt = generate_runtime_setup("imag-mv", let rt = generate_runtime_setup("imag-mv",
@ -72,10 +79,71 @@ fn main() {
.unwrap() // unwrap safe by clap .unwrap() // unwrap safe by clap
.map_err_trace_exit_unwrap(1); .map_err_trace_exit_unwrap(1);
// remove links to entry, and re-add them later
let mut linked_entries = {
rt.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap(1)
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
})
.get_internal_links()
.map_err_trace_exit_unwrap(1)
.map(|link| link.get_store_id().clone())
.into_get_iter(rt.store())
.map(|e| {
e.map_err_trace_exit_unwrap(1)
.unwrap_or_else(|| {
error!("Linked entry does not exist");
exit(1)
})
})
.collect::<Vec<_>>()
};
{ // remove links to linked entries from source
let mut entry = rt
.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap(1)
.unwrap_or_else(|| {
error!("Source Entry does not exist");
exit(1)
});
for link in linked_entries.iter_mut() {
let _ = entry.remove_internal_link(link).map_err_trace_exit_unwrap(1);
}
}
let _ = rt let _ = rt
.store() .store()
.move_by_id(sourcename, destname) .move_by_id(sourcename.clone(), destname.clone())
.map_err(|e| { // on error, re-add links
debug!("Re-adding links to source entry because moving failed");
relink(rt.store(), sourcename.clone(), &mut linked_entries);
e
})
.map_err_trace_exit_unwrap(1); .map_err_trace_exit_unwrap(1);
// re-add links to moved entry
relink(rt.store(), destname, &mut linked_entries);
info!("Ok."); info!("Ok.");
} }
fn relink<'a>(store: &'a Store, target: StoreId, linked_entries: &mut Vec<FileLockEntry<'a>>) {
let mut entry = store
.get(target)
.map_err_trace_exit_unwrap(1)
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
});
for mut link in linked_entries {
let _ = entry.add_internal_link(&mut link).map_err_trace_exit_unwrap(1);
}
}