use std::collections::HashMap;
use sqlx::mysql::{MySqlConnectOptions, MySqlPool, MySqlPoolOptions, MySqlSslMode};
use crate::config::{Config, IntoMysqlName, MysqlConfig};
pub fn ssl_mode_from_str(s: &str) -> MySqlSslMode {
match s.trim().to_ascii_lowercase().as_str() {
"disabled" | "disable" | "off" => MySqlSslMode::Disabled,
"required" | "require" => MySqlSslMode::Required,
"verify-ca" | "verify_ca" => MySqlSslMode::VerifyCa,
"verify-identity" | "verify_identity" => MySqlSslMode::VerifyIdentity,
_ => MySqlSslMode::Preferred,
}
}
pub fn connect_options(cfg: &MysqlConfig) -> MySqlConnectOptions {
let mut opts = MySqlConnectOptions::new()
.host(&cfg.host)
.port(cfg.port)
.username(&cfg.user)
.password(&cfg.password)
.ssl_mode(ssl_mode_from_str(&cfg.ssl_mode));
if !cfg.database.is_empty() {
opts = opts.database(&cfg.database);
}
opts
}
pub async fn connect(cfg: &MysqlConfig) -> anyhow::Result<MySqlPool> {
let pool = MySqlPoolOptions::new()
.max_connections(cfg.max_connections)
.connect_with(connect_options(cfg))
.await?;
Ok(pool)
}
pub struct MysqlPools {
pools: HashMap<String, MySqlPool>,
}
impl MysqlPools {
pub async fn from_config(cfg: &Config) -> anyhow::Result<Self> {
let mut pools = HashMap::new();
for (name, mc) in &cfg.mysql {
pools.insert(name.clone(), connect(mc).await?);
}
Ok(Self { pools })
}
pub fn get(&self, name: impl IntoMysqlName) -> Option<&MySqlPool> {
self.pools.get(&name.into_name())
}
pub fn require(&self, name: impl IntoMysqlName) -> anyhow::Result<&MySqlPool> {
let name = name.into_name();
self.pools
.get(&name)
.ok_or_else(|| anyhow::anyhow!("未找到名为 `{}` 的 MySQL 连接", name))
}
pub fn default(&self) -> anyhow::Result<&MySqlPool> {
self.require("default")
}
}