bitwarden_state/sdk_managed/
mod.rs1use 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 remove<T: RepositoryItem>(&self, key: &str) -> Result<(), DatabaseError>;
59}
60
61struct DBRepository<T: RepositoryItem> {
62 database: SystemDatabase,
63 _marker: std::marker::PhantomData<T>,
64}
65
66#[async_trait::async_trait]
67impl<V: RepositoryItem> Repository<V> for DBRepository<V> {
68 async fn get(&self, key: String) -> Result<Option<V>, RepositoryError> {
69 let value = self.database.get::<V>(&key).await?;
70 Ok(value)
71 }
72 async fn list(&self) -> Result<Vec<V>, RepositoryError> {
73 let values = self.database.list::<V>().await?;
74 Ok(values)
75 }
76 async fn set(&self, key: String, value: V) -> Result<(), RepositoryError> {
77 Ok(self.database.set::<V>(&key, value).await?)
78 }
79 async fn remove(&self, key: String) -> Result<(), RepositoryError> {
80 Ok(self.database.remove::<V>(&key).await?)
81 }
82}
83
84impl SystemDatabase {
85 pub(super) fn get_repository<V: RepositoryItem>(&self) -> Arc<dyn Repository<V>> {
86 Arc::new(DBRepository {
87 database: self.clone(),
88 _marker: std::marker::PhantomData,
89 })
90 }
91}