land_core/
db.rs

1use anyhow::Result;
2use envconfig::Envconfig;
3use land_migration::MigratorTrait;
4use once_cell::sync::OnceCell;
5use sea_orm::{ConnectOptions, Database, DatabaseConnection};
6use serde::{Deserialize, Serialize};
7use std::time::Duration;
8use tracing::{debug, info};
9
10#[derive(Envconfig, Debug, Serialize, Deserialize)]
11pub struct DbConfig {
12    #[envconfig(from = "DB_HOST", default = "localhost")]
13    pub host: String,
14    #[envconfig(from = "DB_PORT", default = "3306")]
15    pub port: u16,
16    #[envconfig(from = "DB_USER", default = "root")]
17    pub user: String,
18    #[envconfig(from = "DB_PASSWORD", default = "")]
19    pub password: String,
20    #[envconfig(from = "DB_NAME", default = "land-serverless")]
21    pub database: String,
22    #[envconfig(from = "DB_POOL_SIZE", default = "10")]
23    pub pool_size: u32,
24}
25
26impl DbConfig {
27    pub fn url(&self) -> String {
28        format!(
29            "mysql://{}:{}@{}:{}/{}",
30            self.user, self.password, self.host, self.port, self.database
31        )
32    }
33    pub fn url_safe(&self) -> String {
34        format!(
35            "mysql://{}:{}@{}:{}/{}",
36            self.user, "******", self.host, self.port, self.database
37        )
38    }
39}
40
41impl Default for DbConfig {
42    fn default() -> Self {
43        Self {
44            host: "localhost".to_string(),
45            port: 3306,
46            user: "root".to_string(),
47            password: "".to_string(),
48            database: "moss-serverless".to_string(),
49            pool_size: 10,
50        }
51    }
52}
53
54/// DB connection pool
55pub static DB: OnceCell<DatabaseConnection> = OnceCell::new();
56
57/// init initializes database connection pool
58#[tracing::instrument(name = "[DB]")]
59pub async fn init() -> Result<()> {
60    let cfg = DbConfig::init_from_env().unwrap();
61    debug!("Connecting: {}", cfg.url_safe());
62
63    let mut opt = ConnectOptions::new(cfg.url());
64    opt.max_connections(cfg.pool_size)
65        .min_connections(3)
66        .connect_timeout(Duration::from_secs(10))
67        .acquire_timeout(Duration::from_secs(10))
68        .idle_timeout(Duration::from_secs(600))
69        .max_lifetime(Duration::from_secs(1800))
70        .sqlx_logging(true);
71
72    let db = Database::connect(opt).await?;
73
74    // run migrations
75    land_migration::Migrator::up(&db, None).await?;
76
77    DB.set(db).unwrap();
78    info!("Init success: {}", cfg.url_safe());
79    Ok(())
80}