1use std::{fmt::Debug, future::Future};
7
8use serde::de::DeserializeOwned;
9
10#[cfg(with_testing)]
11use crate::random::generate_test_namespace;
12use crate::{batch::Batch, common::from_bytes_option, ViewError};
13
14pub trait KeyValueStoreError:
16 std::error::Error + From<bcs::Error> + Debug + Send + Sync + 'static
17{
18 const BACKEND: &'static str;
20}
21
22impl<E: KeyValueStoreError> From<E> for ViewError {
23 fn from(error: E) -> Self {
24 Self::StoreError {
25 backend: E::BACKEND,
26 error: Box::new(error),
27 }
28 }
29}
30
31pub trait WithError {
33 type Error: KeyValueStoreError;
35}
36
37#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
39pub trait ReadableKeyValueStore: WithError {
40 const MAX_KEY_SIZE: usize;
42
43 fn max_stream_queries(&self) -> usize;
45
46 async fn read_value_bytes(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
48
49 async fn contains_key(&self, key: &[u8]) -> Result<bool, Self::Error>;
51
52 async fn contains_keys(&self, keys: Vec<Vec<u8>>) -> Result<Vec<bool>, Self::Error>;
54
55 async fn read_multi_values_bytes(
57 &self,
58 keys: Vec<Vec<u8>>,
59 ) -> Result<Vec<Option<Vec<u8>>>, Self::Error>;
60
61 async fn find_keys_by_prefix(&self, key_prefix: &[u8]) -> Result<Vec<Vec<u8>>, Self::Error>;
63
64 async fn find_key_values_by_prefix(
66 &self,
67 key_prefix: &[u8],
68 ) -> Result<Vec<(Vec<u8>, Vec<u8>)>, Self::Error>;
69
70 fn read_value<V: DeserializeOwned>(
76 &self,
77 key: &[u8],
78 ) -> impl Future<Output = Result<Option<V>, Self::Error>> {
79 async { Ok(from_bytes_option(&self.read_value_bytes(key).await?)?) }
80 }
81
82 fn read_multi_values<V: DeserializeOwned + Send + Sync>(
84 &self,
85 keys: Vec<Vec<u8>>,
86 ) -> impl Future<Output = Result<Vec<Option<V>>, Self::Error>> {
87 async {
88 let mut values = Vec::with_capacity(keys.len());
89 for entry in self.read_multi_values_bytes(keys).await? {
90 values.push(from_bytes_option(&entry)?);
91 }
92 Ok(values)
93 }
94 }
95}
96
97#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
99pub trait WritableKeyValueStore: WithError {
100 const MAX_VALUE_SIZE: usize;
102
103 async fn write_batch(&self, batch: Batch) -> Result<(), Self::Error>;
105
106 async fn clear_journal(&self) -> Result<(), Self::Error>;
109}
110
111#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
113pub trait AdminKeyValueStore: WithError + Sized {
114 type Config: Send + Sync;
116 fn get_name() -> String;
118
119 async fn connect(config: &Self::Config, namespace: &str) -> Result<Self, Self::Error>;
121
122 fn open_exclusive(&self, root_key: &[u8]) -> Result<Self, Self::Error>;
129
130 async fn list_all(config: &Self::Config) -> Result<Vec<String>, Self::Error>;
132
133 async fn list_root_keys(
136 config: &Self::Config,
137 namespace: &str,
138 ) -> Result<Vec<Vec<u8>>, Self::Error>;
139
140 fn delete_all(config: &Self::Config) -> impl Future<Output = Result<(), Self::Error>> {
142 async {
143 let namespaces = Self::list_all(config).await?;
144 for namespace in namespaces {
145 Self::delete(config, &namespace).await?;
146 }
147 Ok(())
148 }
149 }
150
151 async fn exists(config: &Self::Config, namespace: &str) -> Result<bool, Self::Error>;
153
154 async fn create(config: &Self::Config, namespace: &str) -> Result<(), Self::Error>;
156
157 async fn delete(config: &Self::Config, namespace: &str) -> Result<(), Self::Error>;
159
160 fn maybe_create_and_connect(
162 config: &Self::Config,
163 namespace: &str,
164 ) -> impl Future<Output = Result<Self, Self::Error>> {
165 async {
166 if !Self::exists(config, namespace).await? {
167 Self::create(config, namespace).await?;
168 }
169 Self::connect(config, namespace).await
170 }
171 }
172
173 fn recreate_and_connect(
175 config: &Self::Config,
176 namespace: &str,
177 ) -> impl Future<Output = Result<Self, Self::Error>> {
178 async {
179 if Self::exists(config, namespace).await? {
180 Self::delete(config, namespace).await?;
181 }
182 Self::create(config, namespace).await?;
183 Self::connect(config, namespace).await
184 }
185 }
186}
187
188pub trait RestrictedKeyValueStore: ReadableKeyValueStore + WritableKeyValueStore {}
190
191impl<T> RestrictedKeyValueStore for T where T: ReadableKeyValueStore + WritableKeyValueStore {}
192
193pub trait KeyValueStore:
195 ReadableKeyValueStore + WritableKeyValueStore + AdminKeyValueStore
196{
197}
198
199impl<T> KeyValueStore for T where
200 T: ReadableKeyValueStore + WritableKeyValueStore + AdminKeyValueStore
201{
202}
203
204#[cfg(with_testing)]
206pub trait TestKeyValueStore: KeyValueStore {
207 async fn new_test_config() -> Result<Self::Config, Self::Error>;
209
210 async fn new_test_store() -> Result<Self, Self::Error> {
212 let config = Self::new_test_config().await?;
213 let namespace = generate_test_namespace();
214 Self::recreate_and_connect(&config, &namespace).await
215 }
216}