use colored::Colorize;
pub fn run(args: Vec<String>) {
if args.is_empty() {
eprintln!(
"{}",
"esql: no connection given. Try `esql ls` or just `esql`.".red()
);
std::process::exit(2);
}
let conn = match crate::engines::find(&args[0]) {
Ok(c) => c,
Err(e) => {
eprintln!("{}", format!("esql: {e}").red());
std::process::exit(2);
}
};
match crate::vias::ensure(&conn.key()) {
Some(Ok(msg)) => eprintln!("{}", format!("esql: {msg}").dimmed()),
Some(Err(e)) => {
eprintln!(
"{}",
format!("esql: could not reopen the tunnel: {e}").red()
);
eprintln!(
"{}",
" the connection points at it, so this will not connect.".dimmed()
);
std::process::exit(1);
}
None => {}
}
crate::history::record(&conn.key());
let settings = crate::settings::load();
let mut argv = conn.connect_argv(&settings);
let rest: Vec<String> = args.into_iter().skip(1).collect();
let session = rest.is_empty();
let snippet: Option<String> = rest
.first()
.and_then(|a| a.strip_prefix(':'))
.map(str::to_string);
match snippet.as_deref() {
Some(name) => {
let Some(s) = crate::snippets::get(name) else {
eprintln!("{}", format!("esql: no snippet called '{name}'").red());
eprintln!(
"{}",
" `esql` and the Snippets tab list and create them.".dimmed()
);
std::process::exit(2);
};
if let Some(flag) = conn.engine.query_flag() {
argv.push(flag.to_string());
}
argv.push(s.sql);
argv.extend(rest.into_iter().skip(1));
}
None => argv.extend(rest),
}
if conn.engine == crate::engines::Engine::Pg && snippet.is_none() {
let _ = crate::snippets::sync_psqlrc();
}
if settings.hints && session {
eprintln!(
"{}",
format!(" {}", crate::engines::hint_line(conn.engine)).dimmed()
);
}
let (program, rest) = argv.split_first().expect("connect_argv is never empty");
let program = program.clone();
let rest: Vec<String> = rest.to_vec();
if !crate::engines::on_path(&program) {
eprintln!(
"{}",
format!("esql: {program} is not installed, and easysql is only a front end for it.")
.red()
);
eprintln!(
" {} {}",
"install it:".dimmed(),
crate::engines::install_hint(conn.engine).bold()
);
if crate::engines::install_argv(conn.engine).is_some() {
eprintln!(
" {}",
"or run `esql` and press Enter on it, which offers to do this for you.".dimmed()
);
}
std::process::exit(127);
}
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
let err = std::process::Command::new(&program).args(&rest).exec();
eprintln!("{}", format!("esql: could not run {program}: {err}").red());
eprintln!(
"{}",
format!("install it: {}", crate::engines::install_hint(conn.engine)).dimmed()
);
std::process::exit(127);
}
#[cfg(not(unix))]
{
match std::process::Command::new(&program).args(&rest).status() {
Ok(status) => std::process::exit(status.code().unwrap_or(1)),
Err(e) => {
eprintln!("{}", format!("esql: could not run {program}: {e}").red());
std::process::exit(127);
}
}
}
}