Join sounds per-server

This commit is contained in:
jude
2022-07-31 14:56:38 +01:00
parent 31b6f7a0ab
commit f5acab7440
9 changed files with 300 additions and 127 deletions

View File

@ -1,45 +1,69 @@
use poise::serenity::{async_trait, model::id::UserId};
use poise::{
serenity::{async_trait, model::id::UserId},
serenity_prelude::GuildId,
};
use crate::Data;
#[async_trait]
pub trait JoinSoundCtx {
async fn join_sound<U: Into<UserId> + Send + Sync>(&self, user_id: U) -> Option<u32>;
async fn update_join_sound<U: Into<UserId> + Send + Sync>(
async fn join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
) -> Option<u32>;
async fn update_join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
join_id: Option<u32>,
);
) -> Result<(), sqlx::Error>;
}
#[async_trait]
impl JoinSoundCtx for Data {
async fn join_sound<U: Into<UserId> + Send + Sync>(&self, user_id: U) -> Option<u32> {
async fn join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
) -> Option<u32> {
let user_id = user_id.into();
let guild_id = guild_id.map(|g| g.into());
let x = if let Some(join_sound_id) = self.join_sound_cache.get(&user_id) {
join_sound_id.value().clone()
let cached_join_id = self
.join_sound_cache
.get(&user_id)
.map(|d| d.get(&guild_id).map(|i| i.value().clone()))
.flatten();
let x = if let Some(join_sound_id) = cached_join_id {
join_sound_id
} else {
let join_sound_id = {
let join_id_res = sqlx::query!(
"
SELECT join_sound_id
FROM users
FROM join_sounds
WHERE user = ?
AND (guild IS NULL OR guild = ?)
ORDER BY guild IS NULL
",
user_id.as_u64()
user_id.as_u64(),
guild_id.map(|g| g.0)
)
.fetch_one(&self.database)
.await;
if let Ok(row) = join_id_res {
row.join_sound_id
Some(row.join_sound_id)
} else {
None
}
};
self.join_sound_cache.insert(user_id, join_sound_id);
self.join_sound_cache.entry(user_id).and_modify(|d| {
d.insert(guild_id, join_sound_id);
});
join_sound_id
};
@ -47,39 +71,54 @@ SELECT join_sound_id
x
}
async fn update_join_sound<U: Into<UserId> + Send + Sync>(
async fn update_join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
join_id: Option<u32>,
) {
) -> Result<(), sqlx::Error> {
let user_id = user_id.into();
let guild_id = guild_id.map(|g| g.into());
self.join_sound_cache.insert(user_id, join_id);
self.join_sound_cache.entry(user_id).and_modify(|d| {
d.insert(guild_id, join_id);
});
let pool = self.database.clone();
let mut transaction = self.database.begin().await?;
let _ = sqlx::query!(
"
INSERT IGNORE INTO users (user)
VALUES (?)
",
user_id.as_u64()
)
.execute(&pool)
.await;
match join_id {
Some(join_id) => {
sqlx::query!(
"DELETE FROM join_sounds WHERE user = ? AND guild <=> ?",
user_id.0,
guild_id.map(|g| g.0)
)
.execute(&mut transaction)
.await?;
let _ = sqlx::query!(
"
UPDATE users
SET
join_sound_id = ?
WHERE
user = ?
",
join_id,
user_id.as_u64()
)
.execute(&pool)
.await;
sqlx::query!(
"INSERT INTO join_sounds (user, join_sound_id, guild) VALUES (?, ?, ?)",
user_id.0,
join_id,
guild_id.map(|g| g.0)
)
.execute(&mut transaction)
.await?;
}
None => {
sqlx::query!(
"DELETE FROM join_sounds WHERE user = ? AND guild <=> ?",
user_id.0,
guild_id.map(|g| g.0)
)
.execute(&mut transaction)
.await?;
}
}
transaction.commit().await?;
Ok(())
}
}