1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
use chrono::{DateTime, Utc}; use serde_json::Value as JsonValue; #[derive(Debug, PartialEq, Clone, sqlx::FromRow)] pub struct Coupon { pub coupon: String, pub discount: JsonValue, pub remaining: i32, pub email: Option<String>, pub valid_until: Option<DateTime<Utc>>, pub created_at: DateTime<Utc>, } pub async fn fetch_for_update<'e>( coupon: &str, conn: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<Option<Coupon>, sqlx::Error> { sqlx::query_as("SELECT * FROM coupons WHERE coupon = $1 FOR UPDATE") .bind(coupon) .fetch_optional(conn) .await } pub async fn decrease_remaining<'e>( coupon: &str, conn: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<(), sqlx::Error> { sqlx::query("UPDATE coupons SET remaining = remaining - 1 WHERE coupon = $1") .bind(coupon) .execute(conn) .await?; Ok(()) }