diff --git a/db/db_impl.cc b/db/db_impl.cc index e7a09af..7e04196 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -302,7 +302,7 @@ Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) { // committed only when the descriptor is created, and this directory // may already exist from a previous failed creation attempt. if (path_->IsDirectory()) { - path_->CreateDirectories(); + path_->CreateDirs(); } env_->CreateDir(dbname_); diff --git a/include/leveldb/filesystem.h b/include/leveldb/filesystem.h index 3c43e27..7c87bef 100644 --- a/include/leveldb/filesystem.h +++ b/include/leveldb/filesystem.h @@ -5,6 +5,7 @@ #include #include "leveldb/export.h" +#include "leveldb/status.h" namespace leveldb { @@ -19,9 +20,9 @@ public: static const char kAltDirecttorySeparator = '/'; static const char kVolumeSeparatorChar = ':'; - Path() : isDir_{false}, path_("") {} + Path() : is_dir_{false}, path_("") {} Path(const std::string& path) : path_(path) { - isDir_ = !IsEmpty() && IsDirectorySeparator(path_[Size() - 1]); + is_dir_ = !IsEmpty() && IsDirectorySeparator(path_[Size() - 1]); } virtual ~Path() {} @@ -31,17 +32,17 @@ public: virtual bool IsAbsolute() const = 0; virtual bool IsRelative() const = 0; - virtual bool CreateDirectories() = 0; - virtual bool CreateDirectory() = 0; + virtual Status CreateDirs() = 0; + virtual Status CreateDir() = 0; inline size_t Size() const { return path_.size(); } inline bool IsEmpty() const { return path_.empty(); } - inline bool IsDirectory() const { return isDir_; } + inline bool IsDirectory() const { return is_dir_; } // Utility functions inline bool HasExtension() { - if (!IsEmpty()) { + if (!IsEmpty() && !is_dir_) { std::string::reverse_iterator& path_iter = path_.rbegin(); while (path_iter != path_.rend()) { @@ -60,14 +61,12 @@ public: } protected: - bool isDir_; + bool is_dir_; std::string path_; virtual void Normalize() = 0; }; -#ifdef LEVELDB_PLATFORM_WINDOWS - class WindowsFilePath : public Path { public: explicit WindowsFilePath(const std::string& path) : Path(path) { @@ -79,8 +78,8 @@ public: bool IsAbsolute() const override; bool IsRelative() const override; - bool CreateDirectories() override; - bool CreateDirectory() override; + Status CreateDirs() override; + Status CreateDir() override; protected: void Normalize() override; @@ -91,16 +90,13 @@ inline bool IsValidDriveChar(const char c) { return drive_char >= 'A' && drive_char <= 'Z'; } -#endif - // Factory class PathFactory { - public: - static Path* Create(const std::string& path); +public: + PathFactory() = delete; + ~PathFactory() = delete; - private: - PathFactory() {} - ~PathFactory() {} + static Path* Create(const std::string& path); }; } // namespace filesystem diff --git a/util/filesystem.cc b/util/filesystem.cc index 0c30ccb..8af38ae 100644 --- a/util/filesystem.cc +++ b/util/filesystem.cc @@ -7,18 +7,10 @@ bool IsDirectorySeparator(const char c) { return (c == Path::kDirectorySeparator || c == Path::kAltDirecttorySeparator); } -Path* PathFactory::Create(const std::string& path) -{ - #ifdef LEVELDB_PLATFORM_WINDOWS - return new WindowsFilePath(path); - #elif LEVELDB_PLATFORM_POSIX - return nullptr; - #endif - return nullptr; -} - #ifdef LEVELDB_PLATFORM_WINDOWS +#include + bool WindowsFilePath::IsAbsolute() const { return path_.size() >= 3 && IsValidDriveChar(path_[0]) && path_[1] == Path::kVolumeSeparatorChar; @@ -39,7 +31,6 @@ bool WindowsFilePath::IsRelative() const { IsDirectorySeparator(path_[2])) { return IsValidDriveChar(path_[0]); } - return true; }; @@ -49,7 +40,7 @@ void WindowsFilePath::Normalize() { for (const char c : path_) { if (!IsDirectorySeparator(c)) { *(out++) = c; - } else if (out == path_.begin() || IsDirectorySeparator(*std::prev(out))) { + } else if (out == path_.begin() || !IsDirectorySeparator(*std::prev(out))) { *(out++) = Path::kDirectorySeparator; } else { continue; @@ -59,12 +50,29 @@ void WindowsFilePath::Normalize() { path_.erase(out, path_.end()); } -bool WindowsFilePath::CreateDirectories() { return true; } +Status WindowsFilePath::CreateDirs() { return Status::OK(); } -bool WindowsFilePath::CreateDirectory() { return true; } +Status WindowsFilePath::CreateDir() { + if (!CreateDirectoryA(Path::ToCString(), nullptr)) { + DWORD error_code = GetLastError(); + if (error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_PATH_NOT_FOUND) + return Status::NotFound(path_ + "not foud."); + return Status::IOError("I/O error occured during " + path_ + " creation"); + } + return Status::OK(); +} #endif +Path* PathFactory::Create(const std::string& path) { +#ifdef LEVELDB_PLATFORM_WINDOWS + return new WindowsFilePath(path); +#elif LEVELDB_PLATFORM_POSIX + return nullptr; +#endif + return nullptr; +} + } }