1#include "duckdb/common/virtual_file_system.hpp"
2
3#include "duckdb/common/gzip_file_system.hpp"
4#include "duckdb/common/pipe_file_system.hpp"
5#include "duckdb/common/string_util.hpp"
6
7namespace duckdb {
8
9VirtualFileSystem::VirtualFileSystem() : default_fs(FileSystem::CreateLocal()) {
10 VirtualFileSystem::RegisterSubSystem(compression_type: FileCompressionType::GZIP, fs: make_uniq<GZipFileSystem>());
11}
12
13unique_ptr<FileHandle> VirtualFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock,
14 FileCompressionType compression, FileOpener *opener) {
15 if (compression == FileCompressionType::AUTO_DETECT) {
16 // auto detect compression settings based on file name
17 auto lower_path = StringUtil::Lower(str: path);
18 if (StringUtil::EndsWith(str: lower_path, suffix: ".tmp")) {
19 // strip .tmp
20 lower_path = lower_path.substr(pos: 0, n: lower_path.length() - 4);
21 }
22 if (StringUtil::EndsWith(str: lower_path, suffix: ".gz")) {
23 compression = FileCompressionType::GZIP;
24 } else if (StringUtil::EndsWith(str: lower_path, suffix: ".zst")) {
25 compression = FileCompressionType::ZSTD;
26 } else {
27 compression = FileCompressionType::UNCOMPRESSED;
28 }
29 }
30 // open the base file handle
31 auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, compression: FileCompressionType::UNCOMPRESSED, opener);
32 if (file_handle->GetType() == FileType::FILE_TYPE_FIFO) {
33 file_handle = PipeFileSystem::OpenPipe(handle: std::move(file_handle));
34 } else if (compression != FileCompressionType::UNCOMPRESSED) {
35 auto entry = compressed_fs.find(x: compression);
36 if (entry == compressed_fs.end()) {
37 throw NotImplementedException(
38 "Attempting to open a compressed file, but the compression type is not supported");
39 }
40 file_handle = entry->second->OpenCompressedFile(handle: std::move(file_handle), write: flags & FileFlags::FILE_FLAGS_WRITE);
41 }
42 return file_handle;
43}
44
45} // namespace duckdb
46