From 29e1107d3ebe24dea1a244607480c708e012a6d5 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 17 Sep 2017 15:43:57 +0200 Subject: [PATCH 1/2] Add file abstraction function to check whether path exists --- lib/core/libimagstore/src/file_abstraction/fs.rs | 4 ++++ lib/core/libimagstore/src/file_abstraction/inmemory.rs | 7 +++++++ lib/core/libimagstore/src/file_abstraction/mod.rs | 2 ++ lib/core/libimagstore/src/file_abstraction/stdio/mod.rs | 4 ++++ lib/core/libimagstore/src/file_abstraction/stdio/out.rs | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/lib/core/libimagstore/src/file_abstraction/fs.rs b/lib/core/libimagstore/src/file_abstraction/fs.rs index 51206314..2c649c22 100644 --- a/lib/core/libimagstore/src/file_abstraction/fs.rs +++ b/lib/core/libimagstore/src/file_abstraction/fs.rs @@ -133,6 +133,10 @@ impl FileAbstraction for FSFileAbstraction { create_dir_all(path).chain_err(|| SEK::DirNotCreated) } + fn exists(&self, path: &PathBuf) -> Result { + Ok(path.exists()) + } + fn new_instance(&self, p: PathBuf) -> Box { Box::new(FSFileAbstractionInstance::Absent(p)) } diff --git a/lib/core/libimagstore/src/file_abstraction/inmemory.rs b/lib/core/libimagstore/src/file_abstraction/inmemory.rs index 5134281b..909aad9d 100644 --- a/lib/core/libimagstore/src/file_abstraction/inmemory.rs +++ b/lib/core/libimagstore/src/file_abstraction/inmemory.rs @@ -152,6 +152,13 @@ impl FileAbstraction for InMemoryFileAbstraction { Ok(()) } + fn exists(&self, pb: &PathBuf) -> Result { + let mut mtx = self.backend().lock().expect("Locking Mutex failed"); + let backend = mtx.get_mut(); + + Ok(backend.contains_key(pb)) + } + fn new_instance(&self, p: PathBuf) -> Box { Box::new(InMemoryFileAbstractionInstance::new(self.backend().clone(), p)) } diff --git a/lib/core/libimagstore/src/file_abstraction/mod.rs b/lib/core/libimagstore/src/file_abstraction/mod.rs index f34a6f1e..47b24da4 100644 --- a/lib/core/libimagstore/src/file_abstraction/mod.rs +++ b/lib/core/libimagstore/src/file_abstraction/mod.rs @@ -43,6 +43,8 @@ pub trait FileAbstraction : Debug { fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE>; fn create_dir_all(&self, _: &PathBuf) -> Result<(), SE>; + fn exists(&self, &PathBuf) -> Result; + fn new_instance(&self, p: PathBuf) -> Box; fn drain(&self) -> Result; diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs b/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs index 725ecf5a..a9606c91 100644 --- a/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs +++ b/lib/core/libimagstore/src/file_abstraction/stdio/mod.rs @@ -115,6 +115,10 @@ impl FileAbstraction for StdIoFileAbstraction { self.0.new_instance(p) } + fn exists(&self, p: &PathBuf) -> Result { + self.0.exists(p) + } + fn drain(&self) -> Result { self.0.drain() } diff --git a/lib/core/libimagstore/src/file_abstraction/stdio/out.rs b/lib/core/libimagstore/src/file_abstraction/stdio/out.rs index 23f961f2..456fe9d4 100644 --- a/lib/core/libimagstore/src/file_abstraction/stdio/out.rs +++ b/lib/core/libimagstore/src/file_abstraction/stdio/out.rs @@ -136,6 +136,10 @@ impl FileAbstraction for StdoutFileAbstraction { self.mem.new_instance(p) } + fn exists(&self, p: &PathBuf) -> Result { + self.mem.exists(p) + } + fn drain(&self) -> Result { self.backend_cloned().map(Drain::new) } From a01a2c18f879bf9b5426279a0aa3abcc7e2b7746 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 17 Sep 2017 15:44:19 +0200 Subject: [PATCH 2/2] Check in Store::move_by_id() whether target exists, not only in cache but also on FS --- lib/core/libimagstore/src/store.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs index 7b48e500..5ba3754f 100644 --- a/lib/core/libimagstore/src/store.rs +++ b/lib/core/libimagstore/src/store.rs @@ -755,6 +755,10 @@ impl Store { let old_id_pb = try!(old_id.clone().with_base(self.path().clone()).into_pathbuf()); let new_id_pb = try!(new_id.clone().with_base(self.path().clone()).into_pathbuf()); + if try!(self.backend.exists(&new_id_pb)) { + return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone()))); + } + match self.backend.rename(&old_id_pb, &new_id_pb) { Err(e) => return Err(e).chain_err(|| SEK::EntryRenameError(old_id_pb, new_id_pb)), Ok(_) => {