7#include "searchquery.h"
8#include "akonadicore_debug.h"
10#include <QJsonDocument>
16class Akonadi::SearchTermPrivate :
public QSharedData
19 bool operator==(
const SearchTermPrivate &other)
const
21 return relation == other.relation && isNegated == other.isNegated && terms == other.terms && key == other.key && value == other.value
22 && condition == other.condition;
27 SearchTerm::Condition condition = SearchTerm::CondEqual;
28 SearchTerm::Relation relation = SearchTerm::RelAnd;
29 QList<SearchTerm> terms;
30 bool isNegated =
false;
33class Akonadi::SearchQueryPrivate :
public QSharedData
36 bool operator==(
const SearchQueryPrivate &other)
const
38 return rootTerm == other.rootTerm && limit == other.limit;
41 static QVariantMap termToJSON(
const SearchTerm &term)
43 const QList<SearchTerm> &subTerms = term.
subTerms();
48 termJSON.
insert(QStringLiteral(
"key"), term.
key());
49 termJSON.
insert(QStringLiteral(
"value"), term.
value());
50 termJSON.
insert(QStringLiteral(
"cond"),
static_cast<int>(term.
condition()));
53 termJSON.
insert(QStringLiteral(
"rel"),
static_cast<int>(term.
relation()));
54 QVariantList subTermsJSON;
55 subTermsJSON.reserve(subTerms.
count());
56 for (
const SearchTerm &term : std::as_const(subTerms)) {
57 subTermsJSON.append(termToJSON(term));
59 termJSON.
insert(QStringLiteral(
"subTerms"), subTermsJSON);
65 static SearchTerm JSONToTerm(
const QVariantMap &map)
69 }
else if (
map.contains(QStringLiteral(
"key"))) {
70 SearchTerm term(map[QStringLiteral(
"key")].
toString(),
71 map[QStringLiteral(
"value")],
72 static_cast<SearchTerm::Condition
>(map[QStringLiteral(
"cond")].toInt()));
73 term.
setIsNegated(map[QStringLiteral(
"negated")].toBool());
75 }
else if (
map.contains(QStringLiteral(
"rel"))) {
76 SearchTerm term(
static_cast<SearchTerm::Relation
>(map[QStringLiteral(
"rel")].toInt()));
77 term.
setIsNegated(map[QStringLiteral(
"negated")].toBool());
78 const QList<QVariant>
list =
map[QStringLiteral(
"subTerms")].toList();
79 for (
const QVariant &var : list) {
84 qCWarning(AKONADICORE_LOG) <<
"Invalid JSON for term: " <<
map;
94 : d(new SearchTermPrivate)
100 : d(new SearchTermPrivate)
102 d->relation = RelAnd;
113SearchTerm::~SearchTerm() =
default;
121bool SearchTerm::operator==(
const SearchTerm &other)
const
123 return *d == *other.d;
126bool SearchTerm::isNull()
const
128 return d->key.isEmpty() && d->value.isNull() && d->terms.isEmpty();
148 d->isNegated = negated;
172 : d(new SearchQueryPrivate)
182SearchQuery::~SearchQuery()
192bool SearchQuery::operator==(
const SearchQuery &other)
const
194 return *d == *other.d;
197bool SearchQuery::isNull()
const
199 return d->rootTerm.isNull();
214 d->rootTerm.addSubTerm(
term);
235 if (!d->rootTerm.isNull()) {
236 root = SearchQueryPrivate::termToJSON(d->rootTerm);
237 root.
insert(QStringLiteral(
"limit"), d->limit);
246SearchQuery SearchQuery::fromJSON(
const QByteArray &jsonData)
248 QJsonParseError
error;
255 const QJsonObject obj = json.
object();
257 if (obj.
contains(QLatin1StringView(
"limit"))) {
263static QMap<EmailSearchTerm::EmailSearchField, QString> emailSearchFieldMapping()
265 static QMap<EmailSearchTerm::EmailSearchField, QString> mapping;
267 mapping.
insert(EmailSearchTerm::Body, QStringLiteral(
"body"));
268 mapping.
insert(EmailSearchTerm::Headers, QStringLiteral(
"headers"));
269 mapping.
insert(EmailSearchTerm::Subject, QStringLiteral(
"subject"));
270 mapping.
insert(EmailSearchTerm::Message, QStringLiteral(
"message"));
271 mapping.
insert(EmailSearchTerm::HeaderFrom, QStringLiteral(
"from"));
272 mapping.
insert(EmailSearchTerm::HeaderTo, QStringLiteral(
"to"));
273 mapping.
insert(EmailSearchTerm::HeaderCC, QStringLiteral(
"cc"));
274 mapping.
insert(EmailSearchTerm::HeaderBCC, QStringLiteral(
"bcc"));
275 mapping.
insert(EmailSearchTerm::HeaderReplyTo, QStringLiteral(
"replyto"));
276 mapping.
insert(EmailSearchTerm::HeaderOrganization, QStringLiteral(
"organization"));
277 mapping.
insert(EmailSearchTerm::HeaderListId, QStringLiteral(
"listid"));
278 mapping.
insert(EmailSearchTerm::HeaderResentFrom, QStringLiteral(
"resentfrom"));
279 mapping.
insert(EmailSearchTerm::HeaderXLoop, QStringLiteral(
"xloop"));
280 mapping.
insert(EmailSearchTerm::HeaderXMailingList, QStringLiteral(
"xmailinglist"));
281 mapping.
insert(EmailSearchTerm::HeaderXSpamFlag, QStringLiteral(
"xspamflag"));
282 mapping.
insert(EmailSearchTerm::HeaderDate, QStringLiteral(
"date"));
283 mapping.
insert(EmailSearchTerm::HeaderOnlyDate, QStringLiteral(
"onlydate"));
284 mapping.
insert(EmailSearchTerm::MessageStatus, QStringLiteral(
"messagestatus"));
285 mapping.
insert(EmailSearchTerm::MessageTag, QStringLiteral(
"messagetag"));
286 mapping.
insert(EmailSearchTerm::ByteSize, QStringLiteral(
"size"));
287 mapping.
insert(EmailSearchTerm::Attachment, QStringLiteral(
"attachment"));
300 return emailSearchFieldMapping().value(field);
305 return emailSearchFieldMapping().key(
key);
312 mapping.
insert(ContactSearchTerm::Name, QStringLiteral(
"name"));
313 mapping.
insert(ContactSearchTerm::Nickname, QStringLiteral(
"nickname"));
314 mapping.
insert(ContactSearchTerm::Email, QStringLiteral(
"email"));
315 mapping.
insert(ContactSearchTerm::Uid, QStringLiteral(
"uid"));
316 mapping.
insert(ContactSearchTerm::All, QStringLiteral(
"all"));
321ContactSearchTerm::ContactSearchTerm(ContactSearchTerm::ContactSearchField field,
const QVariant &value, SearchTerm::Condition condition)
328 return contactSearchFieldMapping().value(field);
333 return contactSearchFieldMapping().key(
key);
340 mapping.
insert(IncidenceSearchTerm::All, QStringLiteral(
"all"));
341 mapping.
insert(IncidenceSearchTerm::PartStatus, QStringLiteral(
"partstatus"));
342 mapping.
insert(IncidenceSearchTerm::Organizer, QStringLiteral(
"organizer"));
343 mapping.
insert(IncidenceSearchTerm::Summary, QStringLiteral(
"summary"));
344 mapping.
insert(IncidenceSearchTerm::Location, QStringLiteral(
"location"));
349IncidenceSearchTerm::IncidenceSearchTerm(IncidenceSearchTerm::IncidenceSearchField field,
const QVariant &value, SearchTerm::Condition condition)
356 return incidenceSearchFieldMapping().value(field);
361 return incidenceSearchFieldMapping().key(
key);
static EmailSearchField fromKey(const QString &key)
Translates key to field.
EmailSearchTerm(EmailSearchField field, const QVariant &value, SearchTerm::Condition condition=SearchTerm::CondEqual)
Constructs an email end term.
static QString toKey(EmailSearchField)
Translates field to key.
EmailSearchField
All fields expect a search string unless noted otherwise.
static IncidenceSearchField fromKey(const QString &key)
Translates key to field.
static QString toKey(IncidenceSearchField)
Translates field to key.
A query that can be passed to ItemSearchJob or others.
void setTerm(const SearchTerm &term)
Sets the root term.
void addTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition=SearchTerm::CondEqual)
Adds a new term.
void setLimit(int limit)
Sets the maximum number of results.
int limit() const
Returns the maximum number of results.
SearchQuery(SearchTerm::Relation rel=SearchTerm::RelAnd)
Constructs query where all added terms will be in given relation.
SearchTerm term() const
Returns the root term.
Search term represents the actual condition within query.
QVariant value() const
Returns value of this end term.
QString key() const
Returns key of this end term.
void addSubTerm(const SearchTerm &term)
Adds a new subterm to this term.
void setIsNegated(bool negated)
Sets whether the entire term is negated.
SearchTerm::Condition condition() const
Returns relation between key and value.
SearchTerm(SearchTerm::Relation relation=SearchTerm::RelAnd)
Constructs a term where all subterms will be in given relation.
bool isNegated() const
Returns whether the entire term is negated.
QList< SearchTerm > subTerms() const
Returns all subterms, or an empty list if this is an end term.
SearchTerm::Relation relation() const
Returns relation in which all subterms are.
Helper integration between Akonadi and Qt.
char * toString(const EngineQuery &query)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
bool isNull() const const
QJsonObject object() const const
void setObject(const QJsonObject &object)
QByteArray toJson(JsonFormat format) const const
bool contains(QLatin1StringView key) const const
QJsonObject fromVariantMap(const QVariantMap &map)
QVariantMap toVariantMap() const const
QJsonValue value(QLatin1StringView key) const const
int toInt(int defaultValue) const const
qsizetype count() const const
bool isEmpty() const const
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)