autopush_common/db/
client.rs

1use std::collections::HashSet;
2use std::fmt::Debug;
3
4use async_trait::async_trait;
5use mockall::automock;
6use uuid::Uuid;
7
8use crate::db::error::DbResult;
9use crate::db::User;
10use crate::notification::Notification;
11
12#[derive(Default, Debug)]
13pub struct FetchMessageResponse {
14    pub timestamp: Option<u64>,
15    pub messages: Vec<Notification>,
16}
17
18/// Provides high-level operations for data management.
19///
20/// This is usually manifested by _database_::DbClientImpl
21///
22#[automock] // must appear before #[async_trait]
23#[async_trait]
24pub trait DbClient: Send + Sync {
25    /// Add a new user to the database. An error will occur if the user already
26    /// exists.
27    async fn add_user(&self, user: &User) -> DbResult<()>;
28
29    /// Update a user in the database. Returns whether the update occurred. The
30    /// update will not occur if the user does not already exist, has a
31    /// different router type, or has a newer `connected_at` timestamp.
32    // TODO: make the bool a #[must_use]
33    async fn update_user(&self, user: &mut User) -> DbResult<bool>;
34
35    /// Read a user from the database
36    async fn get_user(&self, uaid: &Uuid) -> DbResult<Option<User>>;
37
38    /// Delete a user from the router table
39    async fn remove_user(&self, uaid: &Uuid) -> DbResult<()>;
40
41    /// Add a channel to a user
42    async fn add_channel(&self, uaid: &Uuid, channel_id: &Uuid) -> DbResult<()>;
43
44    /// Add a batch of channels to a user
45    async fn add_channels(&self, uaid: &Uuid, channels: HashSet<Uuid>) -> DbResult<()>;
46
47    /// Get the set of channel IDs for a user
48    async fn get_channels(&self, uaid: &Uuid) -> DbResult<HashSet<Uuid>>;
49
50    /// Remove a channel from a user. Returns if the removed channel did exist.
51    async fn remove_channel(&self, uaid: &Uuid, channel_id: &Uuid) -> DbResult<bool>;
52
53    /// Remove the node ID from a user in the router table. Returns whether the
54    /// removal occurred. The node ID will only be removed if `connected_at`
55    /// matches up with the item's `connected_at`.
56    async fn remove_node_id(
57        &self,
58        uaid: &Uuid,
59        node_id: &str,
60        connected_at: u64,
61        version: &Option<Uuid>,
62    ) -> DbResult<bool>;
63
64    /// Save a message to the message table
65    async fn save_message(&self, uaid: &Uuid, message: Notification) -> DbResult<()>;
66
67    /// Save multiple messages to the message table
68    async fn save_messages(&self, uaid: &Uuid, messages: Vec<Notification>) -> DbResult<()>;
69
70    /// Fetch stored messages for a user
71    async fn fetch_topic_messages(
72        &self,
73        uaid: &Uuid,
74        limit: usize,
75    ) -> DbResult<FetchMessageResponse>;
76
77    /// Fetch stored messages later than a given
78    async fn fetch_timestamp_messages(
79        &self,
80        uaid: &Uuid,
81        timestamp: Option<u64>,
82        limit: usize,
83    ) -> DbResult<FetchMessageResponse>;
84
85    /// Update the last read timestamp for a user
86    async fn increment_storage(&self, uaid: &Uuid, timestamp: u64) -> DbResult<()>;
87
88    /// Delete a notification
89    async fn remove_message(&self, uaid: &Uuid, chidmessageid: &str) -> DbResult<()>;
90
91    /// Check if the router table exists
92    async fn router_table_exists(&self) -> DbResult<bool>;
93
94    /// Check if the message table exists
95    async fn message_table_exists(&self) -> DbResult<bool>;
96
97    /// Perform the health check on this data store
98    async fn health_check(&self) -> DbResult<bool>;
99
100    /// Provide the module name.
101    /// This was added for simple dual mode testing (legacy), but may be useful in
102    /// other situations.
103    fn name(&self) -> String;
104
105    /// Return the current deadpool Status (if using deadpool)
106    fn pool_status(&self) -> Option<deadpool::Status> {
107        None
108    }
109
110    /// Record the Reliability Report to long term storage.
111    #[cfg(feature = "reliable_report")]
112    async fn log_report(
113        &self,
114        reliability_id: &str,
115        state: crate::reliability::ReliabilityState,
116    ) -> DbResult<()>;
117
118    fn box_clone(&self) -> Box<dyn DbClient>;
119}
120
121impl Clone for Box<dyn DbClient> {
122    fn clone(&self) -> Self {
123        self.box_clone()
124    }
125}