mycelium_lib/
lib.rs

1extern crate bincode;
2extern crate bytes;
3extern crate chrono;
4extern crate fern;
5extern crate mycelium_command;
6extern crate mycelium_experimental;
7extern crate mycelium_index;
8extern crate ron;
9#[macro_use]
10extern crate serde;
11extern crate serde_json;
12extern crate socket2;
13extern crate uuid;
14
15mod client;
16pub mod prelude;
17mod tcp_server;
18mod udp_server;
19
20use std::sync::Arc;
21
22use crate::prelude::*;
23use mycelium_command::prelude::*;
24use mycelium_experimental::crossbeam_skiplist::map::SkipMap;
25use mycelium_experimental::crossbeam_skiplist::set::SkipSet;
26use std::net::Ipv4Addr;
27
28///
29/// # Mycelium
30///
31/// Primary method to embed database into applications is
32/// through this struct.
33///
34/// TCP, UDP, or calling functions implemented on Mycelium
35/// in this library to interact with the database.
36///
37/// TCP (localhost) is not required. UDP server
38/// should be started for distributed behavior, but is not
39/// required if that behavior is not desired.
40///
41pub struct Mycelium {
42    pub config: Config,
43    data: Index,
44    network: SkipMap<String, SkipSet<(Ipv4Addr, usize, usize)>>,
45}
46
47impl Mycelium {
48    ///
49    /// # Init_db
50    ///
51    /// Initialize a new instance of Mycelium
52    ///
53    /// ```
54    /// use mycelium_lib::prelude::*;
55    ///
56    /// let config = Config::default()
57    ///  .with_data_directory("./");
58    ///
59    /// let db = Mycelium::init_db(config);
60    ///
61    /// ```
62    ///
63    pub fn init_db(config: Config) -> std::sync::Arc<Mycelium> {
64        let idx = Index::init(Some(config.clone())).expect("Failed to init db.");
65        Arc::new(Mycelium {
66            config,
67            data: idx,
68            network: SkipMap::new(),
69        })
70    }
71
72    pub fn config(&self) -> Config {
73        self.config.clone()
74    }
75
76    ///
77    /// Embedded option
78    ///
79    /// ```
80    /// use mycelium_command::prelude::*;
81    /// use mycelium_lib::{ prelude::*, Mycelium };
82    /// use mycelium_index::prelude::Config;
83    ///
84    /// let config = Config::fetch_or_default(&std::env::current_exe().expect("a path"))
85    ///     .expect("failed to get a default config");
86    /// let db = Mycelium::init_db(config.0);
87    /// let cmd = Command::new()
88    ///     .with_action(Action::Insert(b"Mastiff, Pyranese, Shepard...
89    ///         I do not know my dogs well.".to_vec()))
90    ///     .with_tag("dog")
91    ///     .with_what(What::Index("working".to_string()));
92    ///
93    /// match db.execute_command(cmd) {
94    ///     Ok(_) => assert!(true),
95    ///     Err(_) => assert!((false)),
96    /// }
97    /// ```
98    ///
99    pub fn execute_command(
100        &self,
101        cmd: Command,
102    ) -> std::result::Result<mycelium_command::Result, Box<dyn std::error::Error>> {
103        match &cmd.action {
104            Action::Default => Ok(mycelium_command::Result::Some((
105                None,
106                Some("Search action not set.".to_string()),
107                None,
108                None,
109                None,
110            ))),
111            Action::Archive(_id) => unimplemented!(),
112            Action::Insert(item) => {
113                let id = self
114                    .data
115                    .add(&cmd.tag, item)
116                    .expect("Failed to add item to db.");
117                self.data.save_all()?;
118                Ok(mycelium_command::Result::Some((
119                    Some(id),
120                    None,
121                    None,
122                    None,
123                    None,
124                )))
125            }
126            Action::Select => match cmd.what {
127                What::Index(t) => {
128                    let result = self
129                        .data
130                        .search(cmd.tag.as_str(), vec![t.as_str()].as_slice())
131                        .unwrap();
132                    let result: Vec<Vec<u8>> = result.iter().map(|x| x.get_item()).collect();
133                    Ok(mycelium_command::Result::Some((
134                        None,
135                        None,
136                        None,
137                        Some(result),
138                        None,
139                    )))
140                }
141                What::Id(id) => {
142                    let result = self.data.get(cmd.tag.as_str(), &[id]).unwrap();
143                    let result: Vec<Vec<u8>> = result.iter().map(|x| x.get_item()).collect();
144                    Ok(mycelium_command::Result::Some((
145                        None,
146                        None,
147                        None,
148                        Some(result),
149                        None,
150                    )))
151                }
152                What::Default => {
153                    self.data.db.load_tag(cmd.tag.as_str())?;
154                    let result = self.data.db.get_tag(cmd.tag.as_str()).unwrap();
155                    let result: ResultList = result.iter().map(|x| x.get_item()).collect();
156                    Ok(mycelium_command::Result::Some((
157                        None,
158                        None,
159                        None,
160                        Some(result),
161                        None,
162                    )))
163                }
164            },
165            Action::Update((_id, _item)) => unimplemented!(),
166        }
167    }
168}