use sqlx's query macro in some places
Some checks failed
Docker Image CI / build_amd64 (push) Has been cancelled
Docker Image CI / build_arm64 (push) Has been cancelled
Docker Image CI / create_manifest (push) Has been cancelled

This commit is contained in:
2025-06-27 13:30:38 -04:00
parent c054ef1c1c
commit a1cd0e6a25
8 changed files with 82 additions and 95 deletions

View File

@@ -6,9 +6,9 @@ use poise::serenity_prelude as serenity;
#[poise::command(slash_command, prefix_command, aliases("bal", "b"))]
pub async fn balance(ctx: Context<'_>, user: Option<serenity::User>) -> Result<(), Error> {
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).",
if user.id == ctx.author().id {

View File

@@ -1,58 +1,54 @@
use crate::{Context, Error};
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;
async fn get_streak<'a, E>(db: E, user: UserId) -> Result<Option<i32>, Error>
where
E: PgExecutor<'a>,
{
match sqlx::query(
"SELECT streak FROM dailies WHERE userid = $1"
).bind(user.get() as i64).fetch_one(db).await
{
Ok(row) => Ok(Some(row.get(0))),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(Box::new(e)),
}
pub async fn get_streak(conn: &mut PgConnection, user: UserId) -> Result<Option<i32>, Error> {
let result = sqlx::query!(
"SELECT streak FROM dailies WHERE userid = $1",
user.get() as i64
)
.fetch_optional(conn)
.await?;
Ok(result.map(|r| r.streak).unwrap_or(None))
}
async fn set_streak<'a, E>(db: E, user: UserId, streak: i32) -> Result<(), Error>
where
E: PgExecutor<'a>,
{
sqlx::query("INSERT INTO dailies (userid, streak) VALUES ($1, $2) ON CONFLICT (userid) DO UPDATE SET streak = EXCLUDED.streak")
.bind(user.get() as i64)
.bind(streak)
.execute(db).await?;
pub async fn set_streak(conn: &mut PgConnection, user: UserId, streak: i32) -> Result<(), Error> {
sqlx::query!(
"INSERT INTO dailies (userid, streak) VALUES ($1, $2)
ON CONFLICT (userid) DO UPDATE SET streak = EXCLUDED.streak",
user.get() as i64,
streak
)
.execute(conn)
.await?;
Ok(())
}
async fn get_last<'a, E>(db: E, user: UserId) -> Result<Option<DateTime<Utc>>, Error>
where
E: PgExecutor<'a>,
{
match sqlx::query(
"SELECT last FROM dailies WHERE userid = $1"
).bind(user.get() as i64).fetch_one(db).await
{
Ok(row) => Ok(Some(row.get(0))),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(Box::new(e)),
}
pub async fn get_last(conn: &mut PgConnection, user: UserId) -> Result<Option<DateTime<Utc>>, Error> {
let result = sqlx::query!(
"SELECT last FROM dailies WHERE userid = $1",
user.get() as i64
)
.fetch_optional(conn)
.await?;
Ok(result.map(|r| r.last).unwrap_or(None))
}
async fn set_last<'a, E>(db: E, user: UserId, last: DateTime<Utc>) -> Result<(), Error>
where
E: PgExecutor<'a>,
{
sqlx::query("INSERT INTO dailies (userid, last) VALUES ($1, $2) ON CONFLICT (userid) DO UPDATE SET last = EXCLUDED.last")
.bind(user.get() as i64)
.bind(last)
.execute(db).await?;
pub async fn set_last(conn: &mut PgConnection, user: UserId, last: DateTime<Utc>) -> Result<(), Error> {
sqlx::query!(
"INSERT INTO dailies (userid, last) VALUES ($1, $2)
ON CONFLICT (userid) DO UPDATE SET last = EXCLUDED.last",
user.get() as i64,
last
)
.execute(conn)
.await?;
Ok(())
}
@@ -60,13 +56,14 @@ where
/// Tells you what your current daily streak is
#[poise::command(slash_command, prefix_command)]
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 {
Some(user) => (user.id, format!("{} has", user.display_name())),
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(())
}

View File

@@ -1,7 +1,6 @@
use crate::common::{Context, Error};
use poise::serenity_prelude::UserId;
use sqlx::Row;
enum LeaderboardType {
Tokens(usize),
@@ -13,15 +12,16 @@ async fn display_leaderboard(ctx: Context<'_>, t: LeaderboardType) -> Result<(),
match t {
LeaderboardType::Tokens(count) => {
let rows = sqlx::query(
let rows = sqlx::query!(
r#"
SELECT id, balance FROM bank
ORDER BY balance DESC
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();
for (id, balance) in users {
@@ -32,15 +32,16 @@ async fn display_leaderboard(ctx: Context<'_>, t: LeaderboardType) -> Result<(),
ctx.reply(format!("```\n{output}```")).await?;
}
LeaderboardType::Dailies(count) => {
let rows = sqlx::query(
let rows = sqlx::query!(
r#"
SELECT userid, streak FROM dailies
ORDER BY streak DESC
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();
for (id, streak) in users {

View File

@@ -9,7 +9,7 @@ pub mod blackjack;
use crate::{inventory::{self, Inventory}, common::{Context, Error}};
use poise::serenity_prelude::{self as serenity, futures::StreamExt, UserId};
use sqlx::{Row, PgExecutor};
use sqlx::PgConnection;
use std::collections::HashMap;
#[derive(Clone)]
@@ -79,16 +79,15 @@ mod items {
}
}
pub async fn get_balance<'a, E>(id: UserId, db: E) -> Result<i32, Error>
where
E: PgExecutor<'a>,
pub async fn get_balance(id: UserId, db: &mut PgConnection) -> Result<i32, Error>
{
let row = sqlx::query("SELECT balance FROM bank WHERE id = $1")
.bind(id.get() as i64)
.fetch_one(db).await.ok();
let row = sqlx::query!(
"SELECT balance FROM bank WHERE id = $1",
id.get() as i64
).fetch_one(db).await.ok();
let balance = if let Some(row) = row {
row.try_get("balance")?
row.balance.unwrap_or(100)
} else {
100
};
@@ -96,14 +95,13 @@ where
Ok(balance)
}
pub async fn change_balance<'a, E>(id: UserId, balance: i32, db: E) -> Result<(), Error>
where
E: PgExecutor<'a>,
pub async fn change_balance(id: UserId, balance: i32, db: &mut PgConnection) -> Result<(), Error>
{
sqlx::query("INSERT INTO bank (id, balance) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET balance = EXCLUDED.balance")
.bind(id.get() as i64)
.bind(balance)
.execute(db).await?;
sqlx::query!(
r#"INSERT INTO bank (id, balance) VALUES ($1, $2)
ON CONFLICT (id) DO UPDATE SET balance = EXCLUDED.balance"#,
id.get() as i64, balance
).execute(db).await?;
Ok(())
}

View File

@@ -16,8 +16,8 @@ async fn autocomplete_shop<'a>(
ctx: Context<'_>,
partial: &'a str,
) -> impl Iterator<Item = serenity::AutocompleteChoice> + use<'a> {
let db = &ctx.data().database;
let balance = super::get_balance(ctx.author().id, db).await;
let mut tx = ctx.data().database.begin().await.unwrap();
let balance = super::get_balance(ctx.author().id, &mut *tx).await;
ITEMS.values()
.filter(move |(_, item)| item.name.contains(partial))