typed_store/
lib.rs

1// Copyright (c) 2021, Facebook, Inc. and its affiliates
2// Copyright (c) Mysten Labs, Inc.
3// Modifications Copyright (c) 2024 IOTA Stiftung
4// SPDX-License-Identifier: Apache-2.0
5
6#![warn(
7    future_incompatible,
8    nonstandard_style,
9    rust_2018_idioms,
10    rust_2021_compatibility
11)]
12
13// Re-export rocksdb so that consumers can use the version of rocksdb via
14// typed-store
15pub use rocksdb;
16
17pub mod traits;
18pub use traits::Map;
19pub mod metrics;
20pub mod rocks;
21pub use typed_store_error::TypedStoreError;
22pub mod sally;
23pub mod test_db;
24pub use metrics::DBMetrics;
25
26pub type StoreError = typed_store_error::TypedStoreError;
27
28/// A helper macro to simplify common operations for opening and debugging
29/// TypedStore (currently internally structs of DBMaps) It operates on a struct
30/// where all the members are of Store<K, V> or DBMap<K, V> `TypedStoreDebug`
31/// traits are then derived The main features are:
32/// 1. Flexible configuration of each table (column family) via defaults and
33///    overrides
34/// 2. Auto-generated `open` routine
35/// 3. Auto-generated `read_only_mode` handle
36/// 4. Auto-generated memory stats method
37/// 5. Other convenience features
38///
39/// 1. Flexible configuration: a. Static options specified at struct definition
40///
41/// The definer of the struct can specify the default options for each table
42/// using annotations We can also supply column family options on the default
43/// ones A user defined function of signature () -> Options can be provided for
44/// each table If a an override function is not specified, the default in
45/// `typed_store::rocks::default_db_options` is used
46/// ```
47/// use core::fmt::Error;
48///
49/// use typed_store::{
50///     DBMapUtils,
51///     rocks::{DBMap, DBOptions, MetricConf},
52///     traits::{TableSummary, TypedStoreDebug},
53/// };
54/// /// Define a struct with all members having type DBMap<K, V>
55///
56/// fn custom_fn_name1() -> DBOptions {
57///     DBOptions::default()
58/// }
59/// fn custom_fn_name2() -> DBOptions {
60///     let mut op = custom_fn_name1();
61///     op.options.set_write_buffer_size(123456);
62///     op
63/// }
64/// #[derive(DBMapUtils)]
65/// struct Tables {
66///     /// Specify custom options function `custom_fn_name1`
67///     #[default_options_override_fn = "custom_fn_name1"]
68///     table1: DBMap<String, String>,
69///     #[default_options_override_fn = "custom_fn_name2"]
70///     table2: DBMap<i32, String>,
71///     // Nothing specified so `typed_store::rocks::default_db_options` is used
72///     table3: DBMap<i32, String>,
73///     #[default_options_override_fn = "custom_fn_name1"]
74///     table4: DBMap<i32, String>,
75/// }
76///
77/// // b. Options specified by DB opener
78/// // For finer control, we also allow the opener of the DB to specify their
79/// // own options which override the defaults set by the definer
80/// // This is done via a configurator which gives one a struct with field
81/// // similarly named as that of the DB, but of type Options
82///
83/// #[tokio::main]
84/// async fn main() -> Result<(), Error> {
85///     // Get a configurator for this table
86///     let mut config = Tables::configurator();
87///     // Config table 1
88///     config.table1 = DBOptions::default();
89///     config.table1.options.create_if_missing(true);
90///     config.table1.options.set_write_buffer_size(123456);
91///
92///     let primary_path = tempfile::tempdir()
93///         .expect(
94///             "Failed to open temporary
95/// directory",
96///         )
97///         .into_path();
98///
99///     // We can then open the DB with the configs
100///     let _ = Tables::open_tables_read_write(
101///         primary_path,
102///         MetricConf::default(),
103///         None,
104///         Some(config.build()),
105///     );
106///     Ok(())
107/// }
108/// ```
109///
110/// 2. Auto-generated `open` routine The function `open_tables_read_write` is
111///    generated which allows for specifying DB wide options and custom table
112///    configs as mentioned above
113///
114/// 3. Auto-generated `read_only_mode` handle This mode provides handle struct
115///    which opens the DB in read only mode and has certain features like
116///    dumping and counting the keys in the tables
117///
118/// Use the function `Tables::get_read_only_handle` which returns a handle that
119/// only allows read only features
120/// ```
121/// use core::fmt::Error;
122///
123/// use typed_store::{
124///     DBMapUtils,
125///     rocks::{DBMap, DBOptions},
126///     traits::{TableSummary, TypedStoreDebug},
127/// };
128/// /// Define a struct with all members having type DBMap<K, V>
129///
130/// fn custom_fn_name1() -> DBOptions {
131///     DBOptions::default()
132/// }
133/// fn custom_fn_name2() -> DBOptions {
134///     let mut op = custom_fn_name1();
135///     op.options.set_write_buffer_size(123456);
136///     op
137/// }
138/// #[derive(DBMapUtils)]
139/// struct Tables {
140///     /// Specify custom options function `custom_fn_name1`
141///     #[default_options_override_fn = "custom_fn_name1"]
142///     table1: DBMap<String, String>,
143///     #[default_options_override_fn = "custom_fn_name2"]
144///     table2: DBMap<i32, String>,
145///     // Nothing specified so `typed_store::rocks::default_db_options` is used
146///     table3: DBMap<i32, String>,
147///     #[default_options_override_fn = "custom_fn_name1"]
148///     table4: DBMap<i32, String>,
149/// }
150/// #[tokio::main]
151/// async fn main() -> Result<(), Error> {
152///     use typed_store::rocks::MetricConf;
153///     let primary_path = tempfile::tempdir()
154///         .expect("Failed to open temporary directory")
155///         .into_path();
156///     let _ = Tables::open_tables_read_write(
157///         primary_path.clone(),
158///         typed_store::rocks::MetricConf::default(),
159///         None,
160///         None,
161///     );
162///
163///     // Get the read only handle
164///     let read_only_handle =
165///         Tables::get_read_only_handle(primary_path, None, None, MetricConf::default());
166///     // Use this handle for dumping
167///     let ret = read_only_handle.dump("table2", 100, 0).unwrap();
168///     let key_count = read_only_handle.count_keys("table1").unwrap();
169///     Ok(())
170/// }
171/// ```
172/// 4. Auto-generated memory stats method `self.get_memory_usage` is derived to
173///    provide memory and cache usage
174///
175/// 5. Other convenience features `Tables::describe_tables` is used to get a
176///    list of the table names and key-value types as string in a BTreeMap
177///
178/// // Bad usage example
179/// // Structs fields most only be of type Store<K, V> or DMBap<K, V>
180/// // This will fail to compile with error `All struct members must be of type
181/// Store<K, V> or DMBap<K, V>` // #[derive(DBMapUtils)]
182/// // struct BadTables {
183/// //     table1: Store<String, String>,
184/// //     bad_field: u32,
185/// // #}
186pub use typed_store_derive::DBMapUtils;
187pub use typed_store_derive::SallyDB;