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
10namespace DB
11{
12static const UInt64 max_block_size = 8192;
13
14namespace ErrorCodes
15{
16 extern const int PATH_ACCESS_DENIED;
17}
18
19
20FileDictionarySource::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
37FileDictionarySource::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
47BlockInputStreamPtr 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
57std::string FileDictionarySource::toString() const
58{
59 return "File: " + filepath + ' ' + format;
60}
61
62
63Poco::Timestamp FileDictionarySource::getLastModification() const
64{
65 return Poco::File{filepath}.getLastModified();
66}
67
68void 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