predawn_sea_orm/
config.rs

1use std::{collections::HashMap, time::Duration};
2
3use predawn::config::{logger::LogLevel, Config, ConfigPrefix};
4use rudi::Singleton;
5use serde::{Deserialize, Serialize};
6use url::Url;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct DataSourcesConfig {
10    #[serde(flatten)]
11    pub data_sources: HashMap<String, Options>,
12}
13
14#[Singleton]
15impl DataSourcesConfig {
16    #[di]
17    pub fn new(#[di(ref)] config: &Config) -> Self {
18        config.get().expect("failed to load `DataSourcesConfig`")
19    }
20}
21
22impl ConfigPrefix for DataSourcesConfig {
23    const PREFIX: &'static str = "data_sources";
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
27#[serde(untagged)]
28pub enum Options {
29    Simple(Url),
30    Detailed(Box<ConnectOptions>),
31}
32
33impl From<Options> for sea_orm::ConnectOptions {
34    fn from(options: Options) -> Self {
35        match options {
36            Options::Simple(url) => sea_orm::ConnectOptions::new(url),
37            Options::Detailed(connect_options) => (*connect_options).into(),
38        }
39    }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(deny_unknown_fields)]
44pub struct SlowStatementsLoggingSettings {
45    #[serde(default)]
46    pub level: LogLevel,
47    #[serde(deserialize_with = "duration_str::deserialize_duration")]
48    #[serde(default)]
49    pub threshold: Duration,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53#[serde(deny_unknown_fields)]
54pub struct ConnectOptions {
55    pub url: Url,
56    #[serde(default)]
57    pub username: Option<String>,
58    #[serde(default)]
59    pub password: Option<String>,
60
61    #[serde(default)]
62    pub max_connections: Option<u32>,
63    #[serde(default)]
64    pub min_connections: Option<u32>,
65
66    #[serde(deserialize_with = "duration_str::deserialize_option_duration")]
67    #[serde(default)]
68    pub connect_timeout: Option<Duration>,
69    #[serde(deserialize_with = "duration_str::deserialize_option_duration")]
70    #[serde(default)]
71    pub idle_timeout: Option<Duration>,
72    #[serde(deserialize_with = "duration_str::deserialize_option_duration")]
73    #[serde(default)]
74    pub acquire_timeout: Option<Duration>,
75    #[serde(deserialize_with = "duration_str::deserialize_option_duration")]
76    #[serde(default)]
77    pub max_lifetime: Option<Duration>,
78
79    #[serde(default)]
80    pub sqlx_logging: Option<bool>,
81    #[serde(default)]
82    pub sqlx_logging_level: Option<LogLevel>,
83    #[serde(default)]
84    pub sqlx_slow_statements_logging_settings: Option<SlowStatementsLoggingSettings>,
85
86    #[serde(default)]
87    pub sqlcipher_key: Option<String>,
88    #[serde(default)]
89    pub schema_search_path: Option<String>,
90    #[serde(default)]
91    pub test_before_acquire: Option<bool>,
92    #[serde(default)]
93    pub connect_lazy: Option<bool>,
94}
95
96impl From<ConnectOptions> for sea_orm::ConnectOptions {
97    fn from(options: ConnectOptions) -> Self {
98        let ConnectOptions {
99            mut url,
100            username,
101            password,
102            max_connections,
103            min_connections,
104            connect_timeout,
105            idle_timeout,
106            acquire_timeout,
107            max_lifetime,
108            sqlx_logging,
109            sqlx_logging_level,
110            sqlx_slow_statements_logging_settings,
111            sqlcipher_key,
112            schema_search_path,
113            test_before_acquire,
114            connect_lazy,
115        } = options;
116
117        if let Some(username) = username {
118            url.set_username(&username)
119                .unwrap_or_else(|_| panic!("failed to set username: {username} to url: {url}"));
120        }
121
122        if let Some(password) = password {
123            url.set_password(Some(&password))
124                .unwrap_or_else(|_| panic!("failed to set password: {password} to url: {url}"));
125        }
126
127        let mut options = sea_orm::ConnectOptions::new(url.to_string());
128
129        if let Some(max_connections) = max_connections {
130            options.max_connections(max_connections);
131        }
132
133        if let Some(min_connections) = min_connections {
134            options.min_connections(min_connections);
135        }
136
137        if let Some(connect_timeout) = connect_timeout {
138            options.connect_timeout(connect_timeout);
139        }
140
141        if let Some(idle_timeout) = idle_timeout {
142            options.idle_timeout(idle_timeout);
143        }
144
145        if let Some(acquire_timeout) = acquire_timeout {
146            options.acquire_timeout(acquire_timeout);
147        }
148
149        if let Some(max_lifetime) = max_lifetime {
150            options.max_lifetime(max_lifetime);
151        }
152
153        if let Some(sqlx_logging) = sqlx_logging {
154            options.sqlx_logging(sqlx_logging);
155        }
156
157        if let Some(sqlx_logging_level) = sqlx_logging_level {
158            options.sqlx_logging_level(sqlx_logging_level.as_log_level_filter());
159        }
160
161        if let Some(SlowStatementsLoggingSettings { level, threshold }) =
162            sqlx_slow_statements_logging_settings
163        {
164            options.sqlx_slow_statements_logging_settings(level.as_log_level_filter(), threshold);
165        }
166
167        if let Some(sqlcipher_key) = sqlcipher_key {
168            options.sqlcipher_key(sqlcipher_key);
169        }
170
171        if let Some(schema_search_path) = schema_search_path {
172            options.set_schema_search_path(schema_search_path);
173        }
174
175        if let Some(test_before_acquire) = test_before_acquire {
176            options.test_before_acquire(test_before_acquire);
177        }
178
179        if let Some(connect_lazy) = connect_lazy {
180            options.connect_lazy(connect_lazy);
181        }
182
183        options
184    }
185}