1
- import 'dart:async' ;
2
1
import 'dart:convert' ;
3
2
4
- import 'package:parse_server_sdk/network/parse_http_client.dart' ;
5
3
import 'package:parse_server_sdk/objects/parse_object.dart' ;
6
- import 'package:parse_server_sdk/objects/parse_response.dart' ;
7
4
8
- class QueryBuilder < T extends ParseObject > {
5
+ class QueryBuilder <T extends ParseObject > {
9
6
10
7
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 ();
17
8
18
9
// 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 () ;
34
25
int limit = 0 ;
35
26
int skip = 0 ;
36
27
37
- String get objectId => null ;
38
- Map <String , dynamic > objectData = {};
39
-
40
28
QueryBuilder (this .object) : super ();
41
29
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
+ }
43
49
44
- void descending (String attribute) {}
50
+ void greaterThan (String column, dynamic value) {
51
+ _greaterThanQueries.add (MapEntry (column, value));
52
+ }
45
53
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
+ }
47
93
48
94
query () async {
49
95
return object.query (_buildQuery ());
50
96
}
51
97
52
98
String _buildQuery () {
53
- var queries = List <String >();
99
+ var queries = List <MapEntry >();
54
100
55
101
// START QUERY
56
102
const String QUERY_START = "where={" ;
@@ -60,36 +106,38 @@ class QueryBuilder <T extends ParseObject> {
60
106
61
107
// ADD PARAM TO MAP
62
108
//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" ));
65
111
66
112
// 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" ));
72
118
73
119
// 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" ));
80
126
81
127
// Works
82
- if (regEx != null ) queries.add ( _buildQueryWithOperatorAndField (regEx , "\$ regex" , field ));
128
+ if (_regExQueries.length != 0 ) queries.addAll ( _getAllQueries (_regExQueries , "\$ regex" ));
83
129
84
130
// 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);
86
134
87
135
// -- BUILD QUERY USING MAP
88
- for (var item in queries){
136
+ for (var item in queries) {
89
137
if (query == QUERY_START ) {
90
- query += item;
138
+ query += item.value ;
91
139
} else {
92
- query += ",$item " ;
140
+ query += ",${ item . value } " ;
93
141
}
94
142
}
95
143
@@ -105,22 +153,28 @@ class QueryBuilder <T extends ParseObject> {
105
153
return query;
106
154
}
107
155
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
+ }
109
163
110
- var queryOperatorAndValueMap = Map ();
111
- var queryString = "\" $tableNameToQuery \" :" ;
164
+ _buildQueryWithColumnValueAndOperator (MapEntry columnAndValue, String queryOperator) {
112
165
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;
116
170
117
171
var formattedQueryOperatorAndValue = JsonEncoder ().convert (queryOperatorAndValueMap);
118
172
queryString += "$formattedQueryOperatorAndValue " ;
119
173
120
- return queryString;
174
+ return MapEntry (columnAndValue.key, queryString) ;
121
175
}
122
176
123
- _runThroughQueryParams (List <dynamic > list, String queryParam ) {
177
+ _runThroughQueryParams (List <MapEntry > list) {
124
178
Map <String , dynamic > mapToReturn = Map <String , dynamic >();
125
179
var params;
126
180
@@ -136,12 +190,11 @@ class QueryBuilder <T extends ParseObject> {
136
190
}
137
191
}
138
192
139
- mapToReturn[queryParam ] = params;
193
+ mapToReturn["wasField" ] = params;
140
194
141
195
return JsonEncoder ().convert (mapToReturn);
142
196
}
143
-
144
- Map <String , String > _runThroughQueryParamsWithSearchTerms (List <dynamic > list, String queryParam, String fieldName) {
197
+ _runThroughQueryParamsWithSearchTerms (List <dynamic > list, String queryParam, String fieldName) {
145
198
Map <String , String > mapToReturn = Map <String , String >();
146
199
Map <String , dynamic > mapWithParamData = Map <String , dynamic >();
147
200
Map <String , String > textEntry = Map <String , String >();
@@ -162,4 +215,45 @@ class QueryBuilder <T extends ParseObject> {
162
215
163
216
return mapToReturn;
164
217
}
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
+ }
165
259
}
0 commit comments