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