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}