deadpool, diesel and errors! #16
3 changed files with 144 additions and 221 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::Error;
|
use crate::error::Error;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::fs::read_to_string;
|
use tokio::fs::read_to_string;
|
||||||
|
|
328
src/structs.rs
328
src/structs.rs
|
@ -1,11 +1,17 @@
|
||||||
use actix_web::HttpResponse;
|
|
||||||
use diesel::{delete, insert_into, prelude::{Insertable, Queryable}, ExpressionMethods, QueryDsl, Selectable, SelectableHelper};
|
use diesel::{delete, insert_into, prelude::{Insertable, Queryable}, ExpressionMethods, QueryDsl, Selectable, SelectableHelper};
|
||||||
use log::error;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use diesel_async::{pooled_connection::AsyncDieselConnectionManager, RunQueryDsl};
|
use diesel_async::{pooled_connection::AsyncDieselConnectionManager, RunQueryDsl};
|
||||||
|
|
||||||
use crate::{Conn, Data, schema::*};
|
use crate::{error::Error, Conn, Data, schema::*};
|
||||||
|
|
||||||
|
fn load_or_empty<T>(query_result: Result<Vec<T>, diesel::result::Error>) -> Result<Vec<T>, diesel::result::Error> {
|
||||||
|
match query_result {
|
||||||
|
Ok(vec) => Ok(vec),
|
||||||
|
Err(diesel::result::Error::NotFound) => Ok(Vec::new()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Queryable, Selectable, Insertable, Clone)]
|
#[derive(Queryable, Selectable, Insertable, Clone)]
|
||||||
#[diesel(table_name = channels)]
|
#[diesel(table_name = channels)]
|
||||||
|
@ -18,13 +24,15 @@ struct ChannelBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelBuilder {
|
impl ChannelBuilder {
|
||||||
async fn build(self, conn: &mut Conn) -> Result<Channel, crate::Error> {
|
async fn build(self, conn: &mut Conn) -> Result<Channel, Error> {
|
||||||
use self::channel_permissions::dsl::*;
|
use self::channel_permissions::dsl::*;
|
||||||
let channel_permission: Vec<ChannelPermission> = channel_permissions
|
let channel_permission: Vec<ChannelPermission> = load_or_empty(
|
||||||
.filter(channel_uuid.eq(self.uuid))
|
channel_permissions
|
||||||
.select((role_uuid, permissions))
|
.filter(channel_uuid.eq(self.uuid))
|
||||||
.load(conn)
|
.select(ChannelPermission::as_select())
|
||||||
.await?;
|
.load(conn)
|
||||||
|
.await
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Channel {
|
Ok(Channel {
|
||||||
uuid: self.uuid,
|
uuid: self.uuid,
|
||||||
|
@ -45,7 +53,7 @@ pub struct Channel {
|
||||||
pub permissions: Vec<ChannelPermission>,
|
pub permissions: Vec<ChannelPermission>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Queryable)]
|
#[derive(Serialize, Deserialize, Clone, Queryable, Selectable)]
|
||||||
#[diesel(table_name = channel_permissions)]
|
#[diesel(table_name = channel_permissions)]
|
||||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
pub struct ChannelPermission {
|
pub struct ChannelPermission {
|
||||||
|
@ -57,69 +65,38 @@ impl Channel {
|
||||||
pub async fn fetch_all(
|
pub async fn fetch_all(
|
||||||
pool: &deadpool::managed::Pool<AsyncDieselConnectionManager<diesel_async::AsyncPgConnection>, Conn>,
|
pool: &deadpool::managed::Pool<AsyncDieselConnectionManager<diesel_async::AsyncPgConnection>, Conn>,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
) -> Result<Vec<Self>, HttpResponse> {
|
) -> Result<Vec<Self>, Error> {
|
||||||
let mut conn = pool.get().await.unwrap();
|
let mut conn = pool.get().await?;
|
||||||
|
|
||||||
use channels::dsl;
|
use channels::dsl;
|
||||||
let channel_builders_result: Result<Vec<ChannelBuilder>, diesel::result::Error> = dsl::channels
|
let channel_builders: Vec<ChannelBuilder> = load_or_empty(
|
||||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
dsl::channels
|
||||||
.select(ChannelBuilder::as_select())
|
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||||
.load(&mut conn)
|
.select(ChannelBuilder::as_select())
|
||||||
.await;
|
.load(&mut conn)
|
||||||
|
.await
|
||||||
if let Err(error) = channel_builders_result {
|
)?;
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
let channel_builders = channel_builders_result.unwrap();
|
|
||||||
|
|
||||||
let channel_futures = channel_builders.iter().map(async move |c| {
|
let channel_futures = channel_builders.iter().map(async move |c| {
|
||||||
let mut conn = pool.get().await?;
|
let mut conn = pool.get().await?;
|
||||||
c.clone().build(&mut conn).await
|
c.clone().build(&mut conn).await
|
||||||
});
|
});
|
||||||
|
|
||||||
|
futures::future::try_join_all(channel_futures).await
|
||||||
let channels = futures::future::try_join_all(channel_futures).await;
|
|
||||||
|
|
||||||
if let Err(error) = channels {
|
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(channels.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_one(
|
pub async fn fetch_one(
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
channel_uuid: Uuid,
|
channel_uuid: Uuid,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
use channels::dsl;
|
use channels::dsl;
|
||||||
let channel_builder_result: Result<ChannelBuilder, diesel::result::Error> = dsl::channels
|
let channel_builder: ChannelBuilder = dsl::channels
|
||||||
.filter(dsl::uuid.eq(channel_uuid))
|
.filter(dsl::uuid.eq(channel_uuid))
|
||||||
.select(ChannelBuilder::as_select())
|
.select(ChannelBuilder::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = channel_builder_result {
|
channel_builder.build(conn).await
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish())
|
|
||||||
}
|
|
||||||
|
|
||||||
let channel_builder = channel_builder_result.unwrap();
|
|
||||||
|
|
||||||
let channel = channel_builder.build(conn).await;
|
|
||||||
|
|
||||||
if let Err(error) = channel {
|
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(channel.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
|
@ -127,8 +104,8 @@ impl Channel {
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
let mut conn = data.pool.get().await.unwrap();
|
let mut conn = data.pool.get().await?;
|
||||||
|
|
||||||
let channel_uuid = Uuid::now_v7();
|
let channel_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
|
@ -139,15 +116,10 @@ impl Channel {
|
||||||
description: description.clone(),
|
description: description.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let insert_result = insert_into(channels::table)
|
insert_into(channels::table)
|
||||||
.values(new_channel)
|
.values(new_channel)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = insert_result {
|
|
||||||
error!("{}", error);
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns different object because there's no reason to build the channelbuilder (wastes 1 database request)
|
// returns different object because there's no reason to build the channelbuilder (wastes 1 database request)
|
||||||
let channel = Self {
|
let channel = Self {
|
||||||
|
@ -158,37 +130,21 @@ impl Channel {
|
||||||
permissions: vec![],
|
permissions: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let cache_result = data
|
data
|
||||||
.set_cache_key(channel_uuid.to_string(), channel.clone(), 1800)
|
.set_cache_key(channel_uuid.to_string(), channel.clone(), 1800)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = cache_result {
|
data.del_cache_key(format!("{}_channels", guild_uuid)).await?;
|
||||||
error!("{}", error);
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
let cache_deletion_result = data.del_cache_key(format!("{}_channels", guild_uuid)).await;
|
|
||||||
|
|
||||||
if let Err(error) = cache_deletion_result {
|
|
||||||
error!("{}", error);
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(channel)
|
Ok(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(self, conn: &mut Conn) -> Result<(), HttpResponse> {
|
pub async fn delete(self, conn: &mut Conn) -> Result<(), Error> {
|
||||||
use channels::dsl;
|
use channels::dsl;
|
||||||
let result = delete(channels::table)
|
delete(channels::table)
|
||||||
.filter(dsl::uuid.eq(self.uuid))
|
.filter(dsl::uuid.eq(self.uuid))
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = result {
|
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -198,22 +154,19 @@ impl Channel {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
amount: i64,
|
amount: i64,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
) -> Result<Vec<Message>, HttpResponse> {
|
) -> Result<Vec<Message>, Error> {
|
||||||
use messages::dsl;
|
use messages::dsl;
|
||||||
let messages: Result<Vec<Message>, diesel::result::Error> = dsl::messages
|
let messages: Vec<Message> = load_or_empty(
|
||||||
.filter(dsl::channel_uuid.eq(self.uuid))
|
dsl::messages
|
||||||
.select(Message::as_select())
|
.filter(dsl::channel_uuid.eq(self.uuid))
|
||||||
.limit(amount)
|
.select(Message::as_select())
|
||||||
.offset(offset)
|
.limit(amount)
|
||||||
.load(conn)
|
.offset(offset)
|
||||||
.await;
|
.load(conn)
|
||||||
|
.await
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Err(error) = messages {
|
Ok(messages)
|
||||||
error!("{}", error);
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(messages.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new_message(
|
pub async fn new_message(
|
||||||
|
@ -221,7 +174,7 @@ impl Channel {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
user_uuid: Uuid,
|
user_uuid: Uuid,
|
||||||
message: String,
|
message: String,
|
||||||
) -> Result<Message, HttpResponse> {
|
) -> Result<Message, Error> {
|
||||||
let message_uuid = Uuid::now_v7();
|
let message_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let message = Message {
|
let message = Message {
|
||||||
|
@ -231,15 +184,10 @@ impl Channel {
|
||||||
message,
|
message,
|
||||||
};
|
};
|
||||||
|
|
||||||
let insert_result = insert_into(messages::table)
|
insert_into(messages::table)
|
||||||
.values(message.clone())
|
.values(message.clone())
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = insert_result {
|
|
||||||
error!("{}", error);
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(message)
|
Ok(message)
|
||||||
}
|
}
|
||||||
|
@ -294,7 +242,7 @@ struct GuildBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuildBuilder {
|
impl GuildBuilder {
|
||||||
async fn build(self, conn: &mut Conn) -> Result<Guild, HttpResponse> {
|
async fn build(self, conn: &mut Conn) -> Result<Guild, Error> {
|
||||||
let member_count = Member::count(conn, self.uuid).await?;
|
let member_count = Member::count(conn, self.uuid).await?;
|
||||||
|
|
||||||
let roles = Role::fetch_all(conn, self.uuid).await?;
|
let roles = Role::fetch_all(conn, self.uuid).await?;
|
||||||
|
@ -323,49 +271,39 @@ pub struct Guild {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Guild {
|
impl Guild {
|
||||||
pub async fn fetch_one(conn: &mut Conn, guild_uuid: Uuid) -> Result<Self, HttpResponse> {
|
pub async fn fetch_one(conn: &mut Conn, guild_uuid: Uuid) -> Result<Self, Error> {
|
||||||
use guilds::dsl;
|
use guilds::dsl;
|
||||||
let guild_builder: Result<GuildBuilder, diesel::result::Error> = dsl::guilds
|
let guild_builder: GuildBuilder = dsl::guilds
|
||||||
.filter(dsl::uuid.eq(guild_uuid))
|
.filter(dsl::uuid.eq(guild_uuid))
|
||||||
.select(GuildBuilder::as_select())
|
.select(GuildBuilder::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await;
|
.await?;
|
||||||
|
|
||||||
if let Err(error) = guild_builder {
|
guild_builder.build(conn).await
|
||||||
error!("{}", error);
|
|
||||||
|
|
||||||
return Err(HttpResponse::InternalServerError().finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
let guild = guild_builder.unwrap().build(conn).await?;
|
|
||||||
|
|
||||||
Ok(guild)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_amount(
|
pub async fn fetch_amount(
|
||||||
pool: &deadpool::managed::Pool<AsyncDieselConnectionManager<diesel_async::AsyncPgConnection>, Conn>,
|
pool: &deadpool::managed::Pool<AsyncDieselConnectionManager<diesel_async::AsyncPgConnection>, Conn>,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
amount: i64,
|
amount: i64,
|
||||||
) -> Result<Vec<Self>, HttpResponse> {
|
) -> Result<Vec<Self>, Error> {
|
||||||
// Fetch guild data from database
|
// Fetch guild data from database
|
||||||
let mut conn = pool.get().await.unwrap();
|
let mut conn = pool.get().await?;
|
||||||
|
|
||||||
use guilds::dsl;
|
use guilds::dsl;
|
||||||
let guild_builders: Vec<GuildBuilder> = dsl::guilds
|
let guild_builders: Vec<GuildBuilder> = load_or_empty(
|
||||||
.select(GuildBuilder::as_select())
|
dsl::guilds
|
||||||
.order_by(dsl::uuid)
|
.select(GuildBuilder::as_select())
|
||||||
.offset(offset)
|
.order_by(dsl::uuid)
|
||||||
.limit(amount)
|
.offset(offset)
|
||||||
.load(&mut conn)
|
.limit(amount)
|
||||||
.await
|
.load(&mut conn)
|
||||||
.map_err(|error| {
|
.await
|
||||||
error!("{}", error);
|
)?;
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Process each guild concurrently
|
// Process each guild concurrently
|
||||||
let guild_futures = guild_builders.iter().map(async move |g| {
|
let guild_futures = guild_builders.iter().map(async move |g| {
|
||||||
let mut conn = pool.get().await.unwrap();
|
let mut conn = pool.get().await?;
|
||||||
g.clone().build(&mut conn).await
|
g.clone().build(&mut conn).await
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -378,7 +316,7 @@ impl Guild {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
owner_uuid: Uuid,
|
owner_uuid: Uuid,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
let guild_uuid = Uuid::now_v7();
|
let guild_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let guild_builder = GuildBuilder {
|
let guild_builder = GuildBuilder {
|
||||||
|
@ -391,11 +329,21 @@ impl Guild {
|
||||||
insert_into(guilds::table)
|
insert_into(guilds::table)
|
||||||
.values(guild_builder)
|
.values(guild_builder)
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
let member_uuid = Uuid::now_v7();
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
let member = Member {
|
||||||
|
uuid: member_uuid,
|
||||||
|
nickname: None,
|
||||||
|
user_uuid: owner_uuid,
|
||||||
|
guild_uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
insert_into(guild_members::table)
|
||||||
|
.values(member)
|
||||||
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(Guild {
|
Ok(Guild {
|
||||||
uuid: guild_uuid,
|
uuid: guild_uuid,
|
||||||
|
@ -408,17 +356,15 @@ impl Guild {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_invites(&self, conn: &mut Conn) -> Result<Vec<Invite>, HttpResponse> {
|
pub async fn get_invites(&self, conn: &mut Conn) -> Result<Vec<Invite>, Error> {
|
||||||
use invites::dsl;
|
use invites::dsl;
|
||||||
let invites = dsl::invites
|
let invites = load_or_empty(
|
||||||
.filter(dsl::guild_uuid.eq(self.uuid))
|
dsl::invites
|
||||||
.select(Invite::as_select())
|
.filter(dsl::guild_uuid.eq(self.uuid))
|
||||||
.load(conn)
|
.select(Invite::as_select())
|
||||||
.await
|
.load(conn)
|
||||||
.map_err(|error| {
|
.await
|
||||||
error!("{}", error);
|
)?;
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(invites)
|
Ok(invites)
|
||||||
}
|
}
|
||||||
|
@ -428,13 +374,13 @@ impl Guild {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
member: &Member,
|
member: &Member,
|
||||||
custom_id: Option<String>,
|
custom_id: Option<String>,
|
||||||
) -> Result<Invite, HttpResponse> {
|
) -> Result<Invite, Error> {
|
||||||
let invite_id;
|
let invite_id;
|
||||||
|
|
||||||
if let Some(id) = custom_id {
|
if let Some(id) = custom_id {
|
||||||
invite_id = id;
|
invite_id = id;
|
||||||
if invite_id.len() > 32 {
|
if invite_id.len() > 32 {
|
||||||
return Err(HttpResponse::BadRequest().finish());
|
return Err(Error::BadRequest("MAX LENGTH".to_string()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
@ -451,11 +397,7 @@ impl Guild {
|
||||||
insert_into(invites::table)
|
insert_into(invites::table)
|
||||||
.values(invite.clone())
|
.values(invite.clone())
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(invite)
|
Ok(invite)
|
||||||
}
|
}
|
||||||
|
@ -477,17 +419,15 @@ impl Role {
|
||||||
pub async fn fetch_all(
|
pub async fn fetch_all(
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
) -> Result<Vec<Self>, HttpResponse> {
|
) -> Result<Vec<Self>, Error> {
|
||||||
use roles::dsl;
|
use roles::dsl;
|
||||||
let roles: Vec<Role> = dsl::roles
|
let roles: Vec<Role> = load_or_empty(
|
||||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
dsl::roles
|
||||||
.select(Role::as_select())
|
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||||
.load(conn)
|
.select(Role::as_select())
|
||||||
.await
|
.load(conn)
|
||||||
.map_err(|error| {
|
.await
|
||||||
error!("{}", error);
|
)?;
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(roles)
|
Ok(roles)
|
||||||
}
|
}
|
||||||
|
@ -495,17 +435,13 @@ impl Role {
|
||||||
pub async fn fetch_one(
|
pub async fn fetch_one(
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
role_uuid: Uuid,
|
role_uuid: Uuid,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
use roles::dsl;
|
use roles::dsl;
|
||||||
let role: Role = dsl::roles
|
let role: Role = dsl::roles
|
||||||
.filter(dsl::uuid.eq(role_uuid))
|
.filter(dsl::uuid.eq(role_uuid))
|
||||||
.select(Role::as_select())
|
.select(Role::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(role)
|
Ok(role)
|
||||||
}
|
}
|
||||||
|
@ -514,7 +450,7 @@ impl Role {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
name: String,
|
name: String,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
let role_uuid = Uuid::now_v7();
|
let role_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let role = Role {
|
let role = Role {
|
||||||
|
@ -529,11 +465,7 @@ impl Role {
|
||||||
insert_into(roles::table)
|
insert_into(roles::table)
|
||||||
.values(role.clone())
|
.values(role.clone())
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(role)
|
Ok(role)
|
||||||
}
|
}
|
||||||
|
@ -550,17 +482,13 @@ pub struct Member {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Member {
|
impl Member {
|
||||||
async fn count(conn: &mut Conn, guild_uuid: Uuid) -> Result<i64, HttpResponse> {
|
async fn count(conn: &mut Conn, guild_uuid: Uuid) -> Result<i64, Error> {
|
||||||
use guild_members::dsl;
|
use guild_members::dsl;
|
||||||
let count: i64 = dsl::guild_members
|
let count: i64 = dsl::guild_members
|
||||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||||
.count()
|
.count()
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
@ -569,18 +497,14 @@ impl Member {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
user_uuid: Uuid,
|
user_uuid: Uuid,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
use guild_members::dsl;
|
use guild_members::dsl;
|
||||||
let member: Member = dsl::guild_members
|
let member: Member = dsl::guild_members
|
||||||
.filter(dsl::user_uuid.eq(user_uuid))
|
.filter(dsl::user_uuid.eq(user_uuid))
|
||||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||||
.select(Member::as_select())
|
.select(Member::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(member)
|
Ok(member)
|
||||||
}
|
}
|
||||||
|
@ -589,7 +513,7 @@ impl Member {
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
user_uuid: Uuid,
|
user_uuid: Uuid,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
) -> Result<Self, HttpResponse> {
|
) -> Result<Self, Error> {
|
||||||
let member_uuid = Uuid::now_v7();
|
let member_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let member = Member {
|
let member = Member {
|
||||||
|
@ -602,11 +526,7 @@ impl Member {
|
||||||
insert_into(guild_members::table)
|
insert_into(guild_members::table)
|
||||||
.values(member)
|
.values(member)
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
uuid: member_uuid,
|
uuid: member_uuid,
|
||||||
|
@ -639,17 +559,13 @@ pub struct Invite {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Invite {
|
impl Invite {
|
||||||
pub async fn fetch_one(conn: &mut Conn, invite_id: String) -> Result<Self, HttpResponse> {
|
pub async fn fetch_one(conn: &mut Conn, invite_id: String) -> Result<Self, Error> {
|
||||||
use invites::dsl;
|
use invites::dsl;
|
||||||
let invite: Invite = dsl::invites
|
let invite: Invite = dsl::invites
|
||||||
.filter(dsl::id.eq(invite_id))
|
.filter(dsl::id.eq(invite_id))
|
||||||
.select(Invite::as_select())
|
.select(Invite::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|error| {
|
|
||||||
error!("{}", error);
|
|
||||||
HttpResponse::InternalServerError().finish()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(invite)
|
Ok(invite)
|
||||||
}
|
}
|
||||||
|
@ -657,6 +573,6 @@ impl Invite {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct StartAmountQuery {
|
pub struct StartAmountQuery {
|
||||||
pub start: Option<i32>,
|
pub start: Option<i64>,
|
||||||
pub amount: Option<i32>,
|
pub amount: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
33
src/utils.rs
33
src/utils.rs
|
@ -1,5 +1,4 @@
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
HttpResponse,
|
|
||||||
cookie::{Cookie, SameSite, time::Duration},
|
cookie::{Cookie, SameSite, time::Duration},
|
||||||
http::header::HeaderMap,
|
http::header::HeaderMap,
|
||||||
};
|
};
|
||||||
|
@ -8,25 +7,31 @@ use hex::encode;
|
||||||
use redis::RedisError;
|
use redis::RedisError;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::Data;
|
use crate::{error::Error, Data};
|
||||||
|
|
||||||
pub fn get_auth_header(headers: &HeaderMap) -> Result<&str, HttpResponse> {
|
pub fn get_auth_header(headers: &HeaderMap) -> Result<&str, Error> {
|
||||||
let auth_token = headers.get(actix_web::http::header::AUTHORIZATION);
|
let auth_token = headers.get(actix_web::http::header::AUTHORIZATION);
|
||||||
|
|
||||||
if auth_token.is_none() {
|
if auth_token.is_none() {
|
||||||
return Err(HttpResponse::Unauthorized().finish());
|
return Err(Error::Unauthorized("No authorization header provided".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let auth = auth_token.unwrap().to_str();
|
let auth_raw = auth_token.unwrap().to_str()?;
|
||||||
|
|
||||||
if let Err(error) = auth {
|
let mut auth = auth_raw.split_whitespace();
|
||||||
return Err(HttpResponse::Unauthorized().json(format!(r#" {{ "error": "{}" }} "#, error)));
|
|
||||||
|
let auth_type = auth.nth(0);
|
||||||
|
|
||||||
|
let auth_value = auth.nth(0);
|
||||||
|
|
||||||
|
if auth_type.is_none() {
|
||||||
|
return Err(Error::BadRequest("Authorization header is empty".to_string()));
|
||||||
|
} else if auth_type.is_some_and(|at| at != "Bearer") {
|
||||||
|
return Err(Error::BadRequest("Only token auth is supported".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let auth_value = auth.unwrap().split_whitespace().nth(1);
|
|
||||||
|
|
||||||
if auth_value.is_none() {
|
if auth_value.is_none() {
|
||||||
return Err(HttpResponse::BadRequest().finish());
|
return Err(Error::BadRequest("No token provided".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(auth_value.unwrap())
|
Ok(auth_value.unwrap())
|
||||||
|
@ -60,12 +65,12 @@ impl Data {
|
||||||
key: String,
|
key: String,
|
||||||
value: impl Serialize,
|
value: impl Serialize,
|
||||||
expire: u32,
|
expire: u32,
|
||||||
) -> Result<(), RedisError> {
|
) -> Result<(), Error> {
|
||||||
let mut conn = self.cache_pool.get_multiplexed_tokio_connection().await?;
|
let mut conn = self.cache_pool.get_multiplexed_tokio_connection().await?;
|
||||||
|
|
||||||
let key_encoded = encode(key);
|
let key_encoded = encode(key);
|
||||||
|
|
||||||
let value_json = serde_json::to_string(&value).unwrap();
|
let value_json = serde_json::to_string(&value)?;
|
||||||
|
|
||||||
redis::cmd("SET")
|
redis::cmd("SET")
|
||||||
.arg(&[key_encoded.clone(), value_json])
|
.arg(&[key_encoded.clone(), value_json])
|
||||||
|
@ -75,7 +80,9 @@ impl Data {
|
||||||
redis::cmd("EXPIRE")
|
redis::cmd("EXPIRE")
|
||||||
.arg(&[key_encoded, expire.to_string()])
|
.arg(&[key_encoded, expire.to_string()])
|
||||||
.exec_async(&mut conn)
|
.exec_async(&mut conn)
|
||||||
.await
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_cache_key(&self, key: String) -> Result<String, RedisError> {
|
pub async fn get_cache_key(&self, key: String) -> Result<String, RedisError> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue