1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
4mod access_point;
6#[cfg(feature = "audit")]
7pub mod audit;
8pub mod compact;
9mod error;
10mod event_log;
11mod folder;
12mod helpers;
13#[cfg(feature = "preferences")]
14mod preferences;
15mod server_origins;
16#[cfg(feature = "system-messages")]
17mod system_messages;
18mod vault_writer;
19
20pub use access_point::BackendAccessPoint as AccessPoint;
21pub use error::{Error, StorageError};
22pub use event_log::{
23 BackendAccountEventLog as AccountEventLog,
24 BackendDeviceEventLog as DeviceEventLog, BackendEventLog,
25 BackendFolderEventLog as FolderEventLog,
26};
27pub use folder::Folder;
28pub use helpers::extract_vault;
29#[cfg(feature = "preferences")]
30pub use preferences::BackendPreferences as Preferences;
31pub use server_origins::ServerOrigins;
32pub use sos_database as database;
33pub use sos_filesystem::write_exclusive;
34use sos_vault::Summary;
35#[cfg(feature = "system-messages")]
36pub use system_messages::SystemMessages;
37pub use vault_writer::VaultWriter;
38
39#[cfg(feature = "files")]
40pub use event_log::BackendFileEventLog as FileEventLog;
41
42pub(crate) type Result<T> = std::result::Result<T, Error>;
44
45use sos_core::{AccountId, PublicIdentity};
46use sos_database::entity::{
47 AccountEntity, AccountRecord, FolderEntity, FolderRecord,
48};
49
50#[derive(Clone)]
52pub enum BackendTarget {
53 FileSystem(sos_core::Paths),
55 Database(sos_database::async_sqlite::Client),
57}
58
59impl BackendTarget {
60 pub async fn list_accounts(&self) -> Result<Vec<PublicIdentity>> {
62 match self {
63 BackendTarget::FileSystem(paths) => {
64 Ok(sos_vault::list_accounts(Some(paths)).await?)
65 }
66 BackendTarget::Database(client) => {
67 let account_rows = client
68 .conn_and_then(move |conn| {
69 let account = AccountEntity::new(&conn);
70 account.list_accounts()
71 })
72 .await?;
73 let mut accounts = Vec::new();
74 for row in account_rows {
75 let record: AccountRecord = row.try_into()?;
76 accounts.push(record.identity);
77 }
78 Ok(accounts)
79 }
80 }
81 }
82
83 pub async fn list_folders(
85 &self,
86 account_id: &AccountId,
87 ) -> Result<Vec<Summary>> {
88 match self {
89 BackendTarget::FileSystem(paths) => {
90 let paths = paths.with_account_id(account_id);
91 Ok(sos_vault::list_local_folders(&paths)
92 .await?
93 .into_iter()
94 .map(|(s, _)| s)
95 .collect())
96 }
97 BackendTarget::Database(client) => {
98 let account_id = *account_id;
99 let folder_rows = client
100 .conn_and_then(move |conn| {
101 let account = AccountEntity::new(&conn);
102 let folders = FolderEntity::new(&conn);
103 let account_row = account.find_one(&account_id)?;
104 folders.list_user_folders(account_row.row_id)
105 })
106 .await?;
107 let mut folders = Vec::new();
108 for row in folder_rows {
109 let record = FolderRecord::from_row(row).await?;
110 folders.push(record.summary);
111 }
112 Ok(folders)
113 }
114 }
115 }
116}