-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Expand file tree
/
Copy pathCommandWrite.cpp
More file actions
88 lines (75 loc) · 2.99 KB
/
CommandWrite.cpp
File metadata and controls
88 lines (75 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <Interpreters/Context.h>
#include <ICommand.h>
#include <IO/ReadBufferFromEmptyFile.h>
#include <IO/ReadBufferFromFile.h>
#include <IO/WriteBufferFromFile.h>
#include <IO/copyData.h>
#include <Common/TerminalSize.h>
#include <Common/logger_useful.h>
#include <Disks/WriteMode.h>
namespace DB
{
namespace ErrorCodes
{
extern const int BAD_ARGUMENTS;
}
class CommandWrite final : public ICommand
{
public:
CommandWrite() : ICommand("CommandWrite")
{
command_name = "write";
description = "Write a file from `path-from` to `path-to`";
options_description.add_options()(
"path-from",
po::value<String>(),
"file from which we are reading, defaults to `stdin` (input from `stdin` is finished by Ctrl+D)")(
"path-to", po::value<String>(), "file to which we are writing (mandatory, positional)")(
"mode", po::value<String>(), "write mode: `rewrite` (default) or `append`");
positional_options_description.add("path-to", 1);
}
void executeImpl(const CommandLineOptions & options, DisksClient & client) override
{
auto disk = client.getCurrentDiskWithPath();
std::optional<String> path_from = getValueFromCommandLineOptionsWithOptional<String>(options, "path-from");
String path_to = disk.getRelativeFromRoot(getValueFromCommandLineOptionsThrow<String>(options, "path-to"));
std::optional<String> write_mode_param = getValueFromCommandLineOptionsWithOptional<String>(options, "mode");
WriteMode write_mode = WriteMode::Rewrite;
if (write_mode_param.has_value())
{
if (*write_mode_param == "rewrite")
write_mode = WriteMode::Rewrite;
else if (*write_mode_param == "append")
write_mode = WriteMode::Append;
else
throw Exception(
ErrorCodes::BAD_ARGUMENTS, "invalid `mode`, expected `rewrite` or `append`, actual '{}'", *write_mode_param);
}
auto in = [&]() -> std::unique_ptr<ReadBufferFromFileBase>
{
if (!path_from.has_value())
return std::make_unique<ReadBufferFromFileDescriptor>(STDIN_FILENO);
String relative_path_from = disk.getRelativeFromRoot(path_from.value());
auto res = disk.getDisk()->readFileIfExists(relative_path_from, getReadSettings());
if (res)
return res;
/// For backward compatibility.
return std::make_unique<ReadBufferFromEmptyFile>();
}();
LOG_INFO(
log,
"Writing file from '{}' to '{}' with mode '{}' at disk '{}'",
path_from.value_or("stdin"),
path_to,
write_mode,
disk.getDisk()->getName());
auto out = disk.getDisk()->writeFile(path_to, DBMS_DEFAULT_BUFFER_SIZE, write_mode);
copyData(*in, *out);
out->finalize();
}
};
CommandPtr makeCommandWrite()
{
return std::make_shared<DB::CommandWrite>();
}
}