From 1217d88a50955853461819f25b3aefb239ea7c82 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Feb 2018 21:34:33 +0100 Subject: [PATCH] Fix links after moving entry --- bin/core/imag-mv/Cargo.toml | 1 + bin/core/imag-mv/src/main.rs | 70 +++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/bin/core/imag-mv/Cargo.toml b/bin/core/imag-mv/Cargo.toml index b941ff45..d2de054f 100644 --- a/bin/core/imag-mv/Cargo.toml +++ b/bin/core/imag-mv/Cargo.toml @@ -26,4 +26,5 @@ log = "0.4.0" libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.6.0", path = "../../../lib/core/libimagstore" } +libimagentrylink = { version = "0.6.0", path = "../../../lib/entry/libimagentrylink" } diff --git a/bin/core/imag-mv/src/main.rs b/bin/core/imag-mv/src/main.rs index 030763bf..e420067d 100644 --- a/bin/core/imag-mv/src/main.rs +++ b/bin/core/imag-mv/src/main.rs @@ -38,6 +38,9 @@ extern crate clap; extern crate libimagrt; extern crate libimagstore; extern crate libimagerror; +extern crate libimagentrylink; + +use std::process::exit; mod ui; use ui::build_ui; @@ -47,6 +50,10 @@ use std::path::PathBuf; use libimagrt::setup::generate_runtime_setup; use libimagerror::trace::MapErrTrace; use libimagstore::storeid::StoreId; +use libimagstore::store::Store; +use libimagstore::store::FileLockEntry; +use libimagentrylink::internal::InternalLinker; +use libimagstore::iter::get::StoreIdGetIteratorExtension; fn main() { let rt = generate_runtime_setup("imag-mv", @@ -72,10 +79,71 @@ fn main() { .unwrap() // unwrap safe by clap .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::>() + }; + + { // 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 .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); + // re-add links to moved entry + relink(rt.store(), destname, &mut linked_entries); + info!("Ok."); } + +fn relink<'a>(store: &'a Store, target: StoreId, linked_entries: &mut Vec>) { + 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); + } +}