2022-12-08 17:54:24 +00:00
|
|
|
#pragma once
|
|
|
|
|
2024-05-27 11:44:45 +00:00
|
|
|
#include <optional>
|
2023-11-30 03:09:55 +00:00
|
|
|
#include <Disks/DiskSelector.h>
|
2024-05-27 11:44:45 +00:00
|
|
|
#include <Disks/IDisk.h>
|
2022-06-06 11:14:50 +00:00
|
|
|
|
2024-05-31 13:10:42 +00:00
|
|
|
#include <boost/any/bad_any_cast.hpp>
|
2022-04-08 07:52:16 +00:00
|
|
|
#include <boost/program_options.hpp>
|
2022-06-06 11:14:50 +00:00
|
|
|
|
2022-12-08 17:20:54 +00:00
|
|
|
#include <Poco/Util/Application.h>
|
2024-05-27 11:44:45 +00:00
|
|
|
#include "Common/Exception.h"
|
|
|
|
#include <Common/Config/ConfigProcessor.h>
|
|
|
|
|
|
|
|
#include <boost/program_options/positional_options.hpp>
|
2022-06-06 11:14:50 +00:00
|
|
|
|
2024-05-27 11:44:45 +00:00
|
|
|
#include "DisksApp.h"
|
|
|
|
|
|
|
|
#include "DisksClient.h"
|
|
|
|
|
|
|
|
#include "ICommand_fwd.h"
|
2022-04-08 07:52:16 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace po = boost::program_options;
|
2024-05-27 11:44:45 +00:00
|
|
|
using ProgramOptionsDescription = po::options_description;
|
|
|
|
using PositionalProgramOptionsDescription = po::positional_options_description;
|
|
|
|
using CommandLineOptions = po::variables_map;
|
|
|
|
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2024-06-14 11:06:56 +00:00
|
|
|
extern const int BAD_ARGUMENTS;
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|
2022-04-08 07:52:16 +00:00
|
|
|
|
|
|
|
class ICommand
|
|
|
|
{
|
|
|
|
public:
|
2024-05-27 11:44:45 +00:00
|
|
|
explicit ICommand() = default;
|
2022-06-16 17:38:33 +00:00
|
|
|
|
2022-04-08 07:52:16 +00:00
|
|
|
virtual ~ICommand() = default;
|
2022-06-16 17:38:33 +00:00
|
|
|
|
2024-05-27 11:44:45 +00:00
|
|
|
void execute(const Strings & commands, DisksClient & client);
|
2022-04-08 07:52:16 +00:00
|
|
|
|
2024-05-27 11:44:45 +00:00
|
|
|
virtual void executeImpl(const CommandLineOptions & options, DisksClient & client) = 0;
|
2022-06-21 14:40:22 +00:00
|
|
|
|
2024-05-27 11:44:45 +00:00
|
|
|
CommandLineOptions processCommandLineArguments(const Strings & commands);
|
2022-04-08 07:52:16 +00:00
|
|
|
|
2022-06-21 14:40:22 +00:00
|
|
|
protected:
|
2024-05-27 11:44:45 +00:00
|
|
|
template <typename T>
|
|
|
|
static T getValueFromCommandLineOptions(const CommandLineOptions & options, const String & name)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return options[name].as<T>();
|
|
|
|
}
|
2024-06-17 17:40:52 +00:00
|
|
|
catch (boost::bad_any_cast &)
|
2024-05-27 11:44:45 +00:00
|
|
|
{
|
2024-05-28 13:17:49 +00:00
|
|
|
throw DB::Exception(ErrorCodes::BAD_ARGUMENTS, "Argument '{}' has wrong type and can't be parsed", name);
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static T getValueFromCommandLineOptionsThrow(const CommandLineOptions & options, const String & name)
|
|
|
|
{
|
|
|
|
if (options.count(name))
|
|
|
|
return getValueFromCommandLineOptions<T>(options, name);
|
2024-09-19 11:51:02 +00:00
|
|
|
|
|
|
|
throw DB::Exception(ErrorCodes::BAD_ARGUMENTS, "Mandatory argument '{}' is missing", name);
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static T getValueFromCommandLineOptionsWithDefault(const CommandLineOptions & options, const String & name, const T & default_value)
|
|
|
|
{
|
|
|
|
if (options.count(name))
|
|
|
|
return getValueFromCommandLineOptions<T>(options, name);
|
2024-09-19 11:51:02 +00:00
|
|
|
|
|
|
|
return default_value;
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static std::optional<T> getValueFromCommandLineOptionsWithOptional(const CommandLineOptions & options, const String & name)
|
|
|
|
{
|
|
|
|
if (options.count(name))
|
|
|
|
return std::optional{getValueFromCommandLineOptions<T>(options, name)};
|
2024-09-19 11:51:02 +00:00
|
|
|
|
|
|
|
return std::nullopt;
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DiskWithPath & getDiskWithPath(DisksClient & client, const CommandLineOptions & options, const String & name);
|
2022-04-08 07:52:16 +00:00
|
|
|
|
2024-07-01 11:11:16 +00:00
|
|
|
String getTargetLocation(const String & path_from, DiskWithPath & disk_to, const String & path_to)
|
|
|
|
{
|
2024-08-10 22:13:40 +00:00
|
|
|
if (!disk_to.getDisk()->existsDirectory(path_to))
|
2024-07-01 11:11:16 +00:00
|
|
|
{
|
|
|
|
return path_to;
|
|
|
|
}
|
|
|
|
String copied_path_from = path_from;
|
|
|
|
if (copied_path_from.ends_with('/'))
|
|
|
|
{
|
|
|
|
copied_path_from.pop_back();
|
|
|
|
}
|
|
|
|
String plain_filename = fs::path(copied_path_from).filename();
|
|
|
|
|
|
|
|
return fs::path{path_to} / plain_filename;
|
|
|
|
}
|
|
|
|
|
2022-04-08 07:52:16 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
String command_name;
|
|
|
|
String description;
|
2024-05-27 11:44:45 +00:00
|
|
|
ProgramOptionsDescription options_description;
|
2022-04-08 07:52:16 +00:00
|
|
|
|
|
|
|
protected:
|
2024-05-27 11:44:45 +00:00
|
|
|
PositionalProgramOptionsDescription positional_options_description;
|
|
|
|
};
|
2022-04-08 07:52:16 +00:00
|
|
|
|
2022-12-08 17:53:05 +00:00
|
|
|
DB::CommandPtr makeCommandCopy();
|
|
|
|
DB::CommandPtr makeCommandListDisks();
|
2024-05-27 11:44:45 +00:00
|
|
|
DB::CommandPtr makeCommandList();
|
|
|
|
DB::CommandPtr makeCommandChangeDirectory();
|
|
|
|
DB::CommandPtr makeCommandLink();
|
2022-12-08 17:53:05 +00:00
|
|
|
DB::CommandPtr makeCommandMove();
|
|
|
|
DB::CommandPtr makeCommandRead();
|
|
|
|
DB::CommandPtr makeCommandRemove();
|
|
|
|
DB::CommandPtr makeCommandWrite();
|
|
|
|
DB::CommandPtr makeCommandMkDir();
|
2024-05-27 11:44:45 +00:00
|
|
|
DB::CommandPtr makeCommandSwitchDisk();
|
2024-06-13 19:14:16 +00:00
|
|
|
DB::CommandPtr makeCommandGetCurrentDiskAndPath();
|
2024-06-10 16:17:36 +00:00
|
|
|
DB::CommandPtr makeCommandHelp(const DisksApp & disks_app);
|
2024-06-26 15:59:15 +00:00
|
|
|
DB::CommandPtr makeCommandTouch();
|
2024-05-27 14:26:20 +00:00
|
|
|
#ifdef CLICKHOUSE_CLOUD
|
|
|
|
DB::CommandPtr makeCommandPackedIO();
|
|
|
|
#endif
|
2024-05-27 11:44:45 +00:00
|
|
|
}
|