diff --git a/docs/en/operations/utilities/clickhouse-disks.md b/docs/en/operations/utilities/clickhouse-disks.md index aeca49c0e1e..e22bc06b641 100644 --- a/docs/en/operations/utilities/clickhouse-disks.md +++ b/docs/en/operations/utilities/clickhouse-disks.md @@ -56,4 +56,4 @@ In these documentation file all mandatory positional arguments are referred as ` * `switch-disk [--path path] ` Switch to disk `disk` on path `path` (if `path` is not specified default value is a previous path on disk `disk`). * `write (w) [--path-from path] `. - Write a file from `path` (`stdin` if not supplied) to `path-to`. + Write a file from `path` (`stdin` if `path` is not supplied, input must finish by Ctrl+D) to `path-to`. diff --git a/programs/disks/CMakeLists.txt b/programs/disks/CMakeLists.txt index 40f9cf3401c..7e8afe084fb 100644 --- a/programs/disks/CMakeLists.txt +++ b/programs/disks/CMakeLists.txt @@ -14,6 +14,7 @@ set (CLICKHOUSE_DISKS_SOURCES CommandSwitchDisk.cpp CommandWrite.cpp CommandHelp.cpp + CommandTouch.cpp CommandGetCurrentDiskAndPath.cpp) if (CLICKHOUSE_CLOUD) diff --git a/programs/disks/CommandTouch.cpp b/programs/disks/CommandTouch.cpp new file mode 100644 index 00000000000..c0bdb64cf9e --- /dev/null +++ b/programs/disks/CommandTouch.cpp @@ -0,0 +1,34 @@ +#include +#include +#include "DisksApp.h" +#include "DisksClient.h" +#include "ICommand.h" + +namespace DB +{ + +class CommandTouch final : public ICommand +{ +public: + explicit CommandTouch() : ICommand() + { + command_name = "touch"; + description = "Create a file by path"; + options_description.add_options()("path", po::value(), "the path of listing (mandatory, positional)"); + positional_options_description.add("path", 1); + } + + void executeImpl(const CommandLineOptions & options, DisksClient & client) override + { + auto disk = client.getCurrentDiskWithPath(); + String path = getValueFromCommandLineOptionsThrow(options, "path"); + + disk.getDisk()->createFile(disk.getRelativeFromRoot(path)); + } +}; + +CommandPtr makeCommandTouch() +{ + return std::make_shared(); +} +} diff --git a/programs/disks/CommandWrite.cpp b/programs/disks/CommandWrite.cpp index 433ebb3d5cf..ffe27f37c0e 100644 --- a/programs/disks/CommandWrite.cpp +++ b/programs/disks/CommandWrite.cpp @@ -16,7 +16,7 @@ public: { command_name = "write"; description = "Write a file from `FROM_PATH` to `TO_PATH`"; - options_description.add_options()("path-from", po::value(), "file from which we are reading, defaults to `stdin`")( + options_description.add_options()("path-from", po::value(), "file from which we are reading, defaults to `stdin` (input from `stdin` is finished by Ctrl+D)")( "path-to", po::value(), "file to which we are writing (mandatory, positional)"); positional_options_description.add("path-to", 1); } diff --git a/programs/disks/DisksApp.cpp b/programs/disks/DisksApp.cpp index 9ef051a2ece..392fca8e035 100644 --- a/programs/disks/DisksApp.cpp +++ b/programs/disks/DisksApp.cpp @@ -89,6 +89,7 @@ std::vector DisksApp::getCommandsToComplete(const String & command_prefi } if (!answer.empty()) { + std::sort(answer.begin(), answer.end()); return answer; } for (const auto & [word, _] : aliases) @@ -100,6 +101,7 @@ std::vector DisksApp::getCommandsToComplete(const String & command_prefi } if (!answer.empty()) { + std::sort(answer.begin(), answer.end()); return answer; } return {command_prefix}; @@ -179,6 +181,7 @@ std::vector DisksApp::getCompletions(const String & prefix) const } if (!answer.empty()) { + std::sort(answer.begin(), answer.end()); return answer; } else @@ -292,6 +295,7 @@ void DisksApp::addOptions() command_descriptions.emplace("mkdir", makeCommandMkDir()); command_descriptions.emplace("switch-disk", makeCommandSwitchDisk()); command_descriptions.emplace("current_disk_with_path", makeCommandGetCurrentDiskAndPath()); + command_descriptions.emplace("touch", makeCommandTouch()); command_descriptions.emplace("help", makeCommandHelp(*this)); #ifdef CLICKHOUSE_CLOUD command_descriptions.emplace("packed-io", makeCommandPackedIO()); diff --git a/programs/disks/DisksApp.h b/programs/disks/DisksApp.h index 1ecd9944fb8..f8167884c62 100644 --- a/programs/disks/DisksApp.h +++ b/programs/disks/DisksApp.h @@ -84,8 +84,10 @@ private: {"list_disks", "list-disks"}, {"ln", "link"}, {"rm", "remove"}, + {"cat", "read"}, {"r", "read"}, {"w", "write"}, + {"create", "touch"}, {"delete", "remove"}, {"ls-disks", "list-disks"}, {"ls_disks", "list-disks"}, diff --git a/programs/disks/DisksClient.h b/programs/disks/DisksClient.h index 3320c5f7cef..8a55d22af93 100644 --- a/programs/disks/DisksClient.h +++ b/programs/disks/DisksClient.h @@ -32,7 +32,10 @@ public: String getCurrentPath() const { return path; } - bool isDirectory(const String & any_path) const { return disk->isDirectory(getRelativeFromRoot(any_path)); } + bool isDirectory(const String & any_path) const + { + return disk->isDirectory(getRelativeFromRoot(any_path)) || (getRelativeFromRoot(any_path).empty() && (disk->isDirectory("/"))); + } std::vector listAllFilesByPath(const String & any_path) const; diff --git a/programs/disks/ICommand.h b/programs/disks/ICommand.h index 2b409d4ade6..4b0ec731966 100644 --- a/programs/disks/ICommand.h +++ b/programs/disks/ICommand.h @@ -123,6 +123,7 @@ DB::CommandPtr makeCommandMkDir(); DB::CommandPtr makeCommandSwitchDisk(); DB::CommandPtr makeCommandGetCurrentDiskAndPath(); DB::CommandPtr makeCommandHelp(const DisksApp & disks_app); +DB::CommandPtr makeCommandTouch(); #ifdef CLICKHOUSE_CLOUD DB::CommandPtr makeCommandPackedIO(); #endif