From eef1f6f3e811064fd40a37d5c3fbd4fd4947ce24 Mon Sep 17 00:00:00 2001 From: jude Date: Mon, 12 Sep 2022 20:42:48 +0100 Subject: [PATCH] Correct migration. Add guilds on interaction. Correct queries --- migration/05-restructure-guild-table.sql | 138 ++++++++++++----------- src/commands/autocomplete.rs | 2 +- src/commands/command_macro/delete.rs | 2 +- src/commands/command_macro/migrate.rs | 4 +- src/commands/command_macro/record.rs | 10 +- src/commands/todo_cmds.rs | 8 +- src/component_models/mod.rs | 4 +- src/event_handlers.rs | 26 ++++- src/models/channel_data.rs | 2 +- src/models/command_macro.rs | 2 +- src/models/guild_data.rs | 8 +- src/models/mod.rs | 9 +- src/models/reminder/mod.rs | 2 +- 13 files changed, 119 insertions(+), 98 deletions(-) diff --git a/migration/05-restructure-guild-table.sql b/migration/05-restructure-guild-table.sql index cbea4c6..7d4a8f1 100644 --- a/migration/05-restructure-guild-table.sql +++ b/migration/05-restructure-guild-table.sql @@ -1,86 +1,92 @@ -SET FOREIGN_KEY_CHECKS = 0; +SET foreign_key_checks = 0; +START TRANSACTION; + +-- drop existing constraints ALTER TABLE channels DROP FOREIGN KEY `channels_ibfk_1`; -ALTER TABLE channels ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE command_aliases DROP FOREIGN KEY `command_aliases_ibfk_1`; -ALTER TABLE command_aliases ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - -ALTER TABLE command_restrictions DROP FOREIGN KEY `command_restrictions_ibfk_1`; -ALTER TABLE command_restrictions ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE events DROP FOREIGN KEY `events_ibfk_1`; -ALTER TABLE events ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE guild_users DROP FOREIGN KEY `guild_users_ibfk_1`; -ALTER TABLE guild_users ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE macro DROP FOREIGN KEY `macro_ibfk_1`; -ALTER TABLE macro ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE roles DROP FOREIGN KEY `roles_ibfk_1`; -ALTER TABLE roles ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; - ALTER TABLE todos DROP FOREIGN KEY `todos_ibfk_2`; -ALTER TABLE todos ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; +ALTER TABLE reminder_template DROP FOREIGN KEY `reminder_template_ibfk_1`; -ALTER TABLE reminder_template DROP FOREIGN KEY `` -ALTER TABLE roles ADD CONSTRAINT `guild_id_fk` - FOREIGN KEY (`guild_id`) - REFERENCES guilds(`id`) - ON DELETE CASCADE - ON UPDATE CASCADE; +-- 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(`id`) + REFERENCES channels(`channel`) ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE channels MODIFY `guild_id` BIGINT UNSIGNED; -ALTER TABLE command_aliases MODIFY `guild_id` BIGINT UNSIGNED; -ALTER TABLE command_restrictions MODIFY `guild_id` BIGINT UNSIGNED; -ALTER TABLE events MODIFY `guild_id` BIGINT UNSIGNED; -ALTER TABLE guild_users MODIFY `guild_id` 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; +-- re-add constraints +ALTER TABLE channels ADD CONSTRAINT + FOREIGN KEY (`guild_id`) + REFERENCES guilds(`id`) + ON DELETE CASCADE + ON UPDATE CASCADE; -SET FOREIGN_KEY_CHECKS = 1; +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; diff --git a/src/commands/autocomplete.rs b/src/commands/autocomplete.rs index 53725b4..d5981e7 100644 --- a/src/commands/autocomplete.rs +++ b/src/commands/autocomplete.rs @@ -24,7 +24,7 @@ pub async fn macro_name_autocomplete(ctx: Context<'_>, partial: &str) -> Vec 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 ) diff --git a/src/commands/command_macro/migrate.rs b/src/commands/command_macro/migrate.rs index 6a5bc24..e3ad92b 100644 --- a/src/commands/command_macro/migrate.rs +++ b/src/commands/command_macro/migrate.rs @@ -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, diff --git a/src/commands/command_macro/record.rs b/src/commands/command_macro/record.rs index 4ff5f3f..98241c9 100644 --- a/src/commands/command_macro/record.rs +++ b/src/commands/command_macro/record.rs @@ -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,15 +121,15 @@ 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, json ) - .execute(&ctx.data().database) - .await - .unwrap(); + .execute(&ctx.data().database) + .await + .unwrap(); ctx.send(|m| { m.embed(|e| { diff --git a/src/commands/todo_cmds.rs b/src/commands/todo_cmds.rs index 90be423..d4e9667 100644 --- a/src/commands/todo_cmds.rs +++ b/src/commands/todo_cmds.rs @@ -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 diff --git a/src/component_models/mod.rs b/src/component_models/mod.rs index ac9589a..e14375a 100644 --- a/src/component_models/mod.rs +++ b/src/component_models/mod.rs @@ -222,9 +222,7 @@ WHERE channels.channel = ?", .collect::>() } 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) diff --git a/src/event_handlers.rs b/src/event_handlers.rs index 698a34e..44d3735 100644 --- a/src/event_handlers.rs +++ b/src/event_handlers.rs @@ -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,15 +63,27 @@ 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?; + } + } - component_model.act(ctx, data, component).await; + Interaction::MessageComponent(component) => { + let component_model = + ComponentDataModel::from_custom_id(&component.data.custom_id); + + component_model.act(ctx, data, component).await; + } + + _ => {} } } _ => {} diff --git a/src/models/channel_data.rs b/src/models/channel_data.rs index c3d2f0c..3ce040e 100644 --- a/src/models/channel_data.rs +++ b/src/models/channel_data.rs @@ -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, diff --git a/src/models/command_macro.rs b/src/models/command_macro.rs index f7b89ad..bb60a9d 100644 --- a/src/models/command_macro.rs +++ b/src/models/command_macro.rs @@ -43,7 +43,7 @@ pub async fn guild_command_macro( ) -> Option> { 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 diff --git a/src/models/guild_data.rs b/src/models/guild_data.rs index b0058a6..de595d7 100644 --- a/src/models/guild_data.rs +++ b/src/models/guild_data.rs @@ -1,14 +1,16 @@ -use poise::serenity_prelude::{model::channel::Channel, Guild}; +use poise::serenity_prelude::Guild; use sqlx::MySqlPool; +use crate::GuildId; + pub struct GuildData { pub id: u64, pub default_channel: Option, } impl GuildData { - pub async fn from_guild(guild: &Guild, pool: &MySqlPool) -> Result { - let guild_id = guild.id.0; + pub async fn from_guild(guild: GuildId, pool: &MySqlPool) -> Result { + let guild_id = guild.0; if let Ok(row) = sqlx::query_as_unchecked!( Self, diff --git a/src/models/mod.rs b/src/models/mod.rs index ff530ea..e6e8dd5 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -60,16 +60,19 @@ impl Data { guild_id: GuildId, ) -> Result>, 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) } diff --git a/src/models/reminder/mod.rs b/src/models/reminder/mod.rs index d334cd1..a5af677 100644 --- a/src/models/reminder/mod.rs +++ b/src/models/reminder/mod.rs @@ -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() )