Appwrite C++ SDK
Auto-generated API documentation for the Appwrite C++ SDK
Loading...
Searching...
No Matches
Query.hpp
Go to the documentation of this file.
1/// @file Query.hpp
2/// @brief Offers helper methods to construct query parameters for filtering and
3/// sorting API responses.
4
5#ifndef QUERY_HPP_INCLUDED
6#define QUERY_HPP_INCLUDED
7
8#include <cctype>
9#include <iomanip>
10#include <iostream>
11#include <list>
12#include <sstream>
13#include <string>
14#include <type_traits>
15
16/**
17 * @class Queries
18 * @brief Utility class to construct and manage Appwrite-style database query
19 * filters.
20 *
21 * Provides methods to build query filters like equal, contains, range-based,
22 * null checks, and complex queries for Appwrite API requests.
23 */
24class Queries {
25 public:
26 /// Constructor
28
29 /**
30 * @brief Add a raw JSON complex query.
31 * @param jsonQuery A valid Appwrite-style JSON query string.
32 */
33 void addComplexQuery(const std::string jsonQuery);
34
35 /**
36 * @brief Remove a JSON query by index.
37 * @param index The index of the query to remove.
38 * @return True if the query was removed, false if index is invalid.
39 */
40 bool removeJsonQuery(int index);
41
42 /**
43 * @brief Add a cursor query to paginate after the given document ID.
44 * @param documentId The document ID to start after.
45 */
46 void queryCursorAfter(const std::string documentId);
47
48 /**
49 * @brief Limit the number of documents returned.
50 * @param limit The maximum number of documents.
51 */
52 void queryLimit(int limit);
53
54 /**
55 * @brief Filter documents where an attribute is null.
56 * @param attributeId The attribute key to filter.
57 */
58 void queryIsNull(const std::string attributeId);
59
60 /**
61 * @brief Filter documents where an attribute is not null.
62 * @param attributeId The attribute key to filter.
63 */
64 void queryIsNotNull(const std::string attributeId);
65
66 /**
67 * @brief Filter documents where attribute starts with given value.
68 * @param attributeId The attribute key.
69 * @param value The starting value to match.
70 */
71 void queryStartsWith(const std::string attributeId,
72 const std::string &value);
73
74 /**
75 * @brief Filter documents where attribute ends with given value.
76 * @param attributeId The attribute key.
77 * @param value The ending value to match.
78 */
79 void queryEndsWith(const std::string attributeId, const std::string &value);
80
81 /**
82 * @brief Filter documents where attribute contains the value.
83 * @param attributeId The attribute key.
84 * @param value The substring to match.
85 */
86 void queryContains(const std::string attributeId, const std::string &value);
87
88 /// Resets the internal query list.
89 void reset();
90
91 /**
92 * @brief Filter documents where attribute contains any value from list.
93 * @tparam T Type of values in the list.
94 * @param attributeId The attribute key.
95 * @param value List of values to check containment.
96 */
97 template <typename T>
98 void queryContains(const std::string attributeId, std::list<T> &value) {
99 std::string query = "{\"method\":\"contains\",\"attribute\":\"" +
100 attributeId + "\",\"values\":[" +
101 listToString(value) + "]}";
102 if (contains_iter == queries.end()) {
103 queries.push_back(query);
104 contains_iter = std::prev(queries.end());
105 return;
106 }
107 *contains_iter = query;
108 }
109
110 /**
111 * @brief Filter documents where attribute is between two values.
112 * @tparam T Comparable value type.
113 * @param attributeId The attribute key.
114 * @param value1 Lower bound.
115 * @param value2 Upper bound.
116 */
117 template <typename T>
118 void queryBetween(const std::string attributeId, const T &value1,
119 const T &value2) {
120 std::ostringstream oss;
121
122 oss << append_encoded(oss, value1);
123 oss << ",";
124 oss << append_encoded(oss, value2);
125
126 std::string query = "{\"method\":\"between\",\"attribute\":\"" +
127 attributeId + "\",\"values\":[" + oss.str() + "]}";
128 if (between_iter == queries.end()) {
129 queries.push_back(query);
130 between_iter = std::prev(queries.end());
131 return;
132 }
133 *between_iter = query;
134 }
135
136 /**
137 * @brief Filter documents where attribute is greater than or equal to
138 * value.
139 * @tparam T Value type.
140 * @param attributeId The attribute key.
141 * @param value The lower bound.
142 */
143 template <typename T>
144 void queryGreaterThanEqual(const std::string attributeId, const T &value) {
145 std::ostringstream oss;
146 oss << append_encoded(oss, value);
147 std::string query =
148 "{\"method\":\"greaterThanEqual\",\"attribute\":\"" + attributeId +
149 "\",\"values\":[" + oss.str() + "]}";
150 if (greater_than_equal_iter == queries.end()) {
151 queries.push_back(query);
152 greater_than_equal_iter = std::prev(queries.end());
153 return;
154 }
155 *greater_than_equal_iter = query;
156 }
157
158 /**
159 * @brief Filter documents where attribute is greater than value.
160 * @tparam T Value type.
161 * @param attributeId The attribute key.
162 * @param value The threshold.
163 */
164 template <typename T>
165 void queryGreaterThan(const std::string attributeId, const T &value) {
166 std::ostringstream oss;
167 append_encoded(oss, value);
168 std::string query = "{\"method\":\"greaterThan\",\"attribute\":\"" +
169 attributeId + "\",\"values\":[" + oss.str() + "]}";
170 if (greater_than_iter == queries.end()) {
171 queries.push_back(query);
172 greater_than_iter = std::prev(queries.end());
173 return;
174 }
175 *greater_than_iter = query;
176 }
177
178 /**
179 * @brief Filter documents where attribute is less than or equal to value.
180 * @tparam T Value type.
181 * @param attributeId The attribute key.
182 * @param value The upper bound.
183 */
184 template <typename T>
185 void queryLessThanEqual(const std::string attributeId, const T &value) {
186 std::ostringstream oss;
187 append_encoded(oss, value);
188 std::string query = "{\"method\":\"lessThanEqual\",\"attribute\":\"" +
189 attributeId + "\",\"values\":[" + oss.str() + "]}";
190 if (less_than_equal_iter == queries.end()) {
191 queries.push_back(query);
192 less_than_equal_iter = std::prev(queries.end());
193 return;
194 }
195 *less_than_equal_iter = query;
196 }
197
198 /**
199 * @brief Filter documents where attribute is less than value.
200 * @tparam T Value type.
201 * @param attributeId The attribute key.
202 * @param value The threshold.
203 */
204 template <typename T>
205 void queryLessThan(const std::string attributeId, const T &value) {
206 std::ostringstream oss;
207 append_encoded(oss, value);
208 std::string query = "{\"method\":\"lessThan\",\"attribute\":\"" +
209 attributeId + "\",\"values\":[" + oss.str() + "]}";
210 if (less_than_iter == queries.end()) {
211 queries.push_back(query);
212 less_than_iter = std::prev(queries.end());
213 return;
214 }
215 *less_than_iter = query;
216 }
217
218 /**
219 * @brief Filter documents where attribute equals any value in list.
220 * @tparam T Value type.
221 * @param attributeId The attribute key.
222 * @param values List of accepted values.
223 */
224 template <typename T>
225 void queryEqual(const std::string attributeId, std::list<T> &values) {
226 std::string query = "{\"method\":\"equal\",\"attribute\":\"" +
227 attributeId + "\",\"values\":[" +
228 listToString(values) + "]}";
229 if (equal_iter == queries.end()) {
230 queries.push_back(query);
231 equal_iter = std::prev(queries.end());
232 return;
233 }
234 *equal_iter = query;
235 }
236
237 /**
238 * @brief Filter documents where attribute does not equal any value in list.
239 * @tparam T Value type.
240 * @param attributeId The attribute key.
241 * @param values List of disallowed values.
242 */
243 template <typename T>
244 void notEqual(const std::string attributeId, std::list<T> &values) {
245 std::string query = "{\"method\":\"notEqual\",\"attribute\":\"" +
246 attributeId + "\",\"values\":[" +
247 listToString(values) + "]}";
248 if (not_equal_iter == queries.end()) {
249 queries.push_back(query);
250 not_equal_iter = std::prev(queries.end());
251 return;
252 }
253 *not_equal_iter = query;
254 }
255
256 /**
257 * @brief Select only certain fields from the result.
258 * @param values List of field names to return.
259 */
260 void querySelect(std::list<std::string> &values);
261
262 /**
263 * @brief Serialize all added queries into a JSON string.
264 * @return Combined query string.
265 */
266 std::string to_string();
267
268 private:
269 /**
270 * @brief URL-encode a string for query safety.
271 * @param value Raw string.
272 * @return Encoded string.
273 */
274 std::string url_encode(const std::string &value);
275
276 /// Helper template for string values (adds quotes + encodes).
277 template <typename T>
278 typename std::enable_if<std::is_same<T, std::string>::value, void>::type
279 append_encoded(std::ostringstream &oss, const T &iter) {
280 oss << "\"" << url_encode(iter) << "\"";
281 }
282
283 /// Helper template for non-string values.
284 template <typename T>
285 typename std::enable_if<!std::is_same<T, std::string>::value, void>::type
286 append_encoded(std::ostringstream &oss, const T &iter) {
287 oss << iter;
288 }
289
290 /// Specialization for C-string literals.
291 inline void append_encoded(std::ostringstream &oss, const char *iter) {
292 oss << "\"" << url_encode(iter) << "\"";
293 }
294
295 /// Convert list to JSON array (no encoding).
296 template <typename T> std::string listToStringNoEncode(std::list<T> &ls) {
297 int size = ls.size(), count = 0;
298 std::ostringstream oss;
299 for (auto iter : ls) {
300 oss << "\"" << iter << "\"";
301 if (count < size - 1)
302 oss << ",";
303 count++;
304 }
305 return oss.str();
306 }
307
308 /// Convert list to JSON array with encoding.
309 template <typename T> std::string listToString(std::list<T> &ls) {
310 int size = ls.size(), count = 0;
311 std::ostringstream oss;
312 oss << std::boolalpha;
313
314 for (auto iter = ls.begin(); iter != ls.end(); iter++) {
315 append_encoded(oss, *iter);
316 if (count < size - 1) {
317 oss << ",";
318 }
319 count++;
320 }
321 return oss.str();
322 }
323 // Iterators to update specific queries in-place
324 std::list<std::string>::iterator cursor_iter, limit_iter, equal_iter,
325 not_equal_iter, sel_iter, less_than_iter, less_than_equal_iter,
326 greater_than_iter, greater_than_equal_iter, between_iter, is_null_iter,
327 is_not_null_iter, starts_iter, ends_iter, contains_iter;
328
329 /// Internal list of query strings
330 std::list<std::string> queries;
331};
332
333#endif
Utility class to construct and manage Appwrite-style database query filters.
Definition Query.hpp:24
void queryBetween(const std::string attributeId, const T &value1, const T &value2)
Filter documents where attribute is between two values.
Definition Query.hpp:118
void queryGreaterThanEqual(const std::string attributeId, const T &value)
Filter documents where attribute is greater than or equal to value.
Definition Query.hpp:144
Queries()
Constructor.
void queryContains(const std::string attributeId, std::list< T > &value)
Filter documents where attribute contains any value from list.
Definition Query.hpp:98
void addComplexQuery(const std::string jsonQuery)
Add a raw JSON complex query.
void reset()
Resets the internal query list.
void queryEndsWith(const std::string attributeId, const std::string &value)
Filter documents where attribute ends with given value.
std::string to_string()
Serialize all added queries into a JSON string.
void queryCursorAfter(const std::string documentId)
Add a cursor query to paginate after the given document ID.
void queryIsNotNull(const std::string attributeId)
Filter documents where an attribute is not null.
void querySelect(std::list< std::string > &values)
Select only certain fields from the result.
void notEqual(const std::string attributeId, std::list< T > &values)
Filter documents where attribute does not equal any value in list.
Definition Query.hpp:244
void queryLessThan(const std::string attributeId, const T &value)
Filter documents where attribute is less than value.
Definition Query.hpp:205
void queryLessThanEqual(const std::string attributeId, const T &value)
Filter documents where attribute is less than or equal to value.
Definition Query.hpp:185
void queryEqual(const std::string attributeId, std::list< T > &values)
Filter documents where attribute equals any value in list.
Definition Query.hpp:225
void queryContains(const std::string attributeId, const std::string &value)
Filter documents where attribute contains the value.
void queryStartsWith(const std::string attributeId, const std::string &value)
Filter documents where attribute starts with given value.
bool removeJsonQuery(int index)
Remove a JSON query by index.
void queryLimit(int limit)
Limit the number of documents returned.
void queryIsNull(const std::string attributeId)
Filter documents where an attribute is null.
void queryGreaterThan(const std::string attributeId, const T &value)
Filter documents where attribute is greater than value.
Definition Query.hpp:165