summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mu-query-results.hh103
1 files changed, 57 insertions, 46 deletions
diff --git a/lib/mu-query-results.hh b/lib/mu-query-results.hh
index 2505eca..d66ee2c 100644
--- a/lib/mu-query-results.hh
+++ b/lib/mu-query-results.hh
@@ -22,6 +22,7 @@
#include <algorithm>
#include <limits>
+#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -177,7 +178,7 @@ public:
*/
QueryResultsIterator& operator++() {
++mset_it_;
- document_.reset();
+ mdoc_ = Nothing;
return *this;
}
@@ -194,20 +195,40 @@ public:
QueryResultsIterator& operator*() { return *this; }
const QueryResultsIterator& operator*() const { return *this; }
+
/**
- * Get the Mu::Document this iterator is pointing at,
+ * Get the Xapian::Document this iterator is pointing at,
* or an empty document when looking at end().
*
* @return a document
*/
- const Mu::Document& document() const {
- if (!document_)
- document_.emplace(mset_it_.get_document());
- return *document_;
+ Option<Xapian::Document> document() const {
+ return xapian_try([this]()->Option<Xapian::Document> {
+ auto doc{mset_it_.get_document()};
+ if (doc.get_docid() == 0)
+ return Nothing;
+ else
+ return Some(std::move(doc));
+ }, Nothing);
}
/**
+ * get the corresponding Message for this iter, if any
+ *
+ * @return a Message or Nothing
+ */
+ Option<Message> message() const {
+ if (auto&& xdoc{document()}; !xdoc)
+ return Nothing;
+ else if (auto&& doc{Message::make_from_document(std::move(xdoc.value()))};
+ !doc)
+ return Nothing;
+ else
+ return Some(std::move(doc.value()));
+ }
+
+ /**
* Get the doc-id for the document this iterator is pointing at, or 0
* when looking at end.
*
@@ -221,8 +242,7 @@ public:
*
* @return a message-id
*/
- Option<std::string> message_id() const noexcept
- {
+ Option<std::string> message_id() const noexcept {
return opt_string(Field::Id::MessageId);
}
@@ -232,8 +252,7 @@ public:
*
* @return a message-id
*/
- Option<std::string> thread_id() const noexcept
- {
+ Option<std::string> thread_id() const noexcept {
return opt_string(Field::Id::ThreadId);
}
@@ -243,7 +262,9 @@ public:
*
* @return a filesystem path
*/
- Option<std::string> path() const noexcept { return opt_string(Field::Id::Path); }
+ Option<std::string> path() const noexcept {
+ return opt_string(Field::Id::Path);
+ }
/**
* Get the date for the document (message) the iterator is pointing at.
@@ -251,7 +272,9 @@ public:
*
* @return a filesystem path
*/
- Option<std::string> date() const noexcept { return opt_string(Field::Id::Date); }
+ Option<std::string> date() const noexcept {
+ return opt_string(Field::Id::Date);
+ }
/**
* Get the file-system path for the document (message) this iterator is
@@ -259,7 +282,9 @@ public:
*
* @return the subject
*/
- Option<std::string> subject() const noexcept { return opt_string(Field::Id::Subject); }
+ Option<std::string> subject() const noexcept {
+ return opt_string(Field::Id::Subject);
+ }
/**
* Get the references for the document (messages) this is iterator is
@@ -269,7 +294,7 @@ public:
* @return references
*/
std::vector<std::string> references() const noexcept {
- return document().string_vec_value(Field::Id::References);
+ return mu_document().string_vec_value(Field::Id::References);
}
/**
@@ -280,7 +305,7 @@ public:
* @return the value
*/
Option<std::string> opt_string(Field::Id id) const noexcept {
- if (auto&& val{document().string_value(id)}; val.empty())
+ if (auto&& val{mu_document().string_value(id)}; val.empty())
return Nothing;
else
return Some(std::move(val));
@@ -292,48 +317,34 @@ public:
* @return the match info.
*/
QueryMatch& query_match() {
- g_assert(query_matches_.find(document().docid()) != query_matches_.end());
- return query_matches_.find(document().docid())->second;
+ g_assert(query_matches_.find(doc_id()) != query_matches_.end());
+ return query_matches_.find(doc_id())->second;
}
const QueryMatch& query_match() const {
- g_assert(query_matches_.find(document().docid()) != query_matches_.end());
- return query_matches_.find(document().docid())->second;
- }
-
- /**
- * get the corresponding Message for this iter
- *
- * @return a Message or Nothing
- */
- Option<Message> message() const {
- return xapian_try(
- [&]()->Option<Message> {
- auto msg{Message::make_from_document(mset_it_.get_document())};
- if (msg)
- return Some(std::move(msg.value()));
- else
- return Nothing;
- },
- Nothing);
+ g_assert(query_matches_.find(doc_id()) != query_matches_.end());
+ return query_matches_.find(doc_id())->second;
}
+private:
/**
- * get the corresponding Message for this iter a heap-allocated ptr;
+ * Get a (cached) reference for the Mu::Document corresponding
+ * to the current iter.
*
- * @return a unique ptr to a Message or P{}
+ * @return cached mu document,
*/
- std::unique_ptr<Message> unique_message_ptr() const {
- return xapian_try(
- [&]()->std::unique_ptr<Message> {
- return std::make_unique<Message>(mset_it_.get_document());
- }, nullptr);
+ const Mu::Document& mu_document() const {
+ if (!mdoc_) {
+ if (auto xdoc = document(); !xdoc)
+ std::runtime_error("iter without document");
+ else
+ mdoc_ = Mu::Document{xdoc.value()};
+ }
+ return mdoc_.value();
}
-
-private:
+ mutable Option<Mu::Document> mdoc_; // cache.
Xapian::MSetIterator mset_it_;
QueryMatches& query_matches_;
- mutable Option<Mu::Document> document_;
};
constexpr auto MaxQueryResultsSize = std::numeric_limits<size_t>::max();