predawn_sea_orm/
config.rs1use 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}