From 9eb6a377fde44fda6eff019ed1f32715f7c28a63 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 8 Dec 2024 11:39:17 -0600 Subject: [PATCH] file mgr db unit tests and fixes --- .../librepertory/include/db/file_mgr_db.hpp | 34 +++++++ .../include/db/rdb_file_mgr_db.hpp | 7 ++ repertory/librepertory/src/db/file_mgr_db.cpp | 34 +++++++ .../librepertory/src/db/rdb_file_mgr_db.cpp | 94 ++++++++++++++++++- .../src/file_manager/file_manager.cpp | 4 +- .../include/fixtures/file_mgr_db_fixture.hpp | 4 +- .../repertory_test/src/file_mgr_db_test.cpp | 20 ++++ 7 files changed, 188 insertions(+), 9 deletions(-) create mode 100644 repertory/librepertory/include/db/file_mgr_db.hpp create mode 100644 repertory/librepertory/src/db/file_mgr_db.cpp diff --git a/repertory/librepertory/include/db/file_mgr_db.hpp b/repertory/librepertory/include/db/file_mgr_db.hpp new file mode 100644 index 00000000..2ffca0d4 --- /dev/null +++ b/repertory/librepertory/include/db/file_mgr_db.hpp @@ -0,0 +1,34 @@ +/* + Copyright <2018-2024> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#ifndef REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ +#define REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ + +#include "db/i_file_mgr_db.hpp" + +namespace repertory { +class app_config; + +[[nodiscard]] auto +create_file_mgr_db(const app_config &cfg) -> std::unique_ptr; +} // namespace repertory + +#endif // REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ diff --git a/repertory/librepertory/include/db/rdb_file_mgr_db.hpp b/repertory/librepertory/include/db/rdb_file_mgr_db.hpp index dc4f6a0b..ad13fe1d 100644 --- a/repertory/librepertory/include/db/rdb_file_mgr_db.hpp +++ b/repertory/librepertory/include/db/rdb_file_mgr_db.hpp @@ -50,6 +50,13 @@ private: private: void create_or_open(bool clear); + [[nodiscard]] auto create_iterator(rocksdb::ColumnFamilyHandle *family) const + -> std::shared_ptr; + + [[nodiscard]] static auto + perform_action(std::string_view function_name, + std::function action) -> bool; + public: [[nodiscard]] auto add_resume(resume_entry entry) -> bool override; diff --git a/repertory/librepertory/src/db/file_mgr_db.cpp b/repertory/librepertory/src/db/file_mgr_db.cpp new file mode 100644 index 00000000..d94fcdd8 --- /dev/null +++ b/repertory/librepertory/src/db/file_mgr_db.cpp @@ -0,0 +1,34 @@ +/* + Copyright <2018-2024> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#include "db/file_mgr_db.hpp" + +#include "app_config.hpp" +#include "db/i_file_mgr_db.hpp" +#include "db/rdb_file_mgr_db.hpp" +#include "db/sqlite_file_mgr_db.hpp" + +namespace repertory { +auto create_file_mgr_db(const app_config &cfg) + -> std::unique_ptr { + return std::make_unique(cfg); +} +} // namespace repertory diff --git a/repertory/librepertory/src/db/rdb_file_mgr_db.cpp b/repertory/librepertory/src/db/rdb_file_mgr_db.cpp index c52a2700..76b53180 100644 --- a/repertory/librepertory/src/db/rdb_file_mgr_db.cpp +++ b/repertory/librepertory/src/db/rdb_file_mgr_db.cpp @@ -28,6 +28,7 @@ #include "utils/file.hpp" #include "utils/path.hpp" #include "utils/string.hpp" +#include namespace { [[nodiscard]] auto @@ -86,17 +87,53 @@ void rdb_file_mgr_db::create_or_open(bool clear) { upload_family_ = handles[idx++]; } -auto rdb_file_mgr_db::add_resume(resume_entry entry) -> bool {} +auto rdb_file_mgr_db::add_resume(resume_entry entry) -> bool { + REPERTORY_USES_FUNCTION_NAME(); + + return perform_action(function_name, [this, &entry]() -> rocksdb::Status { + auto data = json({ + {"chunk_size", entry.chunk_size}, + {"read_state", utils::string::from_dynamic_bitset(entry.read_state)}, + {"source_path", entry.source_path}, + }); + return db_->Put(rocksdb::WriteOptions{}, resume_family_, entry.api_path, + data.dump()); + }); +} auto rdb_file_mgr_db::add_upload(upload_entry entry) -> bool {} auto rdb_file_mgr_db::add_upload_active(upload_active_entry entry) -> bool {} -void rdb_file_mgr_db::clear() {} +void rdb_file_mgr_db::clear() { create_or_open(true); } + +auto rdb_file_mgr_db::create_iterator(rocksdb::ColumnFamilyHandle *family) const + -> std::shared_ptr { + return std::shared_ptr( + db_->NewIterator(rocksdb::ReadOptions(), family)); +} auto rdb_file_mgr_db::get_next_upload() const -> std::optional {} -auto rdb_file_mgr_db::get_resume_list() const -> std::vector {} +auto rdb_file_mgr_db::get_resume_list() const -> std::vector { + REPERTORY_USES_FUNCTION_NAME(); + + std::vector ret; + + auto iter = create_iterator(resume_family_); + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + auto data = json::parse(iter->value().ToString()); + ret.emplace_back(resume_entry{ + iter->key().ToString(), + data.at("chunk_size").get(), + utils::string::to_dynamic_bitset( + data.at("read_state").get()), + data.at("source_path").get(), + }); + } + + return ret; +} auto rdb_file_mgr_db::get_upload(const std::string &api_path) const -> std::optional {} @@ -104,7 +141,24 @@ auto rdb_file_mgr_db::get_upload(const std::string &api_path) const auto rdb_file_mgr_db::get_upload_active_list() const -> std::vector {} -auto rdb_file_mgr_db::remove_resume(const std::string &api_path) -> bool {} +auto rdb_file_mgr_db::perform_action(std::string_view function_name, + std::function action) + -> bool { + auto res = action(); + if (not res.ok()) { + utils::error::raise_error(function_name, res.ToString()); + } + + return res.ok(); +} + +auto rdb_file_mgr_db::remove_resume(const std::string &api_path) -> bool { + REPERTORY_USES_FUNCTION_NAME(); + + return perform_action(function_name, [this, &api_path]() -> rocksdb::Status { + return db_->Delete(rocksdb::WriteOptions{}, api_path); + }); +} auto rdb_file_mgr_db::remove_upload(const std::string &api_path) -> bool {} @@ -112,5 +166,35 @@ auto rdb_file_mgr_db::remove_upload_active(const std::string &api_path) -> bool {} auto rdb_file_mgr_db::rename_resume(const std::string &from_api_path, - const std::string &to_api_path) -> bool {} + const std::string &to_api_path) -> bool { + REPERTORY_USES_FUNCTION_NAME(); + + std::string value; + auto res = perform_action( + function_name, [this, &from_api_path, &value]() -> rocksdb::Status { + return db_->Get(rocksdb::ReadOptions{}, from_api_path, &value); + }); + if (not res) { + return false; + } + + if (value.empty()) { + return false; + } + + auto data = json::parse(value); + resume_entry entry{ + to_api_path, + data.at("chunk_size").get(), + utils::string::to_dynamic_bitset( + data.at("read_state").get()), + data.at("source_path").get(), + }; + + if (not remove_resume(from_api_path)) { + return false; + } + + return add_resume(entry); +} } // namespace repertory diff --git a/repertory/librepertory/src/file_manager/file_manager.cpp b/repertory/librepertory/src/file_manager/file_manager.cpp index 1767e56f..914b2a4c 100644 --- a/repertory/librepertory/src/file_manager/file_manager.cpp +++ b/repertory/librepertory/src/file_manager/file_manager.cpp @@ -22,7 +22,7 @@ #include "file_manager/file_manager.hpp" #include "app_config.hpp" -#include "db/sqlite_file_mgr_db.hpp" +#include "db/file_mgr_db.hpp" #include "file_manager/events.hpp" #include "file_manager/open_file.hpp" #include "file_manager/open_file_base.hpp" @@ -42,7 +42,7 @@ namespace repertory { file_manager::file_manager(app_config &config, i_provider &provider) : config_(config), provider_(provider) { - mgr_db_ = std::make_unique(config_); + mgr_db_ = create_file_mgr_db(config); if (provider_.is_read_only()) { return; diff --git a/repertory/repertory_test/include/fixtures/file_mgr_db_fixture.hpp b/repertory/repertory_test/include/fixtures/file_mgr_db_fixture.hpp index a9c10692..534ac57a 100644 --- a/repertory/repertory_test/include/fixtures/file_mgr_db_fixture.hpp +++ b/repertory/repertory_test/include/fixtures/file_mgr_db_fixture.hpp @@ -25,7 +25,7 @@ #include "test_common.hpp" #include "app_config.hpp" -// #include "db/rdb_meta_db.hpp" +#include "db/rdb_file_mgr_db.hpp" #include "db/sqlite_file_mgr_db.hpp" #include "events/consumers/console_consumer.hpp" #include "events/event_system.hpp" @@ -58,7 +58,7 @@ protected: } }; -using file_mgr_db_types = ::testing::Types; +using file_mgr_db_types = ::testing::Types; template std::unique_ptr file_mgr_db_test::config; diff --git a/repertory/repertory_test/src/file_mgr_db_test.cpp b/repertory/repertory_test/src/file_mgr_db_test.cpp index 7610f9b7..fb51bdc3 100644 --- a/repertory/repertory_test/src/file_mgr_db_test.cpp +++ b/repertory/repertory_test/src/file_mgr_db_test.cpp @@ -93,4 +93,24 @@ TYPED_TEST(file_mgr_db_test, can_replace_resume) { EXPECT_TRUE(this->file_mgr_db->remove_resume("/test0")); } + +TYPED_TEST(file_mgr_db_test, can_rename_resume) { + this->file_mgr_db->clear(); + + EXPECT_TRUE(this->file_mgr_db->add_resume({ + "/test0", + 2ULL, + {}, + "/src/test0", + })); + EXPECT_TRUE(this->file_mgr_db->rename_resume("/test0", "/test1")); + + auto list = this->file_mgr_db->get_resume_list(); + EXPECT_EQ(1U, list.size()); + EXPECT_STREQ("/test1", list.at(0U).api_path.c_str()); + EXPECT_EQ(2ULL, list.at(0U).chunk_size); + EXPECT_STREQ("/src/test0", list.at(0U).source_path.c_str()); + + EXPECT_TRUE(this->file_mgr_db->remove_resume("/test0")); +} } // namespace repertory