summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-03-22 22:04:29 +0100
committerGitHub <noreply@github.com>2018-03-22 22:04:29 +0100
commitc39a1f82e26be1b6f414e634d451ea2a490e5e4d (patch)
tree69dd6c1bc672abb811e972a6b0e9f4a9b1185f41
parentc857f97287ee2d29e0981ccaa5942ca54fe7978e (diff)
parent41f7bab1c568d9affc6152c385068fe12d4c1237 (diff)
downloadimag-c39a1f82e26be1b6f414e634d451ea2a490e5e4d.zip
imag-c39a1f82e26be1b6f414e634d451ea2a490e5e4d.tar.gz
Merge pull request #1355 from matthiasbeyer/libimagstore/create-semantic-fix
Fix: Store::create() should fail if the entry exists
-rw-r--r--lib/core/libimagstore/src/store.rs14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs
index bab9a6f..a9c3aad 100644
--- a/lib/core/libimagstore/src/store.rs
+++ b/lib/core/libimagstore/src/store.rs
@@ -317,6 +317,7 @@ impl Store {
///
/// On error:
/// - Errors StoreId::into_storeid() might return
+ /// - EntryAlreadyExists(id) if the entry exists
/// - CreateCallError(LockPoisoned()) if the internal lock is poisened.
/// - CreateCallError(EntryAlreadyExists()) if the entry exists already.
///
@@ -325,6 +326,17 @@ impl Store {
debug!("Creating id: '{}'", id);
+ let exists = id.exists()? || self.entries
+ .read()
+ .map(|map| map.contains_key(&id))
+ .map_err(|_| SE::from_kind(SEK::LockPoisoned))
+ .chain_err(|| SEK::CreateCallError)?;
+
+ if exists {
+ debug!("Entry exists: {:?}", id);
+ return Err(SEK::EntryAlreadyExists(id).into());
+ }
+
{
let mut hsmap = self
.entries
@@ -1420,7 +1432,7 @@ mod store_tests {
for n in 1..100 {
let s = format!("test-{}", n % 50);
store.create(PathBuf::from(s.clone()))
- .map_err(|e| assert!(is_match!(e.kind(), &SEK::CreateCallError) && n >= 50))
+ .map_err(|e| assert!(is_match!(e.kind(), &SEK::EntryAlreadyExists(_)) && n >= 50))
.ok()
.map(|entry| {
assert!(entry.verify().is_ok());