inspirer_foundation/component/
database.rs1use crate::service::Service;
2use crate::{Error, Result};
3use sea_orm::{Database, DatabaseConnection};
4use std::env;
5use std::ops::Deref;
6
7pub use sea_orm::ConnectionTrait;
8
9use super::config::{Config, ConfigAdapter};
10use super::ComponentConstructor;
11
12pub async fn create_connection(database_url: &str) -> Result<DatabaseConnection> {
13 Database::connect(database_url).await.map_err(Into::into)
14}
15
16pub struct DatabaseComponentConstructor;
17
18#[async_trait]
19impl ComponentConstructor for DatabaseComponentConstructor {
20 async fn constructor(&self, service: Service) -> Result<()> {
21 let database_url = match service.try_get_component::<Config>().await {
22 Some(config) => config
23 .try_get::<String>("database.connection_url")
24 .await
25 .map(|res| res.or_else(|| env::var("DATABASE_URL").ok()))?,
26 None => env::var("DATABASE_URL").ok(),
27 };
28
29 if let Some(database_url) = database_url {
30 service
31 .register_component(create_connection(database_url.as_str()).await?)
32 .await;
33
34 Ok(())
35 } else {
36 log::error!("Get connection configuration field failed.");
37 Err(Error::GetConfigurationFailedError)
38 }
39 }
40}
41
42#[async_trait]
43pub trait DaoService {
44 async fn database_connection(&self) -> DatabaseConnection;
45}
46
47#[async_trait]
48impl DaoService for Service {
49 async fn database_connection(&self) -> DatabaseConnection {
50 self.component::<DatabaseConnection>().await
51 }
52}
53
54pub struct Dao<'a, C: ConnectionTrait>(pub &'a C);
55
56impl<'a, C> Deref for Dao<'a, C>
57where
58 C: ConnectionTrait,
59{
60 type Target = C;
61
62 fn deref(&self) -> &Self::Target {
63 self.0
64 }
65}