forked from jmug/stoatchat
chore(monorepo): delta, january, quark
This commit is contained in:
228
crates/quark/src/impl/mongo/servers/server.rs
Normal file
228
crates/quark/src/impl/mongo/servers/server.rs
Normal file
@@ -0,0 +1,228 @@
|
||||
use bson::{to_document, Bson, Document};
|
||||
|
||||
use crate::models::server::{FieldsRole, FieldsServer, PartialRole, PartialServer, Role, Server};
|
||||
use crate::r#impl::mongo::IntoDocumentPath;
|
||||
use crate::{AbstractServer, Database, Error, Result};
|
||||
|
||||
use super::super::MongoDb;
|
||||
|
||||
static COL: &str = "servers";
|
||||
|
||||
impl MongoDb {
|
||||
pub async fn delete_associated_server_objects(&self, server: &Server) -> Result<()> {
|
||||
// Check if there are any attachments we need to delete.
|
||||
self.delete_bulk_messages(doc! {
|
||||
"channel": {
|
||||
"$in": &server.channels
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
// Delete all channels.
|
||||
self.col::<Document>("channels")
|
||||
.delete_many(
|
||||
doc! {
|
||||
"server": &server.id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_many",
|
||||
with: "channels",
|
||||
})?;
|
||||
|
||||
// Delete any associated objects, e.g. unreads and invites.
|
||||
self.delete_associated_channel_objects(Bson::Document(doc! { "$in": &server.channels }))
|
||||
.await?;
|
||||
|
||||
// Delete members and bans.
|
||||
for with in &["server_members", "server_bans"] {
|
||||
self.col::<Document>(with)
|
||||
.delete_many(
|
||||
doc! {
|
||||
"_id.server": &server.id
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "delete_many",
|
||||
with,
|
||||
})?;
|
||||
}
|
||||
|
||||
// Update many attachments with parent id.
|
||||
self.delete_many_attachments(doc! {
|
||||
"object_id": &server.id
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AbstractServer for MongoDb {
|
||||
async fn fetch_server(&self, id: &str) -> Result<Server> {
|
||||
self.find_one_by_id(COL, id).await
|
||||
}
|
||||
|
||||
async fn fetch_servers<'a>(&self, ids: &'a [String]) -> Result<Vec<Server>> {
|
||||
self.find(
|
||||
COL,
|
||||
doc! {
|
||||
"_id": {
|
||||
"$in": ids
|
||||
}
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn insert_server(&self, server: &Server) -> Result<()> {
|
||||
self.insert_one(COL, server).await.map(|_| ())
|
||||
}
|
||||
|
||||
async fn update_server(
|
||||
&self,
|
||||
id: &str,
|
||||
server: &PartialServer,
|
||||
remove: Vec<FieldsServer>,
|
||||
) -> Result<()> {
|
||||
self.update_one_by_id(
|
||||
COL,
|
||||
id,
|
||||
server,
|
||||
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn delete_server(&self, server: &Server) -> Result<()> {
|
||||
self.delete_associated_server_objects(server).await?;
|
||||
self.delete_one_by_id(COL, &server.id).await.map(|_| ())
|
||||
}
|
||||
|
||||
async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()> {
|
||||
self.col::<Database>(COL)
|
||||
.update_one(
|
||||
doc! {
|
||||
"_id": server_id
|
||||
},
|
||||
doc! {
|
||||
"$set": {
|
||||
"roles.".to_owned() + role_id: to_document(role)
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "to_document",
|
||||
with: "role"
|
||||
})?
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "server",
|
||||
})
|
||||
}
|
||||
|
||||
async fn update_role(
|
||||
&self,
|
||||
server_id: &str,
|
||||
role_id: &str,
|
||||
role: &PartialRole,
|
||||
remove: Vec<FieldsRole>,
|
||||
) -> Result<()> {
|
||||
self.update_one_by_id(
|
||||
COL,
|
||||
server_id,
|
||||
role,
|
||||
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(),
|
||||
"roles.".to_owned() + role_id + ".",
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn delete_role(&self, server_id: &str, role_id: &str) -> Result<()> {
|
||||
self.col::<Document>("server_members")
|
||||
.update_many(
|
||||
doc! {
|
||||
"_id.server": server_id
|
||||
},
|
||||
doc! {
|
||||
"$pull": {
|
||||
"roles": &role_id
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_many",
|
||||
with: "server_members",
|
||||
})?;
|
||||
|
||||
self.col::<Document>("channels")
|
||||
.update_one(
|
||||
doc! {
|
||||
"server": server_id
|
||||
},
|
||||
doc! {
|
||||
"$unset": {
|
||||
"role_permissions.".to_owned() + role_id: 1_i32
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "channels",
|
||||
})?;
|
||||
|
||||
self.col::<Document>("servers")
|
||||
.update_one(
|
||||
doc! {
|
||||
"_id": server_id
|
||||
},
|
||||
doc! {
|
||||
"$unset": {
|
||||
"roles.".to_owned() + role_id: 1_i32
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "servers",
|
||||
})
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDocumentPath for FieldsServer {
|
||||
fn as_path(&self) -> Option<&'static str> {
|
||||
Some(match self {
|
||||
FieldsServer::Banner => "banner",
|
||||
FieldsServer::Categories => "categories",
|
||||
FieldsServer::Description => "description",
|
||||
FieldsServer::Icon => "icon",
|
||||
FieldsServer::SystemMessages => "system_messages",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDocumentPath for FieldsRole {
|
||||
fn as_path(&self) -> Option<&'static str> {
|
||||
Some(match self {
|
||||
FieldsRole::Colour => "colour",
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user