diff --git a/CMakeLists.txt b/CMakeLists.txt index 066d4c52ba..84975770fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,7 +197,7 @@ endif () if(${BUILD_KUZU}) add_definitions(-DKUZU_ROOT_DIRECTORY="${PROJECT_SOURCE_DIR}") add_definitions(-DKUZU_CMAKE_VERSION="${CMAKE_PROJECT_VERSION}") -add_definitions(-DKUZU_EXTENSION_VERSION="0.2.3") +add_definitions(-DKUZU_EXTENSION_VERSION="0.2.4") include_directories(src/include) include_directories(third_party/antlr4_cypher/include) diff --git a/src/common/file_system/file_system.cpp b/src/common/file_system/file_system.cpp index bc595b94d8..989ea54c73 100644 --- a/src/common/file_system/file_system.cpp +++ b/src/common/file_system/file_system.cpp @@ -23,6 +23,11 @@ bool FileSystem::fileOrPathExists(const std::string& /*path*/) const { KU_UNREACHABLE; } +std::string FileSystem::expandPath( + main::ClientContext* /*context*/, const std::string& path) const { + return path; +} + std::string FileSystem::joinPath(const std::string& base, const std::string& part) { return (std::filesystem::path{base} / part).string(); } diff --git a/src/common/file_system/local_file_system.cpp b/src/common/file_system/local_file_system.cpp index 71ff32ff9a..61bf453ac5 100644 --- a/src/common/file_system/local_file_system.cpp +++ b/src/common/file_system/local_file_system.cpp @@ -41,12 +41,7 @@ LocalFileInfo::~LocalFileInfo() { std::unique_ptr LocalFileSystem::openFile( const std::string& path, int flags, main::ClientContext* context, FileLockType lock_type) { - auto fullPath = path; - if (path.starts_with('~')) { - fullPath = - context->getCurrentSetting(main::HomeDirectorySetting::name).getValue() + - fullPath.substr(1); - } + auto fullPath = expandPath(context, path); #if defined(_WIN32) auto dwDesiredAccess = 0ul; auto dwCreationDisposition = (flags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING; @@ -194,6 +189,17 @@ bool LocalFileSystem::fileOrPathExists(const std::string& path) const { return std::filesystem::exists(path); } +std::string LocalFileSystem::expandPath( + main::ClientContext* context, const std::string& path) const { + auto fullPath = path; + if (path.starts_with('~')) { + fullPath = + context->getCurrentSetting(main::HomeDirectorySetting::name).getValue() + + fullPath.substr(1); + } + return fullPath; +} + void LocalFileSystem::readFromFile( FileInfo* fileInfo, void* buffer, uint64_t numBytes, uint64_t position) const { auto localFileInfo = ku_dynamic_cast(fileInfo); diff --git a/src/common/file_system/virtual_file_system.cpp b/src/common/file_system/virtual_file_system.cpp index d54bbc7cf4..bc461a3943 100644 --- a/src/common/file_system/virtual_file_system.cpp +++ b/src/common/file_system/virtual_file_system.cpp @@ -41,6 +41,11 @@ bool VirtualFileSystem::fileOrPathExists(const std::string& path) const { return findFileSystem(path)->fileOrPathExists(path); } +std::string VirtualFileSystem::expandPath( + main::ClientContext* context, const std::string& path) const { + return findFileSystem(path)->expandPath(context, path); +} + void VirtualFileSystem::readFromFile( FileInfo* /*fileInfo*/, void* /*buffer*/, uint64_t /*numBytes*/, uint64_t /*position*/) const { KU_UNREACHABLE; diff --git a/src/include/common/file_system/file_system.h b/src/include/common/file_system/file_system.h index 8e7860a134..0562f4e9b0 100644 --- a/src/include/common/file_system/file_system.h +++ b/src/include/common/file_system/file_system.h @@ -37,6 +37,8 @@ class KUZU_API FileSystem { virtual bool fileOrPathExists(const std::string& path) const; + 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); diff --git a/src/include/common/file_system/local_file_system.h b/src/include/common/file_system/local_file_system.h index c29f7b577d..60db562802 100644 --- a/src/include/common/file_system/local_file_system.h +++ b/src/include/common/file_system/local_file_system.h @@ -44,6 +44,8 @@ class LocalFileSystem final : public FileSystem { bool fileOrPathExists(const std::string& path) const override; + std::string expandPath(main::ClientContext* context, const std::string& path) const override; + protected: void readFromFile( FileInfo* fileInfo, void* buffer, uint64_t numBytes, uint64_t position) const override; diff --git a/src/include/common/file_system/virtual_file_system.h b/src/include/common/file_system/virtual_file_system.h index 851380e6e7..2cc61a928f 100644 --- a/src/include/common/file_system/virtual_file_system.h +++ b/src/include/common/file_system/virtual_file_system.h @@ -30,6 +30,8 @@ class VirtualFileSystem final : public FileSystem { bool fileOrPathExists(const std::string& path) const override; + std::string expandPath(main::ClientContext* context, const std::string& path) const override; + protected: void readFromFile( FileInfo* fileInfo, void* buffer, uint64_t numBytes, uint64_t position) const override; diff --git a/src/main/database.cpp b/src/main/database.cpp index 931065f11e..7a34406fa3 100644 --- a/src/main/database.cpp +++ b/src/main/database.cpp @@ -1,5 +1,6 @@ #include "main/database.h" +#include "common/random_engine.h" #include "main/database_manager.h" #if defined(_WIN32) @@ -72,10 +73,15 @@ static void getLockFileFlagsAndType(bool readOnly, bool createNew, int& flags, F } Database::Database(std::string_view databasePath, SystemConfig systemConfig) - : databasePath{databasePath}, systemConfig{systemConfig} { + : systemConfig{systemConfig} { initLoggers(); logger = LoggerUtils::getLogger(LoggerConstants::LoggerEnum::DATABASE); vfs = std::make_unique(); + // To expand a path with home directory(~), we have to pass in a dummy clientContext which + // handles the home directory expansion. + auto clientContext = ClientContext(this); + auto dbPathStr = std::string(databasePath); + this->databasePath = vfs->expandPath(&clientContext, dbPathStr); bufferManager = std::make_unique( this->systemConfig.bufferPoolSize, this->systemConfig.maxDBSize); memoryManager = std::make_unique(bufferManager.get(), vfs.get()); diff --git a/test/c_api/database_test.cpp b/test/c_api/database_test.cpp index 5424e03fda..1d7cbfd17d 100644 --- a/test/c_api/database_test.cpp +++ b/test/c_api/database_test.cpp @@ -58,3 +58,9 @@ TEST_F(CApiDatabaseTest, CreationInvalidPath) { auto database = kuzu_database_init(databasePathCStr, kuzu_default_system_config()); ASSERT_EQ(database, nullptr); } + +TEST_F(CApiDatabaseTest, CreationHomeDir) { + auto databasePathCStr = (char*)"~/ku_test.db"; + auto database = kuzu_database_init(databasePathCStr, kuzu_default_system_config()); + ASSERT_NE(database, nullptr); +}