1 /*
2     SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include <QSharedPointer>
10 
11 #include "akonadicore_export.h"
12 
13 namespace Akonadi
14 {
15 class SearchTermPrivate;
16 
17 /**
18  * Search term represents the actual condition within query.
19  *
20  * SearchTerm can either have multiple subterms, or can be so-called endterm, when
21  * there are no more subterms, but instead the actual condition is specified, that
22  * is have key, value and relation between them.
23  *
24  * @since 4.13
25  */
26 class AKONADICORE_EXPORT SearchTerm
27 {
28 public:
29     enum Relation {
30         RelAnd,
31         RelOr,
32     };
33 
34     enum Condition {
35         CondEqual,
36         CondGreaterThan,
37         CondGreaterOrEqual,
38         CondLessThan,
39         CondLessOrEqual,
40         CondContains,
41     };
42 
43     /**
44      * Constructs a term where all subterms will be in given relation
45      */
46     explicit SearchTerm(SearchTerm::Relation relation = SearchTerm::RelAnd);
47 
48     /**
49      * Constructs an end term
50      */
51     SearchTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition = SearchTerm::CondEqual);
52 
53     SearchTerm(const SearchTerm &other);
54     ~SearchTerm();
55 
56     SearchTerm &operator=(const SearchTerm &other);
57     Q_REQUIRED_RESULT bool operator==(const SearchTerm &other) const;
58 
59     Q_REQUIRED_RESULT bool isNull() const;
60 
61     /**
62      * Returns key of this end term.
63      */
64     Q_REQUIRED_RESULT QString key() const;
65 
66     /**
67      * Returns value of this end term.
68      */
69     Q_REQUIRED_RESULT QVariant value() const;
70 
71     /**
72      * Returns relation between key and value.
73      */
74     Q_REQUIRED_RESULT SearchTerm::Condition condition() const;
75 
76     /**
77      * Adds a new subterm to this term.
78      *
79      * Subterms will be in relation as specified in SearchTerm constructor.
80      *
81      * If there are subterms in a term, key, value and condition are ignored.
82      */
83     void addSubTerm(const SearchTerm &term);
84 
85     /**
86      * Returns all subterms, or an empty list if this is an end term.
87      */
88     Q_REQUIRED_RESULT QList<SearchTerm> subTerms() const;
89 
90     /**
91      * Returns relation in which all subterms are.
92      */
93     Q_REQUIRED_RESULT SearchTerm::Relation relation() const;
94 
95     /**
96      * Sets whether the entire term is negated.
97      */
98     void setIsNegated(bool negated);
99 
100     /**
101      * Returns whether the entire term is negated.
102      */
103     Q_REQUIRED_RESULT bool isNegated() const;
104 
105 private:
106     QSharedDataPointer<SearchTermPrivate> d;
107 };
108 
109 class SearchQueryPrivate;
110 
111 /**
112  * @brief A query that can be passed to ItemSearchJob or others.
113  *
114  * @since 4.13
115  */
116 class AKONADICORE_EXPORT SearchQuery
117 {
118 public:
119     /**
120      * Constructs query where all added terms will be in given relation
121      */
122     explicit SearchQuery(SearchTerm::Relation rel = SearchTerm::RelAnd);
123 
124     ~SearchQuery();
125     SearchQuery(const SearchQuery &other);
126     SearchQuery &operator=(const SearchQuery &other);
127     bool operator==(const SearchQuery &other) const;
128 
129     bool isNull() const;
130 
131     /**
132      * Adds a new term.
133      */
134     void addTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition = SearchTerm::CondEqual);
135 
136     /**
137      * Adds a new term with subterms
138      */
139     void addTerm(const SearchTerm &term);
140 
141     /**
142      * Sets the root term
143      */
144     void setTerm(const SearchTerm &term);
145 
146     /**
147      * Returns the root term.
148      */
149     SearchTerm term() const;
150 
151     /**
152      * Sets the maximum number of results.
153      *
154      * Note that this limit is only evaluated per search backend,
155      * so the total number of results retrieved may be larger.
156      */
157     void setLimit(int limit);
158 
159     /**
160      * Returns the maximum number of results.
161      *
162      * The default value is -1, indicating no limit.
163      */
164     int limit() const;
165 
166     QByteArray toJSON() const;
167     static SearchQuery fromJSON(const QByteArray &json);
168 
169 private:
170     QSharedDataPointer<SearchQueryPrivate> d;
171 };
172 
173 /**
174  * A search term for an email field.
175  *
176  * This class can be used to create queries that akonadi email search backends understand.
177  *
178  * @since 4.13
179  */
180 class AKONADICORE_EXPORT EmailSearchTerm : public SearchTerm
181 {
182 public:
183     /**
184      * All fields expect a search string unless noted otherwise.
185      */
186     enum EmailSearchField {
187         Unknown,
188         Subject,
189         Body,
190         Message, // Complete message including headers, body and attachment
191         Headers, // All headers
192         HeaderFrom,
193         HeaderTo,
194         HeaderCC,
195         HeaderBCC,
196         HeaderReplyTo,
197         HeaderOrganization,
198         HeaderListId,
199         HeaderResentFrom,
200         HeaderXLoop,
201         HeaderXMailingList,
202         HeaderXSpamFlag,
203         HeaderDate, // Expects QDateTime
204         HeaderOnlyDate, // Expects QDate
205         MessageStatus, // Expects message flag from Akonadi::MessageFlags. Boolean filter.
206         ByteSize, // Expects int
207         Attachment, // Textsearch on attachment
208         MessageTag
209     };
210 
211     /**
212      * Constructs an email end term
213      */
214     EmailSearchTerm(EmailSearchField field, const QVariant &value, SearchTerm::Condition condition = SearchTerm::CondEqual);
215 
216     /**
217      * Translates field to key
218      */
219     static QString toKey(EmailSearchField);
220 
221     /**
222      * Translates key to field
223      */
224     static EmailSearchField fromKey(const QString &key);
225 };
226 
227 /**
228  * A search term for a contact field.
229  *
230  * This class can be used to create queries that akonadi contact search backends understand.
231  *
232  * @since 4.13
233  */
234 class AKONADICORE_EXPORT ContactSearchTerm : public SearchTerm
235 {
236 public:
237     enum ContactSearchField {
238         Unknown,
239         Name,
240         Email,
241         Nickname,
242         Uid,
243         All // Special field: matches all contacts.
244     };
245 
246     ContactSearchTerm(ContactSearchField field, const QVariant &value, SearchTerm::Condition condition = SearchTerm::CondEqual);
247 
248     /**
249      * Translates field to key
250      */
251     static QString toKey(ContactSearchField);
252 
253     /**
254      * Translates key to field
255      */
256     static ContactSearchField fromKey(const QString &key);
257 };
258 
259 /**
260  * A search term for a incidence field.
261  *
262  * This class can be used to create queries that akonadi incidence search backends understand.
263  *
264  * @since 5.0
265  */
266 class AKONADICORE_EXPORT IncidenceSearchTerm : public SearchTerm
267 {
268 public:
269     enum IncidenceSearchField {
270         Unknown,
271         All,
272         PartStatus, // Own PartStatus
273         Organizer,
274         Summary,
275         Location
276     };
277 
278     IncidenceSearchTerm(IncidenceSearchField field, const QVariant &value, SearchTerm::Condition condition = SearchTerm::CondEqual);
279 
280     /**
281      * Translates field to key
282      */
283     static QString toKey(IncidenceSearchField);
284 
285     /**
286      * Translates key to field
287      */
288     static IncidenceSearchField fromKey(const QString &key);
289 };
290 
291 }
292 
293