From d71f726c42963d55809605b4dc4144970ca0f230 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 16 May 2023 14:11:38 +1000 Subject: Add pagination to database queries --- src/database/include/database.hpp | 81 +++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 46 deletions(-) (limited to 'src/database/include/database.hpp') diff --git a/src/database/include/database.hpp b/src/database/include/database.hpp index 29872e8d..da0ed083 100644 --- a/src/database/include/database.hpp +++ b/src/database/include/database.hpp @@ -22,7 +22,15 @@ namespace database { -typedef std::unique_ptr Continuation; +template +struct Continuation { + std::shared_ptr> iterator; + std::string prefix; + std::string start_key; + bool forward; + bool was_prev_forward; + size_t page_size; +}; /* * Wrapper for a set of results from the database. Owns the list of results, as @@ -32,29 +40,23 @@ typedef std::unique_ptr Continuation; template class Result { public: - auto values() -> std::vector* { return values_.release(); } - auto continuation() -> Continuation { return std::move(c_); } - auto HasMore() -> bool { return c_->Valid(); } - - Result(std::vector* values, Continuation c) - : values_(values), c_(std::move(c)) {} - - Result(std::unique_ptr> values, Continuation c) - : values_(std::move(values)), c_(std::move(c)) {} + auto values() const -> const std::vector& { return values_; } - Result(Result&& other) - : values_(move(other.values_)), c_(std::move(other.c_)) {} + auto next_page() -> std::optional>& { return next_page_; } + auto prev_page() -> std::optional>& { return prev_page_; } - Result operator=(Result&& other) { - return Result(other.values(), std::move(other.continuation())); - } + Result(const std::vector&& values, + std::optional> next, + std::optional> prev) + : values_(values), next_page_(next), prev_page_(prev) {} Result(const Result&) = delete; Result& operator=(const Result&) = delete; private: - std::unique_ptr> values_; - Continuation c_; + std::vector values_; + std::optional> next_page_; + std::optional> prev_page_; }; class Database { @@ -73,13 +75,11 @@ class Database { auto Update() -> std::future; - auto GetSongs(std::size_t page_size) -> std::future>; - auto GetMoreSongs(std::size_t page_size, Continuation c) - -> std::future>; + auto GetSongs(std::size_t page_size) -> std::future*>; + auto GetDump(std::size_t page_size) -> std::future*>; - auto GetDump(std::size_t page_size) -> std::future>; - auto GetMoreDump(std::size_t page_size, Continuation c) - -> std::future>; + template + auto GetPage(Continuation* c) -> std::future*>; Database(const Database&) = delete; Database& operator=(const Database&) = delete; @@ -110,31 +110,20 @@ class Database { -> void; template - using Parser = std::function(const leveldb::Slice& key, - const leveldb::Slice& value)>; - - template - auto Query(const leveldb::Slice& prefix, - std::size_t max_results, - Parser parser) -> Result { - leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions()); - it->Seek(prefix); - return Query(it, max_results, parser); - } + auto dbGetPage(const Continuation& c) -> Result*; template - auto Query(leveldb::Iterator* it, std::size_t max_results, Parser parser) - -> Result { - auto results = std::make_unique>(); - for (std::size_t i = 0; i < max_results && it->Valid(); i++) { - std::optional r = std::invoke(parser, it->key(), it->value()); - if (r) { - results->push_back(*r); - } - it->Next(); - } - return {std::move(results), std::unique_ptr(it)}; - } + auto ParseRecord(const leveldb::Slice& key, const leveldb::Slice& val) + -> std::optional; }; +template <> +auto Database::ParseRecord(const leveldb::Slice& key, + const leveldb::Slice& val) + -> std::optional; +template <> +auto Database::ParseRecord(const leveldb::Slice& key, + const leveldb::Slice& val) + -> std::optional; + } // namespace database -- cgit v1.2.3