1 | #include "FileDictionarySource.h" |
2 | #include <DataStreams/OwningBlockInputStream.h> |
3 | #include <IO/ReadBufferFromFile.h> |
4 | #include <Interpreters/Context.h> |
5 | #include <Poco/File.h> |
6 | #include "DictionarySourceFactory.h" |
7 | #include "DictionaryStructure.h" |
8 | #include "registerDictionaries.h" |
9 | |
10 | namespace DB |
11 | { |
12 | static const UInt64 max_block_size = 8192; |
13 | |
14 | namespace ErrorCodes |
15 | { |
16 | extern const int PATH_ACCESS_DENIED; |
17 | } |
18 | |
19 | |
20 | FileDictionarySource::FileDictionarySource( |
21 | const std::string & filepath_, const std::string & format_, |
22 | Block & sample_block_, const Context & context_, bool check_config) |
23 | : filepath{filepath_} |
24 | , format{format_} |
25 | , sample_block{sample_block_} |
26 | , context(context_) |
27 | { |
28 | if (check_config) |
29 | { |
30 | const String user_files_path = context.getUserFilesPath(); |
31 | if (!startsWith(filepath, user_files_path)) |
32 | throw Exception("File path " + filepath + " is not inside " + user_files_path, ErrorCodes::PATH_ACCESS_DENIED); |
33 | } |
34 | } |
35 | |
36 | |
37 | FileDictionarySource::FileDictionarySource(const FileDictionarySource & other) |
38 | : filepath{other.filepath} |
39 | , format{other.format} |
40 | , sample_block{other.sample_block} |
41 | , context(other.context) |
42 | , last_modification{other.last_modification} |
43 | { |
44 | } |
45 | |
46 | |
47 | BlockInputStreamPtr FileDictionarySource::loadAll() |
48 | { |
49 | auto in_ptr = std::make_unique<ReadBufferFromFile>(filepath); |
50 | auto stream = context.getInputFormat(format, *in_ptr, sample_block, max_block_size); |
51 | last_modification = getLastModification(); |
52 | |
53 | return std::make_shared<OwningBlockInputStream<ReadBuffer>>(stream, std::move(in_ptr)); |
54 | } |
55 | |
56 | |
57 | std::string FileDictionarySource::toString() const |
58 | { |
59 | return "File: " + filepath + ' ' + format; |
60 | } |
61 | |
62 | |
63 | Poco::Timestamp FileDictionarySource::getLastModification() const |
64 | { |
65 | return Poco::File{filepath}.getLastModified(); |
66 | } |
67 | |
68 | void registerDictionarySourceFile(DictionarySourceFactory & factory) |
69 | { |
70 | auto createTableSource = [=](const DictionaryStructure & dict_struct, |
71 | const Poco::Util::AbstractConfiguration & config, |
72 | const std::string & config_prefix, |
73 | Block & sample_block, |
74 | const Context & context, |
75 | bool check_config) -> DictionarySourcePtr |
76 | { |
77 | if (dict_struct.has_expressions) |
78 | throw Exception{"Dictionary source of type `file` does not support attribute expressions" , ErrorCodes::LOGICAL_ERROR}; |
79 | |
80 | const auto filepath = config.getString(config_prefix + ".file.path" ); |
81 | const auto format = config.getString(config_prefix + ".file.format" ); |
82 | |
83 | return std::make_unique<FileDictionarySource>(filepath, format, sample_block, context, check_config); |
84 | }; |
85 | |
86 | factory.registerSource("file" , createTableSource); |
87 | } |
88 | |
89 | } |
90 | |