aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorilnaz <ilnaz@ydb.tech>2023-03-20 17:40:49 +0300
committerilnaz <ilnaz@ydb.tech>2023-03-20 17:40:49 +0300
commitef2805fc73eed81da2e02b0c8e45e67366a4ab62 (patch)
tree325b7b88401ada64e5c8cfa2666aed40eb07a774
parent2d4c22bc43cfc5218e01963d333c9eab2dba93a8 (diff)
downloadydb-ef2805fc73eed81da2e02b0c8e45e67366a4ab62.tar.gz
Recursive rmdir
-rw-r--r--ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp35
-rw-r--r--ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h8
-rw-r--r--ydb/public/lib/ydb_cli/common/recursive_remove.cpp49
-rw-r--r--ydb/public/lib/ydb_cli/common/recursive_remove.h9
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);