pub mod mysql_client;
pub mod with_mysql;
pub use mysql_client::*;
pub use with_mysql::*;
use sqlx::mysql::MySqlConnectOptions;
use sqlx::mysql::MySqlPoolOptions;
use sqlx::mysql::MySqlSslMode;
use sqlx::ConnectOptions;
use sqlx::MySql;
use sqlx::Pool;
#[derive(serde::Deserialize, Clone)]
pub struct MysqlSettings {
pub enable: Option<bool>,
pub username: Option<String>,
pub password: Option<String>,
pub port: Option<u16>,
pub host: Option<String>,
pub database_name: Option<String>,
pub require_ssl: Option<bool>,
pub mappers: Option<String>,
}
impl Default for MysqlSettings {
fn default() -> Self {
Self {
enable: Some(false),
username: Some(String::from("root")),
password: Some(String::from("Cc")),
port: Some(3306),
host: Some(String::from("127.0.0.1")),
database_name: Some(String::from("mysql")),
require_ssl: Some(false),
mappers: Some(String::from("./resources/mappers/**/*.yaml")),
}
}
}
impl MysqlSettings {
pub fn enabled(&self) -> bool {
self.enable.unwrap_or_default()
}
pub fn get(settings: &Option<MysqlSettings>) -> Self {
let _default = Self::default();
if settings.is_some() {
let mut s = settings.clone().unwrap();
if s.enable.is_none() {
s.enable = _default.enable;
}
if s.username.is_none() {
s.username = _default.username;
}
if s.password.is_none() {
s.password = _default.password;
}
if s.port.is_none() {
s.port = _default.port;
}
if s.host.is_none() {
s.host = _default.host;
}
if s.database_name.is_none() {
s.database_name = _default.database_name;
}
if s.require_ssl.is_none() {
s.require_ssl = _default.require_ssl;
}
if s.mappers.is_none() {
s.mappers = _default.mappers;
}
s
} else {
_default
}
}
pub fn connection_string_with_secret(&self) -> String {
format!(
"mysql://{}:{}@{}:{}/{}",
self.username.clone().unwrap(),
"*******",
self.host.clone().unwrap(),
self.port.unwrap(),
self.database_name.clone().unwrap()
)
}
pub fn without_db(&self) -> MySqlConnectOptions {
let ssl_mode = if self.require_ssl.unwrap() {
MySqlSslMode::Required
} else {
MySqlSslMode::Preferred
};
MySqlConnectOptions::new()
.host(&self.host.clone().unwrap())
.username(&self.username.clone().unwrap())
.password(&self.password.clone().unwrap())
.port(self.port.unwrap())
.ssl_mode(ssl_mode)
}
pub fn with_db(&self) -> MySqlConnectOptions {
self.without_db()
.database(&self.database_name.clone().unwrap())
.log_statements(log::LevelFilter::Info)
}
pub fn connect(&self) -> Pool<MySql> {
self.log();
MySqlPoolOptions::new()
.acquire_timeout(std::time::Duration::from_secs(2))
.connect_lazy_with(self.with_db())
}
fn log(&self) {
let line = format!(
"MySqlConnect: connection_string={}, mappers={}",
self.connection_string_with_secret(),
self.mappers.as_deref().unwrap_or_default()
);
if !crate::core::cacheable::exists2s(&line) {
log::info!("{}", line);
crate::core::cacheable::put2s(&line, "");
}
}
}
#[derive(Debug)]
pub enum Ordering {
Asc(String),
Desc(String),
}
impl Ordering {
pub fn order_by(order_by: &str) -> String {
let order_by: Vec<Ordering> = crate::commons::split_str(order_by, ",".to_string())
.iter()
.map(|s| s.trim())
.map(|s| match s.find(' ') {
None => Ordering::Asc(s.to_string()),
Some(i) => {
if s[i + 1..].trim().to_lowercase() == "asc" {
Ordering::Asc(s[..i].trim().to_string())
} else {
Ordering::Desc(s[..i].trim().to_string())
}
}
})
.collect();
let mut result = vec![];
for order in order_by {
match order {
Ordering::Asc(field) => {
if !field.is_empty() {
result.push(format!("{} asc", field))
}
}
Ordering::Desc(field) => {
if !field.is_empty() {
result.push(format!("{} desc", field))
}
}
}
}
if result.is_empty() {
"".to_string()
} else {
format!(" ORDER BY {}", result.join(", "))
}
}
}