Compare commits
	
		
			3 Commits
		
	
	
		
			1.7.4
			...
			jellywx/gu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b0a04bb289 | |||
| eef1f6f3e8 | |||
| 3d08027325 | 
							
								
								
									
										92
									
								
								migration/05-restructure-guild-table.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								migration/05-restructure-guild-table.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
SET foreign_key_checks = 0;
 | 
			
		||||
 | 
			
		||||
START TRANSACTION;
 | 
			
		||||
 | 
			
		||||
-- drop existing constraints
 | 
			
		||||
ALTER TABLE channels DROP FOREIGN KEY `channels_ibfk_1`;
 | 
			
		||||
ALTER TABLE command_aliases DROP FOREIGN KEY `command_aliases_ibfk_1`;
 | 
			
		||||
ALTER TABLE events DROP FOREIGN KEY `events_ibfk_1`;
 | 
			
		||||
ALTER TABLE guild_users DROP FOREIGN KEY `guild_users_ibfk_1`;
 | 
			
		||||
ALTER TABLE macro DROP FOREIGN KEY `macro_ibfk_1`;
 | 
			
		||||
ALTER TABLE roles DROP FOREIGN KEY `roles_ibfk_1`;
 | 
			
		||||
ALTER TABLE todos DROP FOREIGN KEY `todos_ibfk_2`;
 | 
			
		||||
ALTER TABLE reminder_template DROP FOREIGN KEY `reminder_template_ibfk_1`;
 | 
			
		||||
 | 
			
		||||
-- update foreign key types
 | 
			
		||||
ALTER TABLE channels MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE command_aliases MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE events MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE guild_users MODIFY `guild` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE macro MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE roles MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE todos MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE reminder_template MODIFY `guild_id` BIGINT UNSIGNED;
 | 
			
		||||
 | 
			
		||||
-- update foreign key values
 | 
			
		||||
UPDATE channels SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE command_aliases SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE events SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE guild_users SET `guild` = (SELECT `guild` FROM guilds WHERE guilds.`id` = guild_users.`guild`);
 | 
			
		||||
UPDATE macro SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE roles SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE todos SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
UPDATE reminder_template SET `guild_id` = (SELECT `guild` FROM guilds WHERE guilds.`id` = `guild_id`);
 | 
			
		||||
 | 
			
		||||
-- update guilds table
 | 
			
		||||
ALTER TABLE guilds MODIFY `id` BIGINT UNSIGNED NOT NULL;
 | 
			
		||||
UPDATE guilds SET `id` = `guild`;
 | 
			
		||||
ALTER TABLE guilds DROP COLUMN `guild`;
 | 
			
		||||
ALTER TABLE guilds ADD COLUMN `default_channel` BIGINT UNSIGNED;
 | 
			
		||||
ALTER TABLE guilds ADD CONSTRAINT `default_channel_fk`
 | 
			
		||||
    FOREIGN KEY (`default_channel`)
 | 
			
		||||
        REFERENCES channels(`channel`)
 | 
			
		||||
        ON DELETE SET NULL
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
-- re-add constraints
 | 
			
		||||
ALTER TABLE channels ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE command_aliases ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE events ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE guild_users ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE macro ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE roles ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE todos ADD CONSTRAINT
 | 
			
		||||
    FOREIGN KEY (`guild_id`)
 | 
			
		||||
        REFERENCES guilds(`id`)
 | 
			
		||||
        ON DELETE CASCADE
 | 
			
		||||
        ON UPDATE CASCADE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMMIT;
 | 
			
		||||
 | 
			
		||||
SET foreign_key_checks = 1;
 | 
			
		||||
@@ -24,7 +24,7 @@ pub async fn macro_name_autocomplete(ctx: Context<'_>, partial: &str) -> Vec<Str
 | 
			
		||||
SELECT name
 | 
			
		||||
FROM macro
 | 
			
		||||
WHERE
 | 
			
		||||
    guild_id = (SELECT id FROM guilds WHERE guild = ?)
 | 
			
		||||
    guild_id = ?
 | 
			
		||||
    AND name LIKE CONCAT(?, '%')",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
        partial,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ pub async fn delete_macro(
 | 
			
		||||
) -> Result<(), Error> {
 | 
			
		||||
    match sqlx::query!(
 | 
			
		||||
        "
 | 
			
		||||
SELECT id FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?",
 | 
			
		||||
SELECT id FROM macro WHERE guild_id = ? AND name = ?",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
        name
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ pub async fn migrate_macro(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
    let aliases = sqlx::query_as!(
 | 
			
		||||
        Alias,
 | 
			
		||||
        "SELECT name, command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
 | 
			
		||||
        "SELECT name, command FROM command_aliases WHERE guild_id = ?",
 | 
			
		||||
        guild_id.0
 | 
			
		||||
    )
 | 
			
		||||
    .fetch_all(&mut transaction)
 | 
			
		||||
@@ -36,7 +36,7 @@ pub async fn migrate_macro(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
        match parse_text_command(guild_id, alias.name, &alias.command) {
 | 
			
		||||
            Some(cmd_macro) => {
 | 
			
		||||
                sqlx::query!(
 | 
			
		||||
                    "INSERT INTO macro (guild_id, name, description, commands) VALUES ((SELECT id FROM guilds WHERE guild = ?), ?, ?, ?)",
 | 
			
		||||
                    "INSERT INTO macro (guild_id, name, description, commands) VALUES (?, ?, ?, ?)",
 | 
			
		||||
                    cmd_macro.guild_id.0,
 | 
			
		||||
                    cmd_macro.name,
 | 
			
		||||
                    cmd_macro.description,
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ pub async fn record_macro(
 | 
			
		||||
 | 
			
		||||
    let row = sqlx::query!(
 | 
			
		||||
        "
 | 
			
		||||
SELECT 1 as _e FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?",
 | 
			
		||||
SELECT 1 as _e FROM macro WHERE guild_id = ? AND name = ?",
 | 
			
		||||
        guild_id.0,
 | 
			
		||||
        name
 | 
			
		||||
    )
 | 
			
		||||
@@ -121,7 +121,7 @@ pub async fn finish_macro(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
            let json = serde_json::to_string(&command_macro.commands).unwrap();
 | 
			
		||||
 | 
			
		||||
            sqlx::query!(
 | 
			
		||||
                "INSERT INTO macro (guild_id, name, description, commands) VALUES ((SELECT id FROM guilds WHERE guild = ?), ?, ?, ?)",
 | 
			
		||||
                "INSERT INTO macro (guild_id, name, description, commands) VALUES (?, ?, ?, ?)",
 | 
			
		||||
                command_macro.guild_id.0,
 | 
			
		||||
                command_macro.name,
 | 
			
		||||
                command_macro.description,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ use chrono::offset::Utc;
 | 
			
		||||
use chrono_tz::{Tz, TZ_VARIANTS};
 | 
			
		||||
use levenshtein::levenshtein;
 | 
			
		||||
use log::warn;
 | 
			
		||||
use poise::serenity_prelude::{ChannelId, Mentionable};
 | 
			
		||||
 | 
			
		||||
use super::autocomplete::timezone_autocomplete;
 | 
			
		||||
use crate::{consts::THEME_COLOR, models::CtxData, Context, Error};
 | 
			
		||||
@@ -148,11 +149,51 @@ pub async fn unset_allowed_dm(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set defaults for commands
 | 
			
		||||
#[poise::command(
 | 
			
		||||
    slash_command,
 | 
			
		||||
    identifying_name = "default",
 | 
			
		||||
    default_member_permissions = "MANAGE_GUILD"
 | 
			
		||||
)]
 | 
			
		||||
pub async fn default(_ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set a default channel for reminders to be sent to
 | 
			
		||||
#[poise::command(
 | 
			
		||||
    slash_command,
 | 
			
		||||
    guild_only = true,
 | 
			
		||||
    identifying_name = "default_channel",
 | 
			
		||||
    default_member_permissions = "MANAGE_GUILD"
 | 
			
		||||
)]
 | 
			
		||||
pub async fn default_channel(
 | 
			
		||||
    ctx: Context<'_>,
 | 
			
		||||
    #[description = "Channel to send reminders to by default"] channel: Option<ChannelId>,
 | 
			
		||||
) -> Result<(), Error> {
 | 
			
		||||
    if let Some(mut guild_data) = ctx.guild_data().await {
 | 
			
		||||
        guild_data.default_channel = channel.map(|c| c.0);
 | 
			
		||||
 | 
			
		||||
        guild_data.commit_changes(&ctx.data().database).await?;
 | 
			
		||||
 | 
			
		||||
        if let Some(channel) = channel {
 | 
			
		||||
            ctx.send(|r| {
 | 
			
		||||
                r.ephemeral(true).content(format!("Default channel set to {}", channel.mention()))
 | 
			
		||||
            })
 | 
			
		||||
            .await?;
 | 
			
		||||
        } else {
 | 
			
		||||
            ctx.send(|r| r.ephemeral(true).content("Default channel unset.")).await?;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// View the webhook being used to send reminders to this channel
 | 
			
		||||
#[poise::command(
 | 
			
		||||
    slash_command,
 | 
			
		||||
    identifying_name = "webhook_url",
 | 
			
		||||
    required_permissions = "ADMINISTRATOR"
 | 
			
		||||
    required_permissions = "ADMINISTRATOR",
 | 
			
		||||
    default_member_permissions = "ADMINISTRATOR"
 | 
			
		||||
)]
 | 
			
		||||
pub async fn webhook(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
    match ctx.channel_data().await {
 | 
			
		||||
 
 | 
			
		||||
@@ -653,7 +653,9 @@ async fn create_reminder(
 | 
			
		||||
                let list = channels.map(|arg| parse_mention_list(&arg)).unwrap_or_default();
 | 
			
		||||
 | 
			
		||||
                if list.is_empty() {
 | 
			
		||||
                    if ctx.guild_id().is_some() {
 | 
			
		||||
                    if let Some(channel_id) = ctx.default_channel().await {
 | 
			
		||||
                        vec![ReminderScope::Channel(channel_id.0)]
 | 
			
		||||
                    } else if ctx.guild_id().is_some() {
 | 
			
		||||
                        vec![ReminderScope::Channel(ctx.channel_id().0)]
 | 
			
		||||
                    } else {
 | 
			
		||||
                        vec![ReminderScope::User(ctx.author().id.0)]
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ pub async fn todo_guild_add(
 | 
			
		||||
) -> Result<(), Error> {
 | 
			
		||||
    sqlx::query!(
 | 
			
		||||
        "INSERT INTO todos (guild_id, value)
 | 
			
		||||
VALUES ((SELECT id FROM guilds WHERE guild = ?), ?)",
 | 
			
		||||
VALUES (?, ?)",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
        task
 | 
			
		||||
    )
 | 
			
		||||
@@ -70,9 +70,7 @@ VALUES ((SELECT id FROM guilds WHERE guild = ?), ?)",
 | 
			
		||||
)]
 | 
			
		||||
pub async fn todo_guild_view(ctx: Context<'_>) -> Result<(), Error> {
 | 
			
		||||
    let values = sqlx::query!(
 | 
			
		||||
        "SELECT todos.id, value FROM todos
 | 
			
		||||
INNER JOIN guilds ON todos.guild_id = guilds.id
 | 
			
		||||
WHERE guilds.guild = ?",
 | 
			
		||||
        "SELECT todos.id, value FROM todos WHERE guild_id = ?",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
    )
 | 
			
		||||
    .fetch_all(&ctx.data().database)
 | 
			
		||||
@@ -122,7 +120,7 @@ pub async fn todo_channel_add(
 | 
			
		||||
 | 
			
		||||
    sqlx::query!(
 | 
			
		||||
        "INSERT INTO todos (guild_id, channel_id, value)
 | 
			
		||||
VALUES ((SELECT id FROM guilds WHERE guild = ?), (SELECT id FROM channels WHERE channel = ?), ?)",
 | 
			
		||||
VALUES (?, (SELECT id FROM channels WHERE channel = ?), ?)",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
        ctx.channel_id().0,
 | 
			
		||||
        task
 | 
			
		||||
 
 | 
			
		||||
@@ -222,9 +222,7 @@ WHERE channels.channel = ?",
 | 
			
		||||
                        .collect::<Vec<(usize, String)>>()
 | 
			
		||||
                    } else {
 | 
			
		||||
                        sqlx::query!(
 | 
			
		||||
                            "SELECT todos.id, value FROM todos
 | 
			
		||||
INNER JOIN guilds ON todos.guild_id = guilds.id
 | 
			
		||||
WHERE guilds.guild = ?",
 | 
			
		||||
                            "SELECT todos.id, value FROM todos WHERE guild_id = ?",
 | 
			
		||||
                            pager.guild_id,
 | 
			
		||||
                        )
 | 
			
		||||
                        .fetch_all(&data.database)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ use poise::{
 | 
			
		||||
    serenity_prelude::{model::application::interaction::Interaction, utils::shard_id},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{component_models::ComponentDataModel, Data, Error, THEME_COLOR};
 | 
			
		||||
use crate::{
 | 
			
		||||
    component_models::ComponentDataModel, models::guild_data::GuildData, Data, Error, THEME_COLOR,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub async fn listener(
 | 
			
		||||
    ctx: &serenity::Context,
 | 
			
		||||
@@ -27,7 +29,7 @@ pub async fn listener(
 | 
			
		||||
            if *is_new {
 | 
			
		||||
                let guild_id = guild.id.as_u64().to_owned();
 | 
			
		||||
 | 
			
		||||
                sqlx::query!("INSERT IGNORE INTO guilds (guild) VALUES (?)", guild_id)
 | 
			
		||||
                sqlx::query!("INSERT IGNORE INTO guilds (id) VALUES (?)", guild_id)
 | 
			
		||||
                    .execute(&data.database)
 | 
			
		||||
                    .await?;
 | 
			
		||||
 | 
			
		||||
@@ -61,16 +63,28 @@ To stay up to date on the latest features and fixes, join our [Discord](https://
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        poise::Event::GuildDelete { incomplete, .. } => {
 | 
			
		||||
            let _ = sqlx::query!("DELETE FROM guilds WHERE guild = ?", incomplete.id.0)
 | 
			
		||||
            let _ = sqlx::query!("DELETE FROM guilds WHERE id = ?", incomplete.id.0)
 | 
			
		||||
                .execute(&data.database)
 | 
			
		||||
                .await;
 | 
			
		||||
        }
 | 
			
		||||
        poise::Event::InteractionCreate { interaction } => {
 | 
			
		||||
            if let Interaction::MessageComponent(component) = interaction {
 | 
			
		||||
                let component_model = ComponentDataModel::from_custom_id(&component.data.custom_id);
 | 
			
		||||
            match interaction {
 | 
			
		||||
                Interaction::ApplicationCommand(app_command) => {
 | 
			
		||||
                    if let Some(guild_id) = app_command.guild_id {
 | 
			
		||||
                        // check database guild exists
 | 
			
		||||
                        GuildData::from_guild(guild_id, &data.database).await?;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Interaction::MessageComponent(component) => {
 | 
			
		||||
                    let component_model =
 | 
			
		||||
                        ComponentDataModel::from_custom_id(&component.data.custom_id);
 | 
			
		||||
 | 
			
		||||
                    component_model.act(ctx, data, component).await;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                _ => {}
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        _ => {}
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -120,6 +120,10 @@ async fn _main(tx: Sender<()>) -> Result<(), Box<dyn StdError + Send + Sync>> {
 | 
			
		||||
                ],
 | 
			
		||||
                ..command_macro::macro_base()
 | 
			
		||||
            },
 | 
			
		||||
            poise::Command {
 | 
			
		||||
                subcommands: vec![moderation_cmds::default_channel()],
 | 
			
		||||
                ..moderation_cmds::default()
 | 
			
		||||
            },
 | 
			
		||||
            reminder_cmds::pause(),
 | 
			
		||||
            reminder_cmds::offset(),
 | 
			
		||||
            reminder_cmds::nudge(),
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_u
 | 
			
		||||
 | 
			
		||||
            sqlx::query!(
 | 
			
		||||
                "
 | 
			
		||||
INSERT IGNORE INTO channels (channel, name, guild_id) VALUES (?, ?, (SELECT id FROM guilds WHERE guild = ?))
 | 
			
		||||
INSERT IGNORE INTO channels (channel, name, guild_id) VALUES (?, ?, ?)
 | 
			
		||||
                ",
 | 
			
		||||
                channel_id,
 | 
			
		||||
                channel_name,
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,7 @@ pub async fn guild_command_macro(
 | 
			
		||||
) -> Option<CommandMacro<Data, Error>> {
 | 
			
		||||
    let row = sqlx::query!(
 | 
			
		||||
        "
 | 
			
		||||
SELECT * FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?
 | 
			
		||||
SELECT * FROM macro WHERE guild_id = ? AND name = ?
 | 
			
		||||
        ",
 | 
			
		||||
        ctx.guild_id().unwrap().0,
 | 
			
		||||
        name
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/models/guild_data.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/models/guild_data.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
use sqlx::MySqlPool;
 | 
			
		||||
 | 
			
		||||
use crate::GuildId;
 | 
			
		||||
 | 
			
		||||
pub struct GuildData {
 | 
			
		||||
    pub id: u64,
 | 
			
		||||
    pub default_channel: Option<u64>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl GuildData {
 | 
			
		||||
    pub async fn from_guild(guild: GuildId, pool: &MySqlPool) -> Result<Self, sqlx::Error> {
 | 
			
		||||
        let guild_id = guild.0;
 | 
			
		||||
 | 
			
		||||
        if let Ok(row) = sqlx::query_as_unchecked!(
 | 
			
		||||
            Self,
 | 
			
		||||
            "
 | 
			
		||||
SELECT id, default_channel FROM guilds WHERE id = ?
 | 
			
		||||
            ",
 | 
			
		||||
            guild_id
 | 
			
		||||
        )
 | 
			
		||||
        .fetch_one(pool)
 | 
			
		||||
        .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(row)
 | 
			
		||||
        } else {
 | 
			
		||||
            sqlx::query!(
 | 
			
		||||
                "
 | 
			
		||||
INSERT IGNORE INTO guilds (id) VALUES (?)
 | 
			
		||||
                ",
 | 
			
		||||
                guild_id
 | 
			
		||||
            )
 | 
			
		||||
            .execute(&pool.clone())
 | 
			
		||||
            .await?;
 | 
			
		||||
 | 
			
		||||
            Ok(Self { id: guild_id, default_channel: None })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn commit_changes(&self, pool: &MySqlPool) -> Result<(), sqlx::Error> {
 | 
			
		||||
        sqlx::query!(
 | 
			
		||||
            "
 | 
			
		||||
UPDATE guilds SET default_channel = ? WHERE id = ?
 | 
			
		||||
            ",
 | 
			
		||||
            self.default_channel,
 | 
			
		||||
            self.id
 | 
			
		||||
        )
 | 
			
		||||
        .execute(pool)
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +1,28 @@
 | 
			
		||||
pub mod channel_data;
 | 
			
		||||
pub mod command_macro;
 | 
			
		||||
pub mod guild_data;
 | 
			
		||||
pub mod reminder;
 | 
			
		||||
pub mod timer;
 | 
			
		||||
pub mod user_data;
 | 
			
		||||
 | 
			
		||||
use chrono_tz::Tz;
 | 
			
		||||
use poise::serenity_prelude::{async_trait, model::id::UserId};
 | 
			
		||||
use log::warn;
 | 
			
		||||
use poise::serenity_prelude::{async_trait, model::id::UserId, ChannelId};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    models::{channel_data::ChannelData, user_data::UserData},
 | 
			
		||||
    models::{channel_data::ChannelData, guild_data::GuildData, user_data::UserData},
 | 
			
		||||
    CommandMacro, Context, Data, Error, GuildId,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
pub trait CtxData {
 | 
			
		||||
    async fn user_data<U: Into<UserId> + Send>(&self, user_id: U) -> Result<UserData, Error>;
 | 
			
		||||
 | 
			
		||||
    async fn author_data(&self) -> Result<UserData, Error>;
 | 
			
		||||
 | 
			
		||||
    async fn timezone(&self) -> Tz;
 | 
			
		||||
 | 
			
		||||
    async fn channel_data(&self) -> Result<ChannelData, Error>;
 | 
			
		||||
 | 
			
		||||
    async fn guild_data(&self) -> Option<GuildData>;
 | 
			
		||||
    async fn command_macros(&self) -> Result<Vec<CommandMacro<Data, Error>>, Error>;
 | 
			
		||||
    async fn default_channel(&self) -> Option<ChannelId>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
@@ -51,24 +51,55 @@ impl CtxData for Context<'_> {
 | 
			
		||||
    async fn command_macros(&self) -> Result<Vec<CommandMacro<Data, Error>>, Error> {
 | 
			
		||||
        self.data().command_macros(self.guild_id().unwrap()).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn default_channel(&self) -> Option<ChannelId> {
 | 
			
		||||
        match self.guild_id() {
 | 
			
		||||
            Some(guild_id) => {
 | 
			
		||||
                let guild_data = GuildData::from_guild(guild_id, &self.data().database).await;
 | 
			
		||||
 | 
			
		||||
                match guild_data {
 | 
			
		||||
                    Ok(data) => data.default_channel.map(|c| ChannelId(c)),
 | 
			
		||||
 | 
			
		||||
                    Err(e) => {
 | 
			
		||||
                        warn!("SQL error: {:?}", e);
 | 
			
		||||
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            None => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn guild_data(&self) -> Option<GuildData> {
 | 
			
		||||
        match self.guild_id() {
 | 
			
		||||
            Some(guild_id) => GuildData::from_guild(guild_id, &self.data().database).await.ok(),
 | 
			
		||||
 | 
			
		||||
            None => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Data {
 | 
			
		||||
    pub(crate) async fn command_macros(
 | 
			
		||||
    pub async fn command_macros(
 | 
			
		||||
        &self,
 | 
			
		||||
        guild_id: GuildId,
 | 
			
		||||
    ) -> Result<Vec<CommandMacro<Data, Error>>, Error> {
 | 
			
		||||
        let rows = sqlx::query!(
 | 
			
		||||
            "SELECT name, description, commands FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
 | 
			
		||||
            "SELECT name, description, commands FROM macro WHERE guild_id = ?",
 | 
			
		||||
            guild_id.0
 | 
			
		||||
        )
 | 
			
		||||
        .fetch_all(&self.database)
 | 
			
		||||
        .await?.iter().map(|row| CommandMacro {
 | 
			
		||||
        .await?
 | 
			
		||||
        .iter()
 | 
			
		||||
        .map(|row| CommandMacro {
 | 
			
		||||
            guild_id,
 | 
			
		||||
            name: row.name.clone(),
 | 
			
		||||
            description: row.description.clone(),
 | 
			
		||||
            commands: serde_json::from_str(&row.commands).unwrap(),
 | 
			
		||||
        }).collect();
 | 
			
		||||
        })
 | 
			
		||||
        .collect();
 | 
			
		||||
 | 
			
		||||
        Ok(rows)
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -245,7 +245,7 @@ LEFT JOIN
 | 
			
		||||
ON
 | 
			
		||||
    reminders.set_by = users.id
 | 
			
		||||
WHERE
 | 
			
		||||
    channels.guild_id = (SELECT id FROM guilds WHERE guild = ?)
 | 
			
		||||
    channels.guild_id = ?
 | 
			
		||||
                ",
 | 
			
		||||
                    guild_id.as_u64()
 | 
			
		||||
                )
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user