ohlcv_ctl/cli/command/
mod.rs1mod drop;
4use std::fmt;
5
6pub use drop::drop;
7
8mod fetch;
9pub use fetch::fetch;
10
11mod init;
12pub use init::init;
13
14use clap::ArgMatches;
15use inquire::{Password, PasswordDisplayMode};
16use ohlcv::{
17 database::{Credentials, DbType},
18 Database,
19};
20use tracing::instrument;
21
22use crate::Error;
23
24#[instrument(skip(command))]
31pub async fn execute(command: Option<(&str, &ArgMatches)>) -> Result<(), Error> {
32 match command {
33 Some(("drop", args)) => {
34 let config = args.get_one::<std::path::PathBuf>("config");
35 let all = args.get_flag("all");
36
37 drop(all, config).await
38 }
39 Some(("init", args)) => {
40 let config = args.get_one::<std::path::PathBuf>("config");
41
42 init(config).await
43 }
44 Some(("fetch", args)) => {
45 let config = args.get_one::<std::path::PathBuf>("config");
46
47 fetch(config).await
48 }
49 Some((command, _)) => Err(Error::CommandName(command.into())),
50 None => fetch(None).await,
51 }
52}
53
54#[instrument]
55fn ask_password(username: impl AsRef<str> + fmt::Debug) -> Result<String, Error> {
56 let username = username.as_ref();
57
58 Password::new(&format!(
59 "Enter password for the database user `{username}`:"
60 ))
61 .with_display_toggle_enabled()
62 .with_display_mode(PasswordDisplayMode::Hidden)
63 .without_confirmation()
64 .with_help_message("Output is hidden.")
65 .prompt()
66 .map_err(|err| Error::AskPassword(username.into(), Box::new(err)))
67}
68
69fn root_credentials(db: &DbType) -> Result<Option<Credentials>, Error> {
70 if let Some(username) = db.root_username() {
71 let creds = Credentials::new(username);
72
73 if creds.has_password() {
74 return Ok(Some(creds));
75 }
76
77 let password = ask_password(username)?;
78 return Ok(Some(creds.with_password(password)));
79 }
80 Ok(None)
81}