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