feat: now using seperate tables for key info, joined when needed

This commit is contained in:
silver 2023-09-17 00:14:50 +01:00
parent f405cbbb93
commit 591c61b009
6 changed files with 225 additions and 198 deletions

View file

@ -109,17 +109,12 @@ fn str_to_num<T: FromStr + Default>(x: &str) -> T {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Accounts {
pub struct ServerMembers {
pub server: GuildId,
pub id_wolves: String,
pub id_member: String,
pub email: String,
pub expiry: String,
pub discord: Option<String>,
pub minecraft: Option<String>,
}
impl<'r> FromRow<'r, SqliteRow> for Accounts {
impl<'r> FromRow<'r, SqliteRow> for ServerMembers {
fn from_row(row: &'r SqliteRow) -> Result<Self, Error> {
let server_tmp: i64 = row.try_get("server")?;
let server = GuildId::from(server_tmp as u64);
@ -127,9 +122,24 @@ impl<'r> FromRow<'r, SqliteRow> for Accounts {
Ok(Self {
server,
id_wolves: row.try_get("id_wolves")?,
id_member: row.try_get("id_member")?,
email: row.try_get("email")?,
expiry: row.try_get("expiry")?,
})
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Wolves {
pub id_wolves: String,
pub email: String,
pub discord: Option<String>,
pub minecraft: Option<String>,
}
impl<'r> FromRow<'r, SqliteRow> for Wolves {
fn from_row(row: &'r SqliteRow) -> Result<Self, Error> {
Ok(Self {
id_wolves: row.try_get("id_wolves")?,
email: row.try_get("email")?,
discord: row.try_get("discord")?,
minecraft: row.try_get("minecraft")?,
})
@ -180,38 +190,47 @@ pub async fn db_init(config: &Config) -> Result<Pool<Sqlite>, Error> {
let pool = SqlitePoolOptions::new()
.max_connections(5)
.connect_with(SqliteConnectOptions::from_str(&format!("sqlite://{}", database))?.create_if_missing(true))
.connect_with(
SqliteConnectOptions::from_str(&format!("sqlite://{}", database))?
.foreign_keys(true)
.create_if_missing(true),
)
.await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS accounts (
server integer not null,
id_wolves text DEFAULT '',
id_member text DEFAULT '',
email text not null,
expiry text not null,
discord text,
minecraft text,
PRIMARY KEY(server,id_wolves,id_member)
)",
"CREATE TABLE IF NOT EXISTS wolves (
id_wolves text PRIMARY KEY,
email text not null,
discord text,
minecraft text
)",
)
.execute(&pool)
.await?;
sqlx::query("CREATE INDEX IF NOT EXISTS index_server ON accounts (server)").execute(&pool).await?;
sqlx::query("CREATE INDEX IF NOT EXISTS index_id_wolves ON accounts (id_wolves)")
.execute(&pool)
.await?;
sqlx::query("CREATE INDEX IF NOT EXISTS index_discord ON wolves (discord)").execute(&pool).await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS server_members (
server integer not null,
id_wolves text not null,
expiry text not null,
PRIMARY KEY(server,id_wolves),
FOREIGN KEY (id_wolves) REFERENCES wolves (id_wolves)
)",
)
.execute(&pool)
.await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS servers (
server integer key,
wolves_api text not null,
role_past integer,
role_current integer,
member_past integer DEFAULT 0,
member_current integer DEFAULT 0
)",
server integer KEY,
wolves_api text not null,
role_past integer,
role_current integer,
member_past integer DEFAULT 0,
member_current integer DEFAULT 0
)",
)
.execute(&pool)
.await?;
@ -222,10 +241,10 @@ pub async fn db_init(config: &Config) -> Result<Pool<Sqlite>, Error> {
pub async fn get_server_config(db: &Pool<Sqlite>, server: &GuildId) -> Option<Servers> {
sqlx::query_as::<_, Servers>(
r#"
SELECT *
FROM servers
WHERE server = ?
"#,
SELECT *
FROM servers
WHERE server = ?
"#,
)
.bind(*server.as_u64() as i64)
.fetch_one(db)
@ -233,19 +252,36 @@ pub async fn get_server_config(db: &Pool<Sqlite>, server: &GuildId) -> Option<Se
.ok()
}
pub async fn get_server_member(db: &Pool<Sqlite>, server: &GuildId, member: &guild::Member) -> Option<Accounts> {
sqlx::query_as::<_, Accounts>(
pub async fn get_server_member(db: &Pool<Sqlite>, server: &GuildId, member: &guild::Member) -> Option<ServerMembers> {
let wolves_data = sqlx::query_as::<_, Wolves>(
r#"
SELECT *
FROM accounts
WHERE server = ? AND discord = ?
"#,
SELECT *
FROM wolves
WHERE discord = ?
"#,
)
.bind(*server.as_u64() as i64)
.bind(&member.user.name)
.fetch_one(db)
.await
.ok()
.await;
if let Ok(user_wolves) = wolves_data {
// check if the suer is on the server
return sqlx::query_as::<_, ServerMembers>(
r#"
SELECT *
FROM server_members
WHERE server = ? AND id_wolves = ?
"#,
)
.bind(*server.as_u64() as i64)
.bind(&user_wolves.id_wolves)
.fetch_one(db)
.await
.ok();
}
None
}
pub async fn get_server_config_bulk(db: &Pool<Sqlite>) -> Vec<Servers> {