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
16namespace duckdb {
17class ClientContext;
18class FileSystem;
19
20struct FileHandle {
21public:
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
33protected:
34 virtual void Close() = 0;
35
36public:
37 FileSystem &file_system;
38 string path;
39};
40
41enum class FileLockType : uint8_t { NO_LOCK = 0, READ_LOCK = 1, WRITE_LOCK = 2 };
42
43class FileFlags {
44public:
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
57class FileSystem {
58public:
59 virtual ~FileSystem() {
60 }
61
62public:
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
109private:
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