UNPKG

11.6 kBJavaScriptView Raw
1"use strict";
2/*!
3 * Copyright 2014 Google LLC.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.Query = void 0;
19const arrify = require("arrify");
20const filter_1 = require("./filter");
21/**
22 * Build a Query object.
23 *
24 * **Queries are built with {module:datastore#createQuery} and
25 * {@link Transaction#createQuery}.**
26 *
27 * @see {@link http://goo.gl/Cag0r6| Datastore Queries}
28 *
29 * @class
30 * @param {Datastore|Transaction} scope The parent scope the query was created
31 * from.
32 * @param {string} [namespace] Namespace to query entities from.
33 * @param {string[]} kinds Kind to query.
34 *
35 * @example
36 * ```
37 * const {Datastore} = require('@google-cloud/datastore');
38 * const datastore = new Datastore();
39 * const query = datastore.createQuery('AnimalNamespace', 'Lion');
40 * ```
41 */
42class Query {
43 constructor(scope, namespaceOrKinds, kinds) {
44 let namespace = namespaceOrKinds;
45 if (!kinds) {
46 kinds = namespaceOrKinds;
47 namespace = null;
48 }
49 /**
50 * @name Query#scope
51 * @type {Datastore|Transaction}
52 */
53 this.scope = scope;
54 /**
55 * @name Query#namespace
56 * @type {?string}
57 */
58 this.namespace = namespace || null;
59 /**
60 * @name Query#kinds
61 * @type {string}
62 */
63 this.kinds = kinds;
64 /**
65 * @name Query#filters
66 * @type {array}
67 */
68 this.filters = [];
69 /**
70 * @name Query#entityFilters
71 * @type {array}
72 */
73 this.entityFilters = [];
74 /**
75 * @name Query#orders
76 * @type {array}
77 */
78 this.orders = [];
79 /**
80 * @name Query#groupByVal
81 * @type {array}
82 */
83 this.groupByVal = [];
84 /**
85 * @name Query#selectVal
86 * @type {array}
87 */
88 this.selectVal = [];
89 // pagination
90 /**
91 * @name Query#startVal
92 * @type {?number}
93 */
94 this.startVal = null;
95 /**
96 * @name Query#endVal
97 * @type {?number}
98 */
99 this.endVal = null;
100 /**
101 * @name Query#limitVal
102 * @type {number}
103 */
104 this.limitVal = -1;
105 /**
106 * @name Query#offsetVal
107 * @type {number}
108 */
109 this.offsetVal = -1;
110 }
111 filter(propertyOrFilter, operatorOrValue, value) {
112 if (arguments.length > 1) {
113 process.emitWarning('Providing Filter objects like Composite Filter or Property Filter is recommended when using .filter');
114 }
115 switch (arguments.length) {
116 case 1: {
117 if ((0, filter_1.isFilter)(propertyOrFilter)) {
118 this.entityFilters.push(propertyOrFilter);
119 }
120 break;
121 }
122 case 2: {
123 this.filters.push({
124 name: propertyOrFilter.trim(),
125 op: '=',
126 val: operatorOrValue,
127 });
128 break;
129 }
130 case 3: {
131 this.filters.push({
132 name: propertyOrFilter.trim(),
133 op: operatorOrValue.trim(),
134 val: value,
135 });
136 }
137 }
138 return this;
139 }
140 /**
141 * Filter a query by ancestors.
142 *
143 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#datastore-ancestor-query-nodejs| Datastore Ancestor Filters}
144 *
145 * @param {Key} key Key object to filter by.
146 * @returns {Query}
147 *
148 * @example
149 * ```
150 * const {Datastore} = require('@google-cloud/datastore');
151 * const datastore = new Datastore();
152 * const query = datastore.createQuery('MyKind');
153 * const ancestoryQuery = query.hasAncestor(datastore.key(['Parent', 123]));
154 * ```
155 */
156 hasAncestor(key) {
157 this.filters.push({ name: '__key__', op: 'HAS_ANCESTOR', val: key });
158 return this;
159 }
160 /**
161 * Sort the results by a property name in ascending or descending order. By
162 * default, an ascending sort order will be used.
163 *
164 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#datastore-ascending-sort-nodejs| Datastore Sort Orders}
165 *
166 * @param {string} property The property to order by.
167 * @param {object} [options] Options object.
168 * @param {boolean} [options.descending=false] Sort the results by a property
169 * name in descending order.
170 * @returns {Query}
171 *
172 * @example
173 * ```
174 * const {Datastore} = require('@google-cloud/datastore');
175 * const datastore = new Datastore();
176 * const companyQuery = datastore.createQuery('Company');
177 *
178 * // Sort by size ascendingly.
179 * const companiesAscending = companyQuery.order('size');
180 *
181 * // Sort by size descendingly.
182 * const companiesDescending = companyQuery.order('size', {
183 * descending: true
184 * });
185 * ```
186 */
187 order(property, options) {
188 const sign = options && options.descending ? '-' : '+';
189 this.orders.push({ name: property, sign });
190 return this;
191 }
192 /**
193 * Group query results by a list of properties.
194 *
195 * @param {array} properties Properties to group by.
196 * @returns {Query}
197 *
198 * @example
199 * ```
200 * const {Datastore} = require('@google-cloud/datastore');
201 * const datastore = new Datastore();
202 * const companyQuery = datastore.createQuery('Company');
203 * const groupedQuery = companyQuery.groupBy(['name', 'size']);
204 * ```
205 */
206 groupBy(fieldNames) {
207 this.groupByVal = arrify(fieldNames);
208 return this;
209 }
210 /**
211 * Retrieve only select properties from the matched entities.
212 *
213 * Queries that select a subset of properties are called Projection Queries.
214 *
215 * @see {@link https://cloud.google.com/datastore/docs/concepts/projectionqueries| Projection Queries}
216 *
217 * @param {string|string[]} fieldNames Properties to return from the matched
218 * entities.
219 * @returns {Query}
220 *
221 * @example
222 * ```
223 * const {Datastore} = require('@google-cloud/datastore');
224 * const datastore = new Datastore();
225 * const companyQuery = datastore.createQuery('Company');
226 *
227 * // Only retrieve the name property.
228 * const selectQuery = companyQuery.select('name');
229 *
230 * // Only retrieve the name and size properties.
231 * const selectQuery = companyQuery.select(['name', 'size']);
232 * ```
233 */
234 select(fieldNames) {
235 this.selectVal = arrify(fieldNames);
236 return this;
237 }
238 /**
239 * Set a starting cursor to a query.
240 *
241 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets| Query Cursors}
242 *
243 * @param {string} cursorToken The starting cursor token.
244 * @returns {Query}
245 *
246 * @example
247 * ```
248 * const {Datastore} = require('@google-cloud/datastore');
249 * const datastore = new Datastore();
250 * const companyQuery = datastore.createQuery('Company');
251 *
252 * const cursorToken = 'X';
253 *
254 * // Retrieve results starting from cursorToken.
255 * const startQuery = companyQuery.start(cursorToken);
256 * ```
257 */
258 start(start) {
259 this.startVal = start;
260 return this;
261 }
262 /**
263 * Set an ending cursor to a query.
264 *
265 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#Datastore_Query_cursors| Query Cursors}
266 *
267 * @param {string} cursorToken The ending cursor token.
268 * @returns {Query}
269 *
270 * @example
271 * ```
272 * const {Datastore} = require('@google-cloud/datastore');
273 * const datastore = new Datastore();
274 * const companyQuery = datastore.createQuery('Company');
275 *
276 * const cursorToken = 'X';
277 *
278 * // Retrieve results limited to the extent of cursorToken.
279 * const endQuery = companyQuery.end(cursorToken);
280 * ```
281 */
282 end(end) {
283 this.endVal = end;
284 return this;
285 }
286 /**
287 * Set a limit on a query.
288 *
289 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#datastore-limit-nodejs| Query Limits}
290 *
291 * @param {number} n The number of results to limit the query to.
292 * @returns {Query}
293 *
294 * @example
295 * ```
296 * const {Datastore} = require('@google-cloud/datastore');
297 * const datastore = new Datastore();
298 * const companyQuery = datastore.createQuery('Company');
299 *
300 * // Limit the results to 10 entities.
301 * const limitQuery = companyQuery.limit(10);
302 * ```
303 */
304 limit(n) {
305 this.limitVal = n;
306 return this;
307 }
308 /**
309 * Set an offset on a query.
310 *
311 * @see {@link https://cloud.google.com/datastore/docs/concepts/queries#datastore-limit-nodejs| Query Offsets}
312 *
313 * @param {number} n The offset to start from after the start cursor.
314 * @returns {Query}
315 *
316 * @example
317 * ```
318 * const {Datastore} = require('@google-cloud/datastore');
319 * const datastore = new Datastore();
320 * const companyQuery = datastore.createQuery('Company');
321 *
322 * // Start from the 101st result.
323 * const offsetQuery = companyQuery.offset(100);
324 * ```
325 */
326 offset(n) {
327 this.offsetVal = n;
328 return this;
329 }
330 run(optionsOrCallback, cb) {
331 const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
332 const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
333 const runQuery = this.scope.runQuery.bind(this.scope);
334 return runQuery(this, options, callback);
335 }
336 /**
337 * Run the query as a readable object stream.
338 *
339 * @method Query#runStream
340 * @param {object} [options] Optional configuration. See
341 * {@link Query#run} for a complete list of options.
342 * @returns {stream}
343 *
344 * @example
345 * ```
346 * const {Datastore} = require('@google-cloud/datastore');
347 * const datastore = new Datastore();
348 * const query = datastore.createQuery('Company');
349 *
350 * query.runStream()
351 * .on('error', console.error)
352 * .on('data', function (entity) {
353 * // Access the Key object for this entity.
354 * const key = entity[datastore.KEY];
355 * })
356 * .on('info', (info) => {})
357 * .on('end', () => {
358 * // All entities retrieved.
359 * });
360 *
361 * //-
362 * // If you anticipate many results, you can end a stream early to prevent
363 * // unnecessary processing and API requests.
364 * //-
365 * query.runStream()
366 * .on('data', function (entity) {
367 * this.end();
368 * });
369 * ```
370 */
371 runStream(options) {
372 return this.scope.runQueryStream(this, options);
373 }
374}
375exports.Query = Query;
376//# sourceMappingURL=query.js.map
\No newline at end of file