mongodb_migrator/migrator/
shell.rs

1use anyhow::Result;
2use serde_json::Value;
3use std::process::Command;
4
5#[derive(Clone)]
6pub struct ShellConfig {
7    pub host: String,
8    pub port: usize,
9}
10
11impl Default for ShellConfig {
12    fn default() -> Self {
13        Self {
14            host: "localhost".to_string(),
15            port: 27017,
16        }
17    }
18}
19
20#[derive(Default, Clone)]
21pub struct Shell {
22    pub config: ShellConfig,
23}
24
25impl Shell {
26    pub fn execute<S: AsRef<str> + std::fmt::Debug>(&self, db_name: S, query: S) -> Result<Value> {
27        let mongo = { Command::new("mongo").spawn() };
28        let mongo_sh = { Command::new("mongosh").spawn() };
29        let command = if mongo_sh.is_ok() {
30            "mongosh"
31        } else if mongo.is_ok() {
32            "mongo"
33        } else {
34            panic!("mongo[sh] is not installed");
35        };
36
37        let out = Command::new(command)
38            .arg("--host")
39            .arg(&self.config.host)
40            .arg("--port")
41            .arg(self.config.port.to_string())
42            .arg("--eval")
43            .arg(query.as_ref())
44            .arg(db_name.as_ref())
45            .stdout(std::process::Stdio::piped())
46            .spawn()?
47            .wait_with_output();
48
49        let out = std::str::from_utf8(&out.expect("mongo shell finished").stdout)
50            .expect("u8 to string")
51            .to_string();
52        let out_as_json = self.out_to_json(&out).unwrap_or(Value::String(out));
53
54        Ok(out_as_json)
55    }
56
57    fn out_to_json(&self, shell_out: &String) -> Result<Value> {
58        Ok(serde_json::from_str(&shell_out)?)
59    }
60}