use sqlx's query macro in some places
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
.env
|
.env
|
||||||
|
.vscode
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use poise::serenity_prelude as serenity;
|
|||||||
#[poise::command(slash_command, prefix_command, aliases("bal", "b"))]
|
#[poise::command(slash_command, prefix_command, aliases("bal", "b"))]
|
||||||
pub async fn balance(ctx: Context<'_>, user: Option<serenity::User>) -> Result<(), Error> {
|
pub async fn balance(ctx: Context<'_>, user: Option<serenity::User>) -> Result<(), Error> {
|
||||||
let user = user.as_ref().unwrap_or(ctx.author());
|
let user = user.as_ref().unwrap_or(ctx.author());
|
||||||
let db = &ctx.data().database;
|
let mut tx = ctx.data().database.begin().await?;
|
||||||
|
|
||||||
let wealth = super::get_balance(user.id, db).await?;
|
let wealth = super::get_balance(user.id, &mut tx).await?;
|
||||||
|
|
||||||
common::no_ping_reply(&ctx, format!("{} **{}** token(s).",
|
common::no_ping_reply(&ctx, format!("{} **{}** token(s).",
|
||||||
if user.id == ctx.author().id {
|
if user.id == ctx.author().id {
|
||||||
|
|||||||
@@ -1,58 +1,54 @@
|
|||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
|
|
||||||
use poise::serenity_prelude::{UserId, User};
|
use poise::serenity_prelude::{UserId, User};
|
||||||
use sqlx::{types::chrono::{DateTime, Utc, TimeZone}, PgExecutor, Row};
|
use sqlx::{types::chrono::{DateTime, TimeZone, Utc}, PgConnection};
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
async fn get_streak<'a, E>(db: E, user: UserId) -> Result<Option<i32>, Error>
|
pub async fn get_streak(conn: &mut PgConnection, user: UserId) -> Result<Option<i32>, Error> {
|
||||||
where
|
let result = sqlx::query!(
|
||||||
E: PgExecutor<'a>,
|
"SELECT streak FROM dailies WHERE userid = $1",
|
||||||
{
|
user.get() as i64
|
||||||
match sqlx::query(
|
)
|
||||||
"SELECT streak FROM dailies WHERE userid = $1"
|
.fetch_optional(conn)
|
||||||
).bind(user.get() as i64).fetch_one(db).await
|
.await?;
|
||||||
{
|
|
||||||
Ok(row) => Ok(Some(row.get(0))),
|
Ok(result.map(|r| r.streak).unwrap_or(None))
|
||||||
Err(sqlx::Error::RowNotFound) => Ok(None),
|
|
||||||
Err(e) => Err(Box::new(e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_streak<'a, E>(db: E, user: UserId, streak: i32) -> Result<(), Error>
|
pub async fn set_streak(conn: &mut PgConnection, user: UserId, streak: i32) -> Result<(), Error> {
|
||||||
where
|
sqlx::query!(
|
||||||
E: PgExecutor<'a>,
|
"INSERT INTO dailies (userid, streak) VALUES ($1, $2)
|
||||||
{
|
ON CONFLICT (userid) DO UPDATE SET streak = EXCLUDED.streak",
|
||||||
sqlx::query("INSERT INTO dailies (userid, streak) VALUES ($1, $2) ON CONFLICT (userid) DO UPDATE SET streak = EXCLUDED.streak")
|
user.get() as i64,
|
||||||
.bind(user.get() as i64)
|
streak
|
||||||
.bind(streak)
|
)
|
||||||
.execute(db).await?;
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_last<'a, E>(db: E, user: UserId) -> Result<Option<DateTime<Utc>>, Error>
|
pub async fn get_last(conn: &mut PgConnection, user: UserId) -> Result<Option<DateTime<Utc>>, Error> {
|
||||||
where
|
let result = sqlx::query!(
|
||||||
E: PgExecutor<'a>,
|
"SELECT last FROM dailies WHERE userid = $1",
|
||||||
{
|
user.get() as i64
|
||||||
match sqlx::query(
|
)
|
||||||
"SELECT last FROM dailies WHERE userid = $1"
|
.fetch_optional(conn)
|
||||||
).bind(user.get() as i64).fetch_one(db).await
|
.await?;
|
||||||
{
|
|
||||||
Ok(row) => Ok(Some(row.get(0))),
|
Ok(result.map(|r| r.last).unwrap_or(None))
|
||||||
Err(sqlx::Error::RowNotFound) => Ok(None),
|
|
||||||
Err(e) => Err(Box::new(e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_last<'a, E>(db: E, user: UserId, last: DateTime<Utc>) -> Result<(), Error>
|
pub async fn set_last(conn: &mut PgConnection, user: UserId, last: DateTime<Utc>) -> Result<(), Error> {
|
||||||
where
|
sqlx::query!(
|
||||||
E: PgExecutor<'a>,
|
"INSERT INTO dailies (userid, last) VALUES ($1, $2)
|
||||||
{
|
ON CONFLICT (userid) DO UPDATE SET last = EXCLUDED.last",
|
||||||
sqlx::query("INSERT INTO dailies (userid, last) VALUES ($1, $2) ON CONFLICT (userid) DO UPDATE SET last = EXCLUDED.last")
|
user.get() as i64,
|
||||||
.bind(user.get() as i64)
|
last
|
||||||
.bind(last)
|
)
|
||||||
.execute(db).await?;
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -60,13 +56,14 @@ where
|
|||||||
/// Tells you what your current daily streak is
|
/// Tells you what your current daily streak is
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn streak(ctx: Context<'_>, user: Option<User>) -> Result<(), Error> {
|
pub async fn streak(ctx: Context<'_>, user: Option<User>) -> Result<(), Error> {
|
||||||
let db = &ctx.data().database;
|
let mut tx = ctx.data().database.begin().await?;
|
||||||
|
|
||||||
let (user, who) = match user {
|
let (user, who) = match user {
|
||||||
Some(user) => (user.id, format!("{} has", user.display_name())),
|
Some(user) => (user.id, format!("{} has", user.display_name())),
|
||||||
None => (ctx.author().id, "You have".to_string()),
|
None => (ctx.author().id, "You have".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.reply(format!("{who} a daily streak of **{}**", get_streak(db, user).await?.unwrap_or(0))).await?;
|
ctx.reply(format!("{who} a daily streak of **{}**", get_streak(&mut tx, user).await?.unwrap_or(0))).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
use crate::common::{Context, Error};
|
use crate::common::{Context, Error};
|
||||||
use poise::serenity_prelude::UserId;
|
use poise::serenity_prelude::UserId;
|
||||||
use sqlx::Row;
|
|
||||||
|
|
||||||
enum LeaderboardType {
|
enum LeaderboardType {
|
||||||
Tokens(usize),
|
Tokens(usize),
|
||||||
@@ -13,15 +12,16 @@ async fn display_leaderboard(ctx: Context<'_>, t: LeaderboardType) -> Result<(),
|
|||||||
|
|
||||||
match t {
|
match t {
|
||||||
LeaderboardType::Tokens(count) => {
|
LeaderboardType::Tokens(count) => {
|
||||||
let rows = sqlx::query(
|
let rows = sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
SELECT id, balance FROM bank
|
SELECT id, balance FROM bank
|
||||||
ORDER BY balance DESC
|
ORDER BY balance DESC
|
||||||
LIMIT $1
|
LIMIT $1
|
||||||
"#
|
"#,
|
||||||
).bind(count as i32).fetch_all(db).await?;
|
count as i32
|
||||||
|
).fetch_all(db).await?;
|
||||||
|
|
||||||
let users: Vec<(_, i32)> = rows.iter().map(|row| (UserId::new(row.get::<i64, _>(0) as u64), row.get(1))).collect();
|
let users: Vec<(_, i32)> = rows.iter().map(|row| (UserId::new(row.id as u64), row.balance.unwrap_or(100))).collect();
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
for (id, balance) in users {
|
for (id, balance) in users {
|
||||||
@@ -32,15 +32,16 @@ async fn display_leaderboard(ctx: Context<'_>, t: LeaderboardType) -> Result<(),
|
|||||||
ctx.reply(format!("```\n{output}```")).await?;
|
ctx.reply(format!("```\n{output}```")).await?;
|
||||||
}
|
}
|
||||||
LeaderboardType::Dailies(count) => {
|
LeaderboardType::Dailies(count) => {
|
||||||
let rows = sqlx::query(
|
let rows = sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
SELECT userid, streak FROM dailies
|
SELECT userid, streak FROM dailies
|
||||||
ORDER BY streak DESC
|
ORDER BY streak DESC
|
||||||
LIMIT $1
|
LIMIT $1
|
||||||
"#
|
"#,
|
||||||
).bind(count as i32).fetch_all(db).await?;
|
count as i32
|
||||||
|
).fetch_all(db).await?;
|
||||||
|
|
||||||
let users: Vec<(_, i32)> = rows.iter().map(|row| (UserId::new(row.get::<i64, _>(0) as u64), row.get(1))).collect();
|
let users: Vec<(_, i32)> = rows.iter().map(|row| (UserId::new(row.userid as u64), row.streak.unwrap_or(0))).collect();
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
for (id, streak) in users {
|
for (id, streak) in users {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub mod blackjack;
|
|||||||
|
|
||||||
use crate::{inventory::{self, Inventory}, common::{Context, Error}};
|
use crate::{inventory::{self, Inventory}, common::{Context, Error}};
|
||||||
use poise::serenity_prelude::{self as serenity, futures::StreamExt, UserId};
|
use poise::serenity_prelude::{self as serenity, futures::StreamExt, UserId};
|
||||||
use sqlx::{Row, PgExecutor};
|
use sqlx::PgConnection;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -79,16 +79,15 @@ mod items {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_balance<'a, E>(id: UserId, db: E) -> Result<i32, Error>
|
pub async fn get_balance(id: UserId, db: &mut PgConnection) -> Result<i32, Error>
|
||||||
where
|
|
||||||
E: PgExecutor<'a>,
|
|
||||||
{
|
{
|
||||||
let row = sqlx::query("SELECT balance FROM bank WHERE id = $1")
|
let row = sqlx::query!(
|
||||||
.bind(id.get() as i64)
|
"SELECT balance FROM bank WHERE id = $1",
|
||||||
.fetch_one(db).await.ok();
|
id.get() as i64
|
||||||
|
).fetch_one(db).await.ok();
|
||||||
|
|
||||||
let balance = if let Some(row) = row {
|
let balance = if let Some(row) = row {
|
||||||
row.try_get("balance")?
|
row.balance.unwrap_or(100)
|
||||||
} else {
|
} else {
|
||||||
100
|
100
|
||||||
};
|
};
|
||||||
@@ -96,14 +95,13 @@ where
|
|||||||
Ok(balance)
|
Ok(balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn change_balance<'a, E>(id: UserId, balance: i32, db: E) -> Result<(), Error>
|
pub async fn change_balance(id: UserId, balance: i32, db: &mut PgConnection) -> Result<(), Error>
|
||||||
where
|
|
||||||
E: PgExecutor<'a>,
|
|
||||||
{
|
{
|
||||||
sqlx::query("INSERT INTO bank (id, balance) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET balance = EXCLUDED.balance")
|
sqlx::query!(
|
||||||
.bind(id.get() as i64)
|
r#"INSERT INTO bank (id, balance) VALUES ($1, $2)
|
||||||
.bind(balance)
|
ON CONFLICT (id) DO UPDATE SET balance = EXCLUDED.balance"#,
|
||||||
.execute(db).await?;
|
id.get() as i64, balance
|
||||||
|
).execute(db).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ async fn autocomplete_shop<'a>(
|
|||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
partial: &'a str,
|
partial: &'a str,
|
||||||
) -> impl Iterator<Item = serenity::AutocompleteChoice> + use<'a> {
|
) -> impl Iterator<Item = serenity::AutocompleteChoice> + use<'a> {
|
||||||
let db = &ctx.data().database;
|
let mut tx = ctx.data().database.begin().await.unwrap();
|
||||||
let balance = super::get_balance(ctx.author().id, db).await;
|
let balance = super::get_balance(ctx.author().id, &mut *tx).await;
|
||||||
|
|
||||||
ITEMS.values()
|
ITEMS.values()
|
||||||
.filter(move |(_, item)| item.name.contains(partial))
|
.filter(move |(_, item)| item.name.contains(partial))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
use crate::common::{Context, Error};
|
use crate::common::{Context, Error};
|
||||||
use sqlx::{PgConnection, Row};
|
use sqlx::PgConnection;
|
||||||
use poise::serenity_prelude::{EditRole, GuildId, Permissions, RoleId, UserId};
|
use poise::serenity_prelude::{EditRole, GuildId, Permissions, RoleId, UserId};
|
||||||
|
|
||||||
mod whois;
|
mod whois;
|
||||||
@@ -83,18 +83,14 @@ async fn create_role(
|
|||||||
|
|
||||||
/// Remove a row concerning a user's self role from the database
|
/// Remove a row concerning a user's self role from the database
|
||||||
pub async fn remove_user_role(user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<(), Error> {
|
pub async fn remove_user_role(user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<(), Error> {
|
||||||
sqlx::query("DELETE FROM selfroles WHERE userid = $1 AND guildid = $2")
|
sqlx::query!("DELETE FROM selfroles WHERE userid = $1 AND guildid = $2", user.get() as i64, guild.get() as i64)
|
||||||
.bind(user.get() as i64)
|
|
||||||
.bind(guild.get() as i64)
|
|
||||||
.execute(db).await?;
|
.execute(db).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_role(role: RoleId, guild: GuildId, db: &mut PgConnection) -> Result<(), Error> {
|
pub async fn remove_role(role: RoleId, guild: GuildId, db: &mut PgConnection) -> Result<(), Error> {
|
||||||
sqlx::query("DELETE FROM selfroles WHERE roleid = $1 AND guildid = $2")
|
sqlx::query!("DELETE FROM selfroles WHERE roleid = $1 AND guildid = $2", role.get() as i64, guild.get() as i64)
|
||||||
.bind(role.get() as i64)
|
|
||||||
.bind(guild.get() as i64)
|
|
||||||
.execute(db).await?;
|
.execute(db).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -102,10 +98,10 @@ pub async fn remove_role(role: RoleId, guild: GuildId, db: &mut PgConnection) ->
|
|||||||
|
|
||||||
/// Replace a user's custom role with a new one
|
/// Replace a user's custom role with a new one
|
||||||
pub async fn update_user_role(user: UserId, guild: GuildId, role: RoleId, db: &mut PgConnection) -> Result<(), Error> {
|
pub async fn update_user_role(user: UserId, guild: GuildId, role: RoleId, db: &mut PgConnection) -> Result<(), Error> {
|
||||||
sqlx::query("INSERT INTO selfroles (userid, guildid, roleid) VALUES($1, $2, $3) ON CONFLICT (userid, guildid) DO UPDATE SET roleid = EXCLUDED.roleid")
|
sqlx::query!(
|
||||||
.bind(user.get() as i64)
|
r#"INSERT INTO selfroles (userid, guildid, roleid) VALUES($1, $2, $3)
|
||||||
.bind(guild.get() as i64)
|
ON CONFLICT (userid, guildid) DO UPDATE SET roleid = EXCLUDED.roleid"#,
|
||||||
.bind(role.get() as i64)
|
user.get() as i64, guild.get() as i64, role.get() as i64)
|
||||||
.execute(db).await?;
|
.execute(db).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -113,12 +109,10 @@ pub async fn update_user_role(user: UserId, guild: GuildId, role: RoleId, db: &m
|
|||||||
|
|
||||||
/// Get a user's personal role id from the database
|
/// Get a user's personal role id from the database
|
||||||
pub async fn get_user_role(user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<Option<RoleId>, Error> {
|
pub async fn get_user_role(user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<Option<RoleId>, Error> {
|
||||||
match sqlx::query("SELECT roleid FROM selfroles WHERE userid = $1 AND guildid = $2")
|
match sqlx::query!("SELECT roleid FROM selfroles WHERE userid = $1 AND guildid = $2", user.get() as i64, guild.get() as i64)
|
||||||
.bind(user.get() as i64)
|
|
||||||
.bind(guild.get() as i64)
|
|
||||||
.fetch_one(db).await
|
.fetch_one(db).await
|
||||||
{
|
{
|
||||||
Ok(row) => Ok(Some(RoleId::new(row.try_get::<i64, usize>(0)? as u64))),
|
Ok(row) => Ok(Some(RoleId::new(row.roleid.unwrap() as u64))),
|
||||||
Err(sqlx::Error::RowNotFound) => Ok(None),
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
Err(e) => return Err(Box::new(e)),
|
Err(e) => return Err(Box::new(e)),
|
||||||
}
|
}
|
||||||
@@ -126,12 +120,10 @@ pub async fn get_user_role(user: UserId, guild: GuildId, db: &mut PgConnection)
|
|||||||
|
|
||||||
/// Get a user from the role id
|
/// Get a user from the role id
|
||||||
pub async fn get_user_by_role(role: RoleId, guild: GuildId, db: &mut PgConnection) -> Result<Option<UserId>, Error> {
|
pub async fn get_user_by_role(role: RoleId, guild: GuildId, db: &mut PgConnection) -> Result<Option<UserId>, Error> {
|
||||||
match sqlx::query("SELECT userid FROM selfroles WHERE roleid = $1 AND guildid = $2")
|
match sqlx::query!("SELECT userid FROM selfroles WHERE roleid = $1 AND guildid = $2", role.get() as i64, guild.get() as i64)
|
||||||
.bind(role.get() as i64)
|
|
||||||
.bind(guild.get() as i64)
|
|
||||||
.fetch_one(db).await
|
.fetch_one(db).await
|
||||||
{
|
{
|
||||||
Ok(row) => Ok(Some(UserId::new(row.try_get::<i64, usize>(0)? as u64))),
|
Ok(row) => Ok(Some(UserId::new(row.userid as u64))),
|
||||||
Err(sqlx::Error::RowNotFound) => Ok(None),
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
Err(e) => return Err(Box::new(e)),
|
Err(e) => return Err(Box::new(e)),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use crate::common::{self, Context, Error};
|
|||||||
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use serenity::UserId;
|
use serenity::UserId;
|
||||||
use sqlx::Row;
|
|
||||||
|
|
||||||
/// Let you know who is the owner of a role.
|
/// Let you know who is the owner of a role.
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
@@ -11,11 +10,10 @@ pub async fn whois(ctx: Context<'_>, role: serenity::Role) -> Result<(), Error>
|
|||||||
let db = &ctx.data().database;
|
let db = &ctx.data().database;
|
||||||
|
|
||||||
if let Some(guild) = ctx.guild_id() {
|
if let Some(guild) = ctx.guild_id() {
|
||||||
let user = match sqlx::query("SELECT userid FROM selfroles WHERE roleid = $1")
|
let user = match sqlx::query!("SELECT userid FROM selfroles WHERE roleid = $1", role.id.get() as i64)
|
||||||
.bind(role.id.get() as i64)
|
|
||||||
.fetch_one(db).await
|
.fetch_one(db).await
|
||||||
{
|
{
|
||||||
Ok(row) => UserId::new(row.try_get::<i64, usize>(0)? as u64),
|
Ok(row) => UserId::new(row.userid as u64),
|
||||||
Err(sqlx::Error::RowNotFound) => {
|
Err(sqlx::Error::RowNotFound) => {
|
||||||
ctx.reply("This role is not owned by anyone.").await?;
|
ctx.reply("This role is not owned by anyone.").await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
Reference in New Issue
Block a user