#pragma once
#include <filesystem>
#include <vector>
#include "common/assert.h"
#include "common/cast.h"
#include "file_info.h"
namespace lbug {
namespace main {
class ClientContext;
}
namespace common {
enum class FileLockType : uint8_t { NO_LOCK = 0, READ_LOCK = 1, WRITE_LOCK = 2 };
enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2, ZSTD = 3 };
struct FileFlags {
static constexpr uint8_t READ_ONLY = 1 << 0;
static constexpr uint8_t WRITE = 1 << 1;
static constexpr uint8_t CREATE_IF_NOT_EXISTS = 1 << 3;
static constexpr uint8_t CREATE_AND_TRUNCATE_IF_EXISTS = 1 << 4;
static constexpr uint8_t TEMPORARY = 1 << 5;
#ifdef _WIN32
static constexpr uint8_t BINARY = 1 << 5;
#endif
};
struct FileOpenFlags {
int flags;
FileLockType lockType = FileLockType::NO_LOCK;
FileCompressionType compressionType = FileCompressionType::AUTO_DETECT;
explicit FileOpenFlags(int flags) : flags{flags} {}
explicit FileOpenFlags(int flags, FileLockType lockType) : flags{flags}, lockType{lockType} {}
};
class LBUG_API FileSystem {
friend struct FileInfo;
public:
FileSystem() = default;
explicit FileSystem(std::string homeDir) : dbPath(std::move(homeDir)) {}
virtual ~FileSystem() = default;
virtual std::unique_ptr<FileInfo> openFile(const std::string& , FileOpenFlags ,
main::ClientContext* = nullptr) {
UNREACHABLE_CODE;
}
virtual std::vector<std::string> glob(main::ClientContext* ,
const std::string& ) const {
UNREACHABLE_CODE;
}
virtual void overwriteFile(const std::string& from, const std::string& to);
virtual void renameFile(const std::string& from, const std::string& to);
virtual void copyFile(const std::string& from, const std::string& to);
virtual void createDir(const std::string& dir) const;
virtual void removeFileIfExists(const std::string& path,
const main::ClientContext* context = nullptr);
virtual bool fileOrPathExists(const std::string& path, main::ClientContext* context = nullptr);
virtual std::string expandPath(main::ClientContext* context, const std::string& path) const;
static std::string joinPath(const std::string& base, const std::string& part);
static std::string getFileExtension(const std::filesystem::path& path);
static bool isCompressedFile(const std::filesystem::path& path);
static std::string getFileName(const std::filesystem::path& path);
virtual bool canHandleFile(const std::string_view ) const { UNREACHABLE_CODE; }
virtual void syncFile(const FileInfo& fileInfo) const = 0;
virtual bool canPerformSeek() const { return true; }
virtual bool handleFileViaFunction(const std::string& ) const { return false; }
virtual function::TableFunction getHandleFunction(const std::string& ) const {
UNREACHABLE_CODE;
}
template<class TARGET>
TARGET* ptrCast() {
return common::dynamic_cast_checked<TARGET*>(this);
}
template<class TARGET>
const TARGET* constPtrCast() const {
return common::dynamic_cast_checked<const TARGET*>(this);
}
virtual void cleanUP(main::ClientContext* ) {}
protected:
virtual void readFromFile(FileInfo& fileInfo, void* buffer, uint64_t numBytes,
uint64_t position) const = 0;
virtual int64_t readFile(FileInfo& fileInfo, void* buf, size_t numBytes) const = 0;
virtual void writeFile(FileInfo& fileInfo, const uint8_t* buffer, uint64_t numBytes,
uint64_t offset) const;
virtual int64_t seek(FileInfo& fileInfo, uint64_t offset, int whence) const = 0;
virtual void reset(FileInfo& fileInfo);
virtual void truncate(FileInfo& fileInfo, uint64_t size) const;
virtual uint64_t getFileSize(const FileInfo& fileInfo) const = 0;
static bool isGZIPCompressed(const std::filesystem::path& path);
std::string dbPath;
};
} }