coven_database/
database_device.rs1use super::{Database, DbError};
4use crate::{LiveQuery, NewOperation, PendingValue, ProviderAccessChange};
5use coven_foundation::files::DeviceReset;
6use coven_foundation::locks::read_unpoisoned;
7
8impl Database {
9 pub async fn record_device_reset<P: PendingValue>(
12 &self,
13 reset: DeviceReset,
14 operations: Vec<NewOperation>,
15 provider_access: Vec<ProviderAccessChange>,
16 ) -> Result<(), DbError> {
17 self.call(move |inner| {
18 inner.access.with_writer(|writer| {
19 writer.transaction(|db| {
20 if crate::device_reset::read(db)? == Some(reset) {
21 return Ok(());
22 }
23 for operation in &operations {
24 crate::operation::insert(db, operation)?;
25 }
26 crate::provider_access::adopt::<P>(db, &provider_access)?;
27 crate::device_reset::record(db, &reset)
28 })
29 })
30 })
31 .await
32 }
33
34 pub(crate) fn local_device(&self) -> Result<coven_foundation::id_source::DeviceId, DbError> {
36 let guard = read_unpoisoned(&self.inner);
37 Ok(guard.as_ref().ok_or(DbError::StoreClosed)?.access.device)
38 }
39
40 pub async fn members(&self) -> Result<Vec<crate::MemberInfo>, DbError> {
43 let device = self.local_device()?;
44 self.read(move |sql| sql.members(device)).await
45 }
46
47 pub fn subscribe_members<E>(&self) -> LiveQuery<Vec<crate::MemberInfo>, E>
49 where
50 E: From<DbError> + coven_foundation::task::CarriesBug + Send + 'static,
51 {
52 let device = self.local_device().ok();
53 self.subscribe(move |sql| sql.members(device.ok_or(DbError::StoreClosed)?).map_err(E::from))
54 }
55
56 pub async fn circles(&self) -> Result<Vec<crate::Circle>, DbError> {
58 let device = self.local_device()?;
59 self.read(move |sql| sql.circles(device)).await
60 }
61
62 pub fn subscribe_circles<E>(&self) -> LiveQuery<Vec<crate::Circle>, E>
64 where
65 E: From<DbError> + coven_foundation::task::CarriesBug + Send + 'static,
66 {
67 let device = self.local_device().ok();
68 self.subscribe(move |sql| sql.circles(device.ok_or(DbError::StoreClosed)?).map_err(E::from))
69 }
70
71 pub async fn circle_members(
74 &self,
75 circle: coven_foundation::id_source::CircleId,
76 ) -> Result<Vec<crate::CircleMemberInfo>, DbError> {
77 let device = self.local_device()?;
78 self.read(move |sql| sql.circle_members(device, circle)).await
79 }
80
81 pub fn subscribe_circle_members<E>(
83 &self,
84 circle: coven_foundation::id_source::CircleId,
85 ) -> LiveQuery<Vec<crate::CircleMemberInfo>, E>
86 where
87 E: From<DbError> + coven_foundation::task::CarriesBug + Send + 'static,
88 {
89 let device = self.local_device().ok();
90 self.subscribe(move |sql| {
91 sql.circle_members(device.ok_or(DbError::StoreClosed)?, circle).map_err(E::from)
92 })
93 }
94
95 pub async fn device_reset(&self) -> Result<Option<DeviceReset>, DbError> {
97 self.read(|sql| sql.device_reset()).await
98 }
99
100 pub fn subscribe_device_reset<E>(&self) -> LiveQuery<Option<DeviceReset>, E>
102 where
103 E: From<DbError> + coven_foundation::task::CarriesBug + Send + 'static,
104 {
105 self.subscribe(|sql| sql.device_reset().map_err(E::from))
106 }
107}
108
109#[cfg(test)]
110#[path = "database_device_tests.rs"]
111mod tests;