use crate::{db_async_handler, Result}; #[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)] pub enum Error { #[error("Can't load account addresses")] AccountAddresses, #[error("Failed to save account address")] CreateAccountAddress, } #[derive(actix::Message)] #[rtype(result = "Result>")] pub struct AccountAddresses { pub account_id: model::AccountId, } db_async_handler!( AccountAddresses, account_addresses, Vec, inner_account_addresses ); pub(crate) async fn account_addresses( msg: AccountAddresses, pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result> { sqlx::query_as( r#" SELECT id, name, email, street, city, country, zip, account_id, is_default FROM account_addresses WHERE account_id = $1 "#, ) .bind(msg.account_id) .fetch_all(pool) .await .map_err(|_| Error::AccountAddresses.into()) } //// #[derive(actix::Message)] #[rtype(result = "Result")] pub struct FindAccountAddress { pub account_id: model::AccountId, pub address_id: model::AddressId, } db_async_handler!( FindAccountAddress, find_account_address, model::AccountAddress, inner_find_account_address ); pub(crate) async fn find_account_address( msg: FindAccountAddress, pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result { sqlx::query_as( r#" SELECT id, name, email, street, city, country, zip, account_id, is_default FROM account_addresses WHERE account_id = $1 AND id = $2 "#, ) .bind(msg.account_id) .bind(msg.address_id) .fetch_one(pool) .await .map_err(|_| Error::AccountAddresses.into()) } ///// #[derive(actix::Message)] #[rtype(result = "Result")] pub struct DefaultAccountAddress { pub account_id: model::AccountId, } db_async_handler!( DefaultAccountAddress, default_account_address, model::AccountAddress, inner_default_account_address ); pub(crate) async fn default_account_address( msg: DefaultAccountAddress, pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result { sqlx::query_as( r#" SELECT id, name, email, street, city, country, zip, account_id, is_default FROM account_addresses WHERE account_id = $1 AND is_default "#, ) .bind(msg.account_id) .fetch_one(pool) .await .map_err(|_| Error::AccountAddresses.into()) } #[derive(actix::Message)] #[rtype(result = "Result")] pub struct CreateAccountAddress { pub name: model::Name, pub email: model::Email, pub street: model::Street, pub city: model::City, pub country: model::Country, pub zip: model::Zip, pub account_id: Option, pub is_default: bool, } db_async_handler!( CreateAccountAddress, create_address, model::AccountAddress, inner_create_address ); pub(crate) async fn create_address( msg: CreateAccountAddress, pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result { if msg.is_default { if let Err(e) = sqlx::query( r#" UPDATE account_addresses SET is_default = FALSE WHERE account_id = $1 "#, ) .bind(msg.account_id) .fetch_all(&mut *pool) .await { log::error!("{}", e); } } sqlx::query_as( r#" INSERT INTO account_addresses ( name, email, street, city, country, zip, account_id ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, name, email, street, city, country, zip, account_id, is_default "#, ) .bind(msg.name) .bind(msg.email) .bind(msg.street) .bind(msg.city) .bind(msg.country) .bind(msg.zip) .bind(msg.account_id) .fetch_one(pool) .await .map_err(|_| Error::CreateAccountAddress.into()) } #[derive(actix::Message)] #[rtype(result = "Result")] pub struct UpdateAccountAddress { pub id: model::AddressId, pub name: model::Name, pub email: model::Email, pub street: model::Street, pub city: model::City, pub country: model::Country, pub zip: model::Zip, pub account_id: model::AccountId, pub is_default: bool, } db_async_handler!( UpdateAccountAddress, update_account_address, model::AccountAddress, inner_update_account_address ); pub(crate) async fn update_account_address( msg: UpdateAccountAddress, pool: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result { sqlx::query_as( r#" UPDATE account_addresses SET name = $2, email = $3, street = $4, city = $5, country = $6, zip = $7, account_id = $8, is_default = $9 WHERE id = $1 RETURNING id, name, email, street, city, country, zip, account_id, is_default "#, ) .bind(msg.id) .bind(msg.name) .bind(msg.email) .bind(msg.street) .bind(msg.city) .bind(msg.country) .bind(msg.zip) .bind(msg.account_id) .bind(msg.is_default) .fetch_one(pool) .await .map_err(|_| Error::CreateAccountAddress.into()) }