Skip to content

Commit 2fde6f1

Browse files
feat: Query Class for complex data filtering
Added support for pagination and queries in general.
1 parent e87e264 commit 2fde6f1

File tree

7 files changed

+404
-4
lines changed

7 files changed

+404
-4
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ find_package(CURL REQUIRED)
1111
set(SRCS
1212
src/Appwrite.cpp
1313
src/services/Account.cpp
14+
src/services/Query.cpp
1415
src/services/Databases.cpp
1516
src/services/Storage.cpp
1617
src/services/Health.cpp
@@ -31,6 +32,7 @@ set_target_properties(AppwriteSDK PROPERTIES
3132
set(HEADERS
3233
include/Appwrite.hpp
3334
include/classes/Account.hpp
35+
include/classes/Query.hpp
3436
include/classes/Databases.hpp
3537
include/classes/Storage.hpp
3638
include/classes/Health.hpp

examples/database/collection/document/listDocument.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ int main() {
1010
Appwrite appwrite(projectId, apiKey);
1111

1212
try {
13-
std::string response = appwrite.getDatabases().listDocument(databaseId, collectionId);
13+
Queries queries;
14+
queries.queryLimit(50);
15+
std::string response = appwrite.getDatabases().listDocument(databaseId, collectionId, queries);
1416
std::cout << "Documents listed successfully! \nResponse: " << response << std::endl;
1517
} catch (const AppwriteException& ex) {
1618
std::cerr << "Exception: " << ex.what() << std::endl;

include/Appwrite.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define APPWRITE_HPP
33

44
#include "classes/Account.hpp"
5+
#include "classes/Query.hpp"
56
#include "classes/Databases.hpp"
67
#include "classes/Storage.hpp"
78
#include "classes/Health.hpp"

include/classes/Databases.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string>
55
#include "Utils.hpp"
66
#include "json.hpp"
7+
#include "classes/Query.hpp"
78
#include "exceptions/AppwriteException.hpp"
89
#include "enums/HttpStatus.hpp"
910

@@ -49,7 +50,7 @@ class Databases {
4950

5051
// document
5152
std::string createDocument(const std::string& databaseId, const std::string& collectionId, const std::string& documentId, const json& data);
52-
std::string listDocument(const std::string& databaseId, const std::string& collectionId);
53+
std::string listDocument(const std::string& databaseId, const std::string& collectionId, Queries &queries);
5354
std::string deleteDocument(const std::string& databaseId, const std::string& collectionId, const std::string& documentId);
5455
std::string getDocument(const std::string& databaseId, const std::string& collectionId, const std::string& documentId);
5556

include/classes/Query.hpp

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#ifndef QUERY_HPP_INCLUDED
2+
#define QUERY_HPP_INCLUDED
3+
4+
#include <type_traits>
5+
#include <cctype>
6+
#include <iomanip>
7+
#include <iostream>
8+
#include <string>
9+
#include <sstream>
10+
#include <list>
11+
12+
class Queries{
13+
public:
14+
Queries();
15+
void addComplexQuery(const std::string jsonQuery);
16+
bool removeJsonQuery(int index);
17+
18+
void queryCursorAfter(const std::string documentId);
19+
void queryLimit(int limit);
20+
21+
void queryIsNull(const std::string attributeId);
22+
void queryIsNotNull(const std::string attributeId);
23+
24+
void queryStartsWith(const std::string attributeId, const std::string &value);
25+
void queryEndsWith(const std::string attributeId, const std::string &value);
26+
void queryContains(const std::string attributeId, const std::string &value);
27+
void reset();
28+
29+
template<typename T>
30+
void queryContains(const std::string attributeId, std::list<T> &value){
31+
std::string query = "{\"method\":\"contains\",\"attribute\":\""+attributeId+"\",\"values\":["+listToString(value)+"]}";
32+
if(contains_iter == queries.end()){
33+
queries.push_back(query);
34+
contains_iter = std::prev(queries.end());
35+
return;
36+
}
37+
*contains_iter = query;
38+
}
39+
40+
template<typename T>
41+
void queryBetween(const std::string attributeId, const T &value1, const T &value2){
42+
std::ostringstream oss;
43+
44+
oss << append_encoded(oss,value1);
45+
oss << ",";
46+
oss << append_encoded(oss,value2);
47+
48+
std::string query = "{\"method\":\"between\",\"attribute\":\""+attributeId+"\",\"values\":["+oss.str()+"]}";
49+
if(between_iter == queries.end()){
50+
queries.push_back(query);
51+
between_iter = std::prev(queries.end());
52+
return;
53+
}
54+
*between_iter = query;
55+
}
56+
57+
template<typename T>
58+
void queryGreaterThanEqual(const std::string attributeId, const T &value){
59+
std::ostringstream oss;
60+
oss<< append_encoded(oss,value);
61+
std::string query = "{\"method\":\"greaterThanEqual\",\"attribute\":\""+attributeId+"\",\"values\":["+oss.str()+"]}";
62+
if(greater_than_equal_iter == queries.end()){
63+
queries.push_back(query);
64+
greater_than_equal_iter = std::prev(queries.end());
65+
return;
66+
}
67+
*greater_than_equal_iter = query;
68+
}
69+
70+
template<typename T>
71+
void queryGreaterThan(const std::string attributeId, const T &value){
72+
std::ostringstream oss;
73+
append_encoded(oss,value);
74+
std::string query = "{\"method\":\"greaterThan\",\"attribute\":\""+attributeId+"\",\"values\":["+oss.str()+"]}";
75+
if(greater_than_iter == queries.end()){
76+
queries.push_back(query);
77+
greater_than_iter = std::prev(queries.end());
78+
return;
79+
}
80+
*greater_than_iter = query;
81+
}
82+
83+
template<typename T>
84+
void queryLessThanEqual(const std::string attributeId, const T &value){
85+
std::ostringstream oss;
86+
append_encoded(oss, value);
87+
std::string query = "{\"method\":\"lessThanEqual\",\"attribute\":\""+attributeId+"\",\"values\":["+oss.str()+"]}";
88+
if(less_than_equal_iter == queries.end()){
89+
queries.push_back(query);
90+
less_than_equal_iter = std::prev(queries.end());
91+
return;
92+
}
93+
*less_than_equal_iter = query;
94+
}
95+
96+
template<typename T>
97+
void queryLessThan(const std::string attributeId, const T &value){
98+
std::ostringstream oss;
99+
append_encoded(oss,value);
100+
std::string query = "{\"method\":\"lessThan\",\"attribute\":\""+attributeId+"\",\"values\":["+oss.str()+"]}";
101+
if(less_than_iter == queries.end()){
102+
queries.push_back(query);
103+
less_than_iter = std::prev(queries.end());
104+
return;
105+
}
106+
*less_than_iter = query;
107+
}
108+
109+
template<typename T>
110+
void queryEqual(const std::string attributeId, std::list<T> &values){
111+
std::string query = "{\"method\":\"equal\",\"attribute\":\""+attributeId+"\",\"values\":["+listToString(values)+"]}";
112+
if(equal_iter == queries.end()){
113+
queries.push_back(query);
114+
equal_iter = std::prev(queries.end());
115+
return;
116+
}
117+
*equal_iter = query;
118+
}
119+
120+
template<typename T>
121+
void notEqual(const std::string attributeId, std::list<T> &values){
122+
std::string query = "{\"method\":\"notEqual\",\"attribute\":\""+attributeId+"\",\"values\":["+listToString(values)+"]}";
123+
if(not_equal_iter == queries.end()){
124+
queries.push_back(query);
125+
not_equal_iter = std::prev(queries.end());
126+
return;
127+
}
128+
*not_equal_iter = query;
129+
}
130+
void querySelect(std::list<std::string> &values);
131+
std::string to_string();
132+
133+
134+
private:
135+
136+
std::string url_encode(const std::string &value);
137+
138+
template<typename T>
139+
typename std::enable_if<std::is_same<T, std::string>::value, void>::type
140+
append_encoded(std::ostringstream &oss, const T& iter){
141+
oss<< "\"" <<url_encode(iter) <<"\"";
142+
}
143+
144+
template<typename T>
145+
typename std::enable_if<!std::is_same<T, std::string>::value, void>::type
146+
append_encoded(std::ostringstream &oss, const T& iter){
147+
oss<< iter;
148+
}
149+
150+
// Finally handles string literals
151+
inline void append_encoded(std::ostringstream &oss, const char *iter){
152+
oss<< "\"" <<url_encode(iter) <<"\"";
153+
}
154+
155+
template<typename T>
156+
std::string listToStringNoEncode(std::list<T> &ls){
157+
int size = ls.size(), count = 0;
158+
std::ostringstream oss;
159+
for(auto iter:ls){
160+
oss << "\"" << iter <<"\"";
161+
if(count < size -1)
162+
oss <<",";
163+
count ++;
164+
}
165+
return oss.str();
166+
}
167+
168+
template<typename T>
169+
std::string listToString(std::list<T> &ls){
170+
int size = ls.size(), count = 0;
171+
std::ostringstream oss;
172+
oss << std::boolalpha;
173+
174+
for(auto iter = ls.begin(); iter != ls.end(); iter++){
175+
append_encoded(oss, *iter);
176+
if(count < size-1){
177+
oss << ",";
178+
}
179+
count++;
180+
}
181+
return oss.str();
182+
}
183+
std::list<std::string>::iterator cursor_iter, limit_iter, equal_iter,
184+
not_equal_iter, sel_iter, less_than_iter,
185+
less_than_equal_iter, greater_than_iter,
186+
greater_than_equal_iter, between_iter,
187+
is_null_iter, is_not_null_iter,
188+
starts_iter,ends_iter, contains_iter;
189+
std::list<std::string> queries;
190+
};
191+
192+
#endif
193+

src/services/Databases.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,10 +672,10 @@ std::string Databases::createDocument(const std::string& databaseId, const std::
672672
}
673673
}
674674

675-
std::string Databases::listDocument(const std::string& databaseId, const std::string& collectionId){
675+
std::string Databases::listDocument(const std::string& databaseId, const std::string& collectionId, Queries &queries){
676676
Validator::validateDatabaseParams(databaseId, collectionId);
677677

678-
std::string url = Config::API_BASE_URL + "/databases/" + databaseId + "/collections/" + collectionId + "/documents";
678+
std::string url = Config::API_BASE_URL + "/databases/" + databaseId + "/collections/" + collectionId + "/documents" + queries.to_string();
679679

680680
std::vector<std::string> headers = Config::getHeaders(projectId);
681681
headers.push_back("X-Appwrite-Key: " + apiKey);

0 commit comments

Comments
 (0)