#[cfg(feature = "mongodb")]
use ::mongodb::{ClientSession, SessionCursor};
use revolt_result::Result;
use crate::{FieldsMember, Member, MemberCompositeKey, PartialMember};
#[cfg(feature = "mongodb")]
mod mongodb;
mod reference;
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum ChunkedServerMembersGenerator {
#[cfg(feature = "mongodb")]
MongoDb {
session: ClientSession,
cursor: Option<SessionCursor<Member>>,
},
Reference {
offset: i32,
data: Option<Vec<Member>>,
},
}
impl ChunkedServerMembersGenerator {
#[cfg(feature = "mongodb")]
pub fn new_mongo(session: ClientSession, cursor: SessionCursor<Member>) -> Self {
ChunkedServerMembersGenerator::MongoDb {
session,
cursor: Some(cursor),
}
}
pub fn new_reference(data: Vec<Member>) -> Self {
ChunkedServerMembersGenerator::Reference {
offset: 0,
data: Some(data),
}
}
pub async fn next(&mut self) -> Option<Member> {
match self {
#[cfg(feature = "mongodb")]
ChunkedServerMembersGenerator::MongoDb { session, cursor } => {
if let Some(cursor) = cursor {
let value = cursor.next(session).await;
value.map(|val| val.expect("Failed to fetch the next member"))
} else {
warn!("Attempted to access a (MongoDb) server member generator without first setting a cursor");
None
}
}
ChunkedServerMembersGenerator::Reference { offset, data } => {
if let Some(data) = data {
if data.len() as i32 >= *offset {
None
} else {
let resp = &data[*offset as usize];
*offset += 1;
Some(resp.clone())
}
} else {
warn!("Attempted to access a (Reference) server member generator without first providing data");
None
}
}
}
}
}
#[async_trait]
pub trait AbstractServerMembers: Sync + Send {
async fn insert_or_merge_member(&self, member: &Member) -> Result<Option<Member>>;
async fn fetch_member(&self, server_id: &str, user_id: &str) -> Result<Member>;
async fn fetch_all_members(&self, server_id: &str) -> Result<Vec<Member>>;
async fn fetch_all_members_chunked(
&self,
server_id: &str,
) -> Result<ChunkedServerMembersGenerator>;
async fn fetch_all_members_with_roles(
&self,
server_id: &str,
roles: &[String],
) -> Result<Vec<Member>>;
async fn fetch_all_members_with_roles_chunked(
&self,
server_id: &str,
roles: &[String],
) -> Result<ChunkedServerMembersGenerator>;
async fn fetch_all_memberships(&self, user_id: &str) -> Result<Vec<Member>>;
async fn fetch_members(&self, server_id: &str, ids: &[String]) -> Result<Vec<Member>>;
async fn fetch_member_count(&self, server_id: &str) -> Result<usize>;
async fn fetch_server_count(&self, user_id: &str) -> Result<usize>;
async fn update_member(
&self,
id: &MemberCompositeKey,
partial: &PartialMember,
remove: Vec<FieldsMember>,
) -> Result<()>;
async fn soft_delete_member(&self, id: &MemberCompositeKey) -> Result<()>;
async fn force_delete_member(&self, id: &MemberCompositeKey) -> Result<()>;
async fn remove_dangling_members(&self) -> Result<()>;
}