pg_embed_alternative/
pg_commands.rs

1//!
2//! Create postgres command executor
3//!
4//! Command executors for initdb, pg_ctl start, pg_ctl stop
5//!
6use std::path::PathBuf;
7
8use crate::command_executor::{AsyncCommand, AsyncCommandExecutor};
9use crate::pg_enums::{PgAuthMethod, PgProcessType, PgServerStatus};
10use crate::pg_errors::PgEmbedError;
11use crate::pg_types::PgResult;
12
13///
14/// Postgres command executors
15///
16pub struct PgCommand {}
17
18impl PgCommand {
19    ///
20    /// Create initdb command
21    ///
22    pub fn init_db_executor(
23        init_db_exe: &PathBuf,
24        database_dir: &PathBuf,
25        pw_file_path: &PathBuf,
26        user: &str,
27        auth_method: &PgAuthMethod,
28    ) -> PgResult<AsyncCommandExecutor<PgServerStatus, PgEmbedError, PgProcessType>> {
29        let init_db_executable = init_db_exe.as_os_str();
30        let password_file_arg = format!("--pwfile={}", pw_file_path.to_str().unwrap());
31        let auth_host = match auth_method {
32            PgAuthMethod::Plain => "password",
33            PgAuthMethod::MD5 => "md5",
34            PgAuthMethod::ScramSha256 => "scram-sha-256",
35        };
36        let args = [
37            "-A",
38            auth_host,
39            "-U",
40            user,
41            // The postgres-tokio driver uses utf8 encoding, however on windows
42            // if -E is not specified WIN1252 encoding is chosen by default
43            // which can lead to encoding errors like this:
44            //
45            // ERROR: character with byte sequence 0xe0 0xab 0x87 in encoding
46            // "UTF8" has no equivalent in encoding "WIN1252"
47            "-E=UTF8",
48            "-D",
49            database_dir.to_str().unwrap(),
50            &password_file_arg,
51        ];
52
53        let command_executor =
54            AsyncCommandExecutor::<PgServerStatus, PgEmbedError, PgProcessType>::new(
55                init_db_executable,
56                args,
57                PgProcessType::InitDb,
58            )?;
59
60        Ok(command_executor)
61    }
62
63    ///
64    /// Create pg_ctl start command
65    ///
66    pub fn start_db_executor(
67        pg_ctl_exe: &PathBuf,
68        database_dir: &PathBuf,
69        port: &u16,
70    ) -> PgResult<AsyncCommandExecutor<PgServerStatus, PgEmbedError, PgProcessType>> {
71        let pg_ctl_executable = pg_ctl_exe.as_os_str();
72        let port_arg = format!("-F -p {}", port.to_string());
73        let args = [
74            "-o",
75            &port_arg,
76            "start",
77            "-w",
78            "-D",
79            database_dir.to_str().unwrap(),
80        ];
81        let command_executor =
82            AsyncCommandExecutor::<PgServerStatus, PgEmbedError, PgProcessType>::new(
83                pg_ctl_executable,
84                args,
85                PgProcessType::StartDb,
86            )?;
87
88        Ok(command_executor)
89    }
90
91    ///
92    /// Create pg_ctl stop command
93    ///
94    pub fn stop_db_executor(
95        pg_ctl_exe: &PathBuf,
96        database_dir: &PathBuf,
97    ) -> PgResult<AsyncCommandExecutor<PgServerStatus, PgEmbedError, PgProcessType>> {
98        let pg_ctl_executable = pg_ctl_exe.as_os_str();
99        let args = ["stop", "-w", "-D", database_dir.to_str().unwrap()];
100        let command_executor =
101            AsyncCommandExecutor::<PgServerStatus, PgEmbedError, PgProcessType>::new(
102                pg_ctl_executable,
103                args,
104                PgProcessType::StopDb,
105            )?;
106
107        Ok(command_executor)
108    }
109}