mayhem-db 0.2.0-beta.1

A Discord-like chat application optimized for security, stability, speed, and ultimate customization. => Database Module
Documentation
use sea_orm::{ColumnTrait, DbConn, DbErr, EntityTrait, ModelTrait, QueryFilter};
use std::sync::Arc;

use super::{common::ConnectionHolder, server::ServerQueryHelper};
use crate::{
    models::{
        server::{channel, server},
        user, user_settings,
    },
    util::{CompleteMember, CompleteRole, CompleteServer, CompleteUser},
};

#[derive(Clone)]
pub struct UserQueryHelper {
    pub client: Arc<DbConn>,
    pub server: Arc<ServerQueryHelper>,
}

unsafe impl Sync for UserQueryHelper {}
unsafe impl Send for UserQueryHelper {}

impl ConnectionHolder for UserQueryHelper {
    fn get_connection(&self) -> &DbConn {
        return &self.client as &DbConn;
    }

    fn get_connection_ref(&self) -> Arc<DbConn> {
        return self.client.clone();
    }

    fn get_connection_raw(&self) -> *const DbConn {
        return Arc::into_raw(self.client.clone());
    }
}

impl UserQueryHelper {
    pub async fn find_user_servers(
        &self,
        user: &user::Model,
    ) -> Result<Vec<CompleteServer>, DbErr> {
        let mut servers: Vec<CompleteServer> = Vec::new();

        let servers_result = user
            .find_related(server::Entity)
            .all(&self.client as &DbConn)
            .await;

        let servers_query: Vec<server::Model> = match servers_result {
            Ok(res) => res,
            Err(err) => return Err(err),
        };

        for server in servers_query {
            let roles_found = self.server.find_server_roles(&server).await;
            let members_found = self.server.find_server_members(&server).await;
            let channels_found = self.server.find_server_channels(&server).await;

            let roles: Vec<CompleteRole> = match roles_found {
                Ok(val) => val,
                Err(err) => return Err(err),
            };

            let members: Vec<CompleteMember> = match members_found {
                Ok(val) => val,
                Err(err) => return Err(err),
            };

            let channels: Vec<channel::Model> = match channels_found {
                Ok(val) => val,
                Err(err) => return Err(err),
            };

            servers.push(CompleteServer {
                id: server.id,
                name: server.name,
                roles,
                members,
                channels,
            });
        }

        return Ok(servers);
    }

    pub async fn find_user_by_id(&self, id: i32) -> Result<Option<user::Model>, DbErr> {
        return user::Entity::find_by_id(id)
            .one(&self.client as &DbConn)
            .await;
    }

    pub async fn find_user_by_name(&self, username: String) -> Result<Option<CompleteUser>, DbErr> {
        let user_result = user::Entity::find()
            .filter(user::Column::Username.eq(username.clone()))
            .one(&self.client as &DbConn)
            .await;

        let user_option: Option<user::Model> = match user_result {
            Ok(res) => res,
            Err(err) => return Err(err),
        };

        let user: user::Model = match user_option {
            Some(res) => res,
            None => return Ok(None),
        };

        let servers_result = self.find_user_servers(&user).await;

        let servers: Vec<CompleteServer> = match servers_result {
            Ok(res) => res,
            Err(err) => return Err(err),
        };

        let settings = user
            .find_related(user_settings::Entity)
            .one(&self.client as &DbConn)
            .await
            .unwrap();

        return Ok(Some(CompleteUser {
            id: user.id,
            first_name: user.first_name,
            last_name: user.last_name,
            email: user.email,
            username: user.username,
            password: user.password,
            servers,
            settings,
        }));
    }
}