From 41407ecefb68e56338c1c593d02a75eb72b73f8a Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Mon, 28 Oct 2024 00:59:04 +0000 Subject: [PATCH] feat: split out all the databse interactions into their own file --- src/bin/update_data.rs | 11 +- src/bin/update_minecraft.rs | 3 +- src/bin/update_users.rs | 11 +- src/commands/add_server.rs | 15 +- src/commands/link_email.rs | 7 +- src/commands/minecraft.rs | 14 +- src/commands/role_adder.rs | 5 +- src/common/database.rs | 288 ++++++++++++++++++++++++++++++++++++ src/common/mod.rs | 3 +- src/common/wolves.rs | 3 +- src/lib.rs | 285 +---------------------------------- src/main.rs | 21 +-- 12 files changed, 348 insertions(+), 318 deletions(-) diff --git a/src/bin/update_data.rs b/src/bin/update_data.rs index b5d89a5..e4b662d 100644 --- a/src/bin/update_data.rs +++ b/src/bin/update_data.rs @@ -1,12 +1,13 @@ use serenity::{ - async_trait, - client::{Context, EventHandler}, - model::gateway::{GatewayIntents, Ready}, - Client, + async_trait, + client::{Context, EventHandler}, + model::gateway::{GatewayIntents, Ready}, + Client, }; -use skynet_discord_bot::{db_init, get_config, Config, DataBase}; +use skynet_discord_bot::{get_config, Config}; use std::{process, sync::Arc}; use tokio::sync::RwLock; +use skynet_discord_bot::common::database::{db_init, DataBase}; use skynet_discord_bot::common::wolves::get_data::get_wolves_cns; #[tokio::main] diff --git a/src/bin/update_minecraft.rs b/src/bin/update_minecraft.rs index 72aad1c..f959d99 100644 --- a/src/bin/update_minecraft.rs +++ b/src/bin/update_minecraft.rs @@ -1,5 +1,6 @@ -use skynet_discord_bot::{db_init, get_config, get_minecraft_config, update_server, whitelist_wipe}; +use skynet_discord_bot::{get_config, get_minecraft_config, update_server, whitelist_wipe}; use std::collections::HashSet; +use skynet_discord_bot::common::database::db_init; #[tokio::main] async fn main() { diff --git a/src/bin/update_users.rs b/src/bin/update_users.rs index d46c0e5..cf48650 100644 --- a/src/bin/update_users.rs +++ b/src/bin/update_users.rs @@ -1,12 +1,13 @@ use serenity::{ - async_trait, - client::{Context, EventHandler}, - model::gateway::{GatewayIntents, Ready}, - Client, + async_trait, + client::{Context, EventHandler}, + model::gateway::{GatewayIntents, Ready}, + Client, }; -use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, set_roles, Config, DataBase}; +use skynet_discord_bot::{get_config, set_roles, Config}; use std::{process, sync::Arc}; use tokio::sync::RwLock; +use skynet_discord_bot::common::database::{db_init, get_server_config_bulk, DataBase}; #[tokio::main] async fn main() { diff --git a/src/commands/add_server.rs b/src/commands/add_server.rs index 8c7e9e5..dace04e 100644 --- a/src/commands/add_server.rs +++ b/src/commands/add_server.rs @@ -1,14 +1,15 @@ use serenity::{ - builder::CreateApplicationCommand, - client::Context, - model::{ - application::interaction::application_command::ApplicationCommandInteraction, - prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue}, - }, + builder::CreateApplicationCommand, + client::Context, + model::{ + application::interaction::application_command::ApplicationCommandInteraction, + prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue}, + }, }; use skynet_discord_bot::common::wolves::get_data::get_wolves_cns; -use skynet_discord_bot::{get_server_config, is_admin, set_roles::update_server, DataBase, Servers}; +use skynet_discord_bot::{is_admin, set_roles::update_server}; use sqlx::{Error, Pool, Sqlite}; +use skynet_discord_bot::common::database::{get_server_config, DataBase, Servers}; pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String { // check if user has high enough permisssions diff --git a/src/commands/link_email.rs b/src/commands/link_email.rs index 4961dbb..224c6da 100644 --- a/src/commands/link_email.rs +++ b/src/commands/link_email.rs @@ -13,8 +13,10 @@ use serenity::{ prelude::{command::CommandOptionType, interaction::application_command::CommandDataOptionValue}, }, }; -use skynet_discord_bot::{get_now_iso, random_string, Config, DataBase, Wolves, WolvesVerify}; +use skynet_discord_bot::{get_now_iso, random_string, Config}; use sqlx::{Pool, Sqlite}; +use skynet_discord_bot::common::database::{DataBase, Wolves, WolvesVerify}; + pub mod link { use super::*; @@ -238,8 +240,9 @@ pub mod verify { use super::*; use crate::commands::link_email::link::{db_pending_clear_expired, get_verify_from_db}; use serenity::model::user::User; - use skynet_discord_bot::{get_server_config, ServerMembersWolves, Servers}; + use skynet_discord_bot::common::database::get_server_config; use sqlx::Error; + use skynet_discord_bot::common::database::{ServerMembersWolves, Servers}; pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String { let db_lock = { diff --git a/src/commands/minecraft.rs b/src/commands/minecraft.rs index b6b6dd5..fb87326 100644 --- a/src/commands/minecraft.rs +++ b/src/commands/minecraft.rs @@ -7,7 +7,7 @@ use serenity::{ }, }; -use skynet_discord_bot::DataBase; +use skynet_discord_bot::common::database::DataBase; use sqlx::{Pool, Sqlite}; pub(crate) mod user { @@ -16,8 +16,9 @@ pub(crate) mod user { use super::*; use crate::commands::link_email::link::get_server_member_discord; use serenity::model::id::UserId; - use skynet_discord_bot::{whitelist_update, Config, Minecraft, Wolves}; + use skynet_discord_bot::{whitelist_update, Config}; use sqlx::Error; + use skynet_discord_bot::common::database::{Minecraft, Wolves}; pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { command.name("link_minecraft").description("Link your minecraft account").create_option(|option| { @@ -122,7 +123,8 @@ pub(crate) mod server { use sqlx::Error; // this is to managfe the server side of commands related to minecraft use super::*; - use skynet_discord_bot::{is_admin, update_server, Config, Minecraft}; + use skynet_discord_bot::{is_admin, update_server, Config}; + use skynet_discord_bot::common::database::Minecraft; pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { command.name("minecraft_add").description("Add a minecraft server").create_option(|option| { @@ -201,7 +203,8 @@ pub(crate) mod server { use serenity::builder::CreateApplicationCommand; use serenity::client::Context; use serenity::model::prelude::application_command::ApplicationCommandInteraction; - use skynet_discord_bot::{get_minecraft_config_server, is_admin, server_information, Config, DataBase}; + use skynet_discord_bot::{get_minecraft_config_server, is_admin, server_information, Config}; + use skynet_discord_bot::common::database::DataBase; pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { command.name("minecraft_list").description("List your minecraft servers") @@ -262,8 +265,9 @@ pub(crate) mod server { use serenity::model::application::command::CommandOptionType; use serenity::model::id::GuildId; use serenity::model::prelude::application_command::{ApplicationCommandInteraction, CommandDataOptionValue}; - use skynet_discord_bot::{is_admin, DataBase, Minecraft}; + use skynet_discord_bot::is_admin; use sqlx::{Error, Pool, Sqlite}; + use skynet_discord_bot::common::database::{DataBase, Minecraft}; pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { command.name("minecraft_delete").description("Delete a minecraft server").create_option(|option| { diff --git a/src/commands/role_adder.rs b/src/commands/role_adder.rs index 949bf32..89f9441 100644 --- a/src/commands/role_adder.rs +++ b/src/commands/role_adder.rs @@ -7,8 +7,9 @@ use serenity::{ }, }; -use skynet_discord_bot::{is_admin, DataBase, RoleAdder}; +use skynet_discord_bot::is_admin; use sqlx::{Error, Pool, Sqlite}; +use skynet_discord_bot::common::database::{DataBase, RoleAdder}; pub mod edit { use super::*; @@ -188,7 +189,7 @@ pub mod list {} pub mod tools { use serenity::client::Context; use serenity::model::guild::Member; - use skynet_discord_bot::RoleAdder; + use skynet_discord_bot::common::database::RoleAdder; use sqlx::{Pool, Sqlite}; pub async fn on_role_change(db: &Pool, ctx: &Context, mut new_data: Member) { diff --git a/src/common/database.rs b/src/common/database.rs index e69de29..6eb1734 100644 --- a/src/common/database.rs +++ b/src/common/database.rs @@ -0,0 +1,288 @@ +use serenity::prelude::TypeMapKey; +use std::sync::Arc; +use tokio::sync::RwLock; +use sqlx::{Error, FromRow, Pool, Row, Sqlite}; +use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions, SqliteRow}; +use serenity::model::id::{ChannelId, GuildId, RoleId, UserId}; +use serde::{Deserialize, Serialize}; +use serenity::model::guild; +use std::str::FromStr; +use crate::Config; + +pub struct DataBase; +impl TypeMapKey for DataBase { + type Value = Arc>>; +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ServerMembers { + pub server: GuildId, + pub id_wolves: i64, + pub expiry: String, +} + +impl<'r> FromRow<'r, SqliteRow> for ServerMembers { + fn from_row(row: &'r SqliteRow) -> Result { + let server_tmp: i64 = row.try_get("server")?; + let server = GuildId::from(server_tmp as u64); + + Ok(Self { + server, + id_wolves: row.try_get("id_wolves")?, + expiry: row.try_get("expiry")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ServerMembersWolves { + pub server: GuildId, + pub id_wolves: i64, + pub expiry: String, + pub email: String, + pub discord: Option, + pub minecraft: Option, +} + +impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves { + fn from_row(row: &'r SqliteRow) -> Result { + let server_tmp: i64 = row.try_get("server")?; + let server = GuildId::from(server_tmp as u64); + let discord = match row.try_get("discord") { + Ok(x) => { + let tmp: i64 = x; + if tmp == 0 { + None + } else { + Some(UserId::from(tmp as u64)) + } + } + _ => None, + }; + + Ok(Self { + server, + id_wolves: row.try_get("id_wolves")?, + expiry: row.try_get("expiry")?, + email: row.try_get("email")?, + discord, + minecraft: row.try_get("minecraft")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Wolves { + pub id_wolves: i64, + pub email: String, + pub discord: Option, + pub minecraft: Option, +} + +impl<'r> FromRow<'r, SqliteRow> for Wolves { + fn from_row(row: &'r SqliteRow) -> Result { + let discord = match row.try_get("discord") { + Ok(x) => { + let tmp: i64 = x; + if tmp == 0 { + None + } else { + Some(UserId::from(tmp as u64)) + } + } + _ => None, + }; + + Ok(Self { + id_wolves: row.try_get("id_wolves")?, + email: row.try_get("email")?, + discord, + minecraft: row.try_get("minecraft")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct WolvesVerify { + pub email: String, + pub discord: UserId, + pub auth_code: String, + pub date_expiry: String, +} + +impl<'r> FromRow<'r, SqliteRow> for WolvesVerify { + fn from_row(row: &'r SqliteRow) -> Result { + let user_tmp: i64 = row.try_get("discord")?; + let discord = UserId::from(user_tmp as u64); + + Ok(Self { + email: row.try_get("email")?, + discord, + auth_code: row.try_get("auth_code")?, + date_expiry: row.try_get("date_expiry")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Servers { + pub server: GuildId, + pub wolves_api: String, + pub role_past: Option, + pub role_current: RoleId, + pub member_past: i64, + pub member_current: i64, + pub bot_channel_id: ChannelId, + // TODO: these can be removed in teh future with an API update + pub server_name: String, + pub wolves_link: String, +} + +impl<'r> FromRow<'r, SqliteRow> for Servers { + fn from_row(row: &'r SqliteRow) -> Result { + let server_tmp: i64 = row.try_get("server")?; + let server = GuildId::from(server_tmp as u64); + let role_past = match row.try_get("role_past") { + Ok(x) => { + let tmp: i64 = x; + if tmp == 0 { + None + } else { + Some(RoleId::from(tmp as u64)) + } + } + _ => None, + }; + let role_current = match row.try_get("role_current") { + Ok(x) => { + let tmp: i64 = x; + RoleId::from(tmp as u64) + } + _ => RoleId::from(0u64), + }; + + let bot_channel_tmp: i64 = row.try_get("bot_channel_id")?; + let bot_channel_id = ChannelId::from(bot_channel_tmp as u64); + + Ok(Self { + server, + wolves_api: row.try_get("wolves_api")?, + role_past, + role_current, + member_past: row.try_get("member_past")?, + member_current: row.try_get("member_current")?, + bot_channel_id, + server_name: row.try_get("server_name")?, + wolves_link: row.try_get("wolves_link")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Minecraft { + pub discord: GuildId, + pub minecraft: String, +} + +impl<'r> FromRow<'r, SqliteRow> for Minecraft { + fn from_row(row: &'r SqliteRow) -> Result { + let server_tmp: i64 = row.try_get("server_discord")?; + let discord = GuildId::from(server_tmp as u64); + + Ok(Self { + discord, + minecraft: row.try_get("server_minecraft")?, + }) + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct RoleAdder { + pub server: GuildId, + pub role_a: RoleId, + pub role_b: RoleId, + pub role_c: RoleId, +} + +impl<'r> FromRow<'r, SqliteRow> for RoleAdder { + fn from_row(row: &'r SqliteRow) -> Result { + let server_tmp: i64 = row.try_get("server")?; + let server = GuildId::from(server_tmp as u64); + + Ok(Self { + server, + role_a: get_role_from_row(row, "role_a"), + role_b: get_role_from_row(row, "role_b"), + role_c: get_role_from_row(row, "role_c"), + }) + } +} + +fn get_role_from_row(row: &SqliteRow, col: &str) -> RoleId { + match row.try_get(col) { + Ok(x) => { + let tmp: i64 = x; + RoleId(tmp as u64) + } + _ => RoleId::from(0u64), + } +} + +pub async fn db_init(config: &Config) -> Result, Error> { + let database = format!("{}/{}", &config.home, &config.database); + + let pool = SqlitePoolOptions::new() + .max_connections(5) + .connect_with( + SqliteConnectOptions::from_str(&format!("sqlite://{}", database))? + .foreign_keys(true) + .create_if_missing(true), + ) + .await?; + + // migrations are amazing! + sqlx::migrate!("./db/migrations").run(&pool).await?; + + Ok(pool) +} + +pub async fn get_server_config(db: &Pool, server: &GuildId) -> Option { + sqlx::query_as::<_, Servers>( + r#" + SELECT * + FROM servers + WHERE server = ? + "#, + ) + .bind(*server.as_u64() as i64) + .fetch_one(db) + .await + .ok() +} + +pub async fn get_server_member(db: &Pool, server: &GuildId, member: &guild::Member) -> Result { + sqlx::query_as::<_, ServerMembersWolves>( + r#" + SELECT * + FROM server_members + JOIN wolves USING (id_wolves) + WHERE server = ? AND discord = ? + "#, + ) + .bind(*server.as_u64() as i64) + .bind(*member.user.id.as_u64() as i64) + .fetch_one(db) + .await +} + +pub async fn get_server_config_bulk(db: &Pool) -> Vec { + sqlx::query_as::<_, Servers>( + r#" + SELECT * + FROM servers + "#, + ) + .fetch_all(db) + .await + .unwrap_or_default() +} \ No newline at end of file diff --git a/src/common/mod.rs b/src/common/mod.rs index 5d73638..a992f8b 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1 +1,2 @@ -pub mod wolves; \ No newline at end of file +pub mod wolves; +pub mod database; \ No newline at end of file diff --git a/src/common/wolves.rs b/src/common/wolves.rs index d92c34d..99e7818 100644 --- a/src/common/wolves.rs +++ b/src/common/wolves.rs @@ -18,7 +18,8 @@ pub mod get_data { use serenity::client::Context; use serenity::model::id::GuildId; use sqlx::{Pool, Sqlite}; - use crate::{get_server_config_bulk, Config, DataBase, ServerMembers, ServerMembersWolves, Servers, Wolves}; + use crate::Config; + use crate::common::database::{get_server_config_bulk, DataBase, ServerMembers, ServerMembersWolves, Servers, Wolves}; #[derive(Deserialize, Serialize, Debug)] struct WolvesResultUser { diff --git a/src/lib.rs b/src/lib.rs index 9e1c599..dfc7c4f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,8 @@ pub mod common; use dotenvy::dotenv; use serde::{Deserialize, Serialize}; use serenity::{ - model::{ - guild, - id::{ChannelId, GuildId, RoleId}, - }, - prelude::TypeMapKey, + model::id::{GuildId, RoleId}, + prelude::TypeMapKey, }; use crate::set_roles::get_server_member_bulk; @@ -18,11 +15,11 @@ use serenity::client::Context; use serenity::model::id::UserId; use serenity::model::prelude::application_command::ApplicationCommandInteraction; use sqlx::{ - sqlite::{SqliteConnectOptions, SqlitePoolOptions, SqliteRow}, - Error, FromRow, Pool, Row, Sqlite, + Pool, Sqlite, }; -use std::{env, str::FromStr, sync::Arc}; +use std::{env, sync::Arc}; use tokio::sync::RwLock; +use common::database::{Minecraft, ServerMembersWolves, Servers}; pub struct Config { // manages where teh database is stored @@ -45,11 +42,6 @@ impl TypeMapKey for Config { type Value = Arc>; } -pub struct DataBase; -impl TypeMapKey for DataBase { - type Value = Arc>>; -} - pub fn get_config() -> Config { dotenv().ok(); @@ -98,272 +90,6 @@ pub fn get_config() -> Config { config } -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ServerMembers { - pub server: GuildId, - pub id_wolves: i64, - pub expiry: String, -} -impl<'r> FromRow<'r, SqliteRow> for ServerMembers { - fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server")?; - let server = GuildId::from(server_tmp as u64); - - Ok(Self { - server, - id_wolves: row.try_get("id_wolves")?, - expiry: row.try_get("expiry")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ServerMembersWolves { - pub server: GuildId, - pub id_wolves: i64, - pub expiry: String, - pub email: String, - pub discord: Option, - pub minecraft: Option, -} -impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves { - fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server")?; - let server = GuildId::from(server_tmp as u64); - let discord = match row.try_get("discord") { - Ok(x) => { - let tmp: i64 = x; - if tmp == 0 { - None - } else { - Some(UserId::from(tmp as u64)) - } - } - _ => None, - }; - - Ok(Self { - server, - id_wolves: row.try_get("id_wolves")?, - expiry: row.try_get("expiry")?, - email: row.try_get("email")?, - discord, - minecraft: row.try_get("minecraft")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Wolves { - pub id_wolves: i64, - pub email: String, - pub discord: Option, - pub minecraft: Option, -} -impl<'r> FromRow<'r, SqliteRow> for Wolves { - fn from_row(row: &'r SqliteRow) -> Result { - let discord = match row.try_get("discord") { - Ok(x) => { - let tmp: i64 = x; - if tmp == 0 { - None - } else { - Some(UserId::from(tmp as u64)) - } - } - _ => None, - }; - - Ok(Self { - id_wolves: row.try_get("id_wolves")?, - email: row.try_get("email")?, - discord, - minecraft: row.try_get("minecraft")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct WolvesVerify { - pub email: String, - pub discord: UserId, - pub auth_code: String, - pub date_expiry: String, -} -impl<'r> FromRow<'r, SqliteRow> for WolvesVerify { - fn from_row(row: &'r SqliteRow) -> Result { - let user_tmp: i64 = row.try_get("discord")?; - let discord = UserId::from(user_tmp as u64); - - Ok(Self { - email: row.try_get("email")?, - discord, - auth_code: row.try_get("auth_code")?, - date_expiry: row.try_get("date_expiry")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Servers { - pub server: GuildId, - pub wolves_api: String, - pub role_past: Option, - pub role_current: RoleId, - pub member_past: i64, - pub member_current: i64, - pub bot_channel_id: ChannelId, - // TODO: these can be removed in teh future with an API update - pub server_name: String, - pub wolves_link: String, -} -impl<'r> FromRow<'r, SqliteRow> for Servers { - fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server")?; - let server = GuildId::from(server_tmp as u64); - let role_past = match row.try_get("role_past") { - Ok(x) => { - let tmp: i64 = x; - if tmp == 0 { - None - } else { - Some(RoleId::from(tmp as u64)) - } - } - _ => None, - }; - let role_current = match row.try_get("role_current") { - Ok(x) => { - let tmp: i64 = x; - RoleId::from(tmp as u64) - } - _ => RoleId::from(0u64), - }; - - let bot_channel_tmp: i64 = row.try_get("bot_channel_id")?; - let bot_channel_id = ChannelId::from(bot_channel_tmp as u64); - - Ok(Self { - server, - wolves_api: row.try_get("wolves_api")?, - role_past, - role_current, - member_past: row.try_get("member_past")?, - member_current: row.try_get("member_current")?, - bot_channel_id, - server_name: row.try_get("server_name")?, - wolves_link: row.try_get("wolves_link")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Minecraft { - pub discord: GuildId, - pub minecraft: String, -} -impl<'r> FromRow<'r, SqliteRow> for Minecraft { - fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server_discord")?; - let discord = GuildId::from(server_tmp as u64); - - Ok(Self { - discord, - minecraft: row.try_get("server_minecraft")?, - }) - } -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct RoleAdder { - pub server: GuildId, - pub role_a: RoleId, - pub role_b: RoleId, - pub role_c: RoleId, -} -impl<'r> FromRow<'r, SqliteRow> for RoleAdder { - fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server")?; - let server = GuildId::from(server_tmp as u64); - - Ok(Self { - server, - role_a: get_role_from_row(row, "role_a"), - role_b: get_role_from_row(row, "role_b"), - role_c: get_role_from_row(row, "role_c"), - }) - } -} - -fn get_role_from_row(row: &SqliteRow, col: &str) -> RoleId { - match row.try_get(col) { - Ok(x) => { - let tmp: i64 = x; - RoleId(tmp as u64) - } - _ => RoleId::from(0u64), - } -} - -pub async fn db_init(config: &Config) -> Result, Error> { - let database = format!("{}/{}", &config.home, &config.database); - - let pool = SqlitePoolOptions::new() - .max_connections(5) - .connect_with( - SqliteConnectOptions::from_str(&format!("sqlite://{}", database))? - .foreign_keys(true) - .create_if_missing(true), - ) - .await?; - - // migrations are amazing! - sqlx::migrate!("./db/migrations").run(&pool).await?; - - Ok(pool) -} - -pub async fn get_server_config(db: &Pool, server: &GuildId) -> Option { - sqlx::query_as::<_, Servers>( - r#" - SELECT * - FROM servers - WHERE server = ? - "#, - ) - .bind(*server.as_u64() as i64) - .fetch_one(db) - .await - .ok() -} - -pub async fn get_server_member(db: &Pool, server: &GuildId, member: &guild::Member) -> Result { - sqlx::query_as::<_, ServerMembersWolves>( - r#" - SELECT * - FROM server_members - JOIN wolves USING (id_wolves) - WHERE server = ? AND discord = ? - "#, - ) - .bind(*server.as_u64() as i64) - .bind(*member.user.id.as_u64() as i64) - .fetch_one(db) - .await -} - -pub async fn get_server_config_bulk(db: &Pool) -> Vec { - sqlx::query_as::<_, Servers>( - r#" - SELECT * - FROM servers - "#, - ) - .fetch_all(db) - .await - .unwrap_or_default() -} - pub fn get_now_iso(short: bool) -> String { let now = Utc::now(); if short { @@ -378,6 +104,7 @@ pub fn random_string(len: usize) -> String { } pub mod set_roles { + use crate::common::database::{DataBase, Wolves}; use super::*; pub async fn update_server(ctx: &Context, server: &Servers, remove_roles: &[Option], members_changed: &[UserId]) { let db_lock = { diff --git a/src/main.rs b/src/main.rs index 1b80a6d..6f86f86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,19 +3,20 @@ pub mod commands; use crate::commands::role_adder::tools::on_role_change; use serenity::model::guild::Member; use serenity::{ - async_trait, - client::{Context, EventHandler}, - model::{ - application::{command::Command, interaction::Interaction}, - gateway::{GatewayIntents, Ready}, - prelude::Activity, - user::OnlineStatus, - }, - Client, + async_trait, + client::{Context, EventHandler}, + model::{ + application::{command::Command, interaction::Interaction}, + gateway::{GatewayIntents, Ready}, + prelude::Activity, + user::OnlineStatus, + }, + Client, }; -use skynet_discord_bot::{db_init, get_config, get_server_config, get_server_member, Config, DataBase}; +use skynet_discord_bot::{get_config, Config}; use std::sync::Arc; use tokio::sync::RwLock; +use skynet_discord_bot::common::database::{db_init, get_server_config, get_server_member, DataBase}; struct Handler;