Line data Source code
1 : import 'dart:async';
2 : import 'dart:convert';
3 : import 'package:contentstack/client.dart';
4 : import 'package:contentstack/src/base_query.dart';
5 : import 'package:contentstack/src/enums/operator.dart';
6 : import 'package:contentstack/src/enums/reference.dart';
7 : import 'package:contentstack/src/enums/include.dart' as include;
8 :
9 :
10 : class Query extends BaseQuery {
11 :
12 : final HttpClient _client;
13 : final String _contentTypeUid;
14 : String _path;
15 :
16 1 : Query([this._client, this._contentTypeUid]) {
17 5 : queryParameter['environment'] = _client.stackHeaders['environment'];
18 1 : _path =
19 5 : '/${_client.stack.apiVersion}/content_types/$_contentTypeUid/entries';
20 : }
21 :
22 1 : Map getQueryUrl() {
23 3 : if (parameter != null && parameter.isNotEmpty) {
24 2 : final stringify = json.encode(parameter);
25 3 : queryParameter['query'] = stringify.toString();
26 1 : return queryParameter;
27 : }
28 1 : return queryParameter;
29 : }
30 :
31 1 : Future<T> find<T, K>() async{
32 1 : getQueryUrl();
33 6 : final uri = Uri.https(_client.stack.endpoint, _path, queryParameter);
34 2 : return _client.sendRequest<T, K>(uri);
35 : }
36 :
37 : ///
38 : /// To set headers for Built.io Contentstack rest calls.
39 : /// Scope is limited to this object and followed classes.
40 : /// [key] header name.
41 : /// [value] header value against given header name.
42 : /// Example:
43 : /// final stack = contentstack.Stack('apiKey', 'deliveryToken', 'environment');
44 : /// final query = stack.contentType('content_type_uid').entry().query();
45 : /// query.setHeader('key', 'value');
46 : ///
47 1 : void setHeader(String key, String value) {
48 2 : if (key.isNotEmpty && value.isNotEmpty) {
49 3 : _client.stackHeaders[key] = value;
50 : }
51 : }
52 :
53 : ///
54 : /// Remove header key
55 : /// [key] custom header key
56 : ///
57 : /// Example:
58 : /// final stack = contentstack.Stack('apiKey', 'deliveryToken', 'environment');
59 : /// final query = stack.contentType('content_type_uid').entry().query();
60 : /// query.removeHeader('key');
61 : ///
62 1 : void removeHeader(String key) {
63 3 : if (_client.stackHeaders.containsKey(key)) {
64 3 : _client.stackHeaders.remove(key);
65 : }
66 : }
67 :
68 : ///
69 : /// * Reference Search Equals:
70 : /// Get entries having values based on referenced fields.
71 : /// This query retrieves all entries that satisfy the query
72 : /// conditions made on referenced fields.
73 : ///
74 : /// * Reference Search Not-equals:
75 : /// Get entries having values based on referenced fields.
76 : /// This query works the opposite of $in_query and retrieves
77 : /// all entries that does not satisfy query conditions made on referenced fields.
78 : ///
79 : /// * [referenceUid] is Reference field
80 : /// * [reference] It accepts Enum type
81 : /// QueryReference.include() OR QueryReference.NotInclude()
82 : /// and it accepts instance of Query
83 : /// Example:
84 : ///
85 : /// final query = stack.contentType('room').entry().query();
86 : /// query.referenceSearch('fieldUid', QueryReference.include(query: query));
87 : /// await query.find().then((response){
88 : /// print(response);
89 : /// });
90 : ///
91 1 : void whereReference(String referenceUid, QueryReference reference) {
92 1 : if (referenceUid != null && referenceUid.isNotEmpty) {
93 2 : reference.when(include: (queryInstance) {
94 5 : parameter[referenceUid] = {'\$in_query': queryInstance.query.parameter};
95 1 : }, notInclude: (queryInstance) {
96 3 : parameter[referenceUid] = {
97 2 : '\$nin_query': queryInstance.query.parameter
98 : };
99 : });
100 : }
101 : }
102 :
103 : ///
104 : /// * AND Operator
105 : /// Get entries that satisfy all the conditions provided in the '$and' query.
106 : ///
107 : /// * OR Operator
108 : /// Get all entries that satisfy at least one of the given conditions provided
109 : /// in the '$or' query.
110 : ///
111 : /// * {Example}: operator OR
112 : ///
113 : /// final stackInstance1 = Credential.stack();
114 : /// final queryBase1 = stackInstance1.contentType('room').entry().query();
115 : /// queryBase1.where('title', QueryOperation.equals(value: 'Room 13'));
116 : ///
117 : /// final stackInstance2 = Credential.stack();
118 : /// final queryBase2 = stackInstance2.contentType('room').entry().query();
119 : /// queryBase2.where('attendee', QueryOperation.equals(value: 20));
120 : ///
121 : /// final List<contentstack.Query> listOfQuery = [queryBase1, queryBase2];
122 : /// query.operator(QueryOperator.or(queryObjects: listOfQuery));
123 : /// await query.find().then((response){
124 : /// print(response.toString());
125 : /// }).catchError((onError){
126 : /// print(onError);
127 : /// });
128 : ///
129 : ///
130 : ///
131 : /// * {Example}: And Operator:
132 : ///
133 : /// final stackInstance1 = Credential.stack();
134 : /// final queryBase1 = stackInstance1.contentType('room').entry().query();
135 : /// queryBase1.where('title', QueryOperation.equals(value: 'Room 13'));
136 : ///
137 : /// final stackInstance2 = Credential.stack();
138 : /// final queryBase2 = stackInstance2.contentType('room').entry().query();
139 : /// queryBase2.where('attendee', QueryOperation.equals(value: 20));
140 : ///
141 : /// final List<contentstack.Query> listOfQuery = [queryBase1, queryBase2];
142 : /// query.operator(QueryOperator.and(queryObjects: listOfQuery));
143 : /// await query.find().then((response){
144 : /// print(response.toString());
145 : /// }).catchError((onError){
146 : /// print(onError);
147 : /// });
148 : ///
149 1 : void operator(QueryOperator operator) {
150 2 : operator.when(and: (and) {
151 : final List<Query> queryList =
152 1 : and.queryObjects; //and.queryObjects is list of Query Objects
153 1 : if (queryList.isNotEmpty) {
154 1 : final emptyList = [];
155 2 : for (final item in queryList) {
156 2 : emptyList.add(item.parameter);
157 : }
158 2 : parameter['\$and'] = emptyList;
159 : }
160 1 : }, or: (or) {
161 : final List<Query> queryList =
162 1 : or.queryObjects; //and.queryObjects is list of Query Objects
163 1 : if (queryList.isNotEmpty) {
164 1 : final emptyList = [];
165 2 : for (final item in queryList) {
166 2 : emptyList.add(item.parameter);
167 : }
168 2 : parameter['\$or'] = emptyList;
169 : }
170 : });
171 : }
172 :
173 :
174 :
175 : //
176 : // Entry Queryable functions:
177 : ///
178 : /// [locale] is code of the language of which the entries needs to be included.
179 : /// Only the entries published in this locale will be fetched.
180 : ///
181 : /// Example:
182 : /// final stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
183 : /// final query = stack.contentType("contentTypeUid").entry().query();
184 : /// query.locale('en-eu');
185 : ///
186 1 : void locale(String locale) {
187 2 : queryParameter['locale'] = locale;
188 : }
189 :
190 :
191 : /////////////////////////////////////////////////
192 : //-------------[Entry Queryable]---------------//
193 : /////////////////////////////////////////////////
194 :
195 :
196 : /// Specifies an array of only keys in BASE object that would be included in the response.
197 : /// [fieldUid] Array of the only reference keys to be included in response.
198 : /// [Query] object, so you can chain this call.
199 : ///
200 : /// Example:
201 : /// final stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
202 : /// final query = stack.contentType("contentTypeUid").entry().query();
203 : /// fieldUid is String type of List
204 : /// query.only(fieldUid);
205 : ///
206 1 : void only(List<String> fieldUid) {
207 1 : if (fieldUid != null && fieldUid.isNotEmpty) {
208 1 : final List<String> referenceArray = [];
209 2 : for (final item in fieldUid) {
210 1 : referenceArray.add(item);
211 : }
212 3 : queryParameter['only[BASE][]'] = referenceArray.toString();
213 : }
214 : }
215 :
216 : ///
217 : /// Specifies list of field uids that would be excluded from the response.
218 : /// [fieldUid] field uid which get excluded from the response.
219 : /// [Query] object, so you can chain this call.
220 : ///
221 : /// Example:
222 : /// final stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
223 : /// final query = stack.contentType("contentTypeUid").entry().query();
224 : /// fieldUid is String type of List
225 : /// query.except(fieldUid);
226 : ///
227 1 : void except(List<String> fieldUid) {
228 1 : if (fieldUid != null && fieldUid.isNotEmpty) {
229 1 : final List referenceArray = [];
230 2 : for (final item in fieldUid) {
231 1 : referenceArray.add(item);
232 : }
233 3 : queryParameter['except[BASE][]'] = referenceArray.toString();
234 : }
235 : }
236 :
237 : ///
238 : /// * Include Reference
239 : /// When you fetch an entry of a content type that has a reference field,
240 : /// by default, the content of the referred entry is not fetched.
241 : /// It only fetches the UID of the referred entry, along with the content of
242 : /// the specified entry.
243 : ///
244 : /// If you wish to fetch the content of the entry that is included in the reference field, you need to use the include[] parameter, and specify the UID of the reference field as value. This informs Contentstack that the request also includes fetching the entry used in the specified reference field.
245 : /// Add a constraint that requires a particular reference key details.
246 : /// [includeReference] provides three options, none, only and except
247 : /// i.e accepts list of fieldUid
248 : /// [referenceFieldUid] Key who has reference to some other class object.
249 : /// Array of the only reference keys to be included in response.
250 : ///
251 : /// {Example 1}: Reference type None
252 : ///
253 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
254 : /// final query = stack.contentType('contentTypeUid').entry().query();
255 : /// query.includeReference("referenceFieldUid", IncludeReference.none(fieldUidList: null));
256 : /// await entry.fetch();
257 : ///
258 : /// {Example 2}: Reference type only
259 : ///
260 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
261 : /// final query = stack.contentType('contentTypeUid').entry().query();
262 : /// final fieldUid = list of string type;
263 : /// query.includeReference("referenceFieldUid", IncludeReference.only(fieldUidList: fieldUid));
264 : ///
265 : /// {Example 3}: Reference type except
266 : ///
267 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
268 : /// final query = stack.contentType('contentTypeUid').entry().query();
269 : /// query.includeReference("referenceFieldUid", IncludeReference.except(fieldUidList: fieldUid));
270 : ///
271 1 : void includeReference(String referenceFieldUid,
272 : {include.Include includeReferenceField}) {
273 1 : if (referenceFieldUid != null && referenceFieldUid.isNotEmpty) {
274 1 : final List referenceArray = [];
275 : if (includeReferenceField != null) {
276 2 : includeReferenceField.when(none: (fieldUid) {
277 1 : referenceArray.add(referenceFieldUid);
278 1 : if (fieldUid.fieldUidList != null &&
279 2 : fieldUid.fieldUidList.isNotEmpty) {
280 2 : for (final item in fieldUid.fieldUidList) {
281 1 : referenceArray.add(item);
282 : }
283 : }
284 3 : queryParameter['include[]'] = referenceArray.toString();
285 1 : }, only: (fieldUid) {
286 1 : final Map<String, dynamic> referenceOnlyParam = <String, dynamic>{};
287 1 : if (fieldUid.fieldUidList != null &&
288 2 : fieldUid.fieldUidList.isNotEmpty) {
289 2 : for (final item in fieldUid.fieldUidList) {
290 1 : referenceArray.add(item);
291 : }
292 : }
293 1 : referenceOnlyParam[referenceFieldUid] = referenceArray;
294 : //_include(referenceFieldUid);
295 1 : includeReference(referenceFieldUid);
296 3 : queryParameter['only'] = referenceOnlyParam.toString();
297 1 : }, except: (fieldUid) {
298 1 : final Map<String, dynamic> referenceOnlyParam = <String, dynamic>{};
299 1 : if (fieldUid.fieldUidList != null &&
300 2 : fieldUid.fieldUidList.isNotEmpty) {
301 2 : for (final item in fieldUid.fieldUidList) {
302 1 : referenceArray.add(item);
303 : }
304 : }
305 1 : referenceOnlyParam[referenceFieldUid] = referenceArray;
306 : //_include(referenceFieldUid);
307 1 : includeReference(referenceFieldUid);
308 3 : queryParameter['except'] = referenceOnlyParam.toString();
309 : });
310 : } else {
311 2 : queryParameter['include[]'] = referenceFieldUid;
312 : }
313 : }
314 : }
315 :
316 : ///
317 : /// Include Content Type of all returned objects along with objects themselves.
318 : /// return, [Query] so you can chain this call.
319 : ///
320 : /// Example:
321 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
322 : /// final query = stack.contentType('contentTypeUid').entry().query();
323 : /// query.includeContentType();
324 : ///
325 1 : void includeContentType() {
326 2 : queryParameter['include_content_type'] = 'true';
327 2 : queryParameter['include_global_field_schema'] = 'true';
328 : }
329 :
330 : /// This method also includes the content type UIDs of the referenced entries returned in the response
331 : /// return [Query] so you can chain this call
332 : ///
333 : /// Example:
334 : ///
335 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
336 : /// final query = stack.contentType('contentTypeUid').entry().query();
337 : /// query.includeReferenceContentTypeUID();
338 : ///
339 1 : void includeReferenceContentTypeUID() {
340 2 : queryParameter['include_reference_content_type_uid'] = 'true';
341 : }
342 :
343 : ///
344 : /// This method adds key and value to an Entry.
345 : /// [key] The key as string which needs to be added to an Entry
346 : /// [value] The value as string which needs to be added to an Entry
347 : /// [Query] object, so you can chain this call.
348 : ///
349 : /// Example:
350 : ///
351 : /// final stack = contentstack.Stack('apiKey, 'deliveryKey, 'environment);
352 : /// final query = stack.contentType('contentTypeUid').entry().query();
353 : /// entry.addParam(key, value);
354 : ///
355 1 : void addParam(String key, String value) {
356 2 : if (key != null && value != null && key.isNotEmpty && value.isNotEmpty) {
357 3 : queryParameter[key] = value.toString();
358 : }
359 : }
360 :
361 :
362 :
363 : }
|