1
1
use std::time::Duration;
2

            
3
use bonsaidb::{
4
    core::keyvalue::{KeyStatus, KeyValue},
5
    local::{
6
        config::{Builder, StorageConfiguration},
7
        Database,
8
    },
9
};
10

            
11
// BonsaiDb supports a lightweight, atomic key-value store in addition to its
12
// acid-compliant transactional storage. This interface is meant to replicate
13
// functionality that you might use something like Redis for -- lightweight
14
// caching, or fast atomic operations. As with all of BonsaiDb's core features,
15
// the Key-Value store is supported across all methods of accessing BonsaiDb.
16

            
17
1
fn main() -> Result<(), bonsaidb::core::Error> {
18
1
    let db = Database::open::<()>(StorageConfiguration::new("key-value-store.bonsaidb"))?;
19

            
20
    // The set_key method can be awaited to insert/replace a key. Values can be
21
    // anything supported by Serde.
22
1
    db.set_key("mykey", &1_u32).execute()?;
23

            
24
    // Or, you can customize it's behavior:
25
1
    let old_value = db
26
1
        .set_key("mykey", &2_u32)
27
1
        .only_if_exists()
28
1
        .returning_previous_as()?;
29
1
    assert_eq!(old_value, Some(1_u32));
30

            
31
    // Retrieving is simple too.
32
1
    let value = db.get_key("mykey").into()?;
33
1
    assert_eq!(value, Some(2_u32));
34

            
35
    // Namespacing is built-in as well, so that you can easily separate storage.
36
1
    let value = db
37
1
        .with_key_namespace("anamespace")
38
1
        .get_key("mykey")
39
1
        .query()?;
40
1
    assert!(value.is_none());
41

            
42
    // Because of the atomic nature of the key-value store, you can use set_key
43
    // as a synchronized lock:
44
1
    let result = db
45
1
        .set_key("lockname", &()) // A useful value would be the unique id of the worker that aquired the lock.
46
1
        .only_if_vacant()
47
1
        .expire_in(Duration::from_millis(100))
48
1
        .execute()?;
49
1
    assert_eq!(result, KeyStatus::Inserted);
50

            
51
1
    let second_try = db
52
1
        .set_key("lockname", &())
53
1
        .only_if_vacant()
54
1
        .expire_in(Duration::from_millis(100))
55
1
        .execute()?;
56
1
    assert_eq!(second_try, KeyStatus::NotChanged);
57

            
58
1
    Ok(())
59
1
}
60

            
61
1
#[test]
62
1
fn runs() {
63
1
    let path = std::path::Path::new("key-value-store.bonsaidb");
64
1
    if path.exists() {
65
        std::fs::remove_dir_all(path).unwrap();
66
1
    }
67
1
    main().unwrap()
68
1
}