use serde::{Deserialize, Serialize};
use std::env;
#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum DatabaseType {
Postgres,
MySQL,
SQLite,
MongoDB,
Redis,
}
impl Default for DatabaseType {
fn default() -> Self {
DatabaseType::Postgres
}
}
impl std::fmt::Display for DatabaseType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DatabaseType::Postgres => write!(f, "postgresql"),
DatabaseType::MySQL => write!(f, "mysql"),
DatabaseType::SQLite => write!(f, "sqlite"),
DatabaseType::MongoDB => write!(f, "mongodb"),
DatabaseType::Redis => write!(f, "redis"),
}
}
}
#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RiDatabaseConfig {
pub database_type: DatabaseType,
pub host: String,
pub port: u16,
pub database: String,
pub username: String,
pub password: String,
pub max_connections: u32,
pub min_idle_connections: u32,
pub connection_timeout_secs: u64,
pub idle_timeout_secs: u64,
pub max_lifetime_secs: u64,
pub ssl_mode: SslMode,
pub statement_cache_size: u32,
}
#[cfg(feature = "pyo3")]
#[pyo3::prelude::pymethods]
impl RiDatabaseConfig {
#[new]
fn py_new(
database_type: DatabaseType,
host: String,
port: u16,
database: String,
username: String,
password: String,
max_connections: u32,
min_idle_connections: u32,
connection_timeout_secs: u64,
idle_timeout_secs: u64,
max_lifetime_secs: u64,
ssl_mode: SslMode,
statement_cache_size: u32,
) -> Self {
Self {
database_type,
host,
port,
database,
username,
password,
max_connections,
min_idle_connections,
connection_timeout_secs,
idle_timeout_secs,
max_lifetime_secs,
ssl_mode,
statement_cache_size,
}
}
#[staticmethod]
fn create_postgres() -> Self {
Self::postgres()
}
#[staticmethod]
fn create_mysql() -> Self {
Self::mysql()
}
#[staticmethod]
fn create_sqlite() -> Self {
Self::sqlite(":memory:")
}
fn get_database_type(&self) -> DatabaseType {
self.database_type
}
fn set_database_type(&self, _database_type: DatabaseType) {
}
fn get_host(&self) -> String {
self.host.clone()
}
fn set_host(&mut self, host: String) {
self.host = host;
}
fn get_port(&self) -> u16 {
self.port
}
fn set_port(&mut self, port: u16) {
self.port = port;
}
fn get_database(&self) -> String {
self.database.clone()
}
fn set_database(&mut self, database: String) {
self.database = database;
}
fn get_username(&self) -> String {
self.username.clone()
}
fn set_username(&mut self, username: String) {
self.username = username;
}
fn get_password(&self) -> String {
self.password.clone()
}
fn set_password(&mut self, password: String) {
self.password = password;
}
fn get_max_connections(&self) -> u32 {
self.max_connections
}
fn set_max_connections(&mut self, max_connections: u32) {
self.max_connections = max_connections;
}
fn get_min_idle_connections(&self) -> u32 {
self.min_idle_connections
}
fn set_min_idle_connections(&mut self, min_idle_connections: u32) {
self.min_idle_connections = min_idle_connections;
}
}
#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SslMode {
Disable,
Prefer,
Require,
}
impl Default for SslMode {
fn default() -> Self {
SslMode::Prefer
}
}
impl RiDatabaseConfig {
pub fn postgres() -> Self {
Self {
database_type: DatabaseType::Postgres,
host: env::var("Ri_DB_HOST").unwrap_or_else(|_| "localhost".to_string()),
port: env::var("Ri_DB_PORT")
.unwrap_or_else(|_| "5432".to_string())
.parse()
.unwrap_or(5432),
database: env::var("Ri_DB_NAME").unwrap_or_else(|_| "ri".to_string()),
username: env::var("Ri_DB_USER").unwrap_or_else(|_| "ri".to_string()),
password: env::var("Ri_DB_PASSWORD").unwrap_or_else(|_| "".to_string()),
max_connections: 10,
min_idle_connections: 2,
connection_timeout_secs: 30,
idle_timeout_secs: 600,
max_lifetime_secs: 3600,
ssl_mode: SslMode::Prefer,
statement_cache_size: 100,
}
}
pub fn mysql() -> Self {
Self {
database_type: DatabaseType::MySQL,
host: env::var("Ri_DB_HOST").unwrap_or_else(|_| "localhost".to_string()),
port: env::var("Ri_DB_PORT")
.unwrap_or_else(|_| "3306".to_string())
.parse()
.unwrap_or(3306),
database: env::var("Ri_DB_NAME").unwrap_or_else(|_| "ri".to_string()),
username: env::var("Ri_DB_USER").unwrap_or_else(|_| "ri".to_string()),
password: env::var("Ri_DB_PASSWORD").unwrap_or_else(|_| "".to_string()),
max_connections: 10,
min_idle_connections: 2,
connection_timeout_secs: 30,
idle_timeout_secs: 600,
max_lifetime_secs: 3600,
ssl_mode: SslMode::Prefer,
statement_cache_size: 100,
}
}
pub fn sqlite(path: &str) -> Self {
Self {
database_type: DatabaseType::SQLite,
host: "".to_string(),
port: 0,
database: path.to_string(),
username: "".to_string(),
password: "".to_string(),
max_connections: 10,
min_idle_connections: 1,
connection_timeout_secs: 30,
idle_timeout_secs: 600,
max_lifetime_secs: 3600,
ssl_mode: SslMode::Disable,
statement_cache_size: 100,
}
}
pub fn host(mut self, host: &str) -> Self {
self.host = host.to_string();
self
}
pub fn port(mut self, port: u16) -> Self {
self.port = port;
self
}
pub fn database(mut self, database: &str) -> Self {
self.database = database.to_string();
self
}
pub fn user(mut self, user: &str) -> Self {
self.username = user.to_string();
self
}
pub fn password(mut self, password: &str) -> Self {
self.password = password.to_string();
self
}
pub fn max_connections(mut self, max: u32) -> Self {
self.max_connections = max;
self
}
pub fn min_idle_connections(mut self, min: u32) -> Self {
self.min_idle_connections = min;
self
}
pub fn connection_timeout_secs(mut self, secs: u64) -> Self {
self.connection_timeout_secs = secs;
self
}
pub fn idle_timeout_secs(mut self, secs: u64) -> Self {
self.idle_timeout_secs = secs;
self
}
pub fn max_lifetime_secs(mut self, secs: u64) -> Self {
self.max_lifetime_secs = secs;
self
}
pub fn ssl_mode(mut self, mode: SslMode) -> Self {
self.ssl_mode = mode;
self
}
pub fn statement_cache_size(mut self, size: u32) -> Self {
self.statement_cache_size = size;
self
}
pub fn build(self) -> RiDatabaseConfig {
self
}
pub fn connection_string(&self) -> String {
match self.database_type {
DatabaseType::Postgres => {
format!(
"postgresql://{}:{}@{}:{}/{}",
self.username, self.password, self.host, self.port, self.database
)
}
DatabaseType::MySQL => {
format!(
"mysql://{}:{}@{}:{}/{}",
self.username, self.password, self.host, self.port, self.database
)
}
DatabaseType::SQLite => self.database.clone(),
DatabaseType::MongoDB => {
format!(
"mongodb://{}:{}@{}:{}/{}",
self.username, self.password, self.host, self.port, self.database
)
}
DatabaseType::Redis => {
format!(
"redis://{}:{}@{}:{}",
self.username, self.password, self.host, self.port
)
}
}
}
}
impl Default for RiDatabaseConfig {
fn default() -> Self {
Self::postgres()
}
}