Correct migration. Add guilds on interaction. Correct queries

This commit is contained in:
jude 2022-09-12 20:42:48 +01:00
parent 3d08027325
commit eef1f6f3e8
13 changed files with 119 additions and 98 deletions

View File

@ -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 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 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 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 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 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 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 DROP FOREIGN KEY `todos_ibfk_2`;
ALTER TABLE todos ADD CONSTRAINT `guild_id_fk` ALTER TABLE reminder_template DROP FOREIGN KEY `reminder_template_ibfk_1`;
FOREIGN KEY (`guild_id`)
REFERENCES guilds(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
ALTER TABLE reminder_template DROP FOREIGN KEY `` -- update foreign key types
ALTER TABLE roles ADD CONSTRAINT `guild_id_fk` ALTER TABLE channels MODIFY `guild_id` BIGINT UNSIGNED;
FOREIGN KEY (`guild_id`) ALTER TABLE command_aliases MODIFY `guild_id` BIGINT UNSIGNED;
REFERENCES guilds(`id`) ALTER TABLE events MODIFY `guild_id` BIGINT UNSIGNED;
ON DELETE CASCADE ALTER TABLE guild_users MODIFY `guild` BIGINT UNSIGNED;
ON UPDATE CASCADE; 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; ALTER TABLE guilds MODIFY `id` BIGINT UNSIGNED NOT NULL;
UPDATE guilds SET `id` = `guild`; UPDATE guilds SET `id` = `guild`;
ALTER TABLE guilds DROP COLUMN `guild`; ALTER TABLE guilds DROP COLUMN `guild`;
ALTER TABLE guilds ADD COLUMN `default_channel` BIGINT UNSIGNED; ALTER TABLE guilds ADD COLUMN `default_channel` BIGINT UNSIGNED;
ALTER TABLE guilds ADD CONSTRAINT `default_channel_fk` ALTER TABLE guilds ADD CONSTRAINT `default_channel_fk`
FOREIGN KEY (`default_channel`) FOREIGN KEY (`default_channel`)
REFERENCES channels(`id`) REFERENCES channels(`channel`)
ON DELETE SET NULL ON DELETE SET NULL
ON UPDATE CASCADE; ON UPDATE CASCADE;
ALTER TABLE channels MODIFY `guild_id` BIGINT UNSIGNED; -- re-add constraints
ALTER TABLE command_aliases MODIFY `guild_id` BIGINT UNSIGNED; ALTER TABLE channels ADD CONSTRAINT
ALTER TABLE command_restrictions MODIFY `guild_id` BIGINT UNSIGNED; FOREIGN KEY (`guild_id`)
ALTER TABLE events MODIFY `guild_id` BIGINT UNSIGNED; REFERENCES guilds(`id`)
ALTER TABLE guild_users MODIFY `guild_id` BIGINT UNSIGNED; ON DELETE CASCADE
ALTER TABLE macro MODIFY `guild_id` BIGINT UNSIGNED; ON UPDATE CASCADE;
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;
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;

View File

@ -24,7 +24,7 @@ pub async fn macro_name_autocomplete(ctx: Context<'_>, partial: &str) -> Vec<Str
SELECT name SELECT name
FROM macro FROM macro
WHERE WHERE
guild_id = (SELECT id FROM guilds WHERE guild = ?) guild_id = ?
AND name LIKE CONCAT(?, '%')", AND name LIKE CONCAT(?, '%')",
ctx.guild_id().unwrap().0, ctx.guild_id().unwrap().0,
partial, partial,

View File

@ -17,7 +17,7 @@ pub async fn delete_macro(
) -> Result<(), Error> { ) -> Result<(), Error> {
match sqlx::query!( 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, ctx.guild_id().unwrap().0,
name name
) )

View File

@ -24,7 +24,7 @@ pub async fn migrate_macro(ctx: Context<'_>) -> Result<(), Error> {
let aliases = sqlx::query_as!( let aliases = sqlx::query_as!(
Alias, 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 guild_id.0
) )
.fetch_all(&mut transaction) .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) { match parse_text_command(guild_id, alias.name, &alias.command) {
Some(cmd_macro) => { Some(cmd_macro) => {
sqlx::query!( 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.guild_id.0,
cmd_macro.name, cmd_macro.name,
cmd_macro.description, cmd_macro.description,

View File

@ -31,7 +31,7 @@ pub async fn record_macro(
let row = sqlx::query!( 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, guild_id.0,
name name
) )
@ -121,7 +121,7 @@ pub async fn finish_macro(ctx: Context<'_>) -> Result<(), Error> {
let json = serde_json::to_string(&command_macro.commands).unwrap(); let json = serde_json::to_string(&command_macro.commands).unwrap();
sqlx::query!( 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.guild_id.0,
command_macro.name, command_macro.name,
command_macro.description, command_macro.description,

View File

@ -47,7 +47,7 @@ pub async fn todo_guild_add(
) -> Result<(), Error> { ) -> Result<(), Error> {
sqlx::query!( sqlx::query!(
"INSERT INTO todos (guild_id, value) "INSERT INTO todos (guild_id, value)
VALUES ((SELECT id FROM guilds WHERE guild = ?), ?)", VALUES (?, ?)",
ctx.guild_id().unwrap().0, ctx.guild_id().unwrap().0,
task task
) )
@ -70,9 +70,7 @@ VALUES ((SELECT id FROM guilds WHERE guild = ?), ?)",
)] )]
pub async fn todo_guild_view(ctx: Context<'_>) -> Result<(), Error> { pub async fn todo_guild_view(ctx: Context<'_>) -> Result<(), Error> {
let values = sqlx::query!( let values = sqlx::query!(
"SELECT todos.id, value FROM todos "SELECT todos.id, value FROM todos WHERE guild_id = ?",
INNER JOIN guilds ON todos.guild_id = guilds.id
WHERE guilds.guild = ?",
ctx.guild_id().unwrap().0, ctx.guild_id().unwrap().0,
) )
.fetch_all(&ctx.data().database) .fetch_all(&ctx.data().database)
@ -122,7 +120,7 @@ pub async fn todo_channel_add(
sqlx::query!( sqlx::query!(
"INSERT INTO todos (guild_id, channel_id, value) "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.guild_id().unwrap().0,
ctx.channel_id().0, ctx.channel_id().0,
task task

View File

@ -222,9 +222,7 @@ WHERE channels.channel = ?",
.collect::<Vec<(usize, String)>>() .collect::<Vec<(usize, String)>>()
} else { } else {
sqlx::query!( sqlx::query!(
"SELECT todos.id, value FROM todos "SELECT todos.id, value FROM todos WHERE guild_id = ?",
INNER JOIN guilds ON todos.guild_id = guilds.id
WHERE guilds.guild = ?",
pager.guild_id, pager.guild_id,
) )
.fetch_all(&data.database) .fetch_all(&data.database)

View File

@ -6,7 +6,9 @@ use poise::{
serenity_prelude::{model::application::interaction::Interaction, utils::shard_id}, 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( pub async fn listener(
ctx: &serenity::Context, ctx: &serenity::Context,
@ -27,7 +29,7 @@ pub async fn listener(
if *is_new { if *is_new {
let guild_id = guild.id.as_u64().to_owned(); 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) .execute(&data.database)
.await?; .await?;
@ -61,16 +63,28 @@ To stay up to date on the latest features and fixes, join our [Discord](https://
} }
} }
poise::Event::GuildDelete { incomplete, .. } => { 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) .execute(&data.database)
.await; .await;
} }
poise::Event::InteractionCreate { interaction } => { poise::Event::InteractionCreate { interaction } => {
if let Interaction::MessageComponent(component) = interaction { match interaction {
let component_model = ComponentDataModel::from_custom_id(&component.data.custom_id); 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; component_model.act(ctx, data, component).await;
} }
_ => {}
}
} }
_ => {} _ => {}
} }

View File

@ -38,7 +38,7 @@ SELECT id, name, nudge, blacklisted, webhook_id, webhook_token, paused, paused_u
sqlx::query!( 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_id,
channel_name, channel_name,

View File

@ -43,7 +43,7 @@ pub async fn guild_command_macro(
) -> Option<CommandMacro<Data, Error>> { ) -> Option<CommandMacro<Data, Error>> {
let row = sqlx::query!( 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, ctx.guild_id().unwrap().0,
name name

View File

@ -1,14 +1,16 @@
use poise::serenity_prelude::{model::channel::Channel, Guild}; use poise::serenity_prelude::Guild;
use sqlx::MySqlPool; use sqlx::MySqlPool;
use crate::GuildId;
pub struct GuildData { pub struct GuildData {
pub id: u64, pub id: u64,
pub default_channel: Option<u64>, pub default_channel: Option<u64>,
} }
impl GuildData { impl GuildData {
pub async fn from_guild(guild: &Guild, pool: &MySqlPool) -> Result<Self, sqlx::Error> { pub async fn from_guild(guild: GuildId, pool: &MySqlPool) -> Result<Self, sqlx::Error> {
let guild_id = guild.id.0; let guild_id = guild.0;
if let Ok(row) = sqlx::query_as_unchecked!( if let Ok(row) = sqlx::query_as_unchecked!(
Self, Self,

View File

@ -60,16 +60,19 @@ impl Data {
guild_id: GuildId, guild_id: GuildId,
) -> Result<Vec<CommandMacro<Data, Error>>, Error> { ) -> Result<Vec<CommandMacro<Data, Error>>, Error> {
let rows = sqlx::query!( 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 guild_id.0
) )
.fetch_all(&self.database) .fetch_all(&self.database)
.await?.iter().map(|row| CommandMacro { .await?
.iter()
.map(|row| CommandMacro {
guild_id, guild_id,
name: row.name.clone(), name: row.name.clone(),
description: row.description.clone(), description: row.description.clone(),
commands: serde_json::from_str(&row.commands).unwrap(), commands: serde_json::from_str(&row.commands).unwrap(),
}).collect(); })
.collect();
Ok(rows) Ok(rows)
} }

View File

@ -245,7 +245,7 @@ LEFT JOIN
ON ON
reminders.set_by = users.id reminders.set_by = users.id
WHERE WHERE
channels.guild_id = (SELECT id FROM guilds WHERE guild = ?) channels.guild_id = ?
", ",
guild_id.as_u64() guild_id.as_u64()
) )