pub use account_orders::*; pub use accounts::*; use actix::{Actor, Context}; pub use order_items::*; pub use products::*; pub use shopping_cart_items::*; pub use shopping_carts::*; use sqlx::PgPool; pub use stocks::*; pub use tokens::*; use crate::config::SharedAppConfig; pub mod account_orders; pub mod accounts; pub mod order_items; pub mod products; pub mod shopping_cart_items; pub mod shopping_carts; pub mod stocks; pub mod tokens; #[macro_export] macro_rules! db_async_handler { ($msg: ty, $async: ident, $res: ty) => { impl actix::Handler<$msg> for Database { type Result = actix::ResponseActFuture>; fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result { use actix::WrapFuture; let pool = self.pool.clone(); Box::pin(async { $async(msg, pool).await }.into_actor(self)) } } }; } #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Failed to connect to database. {0:?}")] Connect(#[from] sqlx::Error), #[error("{0}")] Account(#[from] accounts::Error), #[error("{0}")] AccountOrder(#[from] account_orders::Error), #[error("{0}")] Product(#[from] products::Error), #[error("{0}")] Stock(#[from] stocks::Error), #[error("{0}")] OrderItem(#[from] order_items::Error), #[error("{0}")] ShoppingCart(#[from] shopping_carts::Error), #[error("{0}")] ShoppingCartItem(#[from] shopping_cart_items::Error), #[error("{0}")] Token(#[from] tokens::Error), } pub type Result = std::result::Result; pub struct Database { pool: PgPool, } pub type SharedDatabase = actix::Addr; impl Clone for Database { fn clone(&self) -> Self { Self { pool: self.pool.clone(), } } } impl Database { pub(crate) async fn build(config: SharedAppConfig) -> Result { let url = config.lock().database().url(); let pool = sqlx::PgPool::connect(&url).await.map_err(Error::Connect)?; Ok(Database { pool }) } pub fn pool(&self) -> &PgPool { &self.pool } } impl Actor for Database { type Context = Context; }