delta_domain_sdk/
storage.rs

1//! # Storage
2//!
3//! Storage backends for persisting domain state.
4//!
5//! Two backends are available:
6//! - [`in_memory::Storage`] — volatile, for testing and development
7//! - [`rocksdb::Storage`] — persistent, for production (requires `rocksdb`
8//!   feature)
9//!
10//! The default storage for a [`Domain`][crate::Domain] is selected by the
11//! `rocksdb` cargo feature: RocksDB when enabled, in-memory otherwise.
12//! Configure a custom backend with
13//! [`DomainBuilder::with_storage`](crate::builder::DomainBuilder::with_storage).
14
15use domain_runtime::{
16    ports::{
17        DbCommandsPort,
18        DbQueriesPort,
19    },
20    storage::ColumnFamilies,
21};
22use std::sync::Arc;
23use storage::{
24    database::GenericDatabase,
25    key_value::KeyValueStorage,
26};
27
28// Re-export some types in the public interface
29pub use storage::{
30    database::StorageError,
31    key_value::KeyValueStorageWithColumnFamilies,
32};
33
34/// Options for configuring the domain database
35pub mod options;
36
37/// A database abstraction for storing and retrieving domain data
38///
39/// This is a thin wrapper around a [KeyValueStorage] implementation that provides
40/// a more convenient interface for working with column families and ensures
41/// thread-safe access through Arc.
42///
43/// The database can be backed by different storage engines:
44/// - In-memory storage (with the `in_memory` feature)
45/// - [RocksDB](https://rocksdb.org/) persistent storage (with the `rocksdb` feature)
46#[derive(Debug)]
47pub struct Database<Storage: KeyValueStorage> {
48    /// The underlying storage implementation wrapped in an [Arc] for thread-safe access
49    storage: Arc<Storage>,
50}
51
52impl<Storage: KeyValueStorageWithColumnFamilies> Clone for Database<Storage> {
53    fn clone(&self) -> Self {
54        Self {
55            storage: self.storage.clone(),
56        }
57    }
58}
59
60impl<Storage: KeyValueStorageWithColumnFamilies> Database<Storage> {
61    /// Create a new [Database] instance with the given storage backend
62    pub fn new(db: Storage) -> Self {
63        let db = Arc::new(db);
64        Self { storage: db }
65    }
66}
67
68impl<Storage: KeyValueStorageWithColumnFamilies> GenericDatabase for Database<Storage> {
69    type Storage = Storage;
70
71    fn storage(&self) -> &Self::Storage {
72        &self.storage
73    }
74}
75
76impl<S> DbQueriesPort for Database<S> where
77    S: KeyValueStorageWithColumnFamilies<
78            ColumnFamilyIdentifier = ColumnFamilies,
79            Error = StorageError,
80        > + Send
81        + Sync
82        + 'static
83{
84}
85
86impl<S> DbCommandsPort for Database<S> where
87    S: KeyValueStorageWithColumnFamilies<
88            ColumnFamilyIdentifier = ColumnFamilies,
89            Error = StorageError,
90        > + Send
91        + Sync
92        + 'static
93{
94}
95
96/// Default storage type based on the crate feature:
97/// - in-memory storage by default (current)
98/// - RocksDB storage if feature `rocksdb` is set
99#[cfg(not(feature = "rocksdb"))]
100pub(crate) type DefaultStorage = in_memory::Storage;
101/// Default storage type based on the crate feature:
102/// - in-memory storage by default
103/// - RocksDB storage if feature `rocksdb` is set (current)
104#[cfg(feature = "rocksdb")]
105pub(crate) type DefaultStorage = rocksdb::Storage;
106
107/// In-memory storage module
108pub mod in_memory {
109    use super::*;
110    use storage::in_memory::StaticInMemoryStorage;
111
112    /// In-memory storage type for the domain
113    pub type Storage = StaticInMemoryStorage<ColumnFamilies>;
114}
115
116/// RocksDB storage module
117#[cfg(feature = "rocksdb")]
118pub mod rocksdb {
119    use super::*;
120    use storage::database::spec::{
121        DbSpec as DbSpecTrait,
122        StaticDbSpec,
123    };
124    use storage_rocksdb::RocksDb;
125
126    /// DB specification for a RocksDb.
127    #[derive(Debug, Clone, Copy)]
128    pub struct DbSpec;
129
130    impl DbSpecTrait for DbSpec {
131        const NAME: &'static str = "DomainDb";
132    }
133
134    impl StaticDbSpec for DbSpec {
135        type ColumnFamilyIdentifier = ColumnFamilies;
136    }
137
138    /// RocksDB storage type for the domain
139    pub type Storage = RocksDb<DbSpec>;
140}