1
use std::time::Duration;
2

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

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

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

            
16
    // The set_key method can be awaited to insert/replace a key. Values can be
17
    // anything supported by Serde.
18
1
    db.set_key("mykey", &1_u32).execute()?;
19

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

            
27
    // Retrieving is simple too.
28
1
    let value = db.get_key("mykey").into()?;
29
1
    assert_eq!(value, Some(2_u32));
30

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

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

            
47
1
    let second_try = db
48
1
        .set_key("lockname", &())
49
1
        .only_if_vacant()
50
1
        .expire_in(Duration::from_millis(100))
51
1
        .execute()?;
52
1
    assert_eq!(second_try, KeyStatus::NotChanged);
53

            
54
1
    Ok(())
55
1
}
56

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