Skip to content

Commit bed40ea

Browse files
committed
Now can use multiple queries on same fields
1 parent c9beb94 commit bed40ea

File tree

2 files changed

+157
-64
lines changed

2 files changed

+157
-64
lines changed

example/lib/main.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ class _MyAppState extends State<MyApp> {
9191
void query() async {
9292
// Query for an object by name
9393
var queryBuilder = QueryBuilder<DietPlan>(DietPlan())
94-
..field = DietPlan.FAT
95-
..greaterThan = [59]
96-
..lessThan = [61];
94+
..lessThan(DietPlan.FAT, 61)
95+
..greaterThan(DietPlan.FAT, 59);
9796

9897
var response = await queryBuilder.query();
9998

lib/network/parse_query.dart

Lines changed: 155 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,102 @@
1-
import 'dart:async';
21
import 'dart:convert';
32

4-
import 'package:parse_server_sdk/network/parse_http_client.dart';
53
import 'package:parse_server_sdk/objects/parse_object.dart';
6-
import 'package:parse_server_sdk/objects/parse_response.dart';
74

8-
class QueryBuilder <T extends ParseObject> {
5+
class QueryBuilder<T extends ParseObject> {
96

107
T object;
11-
final ParseHTTPClient client = ParseHTTPClient();
12-
String path;
13-
String field;
14-
Map results;
15-
Map constraint;
16-
Map<String, Map<String, String>> whereMap = Map();
178

189
// QueryParams
19-
List<dynamic> equals;
20-
List<dynamic> lessThan;
21-
List<dynamic> lessThanOrEqualTo;
22-
List<dynamic> greaterThan;
23-
List<dynamic> greaterThanOrEqualTo;
24-
List<dynamic> notEqualTo;
25-
List<dynamic> contains;
26-
List<dynamic> containedIn;
27-
List<dynamic> notContainedIn;
28-
List<dynamic> exists;
29-
List<dynamic> select;
30-
List<dynamic> dontSelect;
31-
List<dynamic> all;
32-
List<dynamic> regEx;
33-
List<dynamic> text;
10+
List<MapEntry> _equalsQueries = List();
11+
List<MapEntry> _lessThanQueries = List();
12+
List<MapEntry> _lessThanOrEqualToQueries = List();
13+
List<MapEntry> _greaterThanQueries = List();
14+
List<MapEntry> _greaterThanOrEqualToQueries = List();
15+
List<MapEntry> _notEqualToQueries = List();
16+
List<MapEntry> _containsQueries = List();
17+
List<MapEntry> _containedInQueries = List();
18+
List<MapEntry> _notContainedInQueries = List();
19+
List<MapEntry> _existsQueries = List();
20+
List<MapEntry> _selectQueries = List();
21+
List<MapEntry> _dontSelectQueries = List();
22+
List<MapEntry> _allQueries = List();
23+
List<MapEntry> _regExQueries = List();
24+
List<MapEntry> _textQueries = List();
3425
int limit = 0;
3526
int skip = 0;
3627

37-
String get objectId => null;
38-
Map<String, dynamic> objectData = {};
39-
4028
QueryBuilder(this.object) : super();
4129

42-
void ascending(String attribute) {}
30+
void startsWith(String key, dynamic value) {
31+
_regExQueries.add(MapEntry(key, "^$value"));
32+
}
33+
34+
void endsWith(String key, dynamic value) {
35+
_regExQueries.add(MapEntry(key, "$value^"));
36+
}
37+
38+
void equals(String column, dynamic value) {
39+
_equalsQueries.add(MapEntry(column, value));
40+
}
41+
42+
void lessThan(String column, dynamic value) {
43+
_lessThanQueries.add(MapEntry(column, value));
44+
}
45+
46+
void lessThanOrEqualTo(String column, dynamic value) {
47+
_lessThanOrEqualToQueries.add(MapEntry(column, value));
48+
}
4349

44-
void descending(String attribute) {}
50+
void greaterThan(String column, dynamic value) {
51+
_greaterThanQueries.add(MapEntry(column, value));
52+
}
4553

46-
void startsWith(String key, dynamic value) {}
54+
void greaterThanOrEqualsTo(String column, dynamic value) {
55+
_greaterThanOrEqualToQueries.add(MapEntry(column, value));
56+
}
57+
58+
void notEqualTo(String column, dynamic value) {
59+
_notEqualToQueries.add(MapEntry(column, value));
60+
}
61+
62+
void contains(String column, dynamic value) {
63+
_containsQueries.add(MapEntry(column, value));
64+
}
65+
66+
void containedIn(String column, dynamic value) {
67+
_containedInQueries.add(MapEntry(column, value));
68+
}
69+
70+
void exists(String column, dynamic value) {
71+
_existsQueries.add(MapEntry(column, value));
72+
}
73+
74+
void select(String column, dynamic value) {
75+
_selectQueries.add(MapEntry(column, value));
76+
}
77+
78+
void dontSelect(String column, dynamic value) {
79+
_dontSelectQueries.add(MapEntry(column, value));
80+
}
81+
82+
void all(String column, dynamic value) {
83+
_allQueries.add(MapEntry(column, value));
84+
}
85+
86+
void regEx(String column, dynamic value) {
87+
_regExQueries.add(MapEntry(column, value));
88+
}
89+
90+
void text(String column, dynamic value) {
91+
_textQueries.add(MapEntry(column, value));
92+
}
4793

4894
query() async {
4995
return object.query(_buildQuery());
5096
}
5197

5298
String _buildQuery() {
53-
var queries = List<String>();
99+
var queries = List<MapEntry>();
54100

55101
// START QUERY
56102
const String QUERY_START = "where={";
@@ -60,36 +106,38 @@ class QueryBuilder <T extends ParseObject> {
60106

61107
// ADD PARAM TO MAP
62108
//Needs fixing
63-
if (equals != null) queries.add(_runThroughQueryParams(equals, field));
64-
if (contains != null) queries.add(_buildQueryWithOperatorAndField(contains, "\$term", field));
109+
if (_equalsQueries.length != 0) queries.addAll(_runThroughQueryParams(_equalsQueries));
110+
if (_containsQueries.length != 0) queries.addAll(_getAllQueries(_containsQueries, "\$term"));
65111

66112
// Works
67-
if (lessThan != null) queries.add(_buildQueryWithOperatorAndField(lessThan, "\$lt", field));
68-
if (lessThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(lessThanOrEqualTo, "\$lte", field));
69-
if (greaterThan != null) queries.add(_buildQueryWithOperatorAndField(greaterThan, "\$gt", field));
70-
if (greaterThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(greaterThanOrEqualTo, "\$gte", field));
71-
if (notEqualTo != null) queries.add(_buildQueryWithOperatorAndField(notEqualTo, "\$ne", field));
113+
if (_lessThanQueries.length != 0) queries.addAll(_getAllQueries(_lessThanQueries, "\$lt"));
114+
if (_lessThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_lessThanOrEqualToQueries, "\$lte"));
115+
if (_greaterThanQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanQueries, "\$gt"));
116+
if (_greaterThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanOrEqualToQueries, "\$gte"));
117+
if (_notEqualToQueries.length != 0) queries.addAll(_getAllQueries(_notEqualToQueries, "\$ne"));
72118

73119
// Not sure
74-
if (containedIn != null) queries.add(_buildQueryWithOperatorAndField(containedIn, "\$in", field));
75-
if (notContainedIn != null) queries.add(_buildQueryWithOperatorAndField(notContainedIn, "\$nin", field));
76-
if (exists != null) queries.add(_buildQueryWithOperatorAndField(exists, "\$exists", field));
77-
if (select != null) queries.add(_buildQueryWithOperatorAndField(select, "\$select", field));
78-
if (dontSelect != null) queries.add( _buildQueryWithOperatorAndField(dontSelect, "\$dontSelect", field));
79-
if (all != null) queries.add(_buildQueryWithOperatorAndField(all, "\$all", field));
120+
if (_containedInQueries.length != 0) queries.addAll(_getAllQueries(_containedInQueries, "\$in"));
121+
if (_notContainedInQueries.length != 0) queries.addAll(_getAllQueries(_notContainedInQueries, "\$nin"));
122+
if (_existsQueries.length != 0) queries.addAll(_getAllQueries(_existsQueries, "\$exists"));
123+
if (_selectQueries.length != 0) queries.addAll(_getAllQueries(_selectQueries, "\$select"));
124+
if (_dontSelectQueries.length != 0) queries.addAll(_getAllQueries(_dontSelectQueries, "\$dontSelect"));
125+
if (_allQueries.length != 0) queries.addAll(_getAllQueries(_allQueries, "\$all"));
80126

81127
// Works
82-
if (regEx != null) queries.add(_buildQueryWithOperatorAndField(regEx, "\$regex", field));
128+
if (_regExQueries.length != 0) queries.addAll(_getAllQueries(_regExQueries, "\$regex"));
83129

84130
// Doesnt
85-
if (text != null) queries.add(_buildQueryWithOperatorAndField(text, "\$text", field));
131+
if (_textQueries.length != 0) queries.addAll(_getAllQueries(_textQueries, "\$text"));
132+
133+
queries = _checkForMultipleColumnInstances(queries);
86134

87135
// -- BUILD QUERY USING MAP
88-
for(var item in queries){
136+
for (var item in queries) {
89137
if (query == QUERY_START) {
90-
query += item;
138+
query += item.value;
91139
} else {
92-
query += ",$item";
140+
query += ",${item.value}";
93141
}
94142
}
95143

@@ -105,22 +153,28 @@ class QueryBuilder <T extends ParseObject> {
105153
return query;
106154
}
107155

108-
_buildQueryWithOperatorAndField(List<dynamic> listOfValuesToQuery, String queryOperator, String tableNameToQuery) {
156+
_getAllQueries(List<MapEntry> queries, String queryOperator){
157+
List<MapEntry> queriesToReturn = List();
158+
for (var query in queries){
159+
queriesToReturn.add(_buildQueryWithColumnValueAndOperator(query, queryOperator));
160+
}
161+
return queriesToReturn;
162+
}
109163

110-
var queryOperatorAndValueMap = Map();
111-
var queryString = "\"$tableNameToQuery\":";
164+
_buildQueryWithColumnValueAndOperator(MapEntry columnAndValue, String queryOperator) {
112165

113-
for (var queryValue in listOfValuesToQuery) {
114-
queryOperatorAndValueMap[queryOperator] = queryValue;
115-
}
166+
var queryString = "\"${columnAndValue.key}\":";
167+
168+
var queryOperatorAndValueMap = Map();
169+
queryOperatorAndValueMap[queryOperator] = columnAndValue.value;
116170

117171
var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap);
118172
queryString += "$formattedQueryOperatorAndValue";
119173

120-
return queryString;
174+
return MapEntry(columnAndValue.key, queryString);
121175
}
122176

123-
_runThroughQueryParams(List<dynamic> list, String queryParam) {
177+
_runThroughQueryParams(List<MapEntry> list) {
124178
Map<String, dynamic> mapToReturn = Map<String, dynamic>();
125179
var params;
126180

@@ -136,12 +190,11 @@ class QueryBuilder <T extends ParseObject> {
136190
}
137191
}
138192

139-
mapToReturn[queryParam] = params;
193+
mapToReturn["wasField"] = params;
140194

141195
return JsonEncoder().convert(mapToReturn);
142196
}
143-
144-
Map<String, String> _runThroughQueryParamsWithSearchTerms(List<dynamic> list, String queryParam, String fieldName) {
197+
_runThroughQueryParamsWithSearchTerms(List<dynamic> list, String queryParam, String fieldName) {
145198
Map<String, String> mapToReturn = Map<String, String>();
146199
Map<String, dynamic> mapWithParamData = Map<String, dynamic>();
147200
Map<String, String> textEntry = Map<String, String>();
@@ -162,4 +215,45 @@ class QueryBuilder <T extends ParseObject> {
162215

163216
return mapToReturn;
164217
}
218+
219+
_checkForMultipleColumnInstances(List<MapEntry> queries) {
220+
List<MapEntry> sanitisedQueries = List();
221+
List<String> keysAlreadyCompacted = List();
222+
223+
// Run through each query
224+
for (var query in queries){
225+
226+
// Check if query with same column name has been sanitised
227+
if (!keysAlreadyCompacted.contains(query.key)) {
228+
229+
// If not, check that it now has
230+
keysAlreadyCompacted.add(query.key);
231+
232+
// Build a list of all queries with the same column name
233+
var listOfQueriesCompact = queries.where((i) => query.key == i.key).toList();
234+
235+
// Build first part of query
236+
var queryStart = "\"${query.key}\":";
237+
var queryEnd = "";
238+
239+
// Compact all the queries in the correct format
240+
for (var queryToCompact in listOfQueriesCompact) {
241+
242+
var queryToCompactValue = queryToCompact.value.toString();
243+
queryToCompactValue = queryToCompactValue.replaceFirst("{", "");
244+
queryToCompactValue = queryToCompactValue.replaceAll("}", "");
245+
246+
if (listOfQueriesCompact.first == queryToCompact){
247+
queryEnd += (queryToCompactValue.replaceAll(queryStart, " "));
248+
} else {
249+
queryEnd += (queryToCompactValue.replaceAll(queryStart, ", "));
250+
}
251+
}
252+
253+
sanitisedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}"));
254+
}
255+
}
256+
257+
return sanitisedQueries;
258+
}
165259
}

0 commit comments

Comments
 (0)