1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/common/file_system.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/constants.hpp" |
12 | #include "duckdb/common/file_buffer.hpp" |
13 | |
14 | #include <functional> |
15 | |
16 | namespace duckdb { |
17 | class ClientContext; |
18 | class FileSystem; |
19 | |
20 | struct FileHandle { |
21 | public: |
22 | FileHandle(FileSystem &file_system, string path) : file_system(file_system), path(path) { |
23 | } |
24 | FileHandle(const FileHandle &) = delete; |
25 | virtual ~FileHandle() { |
26 | } |
27 | |
28 | void Read(void *buffer, idx_t nr_bytes, idx_t location); |
29 | void Write(void *buffer, idx_t nr_bytes, idx_t location); |
30 | void Sync(); |
31 | void Truncate(int64_t new_size); |
32 | |
33 | protected: |
34 | virtual void Close() = 0; |
35 | |
36 | public: |
37 | FileSystem &file_system; |
38 | string path; |
39 | }; |
40 | |
41 | enum class FileLockType : uint8_t { NO_LOCK = 0, READ_LOCK = 1, WRITE_LOCK = 2 }; |
42 | |
43 | class FileFlags { |
44 | public: |
45 | //! Open file with read access |
46 | static constexpr uint8_t READ = 1 << 0; |
47 | //! Open file with read/write access |
48 | static constexpr uint8_t WRITE = 1 << 1; |
49 | //! Use direct IO when reading/writing to the file |
50 | static constexpr uint8_t DIRECT_IO = 1 << 2; |
51 | //! Create file if not exists, can only be used together with WRITE |
52 | static constexpr uint8_t CREATE = 1 << 3; |
53 | //! Open file in append mode |
54 | static constexpr uint8_t APPEND = 1 << 4; |
55 | }; |
56 | |
57 | class FileSystem { |
58 | public: |
59 | virtual ~FileSystem() { |
60 | } |
61 | |
62 | public: |
63 | static FileSystem &GetFileSystem(ClientContext &context); |
64 | |
65 | virtual unique_ptr<FileHandle> OpenFile(const char *path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK); |
66 | unique_ptr<FileHandle> OpenFile(string &path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK) { |
67 | return OpenFile(path.c_str(), flags, lock); |
68 | } |
69 | //! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is |
70 | //! equivalent to calling SetFilePointer(location) followed by calling Read(). |
71 | virtual void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); |
72 | //! Write exactly nr_bytes to the specified location in the file. Fails if nr_bytes could not be read. This is |
73 | //! equivalent to calling SetFilePointer(location) followed by calling Write(). |
74 | virtual void Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); |
75 | //! Read nr_bytes from the specified file into the buffer, moving the file pointer forward by nr_bytes. Returns the |
76 | //! amount of bytes read. |
77 | virtual int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes); |
78 | //! Write nr_bytes from the buffer into the file, moving the file pointer forward by nr_bytes. |
79 | virtual int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes); |
80 | |
81 | //! Returns the file size of a file handle, returns -1 on error |
82 | virtual int64_t GetFileSize(FileHandle &handle); |
83 | //! Truncate a file to a maximum size of new_size, new_size should be smaller than or equal to the current size of |
84 | //! the file |
85 | virtual void Truncate(FileHandle &handle, int64_t new_size); |
86 | |
87 | //! Check if a directory exists |
88 | virtual bool DirectoryExists(const string &directory); |
89 | //! Create a directory if it does not exist |
90 | virtual void CreateDirectory(const string &directory); |
91 | //! Recursively remove a directory and all files in it |
92 | virtual void RemoveDirectory(const string &directory); |
93 | //! List files in a directory, invoking the callback method for each one |
94 | virtual bool ListFiles(const string &directory, std::function<void(string)> callback); |
95 | //! Move a file from source path to the target, StorageManager relies on this being an atomic action for ACID |
96 | //! properties |
97 | virtual void MoveFile(const string &source, const string &target); |
98 | //! Check if a file exists |
99 | virtual bool FileExists(const string &filename); |
100 | //! Remove a file from disk |
101 | virtual void RemoveFile(const string &filename); |
102 | //! Path separator for the current file system |
103 | virtual string PathSeparator(); |
104 | //! Join two paths together |
105 | virtual string JoinPath(const string &a, const string &path); |
106 | //! Sync a file handle to disk |
107 | virtual void FileSync(FileHandle &handle); |
108 | |
109 | private: |
110 | //! Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location |
111 | void SetFilePointer(FileHandle &handle, idx_t location); |
112 | }; |
113 | |
114 | } // namespace duckdb |
115 | |