mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-19 16:20:50 +00:00
Change wrong implementations of copy and move
This commit is contained in:
parent
90601e0a1d
commit
bb0b93f77d
@ -1,4 +1,5 @@
|
||||
#include <Interpreters/Context.h>
|
||||
#include "Common/Exception.h"
|
||||
#include <Common/TerminalSize.h>
|
||||
#include "DisksClient.h"
|
||||
#include "ICommand.h"
|
||||
@ -17,7 +18,8 @@ public:
|
||||
"disk-from", po::value<String>(), "disk from which we copy is executed (default value is a current disk)")(
|
||||
"disk-to", po::value<String>(), "disk to which copy is executed (default value is a current disk)")(
|
||||
"path-from", po::value<String>(), "path from which copy is executed (mandatory, positional)")(
|
||||
"path-to", po::value<String>(), "path to which copy is executed (mandatory, positional)");
|
||||
"path-to", po::value<String>(), "path to which copy is executed (mandatory, positional)")(
|
||||
"recursive", "recursively copy the directory");
|
||||
positional_options_description.add("path-from", 1);
|
||||
positional_options_description.add("path-to", 1);
|
||||
}
|
||||
@ -28,9 +30,55 @@ public:
|
||||
auto disk_to = getDiskWithPath(client, options, "disk-to");
|
||||
String path_from = disk_from.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path-from"));
|
||||
String path_to = disk_to.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path-to"));
|
||||
bool recursive = options.count("recursive");
|
||||
|
||||
disk_from.getDisk()->copyDirectoryContent(
|
||||
path_from, disk_to.getDisk(), path_to, /* read_settings= */ {}, /* write_settings= */ {}, /* cancellation_hook= */ {});
|
||||
if (!disk_from.getDisk()->exists(path_from))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "cannot stat '{}': No such file or directory", path_from);
|
||||
}
|
||||
else if (disk_from.getDisk()->isFile(path_from))
|
||||
{
|
||||
auto target_location = getTargetLocation(path_from, disk_to, path_to);
|
||||
if (!disk_to.getDisk()->exists(target_location) || disk_to.getDisk()->isFile(target_location))
|
||||
{
|
||||
disk_from.getDisk()->copyFile(
|
||||
path_from,
|
||||
*disk_to.getDisk(),
|
||||
target_location,
|
||||
/* read_settings= */ {},
|
||||
/* write_settings= */ {},
|
||||
/* cancellation_hook= */ {});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(
|
||||
ErrorCodes::BAD_ARGUMENTS, "cannot overwrite directory {} with non-directory {}", target_location, path_from);
|
||||
}
|
||||
}
|
||||
else if (disk_from.getDisk()->isDirectory(path_from))
|
||||
{
|
||||
if (!recursive)
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "--recursive not specified; omitting directory {}", path_from);
|
||||
}
|
||||
auto target_location = getTargetLocation(path_from, disk_to, path_to);
|
||||
|
||||
if (disk_to.getDisk()->isFile(target_location))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "cannot overwrite non-directory {} with directory {}", path_to, target_location);
|
||||
}
|
||||
else if (!disk_to.getDisk()->exists(target_location))
|
||||
{
|
||||
disk_to.getDisk()->createDirectory(target_location);
|
||||
}
|
||||
disk_from.getDisk()->copyDirectoryContent(
|
||||
path_from,
|
||||
disk_to.getDisk(),
|
||||
target_location,
|
||||
/* read_settings= */ {},
|
||||
/* write_settings= */ {},
|
||||
/* cancellation_hook= */ {});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,14 +13,14 @@ public:
|
||||
{
|
||||
command_name = "mkdir";
|
||||
description = "Creates a directory";
|
||||
options_description.add_options()("recursive", "recursively create directories")(
|
||||
"path", po::value<String>(), "the path of listing (mandatory, positional)");
|
||||
options_description.add_options()("parents", "recursively create directories")(
|
||||
"path", po::value<String>(), "the path on which directory should be created (mandatory, positional)");
|
||||
positional_options_description.add("path", 1);
|
||||
}
|
||||
|
||||
void executeImpl(const CommandLineOptions & options, DisksClient & client) override
|
||||
{
|
||||
bool recursive = options.count("recursive");
|
||||
bool recursive = options.count("parents");
|
||||
auto disk = client.getCurrentDiskWithPath();
|
||||
|
||||
String path = disk.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path"));
|
||||
|
@ -25,9 +25,38 @@ public:
|
||||
String path_to = disk.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path-to"));
|
||||
|
||||
if (disk.getDisk()->isFile(path_from))
|
||||
{
|
||||
disk.getDisk()->moveFile(path_from, path_to);
|
||||
else
|
||||
disk.getDisk()->moveDirectory(path_from, path_to);
|
||||
}
|
||||
else if (disk.getDisk()->isDirectory(path_from))
|
||||
{
|
||||
auto target_location = getTargetLocation(path_from, disk, path_to);
|
||||
if (!disk.getDisk()->exists(target_location))
|
||||
{
|
||||
disk.getDisk()->createDirectory(target_location);
|
||||
disk.getDisk()->moveDirectory(path_from, target_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disk.getDisk()->isFile(target_location))
|
||||
{
|
||||
throw Exception(
|
||||
ErrorCodes::BAD_ARGUMENTS, "cannot overwrite non-directory '{}' with directory '{}'", target_location, path_from);
|
||||
}
|
||||
if (!disk.getDisk()->isDirectoryEmpty(target_location))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "cannot move '{}' to '{}': Directory not empty", path_from, target_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
disk.getDisk()->moveDirectory(path_from, target_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!disk.getDisk()->exists(path_from))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "cannot stat '{}': No such file or directory", path_from);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <Interpreters/Context.h>
|
||||
#include "Common/Exception.h"
|
||||
#include "ICommand.h"
|
||||
|
||||
namespace DB
|
||||
@ -10,8 +11,9 @@ public:
|
||||
CommandRemove()
|
||||
{
|
||||
command_name = "remove";
|
||||
description = "Remove file or directory with all children. Throws exception if file doesn't exists";
|
||||
options_description.add_options()("path", po::value<String>(), "path from which we copy (mandatory, positional)");
|
||||
description = "Remove file or directory. Throws exception if file doesn't exists";
|
||||
options_description.add_options()("path", po::value<String>(), "path from which we copy (mandatory, positional)")(
|
||||
"recursive", "recursively removes the directory (required to remove a directory)");
|
||||
positional_options_description.add("path", 1);
|
||||
}
|
||||
|
||||
@ -19,7 +21,26 @@ public:
|
||||
{
|
||||
auto disk = client.getCurrentDiskWithPath();
|
||||
const String & path = disk.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path"));
|
||||
disk.getDisk()->removeRecursive(path);
|
||||
bool recursive = options.count("recursive");
|
||||
if (!disk.getDisk()->exists(path))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Path {} on disk {} doesn't exist", path, disk.getDisk()->getName());
|
||||
}
|
||||
else if (disk.getDisk()->isDirectory(path))
|
||||
{
|
||||
if (!recursive)
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "cannot remove '{}': Is a directory", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
disk.getDisk()->removeRecursive(path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
disk.getDisk()->removeFileIfExists(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ DiskWithPath::DiskWithPath(DiskPtr disk_, std::optional<String> path_) : disk(di
|
||||
{
|
||||
if (!fs::path{path_.value()}.is_absolute())
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Initializing path {} is not absolute", path_.value());
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Initializing path {} is not absolute", path_.value());
|
||||
}
|
||||
path = path_.value();
|
||||
}
|
||||
|
@ -100,6 +100,22 @@ protected:
|
||||
|
||||
DiskWithPath & getDiskWithPath(DisksClient & client, const CommandLineOptions & options, const String & name);
|
||||
|
||||
String getTargetLocation(const String & path_from, DiskWithPath & disk_to, const String & path_to)
|
||||
{
|
||||
if (!disk_to.getDisk()->isDirectory(path_to))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
String command_name;
|
||||
|
Loading…
Reference in New Issue
Block a user