Skip to main content

coven_database/
database_store.rs

1//! Store names share the transaction that commits their sequence prefix; the
2//! store a join publishes also keeps its new person's name (§13.2).
3
4use super::*;
5
6impl Database {
7    /// Save the name chosen for a local store before publishing its
8    /// directory, which slot 1 will set (§10.3). This row is not sequence
9    /// membership until the applied history creates the store and sets its
10    /// name.
11    pub async fn initialize_store_name(&self, name: String) -> Result<(), DbError> {
12        self.call(move |inner| {
13            inner.access.with_writer(|writer| {
14                writer.transaction(|db| {
15                    crate::store_state_tables::name_before_creation(
16                        db,
17                        inner.access.directory.id(),
18                        &name,
19                        coven_merge::Slot::FIRST,
20                    )
21                })
22            })
23        })
24        .await
25    }
26
27    /// Save what the store a join publishes keeps from its invite before it
28    /// loads, in one transaction: the store's `name`, set by `named_at`, the
29    /// slot the inviting device had applied, and the new person's name,
30    /// `invitee`, which it keeps until the app acknowledges it. A recovery's
31    /// request carries none (§13.2).
32    pub async fn initialize_joined_store(
33        &self,
34        name: String,
35        named_at: coven_merge::Slot,
36        invitee: Option<String>,
37    ) -> Result<(), DbError> {
38        self.call(move |inner| {
39            inner.access.with_writer(|writer| {
40                writer.transaction(|db| {
41                    crate::store_state_tables::name_before_creation(
42                        db,
43                        inner.access.directory.id(),
44                        &name,
45                        named_at,
46                    )?;
47                    match &invitee {
48                        Some(invitee) => crate::joined_invitee::keep(db, invitee),
49                        None => Ok(()),
50                    }
51                })
52            })
53        })
54        .await
55    }
56
57    /// The new person's name the store a join published keeps until the app
58    /// acknowledges it; None for any other store, and once acknowledged
59    /// (§13.2).
60    pub async fn joined_invitee(&self) -> Result<Option<String>, DbError> {
61        self.read(|sql| sql.joined_invitee()).await
62    }
63
64    /// The same name query, live (E4).
65    pub fn subscribe_store_name<E>(&self) -> LiveQuery<String, E>
66    where
67        E: From<DbError> + coven_foundation::task::CarriesBug + Send + 'static,
68    {
69        self.subscribe(|sql| sql.store_name().map_err(E::from))
70    }
71
72    /// The committed name and the slot that set it, including a local
73    /// creation's name, which slot 1 will set. A saved restore code keeps
74    /// whichever name has the later slot (§13.1).
75    pub async fn named_store(&self) -> Result<(String, coven_merge::Slot), crate::DbError> {
76        self.read(|sql| sql.named_store()).await
77    }
78}
79
80impl<M: Mode> Database<M> {
81    /// The name in this device's committed state, including a local creation
82    /// on the writer (E9).
83    pub async fn store_name(&self) -> Result<String, crate::DbError> {
84        self.read(|sql| sql.store_name()).await
85    }
86}