Skip to content

Commit 99eb587

Browse files
Merge pull request #20 from theseus-rs/refactor-pgpassword
refactor: update psql to manage setting the PGPASSWORD environment variable when pg_password is set
2 parents 544a3c9 + 0137a2e commit 99eb587

File tree

4 files changed

+80
-17
lines changed

4 files changed

+80
-17
lines changed

Cargo.lock

Lines changed: 10 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

postgresql_embedded/src/command/psql.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct PsqlBuilder {
4141
username: Option<OsString>,
4242
no_password: bool,
4343
password: bool,
44+
pg_password: Option<OsString>,
4445
}
4546

4647
impl PsqlBuilder {
@@ -267,6 +268,12 @@ impl PsqlBuilder {
267268
self.password = true;
268269
self
269270
}
271+
272+
/// user password
273+
pub fn pg_password<S: AsRef<OsStr>>(mut self, pg_password: S) -> Self {
274+
self.pg_password = Some(pg_password.as_ref().to_os_string());
275+
self
276+
}
270277
}
271278

272279
impl CommandBuilder for PsqlBuilder {
@@ -440,6 +447,17 @@ impl CommandBuilder for PsqlBuilder {
440447

441448
args
442449
}
450+
451+
/// Get the environment variables for the command
452+
fn get_envs(&self) -> Vec<(OsString, OsString)> {
453+
let mut envs: Vec<(OsString, OsString)> = Vec::new();
454+
455+
if let Some(password) = &self.pg_password {
456+
envs.push(("PGPASSWORD".into(), password.into()));
457+
}
458+
459+
envs
460+
}
443461
}
444462

445463
#[cfg(test)]
@@ -496,10 +514,11 @@ mod tests {
496514
.username("postgres")
497515
.no_password()
498516
.password()
517+
.pg_password("password")
499518
.build();
500519

501520
assert_eq!(
502-
r#""psql" "--command" "SELECT * FROM test" "--dbname" "dbname" "--file" "test.sql" "--list" "--variable" "ON_ERROR_STOP=1" "--version" "--no-psqlrc" "--single-transaction" "--help" "options" "--echo-all" "--echo-errors" "--echo-queries" "--echo-hidden" "--log-file" "psql.log" "--no-readline" "--output" "output.txt" "--quiet" "--single-step" "--single-line" "--no-align" "--csv" "--field-separator" "|" "--html" "--pset" "border=1" "--record-separator" "\n" "--tuples-only" "--table-attr" "width=100" "--expanded" "--field-separator-zero" "--record-separator-zero" "--host" "localhost" "--port" "5432" "--username" "postgres" "--no-password" "--password""#,
521+
r#"PGPASSWORD="password" "psql" "--command" "SELECT * FROM test" "--dbname" "dbname" "--file" "test.sql" "--list" "--variable" "ON_ERROR_STOP=1" "--version" "--no-psqlrc" "--single-transaction" "--help" "options" "--echo-all" "--echo-errors" "--echo-queries" "--echo-hidden" "--log-file" "psql.log" "--no-readline" "--output" "output.txt" "--quiet" "--single-step" "--single-line" "--no-align" "--csv" "--field-separator" "|" "--html" "--pset" "border=1" "--record-separator" "\n" "--tuples-only" "--table-attr" "width=100" "--expanded" "--field-separator-zero" "--record-separator-zero" "--host" "localhost" "--port" "5432" "--username" "postgres" "--no-password" "--password""#,
503522
command.to_command_string()
504523
);
505524
}

postgresql_embedded/src/command/traits.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ pub trait CommandBuilder {
2323
}
2424

2525
/// Get the arguments for the command
26-
fn get_args(&self) -> Vec<OsString>;
26+
fn get_args(&self) -> Vec<OsString> {
27+
vec![]
28+
}
29+
30+
/// Get the environment variables for the command
31+
fn get_envs(&self) -> Vec<(OsString, OsString)> {
32+
vec![]
33+
}
2734

2835
/// Build a standard Command
2936
fn build(self) -> std::process::Command
@@ -34,6 +41,7 @@ pub trait CommandBuilder {
3441
let mut command = std::process::Command::new(program_file);
3542

3643
command.args(self.get_args());
44+
command.envs(self.get_envs());
3745
command
3846
}
3947

@@ -47,6 +55,7 @@ pub trait CommandBuilder {
4755
let mut command = tokio::process::Command::new(program_file);
4856

4957
command.args(self.get_args());
58+
command.envs(self.get_envs());
5059
command
5160
}
5261
}
@@ -147,9 +156,32 @@ mod test {
147156
use super::*;
148157
use test_log::test;
149158

159+
#[test]
160+
fn test_command_builder_defaults() {
161+
struct DefaultCommandBuilder {
162+
program_dir: Option<PathBuf>,
163+
}
164+
165+
impl CommandBuilder for DefaultCommandBuilder {
166+
fn get_program(&self) -> &'static OsStr {
167+
"test".as_ref()
168+
}
169+
170+
fn get_program_dir(&self) -> &Option<PathBuf> {
171+
&self.program_dir
172+
}
173+
}
174+
175+
let builder = DefaultCommandBuilder { program_dir: None };
176+
let command = builder.build();
177+
178+
assert_eq!(r#""test""#, command.to_command_string());
179+
}
180+
150181
struct TestCommandBuilder {
151182
program_dir: Option<PathBuf>,
152183
args: Vec<OsString>,
184+
envs: Vec<(OsString, OsString)>,
153185
}
154186

155187
impl CommandBuilder for TestCommandBuilder {
@@ -164,18 +196,26 @@ mod test {
164196
fn get_args(&self) -> Vec<OsString> {
165197
self.args.clone()
166198
}
199+
200+
fn get_envs(&self) -> Vec<(OsString, OsString)> {
201+
self.envs.clone()
202+
}
167203
}
168204

169205
#[test]
170206
fn test_standard_command_builder() {
171207
let builder = TestCommandBuilder {
172208
program_dir: None,
173209
args: vec!["--help".to_string().into()],
210+
envs: vec![(OsString::from("PASSWORD"), OsString::from("foo"))],
174211
};
175212
let command = builder.build();
176213

177214
assert_eq!(
178-
format!(r#""{}" "--help""#, PathBuf::from("test").to_string_lossy()),
215+
format!(
216+
r#"PASSWORD="foo" "{}" "--help""#,
217+
PathBuf::from("test").to_string_lossy()
218+
),
179219
command.to_command_string()
180220
);
181221
}
@@ -186,11 +226,15 @@ mod test {
186226
let builder = TestCommandBuilder {
187227
program_dir: None,
188228
args: vec!["--help".to_string().into()],
229+
envs: vec![(OsString::from("PASSWORD"), OsString::from("foo"))],
189230
};
190231
let command = builder.build_tokio();
191232

192233
assert_eq!(
193-
format!(r#""{}" "--help""#, PathBuf::from("test").to_string_lossy()),
234+
format!(
235+
r#"PASSWORD="foo" "{}" "--help""#,
236+
PathBuf::from("test").to_string_lossy()
237+
),
194238
command.to_command_string()
195239
);
196240
}

postgresql_embedded/src/postgresql.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ impl PostgreSQL {
338338
.host(&self.settings.host)
339339
.port(self.settings.port)
340340
.username(&self.settings.username)
341+
.pg_password(&self.settings.password)
341342
.no_psqlrc()
342343
.no_align()
343344
.tuples_only();
@@ -373,6 +374,7 @@ impl PostgreSQL {
373374
.host(&self.settings.host)
374375
.port(self.settings.port)
375376
.username(&self.settings.username)
377+
.pg_password(&self.settings.password)
376378
.no_psqlrc()
377379
.no_align()
378380
.tuples_only();
@@ -403,6 +405,7 @@ impl PostgreSQL {
403405
.host(&self.settings.host)
404406
.port(self.settings.port)
405407
.username(&self.settings.username)
408+
.pg_password(&self.settings.password)
406409
.no_psqlrc()
407410
.no_align()
408411
.tuples_only();
@@ -428,8 +431,6 @@ impl PostgreSQL {
428431
command_builder: B,
429432
) -> Result<(String, String)> {
430433
let mut command = command_builder.build();
431-
// TODO: move this into the command builder
432-
command.env("PGPASSWORD", &self.settings.password);
433434
command.execute(self.settings.timeout).await
434435
}
435436

@@ -440,8 +441,6 @@ impl PostgreSQL {
440441
command_builder: B,
441442
) -> Result<(String, String)> {
442443
let mut command = command_builder.build_tokio();
443-
// TODO: move this into the command builder
444-
command.env("PGPASSWORD", &self.settings.password);
445444
command.execute(self.settings.timeout).await
446445
}
447446
}

0 commit comments

Comments
 (0)