summaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-11-21 13:49:47 +1100
committerjacqueline <me@jacqueline.id.au>2023-11-21 13:49:47 +1100
commitd70ec9bf447f7a46e347c3bc5ad58fd88aff46a2 (patch)
treeab75c1663934d7408fad36d134a0cfd4f4cb089b /src/database
parentf34b6405884c4073158c3f36158c6351fa135a0f (diff)
downloadtangara-fw-d70ec9bf447f7a46e347c3bc5ad58fd88aff46a2.tar.gz
Add lua functions to get database content
Diffstat (limited to 'src/database')
-rw-r--r--src/database/database.cpp44
-rw-r--r--src/database/include/database.hpp17
2 files changed, 61 insertions, 0 deletions
diff --git a/src/database/database.cpp b/src/database/database.cpp
index 142735d8..0967eb95 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -857,4 +857,48 @@ auto IndexRecord::Expand(std::size_t page_size) const
};
}
+Iterator::Iterator(std::weak_ptr<Database> db, const IndexInfo& idx)
+ : db_(db), prev_pos_(), current_pos_() {
+ std::string prefix = EncodeIndexPrefix(
+ IndexKey::Header{.id = idx.id, .depth = 0, .components_hash = 0});
+ current_pos_ = Continuation{.prefix = {prefix.data(), prefix.size()},
+ .start_key = {prefix.data(), prefix.size()},
+ .forward = true,
+ .was_prev_forward = true,
+ .page_size = 1};
+}
+
+Iterator::Iterator(std::weak_ptr<Database> db, const Continuation& c)
+ : db_(db), prev_pos_(), current_pos_(c) {}
+
+auto Iterator::Prev() -> std::optional<IndexRecord> {
+ if (!prev_pos_) {
+ return {};
+ }
+ auto db = db_.lock();
+ if (!db) {
+ return {};
+ }
+ std::unique_ptr<Result<IndexRecord>> res{
+ db->GetPage<IndexRecord>(&*prev_pos_).get()};
+ prev_pos_ = res->prev_page();
+ current_pos_ = prev_pos_;
+ return *res->values()[0];
+}
+
+auto Iterator::Next() -> std::optional<IndexRecord> {
+ if (!current_pos_) {
+ return {};
+ }
+ auto db = db_.lock();
+ if (!db) {
+ return {};
+ }
+ std::unique_ptr<Result<IndexRecord>> res{
+ db->GetPage<IndexRecord>(&*current_pos_).get()};
+ prev_pos_ = current_pos_;
+ current_pos_ = res->next_page();
+ return *res->values()[0];
+}
+
} // namespace database
diff --git a/src/database/include/database.hpp b/src/database/include/database.hpp
index 544e4a62..972871db 100644
--- a/src/database/include/database.hpp
+++ b/src/database/include/database.hpp
@@ -183,4 +183,21 @@ auto Database::ParseRecord<std::pmr::string>(const leveldb::Slice& key,
const leveldb::Slice& val)
-> std::shared_ptr<std::pmr::string>;
+/*
+ * Utility for accessing a large set of database records, one record at a time.
+ */
+class Iterator {
+ public:
+ Iterator(std::weak_ptr<Database>, const IndexInfo&);
+ Iterator(std::weak_ptr<Database>, const Continuation&);
+
+ auto Prev() -> std::optional<IndexRecord>;
+ auto Next() -> std::optional<IndexRecord>;
+
+ private:
+ std::weak_ptr<Database> db_;
+ std::optional<Continuation> prev_pos_;
+ std::optional<Continuation> current_pos_;
+};
+
} // namespace database