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::database::GenericDatabase;
24
25// Re-export some types in the public interface
26pub use storage::{
27    database::StorageError,
28    key_value::KeyValueStorage,
29};
30
31/// Options for configuring the domain database
32pub mod options;
33
34/// A database abstraction for storing and retrieving domain data
35///
36/// This is a thin wrapper around a [KeyValueStorage] implementation that provides
37/// a more convenient interface for working with column families and ensures
38/// thread-safe access through Arc.
39///
40/// The database can be backed by different storage engines:
41/// - In-memory storage (with the `in_memory` feature)
42/// - [RocksDB](https://rocksdb.org/) persistent storage (with the `rocksdb` feature)
43#[derive(Debug)]
44pub struct Database<Storage: KeyValueStorage> {
45    /// The underlying storage implementation wrapped in an [Arc] for thread-safe access
46    storage: Arc<Storage>,
47}
48
49impl<Storage: KeyValueStorage> Clone for Database<Storage> {
50    fn clone(&self) -> Self {
51        Self {
52            storage: self.storage.clone(),
53        }
54    }
55}
56
57impl<Storage: KeyValueStorage> Database<Storage> {
58    /// Create a new [Database] instance with the given storage backend
59    pub fn new(db: Storage) -> Self {
60        let db = Arc::new(db);
61        Self { storage: db }
62    }
63}
64
65impl<Storage: KeyValueStorage> GenericDatabase for Database<Storage> {
66    type Storage = Storage;
67
68    fn storage(&self) -> &Self::Storage {
69        &self.storage
70    }
71}
72
73impl<S> DbQueriesPort for Database<S> where
74    S: KeyValueStorage<ColumnFamilyIdentifier = ColumnFamilies, Error = StorageError>
75        + Send
76        + Sync
77        + 'static
78{
79}
80
81impl<S> DbCommandsPort for Database<S> where
82    S: KeyValueStorage<ColumnFamilyIdentifier = ColumnFamilies, Error = StorageError>
83        + Send
84        + Sync
85        + 'static
86{
87}
88
89/// Default storage type based on the crate feature:
90/// - in-memory storage by default (current)
91/// - RocksDB storage if feature `rocksdb` is set
92#[cfg(not(feature = "rocksdb"))]
93pub(crate) type DefaultStorage = in_memory::Storage;
94/// Default storage type based on the crate feature:
95/// - in-memory storage by default
96/// - RocksDB storage if feature `rocksdb` is set (current)
97#[cfg(feature = "rocksdb")]
98pub(crate) type DefaultStorage = rocksdb::Storage;
99
100/// In-memory storage module
101pub mod in_memory {
102    use super::*;
103    use storage::in_memory::InMemoryStorage;
104
105    /// In-memory storage type for the domain
106    pub type Storage = InMemoryStorage<ColumnFamilies>;
107}
108
109/// RocksDB storage module
110#[cfg(feature = "rocksdb")]
111pub mod rocksdb {
112    use super::*;
113    use storage::database::spec::DbSpec as DbSpecTrait;
114    use storage_rocksdb::RocksDb;
115
116    /// DB specification for a RocksDb.
117    #[derive(Debug, Clone, Copy)]
118    pub struct DbSpec;
119
120    impl DbSpecTrait for DbSpec {
121        const NAME: &'static str = "DomainDb";
122
123        type ColumnFamilyIdentifier = ColumnFamilies;
124    }
125
126    /// RocksDB storage type for the domain
127    pub type Storage = RocksDb<DbSpec>;
128}