in mysqlshdk/shellcore/shell_options.cc [1056:1312]
bool Shell_options::custom_cmdline_handler(Iterator *iterator) {
const auto option = iterator->option();
if ("--" == option) {
if (m_shell_cli_operation)
throw std::invalid_argument(
"MySQL Shell can handle only one operation at a time");
iterator->next_no_value();
m_shell_cli_operation.reset(new shcore::cli::Shell_cli_operation());
m_shell_cli_operation->parse(iterator->iterator());
} else if ("--file" == option || "-f" == option) {
handle_missing_value(iterator);
const std::string file = iterator->value();
iterator->next();
storage.run_file = file;
if (shcore::str_endswith(file, ".js")) {
storage.initial_mode = shcore::IShell_core::Mode::JavaScript;
} else if (shcore::str_endswith(file, ".py")) {
storage.initial_mode = shcore::IShell_core::Mode::Python;
} else if (shcore::str_endswith(file, ".sql")) {
storage.initial_mode = shcore::IShell_core::Mode::SQL;
}
// the rest of the cmdline options, starting from here are all passed
// through to the script
storage.script_argv.push_back(file);
const auto cmdline = iterator->iterator();
while (cmdline->valid()) storage.script_argv.push_back(cmdline->get());
} else if ("-c" == option || "--pyc" == option) {
// Like --py -f , but with an inline command
// Needed for backwards compatibility with python executable when
// subprocess spawns it
#ifdef HAVE_PYTHON
handle_missing_value(iterator);
storage.initial_mode = shcore::IShell_core::Mode::Python;
storage.execute_statement = iterator->value();
iterator->next();
// the rest of the cmdline options, starting from the next one are all
// passed through to the script
storage.script_argv.push_back("-c");
const auto cmdline = iterator->iterator();
while (cmdline->valid()) storage.script_argv.push_back(cmdline->get());
#else
throw std::invalid_argument("Python is not supported.");
#endif
} else if ("--pym" == option) {
#ifndef HAVE_PYTHON
throw std::invalid_argument("Python is not supported.");
#endif
handle_missing_value(iterator);
const std::string module = iterator->value();
iterator->next();
storage.run_module = module;
storage.initial_mode = shcore::IShell_core::Mode::Python;
// the rest of the cmdline options, starting from here are all passed
// through to the script
storage.script_argv.push_back(module);
const auto cmdline = iterator->iterator();
while (cmdline->valid()) storage.script_argv.push_back(cmdline->get());
} else if ("--uri" == option || '-' != option[0]) {
handle_missing_value(iterator);
storage.set_uri(iterator->value());
{
char *value = const_cast<char *>(iterator->value());
const auto nopwd = mysqlshdk::db::uri::hide_password_in_uri(value);
obfuscate_uri_password(nopwd, value);
}
iterator->next();
} else if ("--user" == option || "--dbuser" == option || "-u" == option) {
handle_missing_value(iterator);
if ("--dbuser" == option) {
// Deprecated handler is not going to be invoked, need to inform the
// user that --dbuser should not longer be used.
// Console is not available at this time, need to use stdout.
m_on_warning(
"WARNING: The --dbuser option was deprecated, "
"please use --user instead.");
}
storage.connection_data.set_user(iterator->value());
iterator->next();
} else if ("--ssh" == option) {
handle_missing_value(iterator);
storage.ssh.uri = iterator->value();
storage.ssh.uri_data =
shcore::get_ssh_connection_options(storage.ssh.uri, false);
if (storage.ssh.uri_data.has_password()) {
char *value = const_cast<char *>(iterator->value());
const auto nopwd = mysqlshdk::db::uri::hide_password_in_uri(value);
obfuscate_uri_password(nopwd, value);
}
iterator->next();
} else if ("--password" == option || "-p" == option ||
"--dbpassword" == option || "--password1" == option) {
// Note that in any connection attempt, password prompt will be done if
// the password is missing.
// The behavior of the password cmd line argument is as follows:
// ARGUMENT EFFECT
// --password forces password prompt no matter it was already
// provided
// --password value forces password prompt no matter it was already
// provided (value is not taken as password)
// --password= sets password to empty (password is available but
// empty so it will not be prompted)
// -p<value> sets the password to <value>
// --password=<value> sets the password to <value>
if ("--dbpassword" == option) {
// Deprecated handler is not going to be invoked, need to inform the
// user that --dbpassword should not longer be used.
// Console is not available at this time, need to use stdout.
m_on_warning(
"WARNING: The --dbpassword option was deprecated, "
"please use --password instead.");
}
if (shcore::Options::Iterator::Type::NO_VALUE == iterator->type()) {
storage.prompt_password = true;
iterator->next_no_value();
} else if (shcore::Options::Iterator::Type::SEPARATE_VALUE !=
iterator->type()) {
// --password=value || -pvalue
const auto value = iterator->value();
storage.connection_data.set_mfa_password(0, value);
const std::string stars(strlen(value), '*');
strncpy(const_cast<char *>(value), stars.c_str(), stars.length() + 1);
iterator->next();
storage.prompt_password = false;
} else { // --password value (value is ignored)
storage.prompt_password = true;
iterator->next_no_value();
}
} else if ("--import" == option) {
m_on_warning(
"WARNING: The --import option was deprecated and will be removed in "
"a future version of the MySQL Shell. Please consider using the CLI "
"call for import-json instead.\nFor additional information: mysqlsh -- "
"util import-json --help");
const auto cmdline = iterator->iterator();
storage.import_args.push_back(cmdline->get()); // omit --import
// Gets the positional arguments for --import
// As they define the target database object for the data
while (cmdline->valid()) {
// We append --import arguments until next shell option in program
// argument list, i.e. -* or --*. Single char '-' is a --import argument.
const char *arg = cmdline->peek();
if (arg[0] == '-' && arg[1] != '\0') {
break;
}
storage.import_args.push_back(cmdline->get());
}
if (storage.import_args[1] == "-") {
// STDIN import will be handled directly in main
// Here we store the import options
while (cmdline->valid()) storage.import_opts.push_back(cmdline->get());
} else {
// Non STDIN import is handled as a CLI API call
if (m_shell_cli_operation)
throw std::invalid_argument(
"MySQL Shell can handle only one operation at a time");
m_shell_cli_operation =
std::make_unique<shcore::cli::Shell_cli_operation>();
m_shell_cli_operation->set_object_name("util");
m_shell_cli_operation->set_method_name("importJson");
m_shell_cli_operation->add_cmdline_argument(storage.import_args.at(1));
// Parses the positional arguments to set them on the CLI operation
switch (storage.import_args.size()) {
case 4: {
const std::string &target = storage.import_args.at(2);
const std::string &column = storage.import_args.at(3);
m_shell_cli_operation->add_cmdline_argument("--table=" + target);
m_shell_cli_operation->add_cmdline_argument("--tableColumn=" +
column);
break;
}
case 3: {
const std::string &target = storage.import_args.at(2);
m_shell_cli_operation->add_cmdline_argument("--collection=" + target);
break;
}
case 2:
break;
default:
throw std::runtime_error(
"Usage: --import <filename> [<collection>|<table> <column>] "
"[options]");
}
// All of the options above are valid
m_shell_cli_operation->parse(cmdline);
}
} else if ("-m" == option) {
bool handled = false;
if (iterator->value()) {
const std::string value = option + iterator->value();
const char *replacement = nullptr;
if ("-ma" == value) {
handled = true;
} else if ("-mc" == value) {
replacement = "--mc";
} else if ("-mx" == value) {
replacement = "--mx";
}
if (nullptr != replacement) {
handled = true;
}
if (handled) {
deprecated(m_on_warning, replacement,
std::bind(&Shell_options::override_session_type, this, _1,
_2))(value, nullptr);
iterator->next();
}
}
if (!handled) {
throw std::invalid_argument(iterator->iterator()->first() +
std::string(": unknown option -m"));
}
} else if ("--dba-log-sql" == option) {
m_on_warning(
"WARNING: The --dba-log-sql option was deprecated, "
"please use --log-sql instead.");
return false;
} else {
return false;
}
return true;
}