1use std::env;
2
3#[derive(Debug, Clone)]
4pub struct DbConfig {
5 pub host: String,
6 pub name: String,
7 pub user: String,
8 pub pass: String,
9 pub port: u16,
10 pub min_pool_size: u32,
11 pub max_pool_size: u32,
12 pub idle_in_transaction_session: u32,
13 pub app_name: String,
14}
15
16pub struct DbConfigBuilder {
17 host: Option<String>,
18 name: Option<String>,
19 user: Option<String>,
20 pass: Option<String>,
21 port: Option<u16>,
22 min_pool_size: Option<u32>,
23 max_pool_size: Option<u32>,
24 idle_in_transaction_session: Option<u32>,
25 app_name: Option<String>,
26}
27
28impl DbConfigBuilder {
29 pub fn new() -> Self {
30 Self {
31 host: None,
32 name: None,
33 user: None,
34 pass: None,
35 port: None,
36 min_pool_size: None,
37 max_pool_size: None,
38 idle_in_transaction_session: None,
39 app_name: None,
40 }
41 }
42
43 pub fn host(mut self, host: &str) -> Self {
44 self.host = Some(host.to_string());
45 self
46 }
47
48 pub fn name(mut self, name: &str) -> Self {
49 self.name = Some(name.to_string());
50 self
51 }
52
53 pub fn user(mut self, user: &str) -> Self {
54 self.user = Some(user.to_string());
55 self
56 }
57
58 pub fn pass(mut self, pass: &str) -> Self {
59 self.pass = Some(pass.to_string());
60 self
61 }
62
63 pub fn port(mut self, port: u16) -> Self {
64 self.port = Some(port);
65 self
66 }
67
68 pub fn min_pool_size(mut self, min_pool_size: u32) -> Self {
69 self.min_pool_size = Some(min_pool_size);
70 self
71 }
72
73 pub fn max_pool_size(mut self, max_pool_size: u32) -> Self {
74 self.max_pool_size = Some(max_pool_size);
75 self
76 }
77
78 pub fn idle_in_transaction_session(mut self, idle: u32) -> Self {
79 self.idle_in_transaction_session = Some(idle);
80 self
81 }
82
83 pub fn app_name(mut self, app_name: &str) -> Self {
84 self.app_name = Some(app_name.to_string());
85 self
86 }
87
88 pub fn build(self) -> Result<DbConfig, &'static str> {
89 Ok(DbConfig {
90 host: self.host.ok_or("host is required")?,
91 name: self.name.ok_or("name is required")?,
92 user: self.user.ok_or("user is required")?,
93 pass: self.pass.ok_or("pass is required")?,
94 port: self.port.ok_or("port is required")?,
95 min_pool_size: self.min_pool_size.ok_or("min_pool_size is required")?,
96 max_pool_size: self.max_pool_size.ok_or("max_pool_size is required")?,
97 idle_in_transaction_session: self
98 .idle_in_transaction_session
99 .ok_or("idle_in_transaction_session is required")?,
100 app_name: self.app_name.ok_or("app_name is required")?,
101 })
102 }
103}
104
105impl DbConfig {
106 pub fn from_env() -> Self {
107 let db_host = env::var("DB_HOST").expect("DB_HOST not present");
108 let db_name = env::var("DB_NAME").expect("DB_NAME not present");
109 let db_user = env::var("DB_USER").expect("DB_USER not present");
110 let db_pass = env::var("DB_PASS").expect("DB_PASS not present");
111 let db_port = env::var("DB_PORT")
112 .ok()
113 .and_then(|s| s.parse::<u16>().ok())
114 .unwrap_or(5432);
115 let db_min_pool_size = env::var("DB_MIN_POOL_SIZE")
116 .ok()
117 .and_then(|s| s.parse::<u32>().ok())
118 .unwrap_or(1);
119 let db_max_pool_size = env::var("DB_MAX_POOL_SIZE")
120 .ok()
121 .and_then(|s| s.parse::<u32>().ok())
122 .unwrap_or(1);
123 let db_app_name = env::var("DB_APP_NAME")
124 .ok()
125 .unwrap_or("app-name-not-defined".to_string());
126
127 let idle_in_transaction_session = env::var("DB_IDLE_IN_TRANSACTION")
128 .ok()
129 .and_then(|s| s.parse::<u32>().ok())
130 .unwrap_or(2000);
131
132 Self {
133 host: db_host,
134 name: db_name,
135 user: db_user,
136 pass: db_pass,
137 port: db_port,
138 min_pool_size: db_min_pool_size,
139 max_pool_size: db_max_pool_size,
140 idle_in_transaction_session,
141 app_name: db_app_name,
142 }
143 }
144
145 pub fn connection_url(&self) -> String {
146 format!(
147 "postgresql://{db_host}:{db_port}?dbname={db_name}&user={db_user}&password={db_pass}&application_name={db_app_name}&options=-c%20idle_in_transaction_session_timeout%3D{idle_in_transaction_session}",
148 db_host = self.host,
149 db_name = self.name,
150 db_user = self.user,
151 db_pass = self.pass,
152 db_port = self.port,
153 db_app_name = self.app_name,
154 idle_in_transaction_session = self.idle_in_transaction_session
155 )
156 }
157}