postgresql_commands/
clusterdb.rs1use crate::Settings;
2use crate::traits::CommandBuilder;
3use std::convert::AsRef;
4use std::ffi::{OsStr, OsString};
5use std::path::PathBuf;
6
7#[derive(Clone, Debug, Default)]
9pub struct ClusterDbBuilder {
10 program_dir: Option<PathBuf>,
11 envs: Vec<(OsString, OsString)>,
12 all: bool,
13 dbname: Option<OsString>,
14 echo: bool,
15 quiet: bool,
16 table: Option<OsString>,
17 verbose: bool,
18 version: bool,
19 help: bool,
20 host: Option<OsString>,
21 port: Option<u16>,
22 username: Option<OsString>,
23 no_password: bool,
24 password: bool,
25 pg_password: Option<OsString>,
26 maintenance_db: Option<OsString>,
27}
28
29impl ClusterDbBuilder {
30 #[must_use]
32 pub fn new() -> Self {
33 Self::default()
34 }
35
36 pub fn from(settings: &dyn Settings) -> Self {
38 Self::new()
39 .program_dir(settings.get_binary_dir())
40 .host(settings.get_host())
41 .port(settings.get_port())
42 .username(settings.get_username())
43 .pg_password(settings.get_password())
44 }
45
46 #[must_use]
48 fn program_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
49 self.program_dir = Some(path.into());
50 self
51 }
52
53 #[must_use]
55 pub fn all(mut self) -> Self {
56 self.all = true;
57 self
58 }
59
60 #[must_use]
62 pub fn dbname<S: AsRef<OsStr>>(mut self, dbname: S) -> Self {
63 self.dbname = Some(dbname.as_ref().to_os_string());
64 self
65 }
66
67 #[must_use]
69 pub fn echo(mut self) -> Self {
70 self.echo = true;
71 self
72 }
73
74 #[must_use]
76 pub fn quiet(mut self) -> Self {
77 self.quiet = true;
78 self
79 }
80
81 #[must_use]
83 pub fn table<S: AsRef<OsStr>>(mut self, table: S) -> Self {
84 self.table = Some(table.as_ref().to_os_string());
85 self
86 }
87
88 #[must_use]
90 pub fn verbose(mut self) -> Self {
91 self.verbose = true;
92 self
93 }
94
95 #[must_use]
97 pub fn version(mut self) -> Self {
98 self.version = true;
99 self
100 }
101
102 #[must_use]
104 pub fn help(mut self) -> Self {
105 self.help = true;
106 self
107 }
108
109 #[must_use]
111 pub fn host<S: AsRef<OsStr>>(mut self, host: S) -> Self {
112 self.host = Some(host.as_ref().to_os_string());
113 self
114 }
115
116 #[must_use]
118 pub fn port(mut self, port: u16) -> Self {
119 self.port = Some(port);
120 self
121 }
122
123 #[must_use]
125 pub fn username<S: AsRef<OsStr>>(mut self, username: S) -> Self {
126 self.username = Some(username.as_ref().to_os_string());
127 self
128 }
129
130 #[must_use]
132 pub fn no_password(mut self) -> Self {
133 self.no_password = true;
134 self
135 }
136
137 #[must_use]
139 pub fn password(mut self) -> Self {
140 self.password = true;
141 self
142 }
143
144 #[must_use]
146 pub fn pg_password<S: AsRef<OsStr>>(mut self, pg_password: S) -> Self {
147 self.pg_password = Some(pg_password.as_ref().to_os_string());
148 self
149 }
150
151 #[must_use]
153 pub fn maintenance_db<S: AsRef<OsStr>>(mut self, db: S) -> Self {
154 self.maintenance_db = Some(db.as_ref().to_os_string());
155 self
156 }
157}
158
159impl CommandBuilder for ClusterDbBuilder {
160 fn get_program(&self) -> &'static OsStr {
162 "clusterdb".as_ref()
163 }
164
165 fn get_program_dir(&self) -> &Option<PathBuf> {
167 &self.program_dir
168 }
169
170 fn get_args(&self) -> Vec<OsString> {
172 let mut args: Vec<OsString> = Vec::new();
173
174 if self.all {
175 args.push("--all".into());
176 }
177
178 if let Some(dbname) = &self.dbname {
179 args.push("--dbname".into());
180 args.push(dbname.into());
181 }
182
183 if self.echo {
184 args.push("--echo".into());
185 }
186
187 if self.quiet {
188 args.push("--quiet".into());
189 }
190
191 if let Some(table) = &self.table {
192 args.push("--table".into());
193 args.push(table.into());
194 }
195
196 if self.verbose {
197 args.push("--verbose".into());
198 }
199
200 if self.version {
201 args.push("--version".into());
202 }
203
204 if self.help {
205 args.push("--help".into());
206 }
207
208 if let Some(host) = &self.host {
209 args.push("--host".into());
210 args.push(host.into());
211 }
212
213 if let Some(port) = &self.port {
214 args.push("--port".into());
215 args.push(port.to_string().into());
216 }
217
218 if let Some(username) = &self.username {
219 args.push("--username".into());
220 args.push(username.into());
221 }
222
223 if self.no_password {
224 args.push("--no-password".into());
225 }
226
227 if self.password {
228 args.push("--password".into());
229 }
230
231 if let Some(maintenance_db) = &self.maintenance_db {
232 args.push("--maintenance-db".into());
233 args.push(maintenance_db.into());
234 }
235
236 args
237 }
238
239 fn get_envs(&self) -> Vec<(OsString, OsString)> {
241 let mut envs: Vec<(OsString, OsString)> = self.envs.clone();
242
243 if let Some(password) = &self.pg_password {
244 envs.push(("PGPASSWORD".into(), password.into()));
245 }
246
247 envs
248 }
249
250 fn env<S: AsRef<OsStr>>(mut self, key: S, value: S) -> Self {
252 self.envs
253 .push((key.as_ref().to_os_string(), value.as_ref().to_os_string()));
254 self
255 }
256}
257
258#[cfg(test)]
259mod tests {
260 use super::*;
261 use crate::TestSettings;
262 use crate::traits::CommandToString;
263 use test_log::test;
264
265 #[test]
266 fn test_builder_new() {
267 let command = ClusterDbBuilder::new().program_dir(".").build();
268 assert_eq!(
269 PathBuf::from(".").join("clusterdb"),
270 PathBuf::from(command.to_command_string().replace('"', ""))
271 );
272 }
273
274 #[test]
275 fn test_builder_from() {
276 let command = ClusterDbBuilder::from(&TestSettings).build();
277 #[cfg(not(target_os = "windows"))]
278 let command_prefix = r#"PGPASSWORD="password" "./clusterdb" "#;
279 #[cfg(target_os = "windows")]
280 let command_prefix = r#"".\\clusterdb" "#;
281
282 assert_eq!(
283 format!(
284 r#"{command_prefix}"--host" "localhost" "--port" "5432" "--username" "postgres""#
285 ),
286 command.to_command_string()
287 );
288 }
289
290 #[test]
291 fn test_builder() {
292 let command = ClusterDbBuilder::new()
293 .env("PGDATABASE", "database")
294 .all()
295 .dbname("dbname")
296 .echo()
297 .quiet()
298 .table("table")
299 .verbose()
300 .version()
301 .help()
302 .host("localhost")
303 .port(5432)
304 .username("postgres")
305 .no_password()
306 .password()
307 .pg_password("password")
308 .maintenance_db("postgres")
309 .build();
310 #[cfg(not(target_os = "windows"))]
311 let command_prefix = r#"PGDATABASE="database" PGPASSWORD="password" "#;
312 #[cfg(target_os = "windows")]
313 let command_prefix = String::new();
314
315 assert_eq!(
316 format!(
317 r#"{command_prefix}"clusterdb" "--all" "--dbname" "dbname" "--echo" "--quiet" "--table" "table" "--verbose" "--version" "--help" "--host" "localhost" "--port" "5432" "--username" "postgres" "--no-password" "--password" "--maintenance-db" "postgres""#
318 ),
319 command.to_command_string()
320 );
321 }
322}