1
use bonsaidb::core::connection::Connection;
2
use bonsaidb::core::document::{BorrowedDocument, Emit};
3
use bonsaidb::core::schema::view::map::ViewMappedValue;
4
use bonsaidb::core::schema::{
5
    Collection, MapReduce, ReduceResult, SerializedCollection, View, ViewMapResult, ViewSchema,
6
};
7
use bonsaidb::core::Error;
8
use bonsaidb::local::config::{Builder, StorageConfiguration};
9
use bonsaidb::local::Database;
10
use serde::{Deserialize, Serialize};
11

            
12
// ANCHOR: struct
13
49
#[derive(Serialize, Deserialize, Debug, Collection)]
14
#[collection(name = "blog-post", views = [BlogPostsByCategory])]
15
pub struct BlogPost {
16
    pub title: String,
17
    pub body: String,
18
    pub category: Option<String>,
19
}
20
// ANCHOR_END: struct
21

            
22
// ANCHOR: view
23
32
#[derive(Debug, Clone, View, ViewSchema)]
24
#[view(collection = BlogPost, key = Option<String>, value = u32, name = "by-category")]
25
pub struct BlogPostsByCategory;
26

            
27
impl MapReduce for BlogPostsByCategory {
28
3
    fn map<'doc>(&self, document: &'doc BorrowedDocument<'_>) -> ViewMapResult<'doc, Self> {
29
3
        let post = BlogPost::document_contents(document)?;
30
3
        document.header.emit_key_and_value(post.category, 1)
31
3
    }
32

            
33
3
    fn reduce(
34
3
        &self,
35
3
        mappings: &[ViewMappedValue<Self::View>],
36
3
        _rereduce: bool,
37
3
    ) -> ReduceResult<Self::View> {
38
5
        Ok(mappings.iter().map(|mapping| mapping.value).sum())
39
3
    }
40
}
41
// ANCHOR_END: view
42

            
43
#[allow(unused_variables)]
44
1
#[test]
45
1
fn example() -> Result<(), Error> {
46
1
    drop(std::fs::remove_dir_all("example.bonsaidb"));
47
1
    let db = Database::open::<BlogPost>(StorageConfiguration::new("example.bonsaidb"))?;
48
    // ANCHOR: insert_data
49
1
    BlogPost {
50
1
        title: String::from("New version of BonsaiDb released"),
51
1
        body: String::from("..."),
52
1
        category: Some(String::from("Rust")),
53
1
    }
54
1
    .push_into(&db)?;
55

            
56
1
    BlogPost {
57
1
        title: String::from("New Rust version released"),
58
1
        body: String::from("..."),
59
1
        category: Some(String::from("Rust")),
60
1
    }
61
1
    .push_into(&db)?;
62

            
63
1
    BlogPost {
64
1
        title: String::from("Check out this great cinnamon roll recipe"),
65
1
        body: String::from("..."),
66
1
        category: Some(String::from("Cooking")),
67
1
    }
68
1
    .push_into(&db)?;
69
    // ANCHOR_END: insert_data
70
    // ANCHOR: query_with_docs
71
1
    let rust_posts = db
72
1
        .view::<BlogPostsByCategory>()
73
1
        .with_key(&Some(String::from("Rust")))
74
1
        .query_with_docs()?;
75
3
    for mapping in &rust_posts {
76
2
        let post = BlogPost::document_contents(mapping.document)?;
77
2
        println!(
78
2
            "Retrieved post #{} \"{}\"",
79
2
            mapping.document.header.id, post.title
80
2
        );
81
    }
82
    // ANCHOR_END: query_with_docs
83
1
    assert_eq!(rust_posts.len(), 2);
84
    // ANCHOR: query_with_collection_docs
85
1
    let rust_posts = db
86
1
        .view::<BlogPostsByCategory>()
87
1
        .with_key(&Some(String::from("Rust")))
88
1
        .query_with_collection_docs()?;
89
3
    for mapping in &rust_posts {
90
2
        println!(
91
2
            "Retrieved post #{} \"{}\"",
92
2
            mapping.document.header.id, mapping.document.contents.title
93
2
        );
94
2
    }
95
    // ANCHOR_END: query_with_collection_docs
96
1
    assert_eq!(rust_posts.len(), 2);
97
    // ANCHOR: reduce_one_key
98
1
    let rust_post_count = db
99
1
        .view::<BlogPostsByCategory>()
100
1
        .with_key(&Some(String::from("Rust")))
101
1
        .reduce()?;
102
1
    assert_eq!(rust_post_count, 2);
103
    // ANCHOR_END: reduce_one_key
104
    // ANCHOR: reduce_multiple_keys
105
1
    let total_post_count = db.view::<BlogPostsByCategory>().reduce()?;
106
1
    assert_eq!(total_post_count, 3);
107
    // ANCHOR_END: reduce_multiple_keys
108
1
    Ok(())
109
1
}