sql_middleware/postgres/
config.rs1use super::typed::PgManager;
2use crate::middleware::{
3 ConfigAndPool, DatabaseType, MiddlewarePool, MiddlewarePoolOptions, SqlMiddlewareDbError,
4};
5
6#[derive(Clone, Debug, Default)]
9pub struct PgConfig {
10 pub dbname: Option<String>,
11 pub host: Option<String>,
12 pub port: Option<u16>,
13 pub user: Option<String>,
14 pub password: Option<String>,
15}
16
17impl PgConfig {
18 #[must_use]
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 #[must_use]
24 pub fn to_tokio_config(&self) -> tokio_postgres::Config {
25 let mut cfg = tokio_postgres::Config::new();
26 if let Some(dbname) = &self.dbname {
27 cfg.dbname(dbname);
28 }
29 if let Some(host) = &self.host {
30 cfg.host(host);
31 }
32 if let Some(port) = self.port {
33 cfg.port(port);
34 }
35 if let Some(user) = &self.user {
36 cfg.user(user);
37 }
38 if let Some(password) = &self.password {
39 cfg.password(password);
40 }
41 cfg
42 }
43}
44
45#[derive(Clone)]
47pub struct PostgresOptions {
48 pub config: PgConfig,
49 pub translate_placeholders: bool,
50 pub pool_options: MiddlewarePoolOptions,
51}
52
53impl PostgresOptions {
54 #[must_use]
55 pub fn new(config: PgConfig) -> Self {
56 Self {
57 config,
58 translate_placeholders: false,
59 pool_options: MiddlewarePoolOptions::default(),
60 }
61 }
62
63 #[must_use]
64 pub fn with_translation(mut self, translate_placeholders: bool) -> Self {
65 self.translate_placeholders = translate_placeholders;
66 self
67 }
68
69 #[must_use]
70 pub fn with_pool_options(mut self, pool_options: MiddlewarePoolOptions) -> Self {
71 self.pool_options = pool_options;
72 self
73 }
74
75 #[must_use]
76 pub fn with_test_on_check_out(mut self, test_on_check_out: bool) -> Self {
77 self.pool_options.test_on_check_out = test_on_check_out;
78 self
79 }
80}
81
82#[derive(Clone)]
84pub struct PostgresOptionsBuilder {
85 opts: PostgresOptions,
86}
87
88impl PostgresOptionsBuilder {
89 #[must_use]
90 pub fn new(config: PgConfig) -> Self {
91 Self {
92 opts: PostgresOptions::new(config),
93 }
94 }
95
96 #[must_use]
97 pub fn translation(mut self, translate_placeholders: bool) -> Self {
98 self.opts.translate_placeholders = translate_placeholders;
99 self
100 }
101
102 #[must_use]
103 pub fn pool_options(mut self, pool_options: MiddlewarePoolOptions) -> Self {
104 self.opts.pool_options = pool_options;
105 self
106 }
107
108 #[must_use]
109 pub fn test_on_check_out(mut self, test_on_check_out: bool) -> Self {
110 self.opts.pool_options.test_on_check_out = test_on_check_out;
111 self
112 }
113
114 #[must_use]
115 pub fn finish(self) -> PostgresOptions {
116 self.opts
117 }
118
119 pub async fn build(self) -> Result<ConfigAndPool, SqlMiddlewareDbError> {
125 ConfigAndPool::new_postgres(self.finish()).await
126 }
127}
128
129impl ConfigAndPool {
130 #[must_use]
131 pub fn postgres_builder(pg_config: PgConfig) -> PostgresOptionsBuilder {
132 PostgresOptionsBuilder::new(pg_config)
133 }
134
135 #[allow(clippy::unused_async)]
140 pub async fn new_postgres(opts: PostgresOptions) -> Result<Self, SqlMiddlewareDbError> {
141 let pg_config = opts.config;
142 let translate_placeholders = opts.translate_placeholders;
143 let pool_options = opts.pool_options;
144
145 if pg_config.dbname.is_none() {
147 return Err(SqlMiddlewareDbError::ConfigError(
148 "dbname is required".to_string(),
149 ));
150 }
151
152 if pg_config.host.is_none() {
153 return Err(SqlMiddlewareDbError::ConfigError(
154 "host is required".to_string(),
155 ));
156 }
157 if pg_config.port.is_none() {
158 return Err(SqlMiddlewareDbError::ConfigError(
159 "port is required".to_string(),
160 ));
161 }
162 if pg_config.user.is_none() {
163 return Err(SqlMiddlewareDbError::ConfigError(
164 "user is required".to_string(),
165 ));
166 }
167 if pg_config.password.is_none() {
168 return Err(SqlMiddlewareDbError::ConfigError(
169 "password is required".to_string(),
170 ));
171 }
172
173 let manager = PgManager::new(pg_config.to_tokio_config()).with_pool_options(pool_options);
175 let pg_pool = manager.build_pool().await?;
176
177 Ok(ConfigAndPool {
178 pool: MiddlewarePool::Postgres(pg_pool),
179 db_type: DatabaseType::Postgres,
180 translate_placeholders,
181 statement_cache_mode: crate::types::StatementCacheMode::Cached,
182 })
183 }
184}