feat: completed migration #11

Merged
silver merged 3 commits from #4-id-instead-of-name into main 2023-09-26 00:16:25 +00:00
3 changed files with 185 additions and 0 deletions
Showing only changes of commit f11fdb4dde - Show all commits

View file

@ -11,6 +11,9 @@ name = "update_data"
[[bin]]
name = "update_users"
[[bin]]
name = "update_id"
[dependencies]
serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] }

144
src/bin/update_id.rs Normal file
View file

@ -0,0 +1,144 @@
use serenity::{
async_trait,
client::{Context, EventHandler},
model::{
gateway::{GatewayIntents, Ready},
},
Client,
};
use skynet_discord_bot::{db_init, get_config, Config, DataBase, ServerMembersWolves, Wolves2};
use sqlx::{Pool, Sqlite};
use std::{process, sync::Arc};
use tokio::sync::RwLock;
#[tokio::main]
async fn main() {
let config = get_config();
let db = match db_init(&config).await {
Ok(x) => x,
Err(_) => return,
};
// Intents are a bitflag, bitwise operations can be used to dictate which intents to use
let intents = GatewayIntents::GUILDS | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS;
// Build our client.
let mut client = Client::builder(&config.discord_token, intents)
.event_handler(Handler {})
.await
.expect("Error creating client");
{
let mut data = client.data.write().await;
data.insert::<Config>(Arc::new(RwLock::new(config)));
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
}
if let Err(why) = client.start().await {
println!("Client error: {:?}", why);
}
}
struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn ready(&self, ctx: Context, ready: Ready) {
let ctx = Arc::new(ctx);
println!("{} is connected!", ready.user.name);
bulk_check(Arc::clone(&ctx)).await;
// finish up
process::exit(0);
}
}
async fn bulk_check(ctx: Arc<Context>) {
let db_lock = {
let data_read = ctx.data.read().await;
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
};
let db = db_lock.read().await;
// get sk
let mut wolves2 = vec![];
// get wolves users
for user in get_server_member_bulk(&db).await{
let discord = match user.discord{
None => {
wolves2.push(Wolves2{
id_wolves: user.id_wolves,
email: user.email,
discord: None,
minecraft: user.minecraft,
});
continue;
}
Some(x) => {x}
};
if let Ok(x) = user.server.search_members(&ctx.http, &discord, None).await {
for user_tmp in x {
if &user_tmp.user.name == &discord {
wolves2.push(Wolves2{
id_wolves: user.id_wolves.to_owned(),
email: user.email.to_owned(),
discord: Some(user_tmp.user.id),
minecraft: user.minecraft.to_owned(),
});
break;
}
}
}
}
for user in wolves2 {
set_member_info(&db, &user).await;
}
}
async fn get_server_member_bulk(db: &Pool<Sqlite>) -> Vec<ServerMembersWolves> {
sqlx::query_as::<_, ServerMembersWolves>(
r#"
SELECT *
FROM server_members
JOIN wolves USING (id_wolves)
"#,
)
.fetch_all(db)
.await
.unwrap_or_default()
}
async fn set_member_info(db: &Pool<Sqlite>, user: &Wolves2){
let discord = user.discord.map(|x| *x.as_u64() as i64);
// save
match sqlx::query_as::<_, Wolves2>(
"
INSERT INTO wolves2 (id_wolves, email, discord)
VALUES ($1, $2, $3)
ON CONFLICT(id_wolves) DO UPDATE SET email = $2, discord = $3
",
)
.bind(&user.id_wolves)
.bind(&user.email)
.bind(discord)
.fetch_optional(db)
.await
{
Ok(_) => {}
Err(e) => {
println!("Failure to insert into {:?}", &user);
println!("{:?}", e);
}
}
}

View file

@ -15,6 +15,7 @@ use sqlx::{
Error, FromRow, Pool, Row, Sqlite,
};
use std::{env, str::FromStr, sync::Arc};
use serenity::model::id::UserId;
use tokio::sync::RwLock;
pub struct Config {
@ -152,6 +153,32 @@ pub struct Wolves {
pub minecraft: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Wolves2 {
pub id_wolves: String,
pub email: String,
pub discord: Option<UserId>,
pub minecraft: Option<String>,
}
impl<'r> FromRow<'r, SqliteRow> for Wolves2 {
fn from_row(row: &'r SqliteRow) -> Result<Self, Error> {
let discord = match row.try_get("discord") {
Ok(x) => {
let tmp: i64 = x;
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, sqlx::FromRow)]
pub struct WolvesVerify {
pub email: String,
@ -222,6 +249,17 @@ pub async fn db_init(config: &Config) -> Result<Pool<Sqlite>, Error> {
.execute(&pool)
.await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS wolves2 (
id_wolves text PRIMARY KEY,
email text not null,
discord integer,
minecraft text
)",
)
.execute(&pool)
.await?;
sqlx::query("CREATE INDEX IF NOT EXISTS index_discord ON wolves (discord)").execute(&pool).await?;
sqlx::query(