2022-08-06 10:34:43 +00:00
|
|
|
use crate::err::Error;
|
|
|
|
use reqwest::blocking::Client;
|
|
|
|
use reqwest::blocking::Response;
|
2022-09-16 01:18:28 +00:00
|
|
|
use reqwest::header::ACCEPT;
|
2022-08-06 10:34:43 +00:00
|
|
|
use rustyline::error::ReadlineError;
|
|
|
|
use rustyline::Editor;
|
|
|
|
use serde_json::Value;
|
|
|
|
|
|
|
|
pub fn init(matches: &clap::ArgMatches) -> Result<(), Error> {
|
|
|
|
// Set the default logging level
|
|
|
|
crate::cli::log::init(3);
|
|
|
|
// Parse all other cli arguments
|
|
|
|
let user = matches.value_of("user").unwrap();
|
|
|
|
let pass = matches.value_of("pass").unwrap();
|
|
|
|
let conn = matches.value_of("conn").unwrap();
|
2022-08-26 22:16:13 +00:00
|
|
|
let ns = matches.value_of("ns");
|
|
|
|
let db = matches.value_of("db");
|
2022-08-26 20:51:44 +00:00
|
|
|
|
2022-08-06 10:34:43 +00:00
|
|
|
// If we should pretty-print responses
|
|
|
|
let pretty = matches.is_present("pretty");
|
|
|
|
// Set the correct import URL
|
2022-12-18 16:00:36 +00:00
|
|
|
let conn = format!("{conn}/sql");
|
2022-08-06 10:34:43 +00:00
|
|
|
// Create a new terminal REPL
|
|
|
|
let mut rl = Editor::<()>::new().unwrap();
|
|
|
|
// Load the command-line history
|
|
|
|
let _ = rl.load_history("history.txt");
|
|
|
|
// Loop over each command-line input
|
|
|
|
loop {
|
|
|
|
// Prompt the user to input SQL
|
|
|
|
let readline = rl.readline("> ");
|
|
|
|
// Check the user input
|
|
|
|
match readline {
|
|
|
|
// The user typed a query
|
|
|
|
Ok(line) => {
|
2022-09-14 23:39:01 +00:00
|
|
|
// Ignore all empty lines
|
|
|
|
if line.is_empty() {
|
|
|
|
continue;
|
|
|
|
}
|
2022-08-06 10:34:43 +00:00
|
|
|
// Add the entry to the history
|
|
|
|
rl.add_history_entry(line.as_str());
|
|
|
|
// Make a new remote request
|
|
|
|
let res = Client::new()
|
|
|
|
.post(&conn)
|
2022-09-16 01:18:28 +00:00
|
|
|
.header(ACCEPT, "application/json")
|
2022-08-26 22:16:13 +00:00
|
|
|
.basic_auth(user, Some(pass));
|
|
|
|
// Add NS header if specified
|
|
|
|
let res = match ns {
|
|
|
|
Some(ns) => res.header("NS", ns),
|
|
|
|
None => res,
|
|
|
|
};
|
|
|
|
// Add DB header if specified
|
|
|
|
let res = match db {
|
|
|
|
Some(db) => res.header("DB", db),
|
|
|
|
None => res,
|
|
|
|
};
|
|
|
|
// Complete request
|
|
|
|
let res = res.body(line).send();
|
2022-08-06 10:34:43 +00:00
|
|
|
// Get the request response
|
|
|
|
match process(pretty, res) {
|
2022-12-18 16:00:36 +00:00
|
|
|
Ok(v) => println!("{v}"),
|
|
|
|
Err(e) => eprintln!("{e}"),
|
2022-08-06 10:34:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// The user types CTRL-C
|
|
|
|
Err(ReadlineError::Interrupted) => {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// The user typed CTRL-D
|
|
|
|
Err(ReadlineError::Eof) => {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// There was en error
|
|
|
|
Err(err) => {
|
2022-12-18 16:00:36 +00:00
|
|
|
eprintln!("Error: {err:?}");
|
2022-08-06 10:34:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Save the inputs to the history
|
|
|
|
let _ = rl.save_history("history.txt");
|
|
|
|
// Everything OK
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn process(pretty: bool, res: reqwest::Result<Response>) -> Result<String, Error> {
|
|
|
|
// Catch any errors
|
|
|
|
let res = res?;
|
|
|
|
// Process the TEXT response
|
|
|
|
let res = res.text()?;
|
|
|
|
// Check if we should prettify
|
|
|
|
match pretty {
|
|
|
|
// Don't prettify the response
|
|
|
|
false => Ok(res),
|
|
|
|
// Yes prettify the response
|
2022-09-25 06:05:04 +00:00
|
|
|
true => match res.is_empty() {
|
|
|
|
// This was an empty response
|
|
|
|
true => Ok(res),
|
|
|
|
// Let's make this response pretty
|
|
|
|
false => {
|
|
|
|
// Parse the JSON response
|
|
|
|
let res: Value = serde_json::from_str(&res)?;
|
|
|
|
// Pretty the JSON response
|
|
|
|
let res = serde_json::to_string_pretty(&res)?;
|
|
|
|
// Everything processed OK
|
|
|
|
Ok(res)
|
|
|
|
}
|
|
|
|
},
|
2022-08-06 10:34:43 +00:00
|
|
|
}
|
|
|
|
}
|