mongodb_migrator/migrator/
shell.rs1use 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}