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