Skip to main content

bitwarden_state/sdk_managed/
mod.rs

1use std::sync::Arc;
2
3use bitwarden_error::bitwarden_error;
4use thiserror::Error;
5
6use crate::repository::{Repository, RepositoryError, RepositoryItem, RepositoryMigrations};
7
8mod configuration;
9pub use configuration::DatabaseConfiguration;
10
11#[cfg(target_arch = "wasm32")]
12mod indexed_db;
13#[cfg(target_arch = "wasm32")]
14pub(super) type SystemDatabase = indexed_db::IndexedDbDatabase;
15#[cfg(target_arch = "wasm32")]
16type InternalError = ::indexed_db::Error<indexed_db::IndexedDbInternalError>;
17
18#[cfg(not(target_arch = "wasm32"))]
19mod sqlite;
20#[cfg(not(target_arch = "wasm32"))]
21pub(super) type SystemDatabase = sqlite::SqliteDatabase;
22#[cfg(not(target_arch = "wasm32"))]
23type InternalError = ::rusqlite::Error;
24
25#[bitwarden_error(flat)]
26#[derive(Debug, Error)]
27pub enum DatabaseError {
28    #[error("Database not supported on this platform: {0:?}")]
29    UnsupportedConfiguration(DatabaseConfiguration),
30
31    #[error(transparent)]
32    ThreadBoundRunner(#[from] bitwarden_threading::CallError),
33
34    #[error("Serialization error: {0}")]
35    Serialization(#[from] serde_json::Error),
36
37    #[error("JS error: {0}")]
38    JS(String),
39
40    #[error(transparent)]
41    Internal(#[from] InternalError),
42}
43
44pub trait Database {
45    async fn initialize(
46        configuration: DatabaseConfiguration,
47        registrations: RepositoryMigrations,
48    ) -> Result<Self, DatabaseError>
49    where
50        Self: Sized;
51
52    async fn get<T: RepositoryItem>(&self, key: &str) -> Result<Option<T>, DatabaseError>;
53
54    async fn list<T: RepositoryItem>(&self) -> Result<Vec<T>, DatabaseError>;
55
56    async fn set<T: RepositoryItem>(&self, key: &str, value: T) -> Result<(), DatabaseError>;
57
58    async fn set_bulk<T: RepositoryItem>(
59        &self,
60        values: Vec<(String, T)>,
61    ) -> Result<(), DatabaseError>;
62
63    async fn remove<T: RepositoryItem>(&self, key: &str) -> Result<(), DatabaseError>;
64
65    async fn remove_bulk<T: RepositoryItem>(&self, keys: Vec<String>) -> Result<(), DatabaseError>;
66
67    async fn remove_all<T: RepositoryItem>(&self) -> Result<(), DatabaseError>;
68}
69
70struct DBRepository<T: RepositoryItem> {
71    database: SystemDatabase,
72    _marker: std::marker::PhantomData<T>,
73}
74
75#[async_trait::async_trait]
76impl<V: RepositoryItem> Repository<V> for DBRepository<V> {
77    async fn get(&self, key: V::Key) -> Result<Option<V>, RepositoryError> {
78        let key = key.to_string();
79        let value = self.database.get::<V>(&key).await?;
80        Ok(value)
81    }
82    async fn list(&self) -> Result<Vec<V>, RepositoryError> {
83        let values = self.database.list::<V>().await?;
84        Ok(values)
85    }
86    async fn set(&self, key: V::Key, value: V) -> Result<(), RepositoryError> {
87        let key = key.to_string();
88        Ok(self.database.set::<V>(&key, value).await?)
89    }
90    async fn set_bulk(&self, values: Vec<(V::Key, V)>) -> Result<(), RepositoryError> {
91        let values = values
92            .into_iter()
93            .map(|(k, v)| (k.to_string(), v))
94            .collect();
95        Ok(self.database.set_bulk::<V>(values).await?)
96    }
97    async fn remove(&self, key: V::Key) -> Result<(), RepositoryError> {
98        let key = key.to_string();
99        Ok(self.database.remove::<V>(&key).await?)
100    }
101    async fn remove_bulk(&self, keys: Vec<V::Key>) -> Result<(), RepositoryError> {
102        let keys = keys.into_iter().map(|k| k.to_string()).collect();
103        Ok(self.database.remove_bulk::<V>(keys).await?)
104    }
105    async fn remove_all(&self) -> Result<(), RepositoryError> {
106        Ok(self.database.remove_all::<V>().await?)
107    }
108}
109
110impl SystemDatabase {
111    pub(super) fn get_repository<V: RepositoryItem>(&self) -> Arc<dyn Repository<V>> {
112        Arc::new(DBRepository {
113            database: self.clone(),
114            _marker: std::marker::PhantomData,
115        })
116    }
117}