Resolve several issues

This commit is contained in:
divanik 2024-05-31 13:10:42 +00:00
parent 75c484a73b
commit 439ac99897
6 changed files with 57 additions and 125 deletions

View File

@ -51,7 +51,6 @@ private:
static void listRecursive(const DiskWithPath & disk, const std::string & relative_path, bool show_hidden)
{
// std::cerr << absolute_path << std::endl;
std::vector<String> file_names = disk.listAllFilesByPath(relative_path);
std::vector<String> selected_and_sorted_file_names{};

View File

@ -1,13 +1,9 @@
#include "DisksApp.h"
#include <Client/ClientBase.h>
#include <Client/ReplxxLineReader.h>
#include <Parsers/parseQuery.h>
#include <Poco/Util/HelpFormatter.h>
#include "Common/Exception.h"
#include "Common/filesystemHelpers.h"
#include <Common/Config/ConfigProcessor.h>
#include <Common/EventNotifier.h>
#include <Common/ZooKeeper/ZooKeeper.h>
#include <Common/filesystemHelpers.h>
#include "DisksClient.h"
#include "ICommand.h"
@ -30,19 +26,20 @@ extern const int BAD_ARGUMENTS;
extern const int LOGICAL_ERROR;
};
LineReader::Patterns DisksApp::query_extenders = {"\\"};
LineReader::Patterns DisksApp::query_delimiters = {""};
String DisksApp::word_break_characters = " \t\v\f\a\b\r\n";
CommandPtr DisksApp::getCommandByName(String command) const
CommandPtr DisksApp::getCommandByName(const String & command) const
{
auto it = aliases.find(command);
if (it != aliases.end())
{
command = it->second;
}
try
{
if (auto it = aliases.find(command); it != aliases.end())
return command_descriptions.at(it->second);
return command_descriptions.at(command);
}
catch (...)
catch (std::out_of_range &)
{
throw Exception(ErrorCodes::BAD_ARGUMENTS, "The command `{}` is unknown", command);
}
@ -75,7 +72,7 @@ std::vector<String> DisksApp::getEmptyCompletion(CommandPtr command_) const
std::vector<String> DisksApp::getCompletions(const String & prefix) const
{
auto arguments = split(prefix, word_break_characters);
auto arguments = po::split_unix(prefix, word_break_characters);
if (arguments.empty())
{
return {};
@ -171,14 +168,14 @@ std::vector<String> DisksApp::getCompletions(const String & prefix) const
}
}
bool DisksApp::processQueryText(String text)
bool DisksApp::processQueryText(const String & text)
{
if (exit_strings.find(text) != exit_strings.end())
return false;
CommandPtr command;
try
{
auto arguments = split(text, word_break_characters);
auto arguments = po::split_unix(text, word_break_characters);
command = getCommandByName(arguments[0]);
arguments.erase(arguments.begin());
command->execute(arguments, *client);
@ -188,7 +185,7 @@ bool DisksApp::processQueryText(String text)
int code = getCurrentExceptionCode();
if (code == ErrorCodes::LOGICAL_ERROR)
{
throw std::move(err);
throw err;
}
else if (code == ErrorCodes::BAD_ARGUMENTS)
{
@ -272,6 +269,13 @@ void DisksApp::addOptions()
#ifdef CLICKHOUSE_CLOUD
command_descriptions.emplace("packed-io", makeCommandPackedIO());
#endif
for (const auto & [command_name, command_ptr] : command_descriptions)
{
if (command_name != command_ptr->command_name)
{
throw Exception(ErrorCodes::LOGICAL_ERROR, "Command name inside map doesn't coincide with actual command name");
}
}
}
void DisksApp::processOptions()
@ -295,63 +299,35 @@ void DisksApp::printEntryHelpMessage()
std::cout << options_description << '\n';
}
size_t DisksApp::getMagicConstant()
{
size_t magic_constant = 0;
for (const auto & [current_command, _] : command_descriptions)
{
std::string command_string{};
command_string += command_descriptions[current_command]->command_name;
bool was = false;
for (const auto & [alias_name, alias_command_name] : aliases)
{
if (alias_command_name == current_command)
{
if (was)
command_string += ",";
else
command_string += "(";
command_string += alias_name;
was = true;
}
}
command_string += (was ? ")" : "");
magic_constant = std::max(magic_constant, command_string.size());
}
return magic_constant + 2;
}
void DisksApp::printAvailableCommandsHelpMessage()
{
size_t magic_constant = getMagicConstant();
std::cout << "\x1b[1;33mAvailable commands:\x1b[0m\n";
std::vector<std::pair<String, String>> commands_with_aliases_and_descrtiptions{};
size_t maximal_command_length = 0;
for (const auto & [current_command, _] : command_descriptions)
{
std::string command_string{};
command_string += command_descriptions[current_command]->command_name;
bool was = false;
std::string command_string = command_descriptions[current_command]->command_name;
bool need_comma = false;
for (const auto & [alias_name, alias_command_name] : aliases)
{
if (alias_command_name == current_command)
{
if (was)
if (std::exchange(need_comma, true))
command_string += ",";
else
command_string += "(";
command_string += alias_name;
was = true;
}
}
command_string += (was ? ")" : "");
std::cout << "\x1b[1;32m" << command_string << "\x1b[0m";
for (size_t i = command_string.size(); i < magic_constant; ++i)
{
std::cout << " ";
}
std::cout << command_descriptions[current_command]->description << "\n";
command_string += (need_comma ? ")" : "");
maximal_command_length = std::max(maximal_command_length, command_string.size());
commands_with_aliases_and_descrtiptions.push_back({std::move(command_string), command_descriptions[current_command]->command_name});
}
for (const auto & [command_with_aliases, description] : commands_with_aliases_and_descrtiptions)
{
std::cout << "\x1b[1;32m" << command_with_aliases << "\x1b[0m"
<< std::string(maximal_command_length + 2 - command_with_aliases.size(), ' ') << description << "\n";
}
}

View File

@ -25,13 +25,13 @@ public:
void processOptions();
bool processQueryText(String text);
bool processQueryText(const String & text);
void init(const std::vector<String> & common_arguments);
int main(const std::vector<String> & /*args*/) override;
CommandPtr getCommandByName(String command) const;
CommandPtr getCommandByName(const String & command) const;
void initializeHistoryFile();
@ -45,8 +45,6 @@ public:
std::vector<String> getEmptyCompletion(CommandPtr command_) const;
size_t getMagicConstant();
~DisksApp() override;
private:
@ -57,11 +55,11 @@ private:
// Fields responsible for the REPL work
String history_file;
LineReader::Suggest suggest;
LineReader::Patterns query_extenders = {"\\"};
LineReader::Patterns query_delimiters = {};
String word_break_characters{" \t\v\f\a\b\r\n"};
static LineReader::Patterns query_extenders;
static LineReader::Patterns query_delimiters;
static String word_break_characters;
// General commang line arguments parsing fields
// General command line arguments parsing fields
ContextMutablePtr global_context;
ProgramOptionsDescription options_description;
CommandLineOptions options;
@ -87,5 +85,4 @@ private:
std::unique_ptr<DisksClient> client{};
};
}

View File

@ -1,17 +1,10 @@
#include "DisksClient.h"
#include <Client/ClientBase.h>
#include <Client/ReplxxLineReader.h>
#include <Parsers/parseQuery.h>
#include <Poco/Util/HelpFormatter.h>
#include <Common/Config/ConfigProcessor.h>
#include <Common/EventNotifier.h>
#include <Common/ZooKeeper/ZooKeeper.h>
#include <Common/filesystemHelpers.h>
#include <Disks/registerDisks.h>
#include <Common/Config/ConfigProcessor.h>
#include <Formats/registerFormats.h>
#include <Common/TerminalSize.h>
namespace ErrorCodes
{
@ -22,46 +15,20 @@ extern const int LOGICAL_ERROR;
namespace DB
{
std::vector<String> split(const String & text, const String & delimiters)
DiskWithPath::DiskWithPath(DiskPtr disk_, std::optional<String> path_) : disk(disk_)
{
std::vector<String> arguments;
auto prev = text.begin();
auto pos = std::find_if(text.begin(), text.end(), [&](char x) { return delimiters.contains(x); });
while (pos != text.end())
if (path_.has_value())
{
if (pos > prev)
if (!fs::path{path_.value()}.is_absolute())
{
arguments.push_back({prev, pos});
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Initializing path {} is not absolute", path_.value());
}
prev = ++pos;
pos = std::find_if(prev, text.end(), [&](char x) { return delimiters.contains(x); });
path = path_.value();
}
if (pos > prev)
else
{
arguments.push_back({prev, text.end()});
path = String{"/"};
}
return arguments;
}
DiskWithPath::DiskWithPath(DiskPtr disk_, std::optional<String> path_)
: disk(disk_)
, path(
[&]()
{
if (path_.has_value())
{
if (!fs::path{path_.value()}.is_absolute())
{
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Initializing path {} is not absolute", path_.value());
}
return path_.value();
}
else
{
return String{"/"};
}
}())
{
if (!disk->isDirectory(normalizePathAndGetAsRelative(path)))
{
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Initializing path {} at disk {} is not a directory", path, disk->getName());
@ -82,7 +49,7 @@ std::vector<String> DiskWithPath::listAllFilesByPath(const String & any_path) co
}
}
std::vector<String> DiskWithPath::getAllFilesByPattern(std::string pattern) const
std::vector<String> DiskWithPath::getAllFilesByPattern(const String & pattern) const
{
auto [path_before, path_after] = [&]() -> std::pair<String, String>
{
@ -149,17 +116,16 @@ String DiskWithPath::validatePathAndGetAsRelative(const String & path)
return lexically_normal_path;
}
std::string DiskWithPath::normalizePathAndGetAsRelative(const std::string & messyPath)
String DiskWithPath::normalizePathAndGetAsRelative(const String & messyPath)
{
std::filesystem::path path(messyPath);
std::filesystem::path canonical_path = std::filesystem::weakly_canonical(path);
std::string npath = canonical_path.make_preferred().string();
String npath = canonical_path.make_preferred().string();
return validatePathAndGetAsRelative(npath);
}
std::string DiskWithPath::normalizePath(const std::string & messyPath)
String DiskWithPath::normalizePath(const String & path)
{
std::filesystem::path path(messyPath);
std::filesystem::path canonical_path = std::filesystem::weakly_canonical(path);
return canonical_path.make_preferred().string();
}
@ -174,7 +140,7 @@ DisksClient::DisksClient(std::vector<std::pair<DiskPtr, std::optional<String>>>
{
begin_disk = disks_with_paths[0].first->getName();
}
bool has_begin_disk = true;
bool has_begin_disk = false;
for (auto & [disk, path] : disks_with_paths)
{
addDisk(disk, path);
@ -265,7 +231,7 @@ std::vector<String> DisksClient::getAllDiskNames() const
return answer;
}
std::vector<String> DisksClient::getAllFilesByPatternFromAllDisks(std::string pattern) const
std::vector<String> DisksClient::getAllFilesByPatternFromAllDisks(const String & pattern) const
{
std::vector<String> answer{};
for (const auto & [_, disk] : disks)

View File

@ -36,7 +36,7 @@ public:
std::vector<String> listAllFilesByPath(const String & any_path) const;
std::vector<String> getAllFilesByPattern(std::string pattern) const;
std::vector<String> getAllFilesByPattern(const String & pattern) const;
DiskPtr getDisk() const { return disk; }
@ -74,7 +74,7 @@ public:
std::vector<String> getAllDiskNames() const;
std::vector<String> getAllFilesByPatternFromAllDisks(std::string pattern) const;
std::vector<String> getAllFilesByPatternFromAllDisks(const String & pattern) const;
private:

View File

@ -4,14 +4,13 @@
#include <Disks/DiskSelector.h>
#include <Disks/IDisk.h>
#include <boost/any/bad_any_cast.hpp>
#include <boost/program_options.hpp>
#include <Parsers/IAST.h>
#include <Poco/Util/Application.h>
#include "Common/Exception.h"
#include <Common/Config/ConfigProcessor.h>
#include <Parsers/parseIdentifierOrStringLiteral.h>
#include <boost/program_options/positional_options.hpp>
#include "DisksApp.h"
@ -46,8 +45,6 @@ public:
CommandLineOptions processCommandLineArguments(const Strings & commands);
void exit() { options_parsed = false; }
protected:
template <typename T>
static T getValueFromCommandLineOptions(const CommandLineOptions & options, const String & name)
@ -56,7 +53,7 @@ protected:
{
return options[name].as<T>();
}
catch (...)
catch (boost::bad_any_cast)
{
throw DB::Exception(ErrorCodes::BAD_ARGUMENTS, "Argument '{}' has wrong type and can't be parsed", name);
}
@ -111,9 +108,6 @@ public:
protected:
PositionalProgramOptionsDescription positional_options_description;
private:
bool options_parsed{};
};
DB::CommandPtr makeCommandCopy();