baichun-framework-db 0.1.0

Database module for Baichun-Rust framework
Documentation
//! 数据库配置模块
//!
//! 本模块提供了数据库连接池的配置选项,支持自定义连接数、超时时间等参数。
//! 所有配置参数都有合理的默认值,可以根据实际需求进行调整。

use serde::{Deserialize, Serialize};
use sqlx::mysql::MySqlPoolOptions;
use std::time::Duration;

/// 数据库配置结构体
///
/// 用于配置数据库连接池的各项参数,包括连接 URL、连接数限制、超时设置等。
/// 所有字段都提供了默认值,可以只设置必要的参数。
///
/// # 示例
///
/// ```rust
/// use baichun_framework_db::DatabaseConfig;
///
/// let config = DatabaseConfig {
///     url: "mysql://user:pass@localhost/db_name".to_string(),
///     max_connections: 20,
///     min_connections: 5,
///     ..Default::default()
/// };
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
    /// 数据库连接 URL
    ///
    /// 支持以下格式:
    /// - MySQL: `mysql://user:pass@host:port/dbname`
    /// - PostgreSQL: `postgresql://user:pass@host:port/dbname`
    /// - SQLite: `sqlite:///path/to/db.sqlite`
    pub url: String,

    /// 连接池中的最大连接数
    ///
    /// 默认值为 CPU 核心数的 2 倍
    #[serde(default = "default_max_connections")]
    pub max_connections: u32,

    /// 连接池中的最小连接数
    ///
    /// 默认值为 CPU 核心数,最小为 1
    #[serde(default = "default_min_connections")]
    pub min_connections: u32,

    /// 连接超时时间(秒)
    ///
    /// 建立新连接时的超时时间,默认为 10 秒
    #[serde(default = "default_connect_timeout")]
    pub connect_timeout: u64,

    /// 连接最大生命周期(秒)
    ///
    /// 一个连接在连接池中的最长存活时间,默认为 1 小时
    #[serde(default = "default_max_lifetime")]
    pub max_lifetime: u64,

    /// 空闲连接超时时间(秒)
    ///
    /// 空闲连接在被关闭前的最长等待时间,默认为 10 分钟
    #[serde(default = "default_idle_timeout")]
    pub idle_timeout: u64,

    /// 获取连接超时时间(秒)
    ///
    /// 从连接池获取连接的最长等待时间,默认为 30 秒
    #[serde(default = "default_acquire_timeout")]
    pub acquire_timeout: u64,
}

impl DatabaseConfig {
    /// 创建一个新的数据库配置实例
    ///
    /// # 示例
    ///
    /// ```rust
    /// use baichun_framework_db::DatabaseConfig;
    ///
    /// let config = DatabaseConfig::new()
    ///     .url("mysql://user:pass@localhost/db_name")
    ///     .max_connections(20)
    ///     .min_connections(5);
    /// ```
    pub fn new() -> Self {
        Self {
            url: String::new(),
            max_connections: default_max_connections(),
            min_connections: default_min_connections(),
            connect_timeout: default_connect_timeout(),
            max_lifetime: default_max_lifetime(),
            idle_timeout: default_idle_timeout(),
            acquire_timeout: default_acquire_timeout(),
        }
    }

    /// 设置数据库连接 URL
    pub fn url<S: Into<String>>(mut self, url: S) -> Self {
        self.url = url.into();
        self
    }

    /// 设置最大连接数
    pub fn max_connections(mut self, max: u32) -> Self {
        self.max_connections = max;
        self
    }

    /// 设置最小连接数
    pub fn min_connections(mut self, min: u32) -> Self {
        self.min_connections = min;
        self
    }

    /// 设置连接超时时间(秒)
    pub fn connect_timeout(mut self, timeout: u64) -> Self {
        self.connect_timeout = timeout;
        self
    }

    /// 设置连接最大生命周期(秒)
    pub fn max_lifetime(mut self, lifetime: u64) -> Self {
        self.max_lifetime = lifetime;
        self
    }

    /// 设置空闲连接超时时间(秒)
    pub fn idle_timeout(mut self, timeout: u64) -> Self {
        self.idle_timeout = timeout;
        self
    }

    /// 设置获取连接超时时间(秒)
    pub fn acquire_timeout(mut self, timeout: u64) -> Self {
        self.acquire_timeout = timeout;
        self
    }

    /// 将配置转换为 SQLx 连接池选项
    pub fn into_pool_options(&self) -> MySqlPoolOptions {
        MySqlPoolOptions::new()
            .max_connections(self.max_connections)
            .min_connections(self.min_connections)
            .acquire_timeout(Duration::from_secs(self.acquire_timeout))
            .idle_timeout(Duration::from_secs(self.idle_timeout))
            .max_lifetime(Some(Duration::from_secs(self.max_lifetime)))
    }
}

impl Default for DatabaseConfig {
    fn default() -> Self {
        Self::new()
    }
}

fn default_max_connections() -> u32 {
    (num_cpus::get() * 2) as u32
}

fn default_min_connections() -> u32 {
    (num_cpus::get() as u32).max(1)
}

fn default_connect_timeout() -> u64 {
    10
}

fn default_max_lifetime() -> u64 {
    3600
}

fn default_idle_timeout() -> u64 {
    600
}

fn default_acquire_timeout() -> u64 {
    30
}