diff options
author | ilnaz <ilnaz@ydb.tech> | 2023-03-20 17:40:49 +0300 |
---|---|---|
committer | ilnaz <ilnaz@ydb.tech> | 2023-03-20 17:40:49 +0300 |
commit | ef2805fc73eed81da2e02b0c8e45e67366a4ab62 (patch) | |
tree | 325b7b88401ada64e5c8cfa2666aed40eb07a774 | |
parent | 2d4c22bc43cfc5218e01963d333c9eab2dba93a8 (diff) | |
download | ydb-ef2805fc73eed81da2e02b0c8e45e67366a4ab62.tar.gz |
Recursive rmdir
4 files changed, 84 insertions, 17 deletions
diff --git a/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp b/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp index c48fc04a25..bbaf60f7e5 100644 --- a/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp +++ b/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp @@ -2,7 +2,7 @@ #include <ydb/public/lib/json_value/ydb_json_value.h> #include <ydb/public/sdk/cpp/client/ydb_proto/accessor.h> -#include <ydb/public/sdk/cpp/client/ydb_table/table.h> +#include <ydb/public/lib/ydb_cli/common/pretty_table.h> #include <ydb/public/lib/ydb_cli/common/print_utils.h> #include <ydb/public/lib/ydb_cli/common/scheme_printers.h> @@ -54,6 +54,14 @@ TCommandRemoveDirectory::TCommandRemoveDirectory() void TCommandRemoveDirectory::Config(TConfig& config) { TYdbOperationCommand::Config(config); + config.Opts->AddLongOption('r', "recursive", "Remove directory and its content recursively. Prompt once by default") + .StoreTrue(&Recursive); + config.Opts->AddLongOption('f', "force", "Never prompt") + .NoArgument().StoreValue(&Prompt, ERecursiveRemovePrompt::Never); + config.Opts->AddCharOption('i', "Prompt before every removal") + .NoArgument().StoreValue(&Prompt, ERecursiveRemovePrompt::Always); + config.Opts->AddCharOption('I', "Prompt once") + .NoArgument().StoreValue(&Prompt, ERecursiveRemovePrompt::Once); config.SetFreeArgsNum(1); SetFreeArgTitle(0, "<path>", "Path to remove"); @@ -65,13 +73,24 @@ void TCommandRemoveDirectory::Parse(TConfig& config) { } int TCommandRemoveDirectory::Run(TConfig& config) { - NScheme::TSchemeClient client(CreateDriver(config)); - ThrowOnError( - client.RemoveDirectory( - Path, - FillSettings(NScheme::TRemoveDirectorySettings()) - ).GetValueSync() - ); + TDriver driver = CreateDriver(config); + NScheme::TSchemeClient schemeClient(driver); + const auto settings = FillSettings(NScheme::TRemoveDirectorySettings()); + + if (Recursive) { + NTable::TTableClient tableClient(driver); + NTopic::TTopicClient topicClient(driver); + const auto prompt = Prompt.GetOrElse(ERecursiveRemovePrompt::Once); + ThrowOnError(RemoveDirectoryRecursive(schemeClient, tableClient, topicClient, Path, prompt, settings)); + } else { + if (Prompt) { + if (!NConsoleClient::Prompt(*Prompt, Path, NScheme::ESchemeEntryType::Directory)) { + return EXIT_SUCCESS; + } + } + ThrowOnError(schemeClient.RemoveDirectory(Path, settings).GetValueSync()); + } + return EXIT_SUCCESS; } diff --git a/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h b/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h index 360eaab66f..bc6f2e867c 100644 --- a/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h +++ b/ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h @@ -5,9 +5,9 @@ #include <ydb/public/sdk/cpp/client/ydb_scheme/scheme.h> #include <ydb/public/sdk/cpp/client/ydb_table/table.h> -#include <ydb/public/lib/ydb_cli/common/format.h> -#include <ydb/public/lib/ydb_cli/common/pretty_table.h> #include <ydb/public/sdk/cpp/client/ydb_topic/topic.h> +#include <ydb/public/lib/ydb_cli/common/format.h> +#include <ydb/public/lib/ydb_cli/common/recursive_remove.h> namespace NYdb { namespace NConsoleClient { @@ -31,6 +31,10 @@ public: virtual void Config(TConfig& config) override; virtual void Parse(TConfig& config) override; virtual int Run(TConfig& config) override; + +private: + bool Recursive = false; + TMaybe<ERecursiveRemovePrompt> Prompt; }; class TCommandDescribe : public TYdbOperationCommand, public TCommandWithPath, public TCommandWithFormat { diff --git a/ydb/public/lib/ydb_cli/common/recursive_remove.cpp b/ydb/public/lib/ydb_cli/common/recursive_remove.cpp index 1fbde05e4e..657dad09ef 100644 --- a/ydb/public/lib/ydb_cli/common/recursive_remove.cpp +++ b/ydb/public/lib/ydb_cli/common/recursive_remove.cpp @@ -1,3 +1,4 @@ +#include "interactive.h" #include "recursive_remove.h" #include <ydb/public/lib/ydb_cli/common/recursive_list.h> @@ -36,17 +37,43 @@ NYql::TIssues MakeIssues(const TString& error) { return issues; } +bool Prompt(const TString& path, ESchemeEntryType type) { + Cout << "Remove " << to_lower(ToString(type)) << " '" << path << "' (y/n)? "; + return AskYesOrNo(); +} + +bool Prompt(ERecursiveRemovePrompt mode, const TString& path, NScheme::ESchemeEntryType type, bool first) { + switch (mode) { + case ERecursiveRemovePrompt::Always: + return Prompt(path, type); + case ERecursiveRemovePrompt::Once: + if (first) { + return Prompt(path, type); + } else { + return true; + } + case ERecursiveRemovePrompt::Never: + return true; + } +} + template <typename TClient, typename TSettings> using TRemoveFunc = TStatus(*)(TClient&, const TString&, const TSettings&); template <typename TClient, typename TSettings> -TStatus Remove(TRemoveFunc<TClient, TSettings> func, TClient* client, const TString& path, const TRemoveDirectorySettings& settings) { +TStatus Remove(TRemoveFunc<TClient, TSettings> func, TClient* client, const TSchemeEntry& entry, + ERecursiveRemovePrompt prompt, const TRemoveDirectorySettings& settings) +{ if (!client) { return TStatus(EStatus::GENERIC_ERROR, MakeIssues(TStringBuilder() << TypeName<TClient>() << " not specified")); } - return func(*client, path, TSettings(settings)); + if (Prompt(prompt, entry.Name, entry.Type, false)) { + return func(*client, entry.Name, TSettings(settings)); + } else { + return TStatus(EStatus::SUCCESS, {}); + } } TStatus RemoveDirectoryRecursive( @@ -54,6 +81,7 @@ TStatus RemoveDirectoryRecursive( TTableClient* tableClient, TTopicClient* topicClient, const TString& path, + ERecursiveRemovePrompt prompt, const TRemoveDirectorySettings& settings, bool removeSelf) { @@ -62,25 +90,31 @@ TStatus RemoveDirectoryRecursive( return recursiveListResult.Status; } + if (prompt == ERecursiveRemovePrompt::Once) { + if (!Prompt(path, ESchemeEntryType::Directory)) { + return TStatus(EStatus::SUCCESS, {}); + } + } + // output order is: Root, Recursive(children)... // we need to reverse it to delete recursively for (auto it = recursiveListResult.Entries.rbegin(); it != recursiveListResult.Entries.rend(); ++it) { const auto& entry = *it; switch (entry.Type) { case ESchemeEntryType::Directory: - if (auto result = Remove(&RemoveDirectory, &schemeClient, entry.Name, settings); !result.IsSuccess()) { + if (auto result = Remove(&RemoveDirectory, &schemeClient, entry, prompt, settings); !result.IsSuccess()) { return result; } break; case ESchemeEntryType::Table: - if (auto result = Remove(&RemoveTable, tableClient, entry.Name, settings); !result.IsSuccess()) { + if (auto result = Remove(&RemoveTable, tableClient, entry, prompt, settings); !result.IsSuccess()) { return result; } break; case ESchemeEntryType::Topic: - if (auto result = Remove(&RemoveTopic, topicClient, entry.Name, settings); !result.IsSuccess()) { + if (auto result = Remove(&RemoveTopic, topicClient, entry, prompt, settings); !result.IsSuccess()) { return result; } break; @@ -101,7 +135,7 @@ TStatus RemoveDirectoryRecursive( const TRemoveDirectorySettings& settings, bool removeSelf) { - return RemoveDirectoryRecursive(schemeClient, &tableClient, nullptr, path, settings, removeSelf); + return RemoveDirectoryRecursive(schemeClient, &tableClient, nullptr, path, ERecursiveRemovePrompt::Never, settings, removeSelf); } TStatus RemoveDirectoryRecursive( @@ -109,10 +143,11 @@ TStatus RemoveDirectoryRecursive( TTableClient& tableClient, TTopicClient& topicClient, const TString& path, + ERecursiveRemovePrompt prompt, const TRemoveDirectorySettings& settings, bool removeSelf) { - return RemoveDirectoryRecursive(schemeClient, &tableClient, &topicClient, path, settings, removeSelf); + return RemoveDirectoryRecursive(schemeClient, &tableClient, &topicClient, path, prompt, settings, removeSelf); } } diff --git a/ydb/public/lib/ydb_cli/common/recursive_remove.h b/ydb/public/lib/ydb_cli/common/recursive_remove.h index 12108b3fd0..392da273d7 100644 --- a/ydb/public/lib/ydb_cli/common/recursive_remove.h +++ b/ydb/public/lib/ydb_cli/common/recursive_remove.h @@ -6,6 +6,14 @@ namespace NYdb::NConsoleClient { +enum class ERecursiveRemovePrompt { + Always, + Once, + Never, +}; + +bool Prompt(ERecursiveRemovePrompt mode, const TString& path, NScheme::ESchemeEntryType type, bool first = true); + TStatus RemoveDirectoryRecursive( NScheme::TSchemeClient& schemeClient, NTable::TTableClient& tableClient, @@ -18,6 +26,7 @@ TStatus RemoveDirectoryRecursive( NTable::TTableClient& tableClient, NTopic::TTopicClient& topicClient, const TString& path, + ERecursiveRemovePrompt prompt, const NScheme::TRemoveDirectorySettings& settings = {}, bool removeSelf = true); |