use db_utils::PgT; use model::v2::*; #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Failed to create product")] CreateProductVariant, #[error("Failed to load variants for products {0:?}")] ProductsVariants(Vec), #[error("Failed to delete product variant {0:?}")] DeleteProductVariant(ProductVariantId), } pub type Result = std::result::Result; #[derive(Debug)] pub struct CreateProductVariant { pub product_id: ProductId, pub name: ProductName, pub short_description: ProductShortDesc, pub long_description: ProductLongDesc, pub price: Price, } impl CreateProductVariant { pub async fn run(self, pool: &mut PgT<'_>) -> Result { sqlx::query_as( r#" INSERT INTO product_variants ( product_id, name, short_description, long_description, price ) VALUES ($1, $2, $3, $4, $5) RETURNING id, product_id, name, short_description, long_description, price "#, ) .bind(self.product_id) .bind(self.name) .bind(self.short_description) .bind(self.long_description) .bind(self.price) .fetch_one(pool) .await .map_err(|e| { tracing::error!("{}", e); dbg!(e); Error::CreateProductVariant }) } } #[derive(Debug)] pub struct ProductsVariants { pub product_ids: Vec, pub limit: Option, pub offset: Option, } impl ProductsVariants { pub async fn run(self, pool: &mut PgT<'_>) -> Result> { db_utils::MultiLoad::new( pool, r#" SELECT pv.id, pv.product_id, pv.name, pv.short_description, pv.long_description, pv.price FROM product_variants pv INNER JOIN products ps ON pv.product_id = ps.id WHERE "#, "products.id = ", ) .allow_over_max() .with_size(1000) .load( self.product_ids.len(), self.product_ids.iter().copied().map(|id| *id), |_| Error::ProductsVariants(self.product_ids.clone()), ) .await } } #[derive(Debug)] pub struct DeleteProductVariant { pub product_variant_id: ProductVariantId, } impl DeleteProductVariant { pub async fn run(self, pool: &mut PgT<'_>) -> Result> { sqlx::query_as( r#" DELETE FROM product_variants WHERE id = $1 "#, ) .bind(self.product_variant_id) .fetch_optional(pool) .await .map_err(|_e| Error::DeleteProductVariant(self.product_variant_id)) } }