UNPKG

14.5 kBJavaScriptView Raw
1/*
2 * Copyright DataStax, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17'use strict';
18
19const utils = require('./utils');
20const types = require('./types');
21const errors = require('./errors');
22
23const proxyExecuteKey = 'ProxyExecute';
24
25/**
26 * A base class that represents a wrapper around the user provided query options with getter methods and proper
27 * default values.
28 * <p>
29 * Note that getter methods might return <code>undefined</code> when not set on the query options or default
30 * {@link Client} options.
31 * </p>
32 */
33class ExecutionOptions {
34
35 /**
36 * Creates a new instance of {@link ExecutionOptions}.
37 */
38 constructor() {
39 }
40
41 /**
42 * Creates an empty instance, where all methods return undefined, used internally.
43 * @ignore
44 * @return {ExecutionOptions}
45 */
46 static empty() {
47 return new ExecutionOptions();
48 }
49
50 /**
51 * Determines if the stack trace before the query execution should be maintained.
52 * @abstract
53 * @returns {Boolean}
54 */
55 getCaptureStackTrace() {
56
57 }
58
59 /**
60 * Gets the [Consistency level]{@link module:types~consistencies} to be used for the execution.
61 * @abstract
62 * @returns {Number}
63 */
64 getConsistency() {
65
66 }
67
68 /**
69 * Key-value payload to be passed to the server. On the server side, implementations of QueryHandler can use
70 * this data.
71 * @abstract
72 * @returns {Object}
73 */
74 getCustomPayload() {
75
76 }
77
78 /**
79 * Gets the amount of rows to retrieve per page.
80 * @abstract
81 * @returns {Number}
82 */
83 getFetchSize() {
84
85 }
86
87 /**
88 * When a fixed host is set on the query options and the query plan for the load-balancing policy is not used, it
89 * gets the host that should handle the query.
90 * @returns {Host}
91 */
92 getFixedHost() {
93
94 }
95
96 /**
97 * Gets the type hints for parameters given in the query, ordered as for the parameters.
98 * @abstract
99 * @returns {Array|Array<Array>}
100 */
101 getHints() {
102
103 }
104
105 /**
106 * Determines whether the driver must retrieve the following result pages automatically.
107 * <p>
108 * This setting is only considered by the [Client#eachRow()]{@link Client#eachRow} method.
109 * </p>
110 * @abstract
111 * @returns {Boolean}
112 */
113 isAutoPage() {
114
115 }
116
117 /**
118 * Determines whether its a counter batch. Only valid for [Client#batch()]{@link Client#batch}, it will be ignored by
119 * other methods.
120 * @abstract
121 * @returns {Boolean} A <code>Boolean</code> value, it can't be <code>undefined</code>.
122 */
123 isBatchCounter() {
124
125 }
126
127 /**
128 * Determines whether the batch should be written to the batchlog. Only valid for
129 * [Client#batch()]{@link Client#batch}, it will be ignored by other methods.
130 * @abstract
131 * @returns {Boolean} A <code>Boolean</code> value, it can't be <code>undefined</code>.
132 */
133 isBatchLogged() {
134
135 }
136
137 /**
138 * Determines whether the query can be applied multiple times without changing the result beyond the initial
139 * application.
140 * @abstract
141 * @returns {Boolean}
142 */
143 isIdempotent() {
144
145 }
146
147 /**
148 * Determines whether the query must be prepared beforehand.
149 * @abstract
150 * @returns {Boolean} A <code>Boolean</code> value, it can't be <code>undefined</code>.
151 */
152 isPrepared() {
153
154 }
155
156 /**
157 * Determines whether query tracing is enabled for the execution.
158 * @abstract
159 * @returns {Boolean}
160 */
161 isQueryTracing() {
162
163 }
164
165 /**
166 * Gets the keyspace for the query when set at query options level.
167 * <p>
168 * Note that this method will return <code>undefined</code> when the keyspace is not set at query options level.
169 * It will only return the keyspace name when the user provided a different keyspace than the current
170 * {@link Client} keyspace.
171 * </p>
172 * @abstract
173 * @returns {String}
174 */
175 getKeyspace() {
176
177 }
178
179 /**
180 * Gets the load balancing policy used for this execution.
181 * @returns {LoadBalancingPolicy} A <code>LoadBalancingPolicy</code> instance, it can't be <code>undefined</code>.
182 */
183 getLoadBalancingPolicy() {
184
185 }
186
187 /**
188 * Gets the Buffer representing the paging state.
189 * @abstract
190 * @returns {Buffer}
191 */
192 getPageState() {
193
194 }
195
196 /**
197 * Internal method that gets the preferred host.
198 * @abstract
199 * @ignore
200 */
201 getPreferredHost() {
202
203 }
204
205 /**
206 * Gets the query options as provided to the execution method without setting the default values.
207 * @returns {QueryOptions}
208 */
209 getRawQueryOptions() {
210
211 }
212
213 /**
214 * Gets the timeout in milliseconds to be used for the execution per coordinator.
215 * <p>
216 * A value of <code>0</code> disables client side read timeout for the execution. Default: <code>undefined</code>.
217 * </p>
218 * @abstract
219 * @returns {Number}
220 */
221 getReadTimeout() {
222
223 }
224
225 /**
226 * Gets the [retry policy]{@link module:policies/retry} to be used.
227 * @abstract
228 * @returns {RetryPolicy} A <code>RetryPolicy</code> instance, it can't be <code>undefined</code>.
229 */
230 getRetryPolicy() {
231
232 }
233
234 /**
235 * Internal method to obtain the row callback, for "by row" results.
236 * @abstract
237 * @ignore
238 */
239 getRowCallback() {
240
241 }
242
243 /**
244 * Internal method to get or generate a timestamp for the request execution.
245 * @ignore
246 * @returns {Long|null}
247 */
248 getOrGenerateTimestamp() {
249
250 }
251
252 /**
253 * Gets the index of the parameters that are part of the partition key to determine the routing.
254 * @abstract
255 * @ignore
256 * @returns {Array}
257 */
258 getRoutingIndexes() {
259
260 }
261
262 /**
263 * Gets the partition key(s) to determine which coordinator should be used for the query.
264 * @abstract
265 * @returns {Buffer|Array<Buffer>}
266 */
267 getRoutingKey() {
268
269 }
270
271 /**
272 * Gets the array of the parameters names that are part of the partition key to determine the
273 * routing. Only valid for non-prepared requests.
274 * @abstract
275 * @ignore
276 */
277 getRoutingNames() {
278
279 }
280
281 /**
282 * Gets the the consistency level to be used for the serial phase of conditional updates.
283 * @abstract
284 * @returns {Number}
285 */
286 getSerialConsistency() {
287
288 }
289
290 /**
291 * Gets the provided timestamp for the execution in microseconds from the unix epoch (00:00:00, January 1st, 1970).
292 * <p>When a timestamp generator is used, this method returns <code>undefined</code>.</p>
293 * @abstract
294 * @returns {Number|Long|undefined|null}
295 */
296 getTimestamp() {
297
298 }
299
300 /**
301 * @param {Array} hints
302 * @abstract
303 * @ignore
304 */
305 setHints(hints) {
306
307 }
308
309 /**
310 * Sets the keyspace for the execution.
311 * @ignore
312 * @abstract
313 * @param {String} keyspace
314 */
315 setKeyspace(keyspace) {
316
317 }
318
319 /**
320 * @abstract
321 * @ignore
322 */
323 setPageState() {
324
325 }
326
327 /**
328 * Internal method that sets the preferred host.
329 * @abstract
330 * @ignore
331 */
332 setPreferredHost() {
333
334 }
335
336 /**
337 * Sets the index of the parameters that are part of the partition key to determine the routing.
338 * @param {Array} routingIndexes
339 * @abstract
340 * @ignore
341 */
342 setRoutingIndexes(routingIndexes) {
343
344 }
345
346 /**
347 * Sets the routing key.
348 * @abstract
349 * @ignore
350 */
351 setRoutingKey(value) {
352
353 }
354}
355
356/**
357 * Internal implementation of {@link ExecutionOptions} that uses the value from the client options and execution
358 * profile into account.
359 * @ignore
360 */
361class DefaultExecutionOptions extends ExecutionOptions {
362 /**
363 * Creates a new instance of {@link ExecutionOptions}.
364 * @param {QueryOptions} queryOptions
365 * @param {Client} client
366 * @param {Function|null} rowCallback
367 */
368 constructor(queryOptions, client, rowCallback) {
369 super();
370
371 this._queryOptions = queryOptions;
372 this._rowCallback = rowCallback;
373 this._routingKey = this._queryOptions.routingKey;
374 this._hints = this._queryOptions.hints;
375 this._keyspace = this._queryOptions.keyspace;
376 this._routingIndexes = this._queryOptions.routingIndexes;
377 this._pageState = typeof this._queryOptions.pageState === 'string' ?
378 utils.allocBufferFromString(this._queryOptions.pageState, 'hex') : this._queryOptions.pageState;
379 this._preferredHost = null;
380
381 this._client = client;
382 this._defaultQueryOptions = client.options.queryOptions;
383 this._profile = client.profileManager.getProfile(this._queryOptions.executionProfile);
384
385 // Build a custom payload object designed for DSE-specific functionality
386 this._customPayload = DefaultExecutionOptions.createCustomPayload(this._queryOptions, this._defaultQueryOptions);
387
388 if (!this._profile) {
389 throw new errors.ArgumentError(`Execution profile "${this._queryOptions.executionProfile}" not found`);
390 }
391 }
392
393 /**
394 * Creates a payload for given user.
395 * @param {QueryOptions} userOptions
396 * @param {QueryOptions} defaultQueryOptions
397 * @private
398 */
399 static createCustomPayload(userOptions, defaultQueryOptions) {
400 let customPayload = userOptions.customPayload || defaultQueryOptions.customPayload;
401 const executeAs = userOptions.executeAs || defaultQueryOptions.executeAs;
402
403 if (executeAs) {
404 if (!customPayload) {
405 customPayload = {};
406 customPayload[proxyExecuteKey] = utils.allocBufferFromString(executeAs);
407 } else if (!customPayload[proxyExecuteKey]) {
408 // Avoid appending to the existing payload object
409 customPayload = utils.extend({}, customPayload);
410 customPayload[proxyExecuteKey] = utils.allocBufferFromString(executeAs);
411 }
412 }
413
414 return customPayload;
415 }
416
417 /**
418 * Creates a new instance {@link ExecutionOptions}, based on the query options.
419 * @param {QueryOptions|null} queryOptions
420 * @param {Client} client
421 * @param {Function|null} [rowCallback]
422 * @ignore
423 * @return {ExecutionOptions}
424 */
425 static create(queryOptions, client, rowCallback) {
426 if (!queryOptions || typeof queryOptions === 'function') {
427 // queryOptions can be null/undefined and could be of type function when is an optional parameter
428 queryOptions = utils.emptyObject;
429 }
430 return new DefaultExecutionOptions(queryOptions, client, rowCallback);
431 }
432
433 getCaptureStackTrace() {
434 return ifUndefined(this._queryOptions.captureStackTrace, this._defaultQueryOptions.captureStackTrace);
435 }
436
437 getConsistency() {
438 return ifUndefined3(this._queryOptions.consistency, this._profile.consistency,
439 this._defaultQueryOptions.consistency);
440 }
441
442 getCustomPayload() {
443 return this._customPayload;
444 }
445
446 getFetchSize() {
447 return ifUndefined(this._queryOptions.fetchSize, this._defaultQueryOptions.fetchSize);
448 }
449
450 getFixedHost() {
451 return this._queryOptions.host;
452 }
453
454 getHints() {
455 return this._hints;
456 }
457
458 isAutoPage() {
459 return ifUndefined(this._queryOptions.autoPage, this._defaultQueryOptions.autoPage);
460 }
461
462 isBatchCounter() {
463 return ifUndefined(this._queryOptions.counter, false);
464 }
465
466 isBatchLogged() {
467 return ifUndefined3(this._queryOptions.logged, this._defaultQueryOptions.logged, true);
468 }
469
470 isIdempotent() {
471 return ifUndefined(this._queryOptions.isIdempotent, this._defaultQueryOptions.isIdempotent);
472 }
473
474 /**
475 * Determines if the query execution must be prepared beforehand.
476 * @return {Boolean}
477 */
478 isPrepared() {
479 return ifUndefined(this._queryOptions.prepare, this._defaultQueryOptions.prepare);
480 }
481
482 isQueryTracing() {
483 return ifUndefined(this._queryOptions.traceQuery, this._defaultQueryOptions.traceQuery);
484 }
485
486 getKeyspace() {
487 return this._keyspace;
488 }
489
490 getLoadBalancingPolicy() {
491 return this._profile.loadBalancing;
492 }
493
494 getOrGenerateTimestamp() {
495 let result = this.getTimestamp();
496
497 if (result === undefined) {
498 const generator = this._client.options.policies.timestampGeneration;
499
500 if ( types.protocolVersion.supportsTimestamp(this._client.controlConnection.protocolVersion) && generator) {
501 result = generator.next(this._client);
502 } else {
503 result = null;
504 }
505 }
506
507 return typeof result === 'number' ? types.Long.fromNumber(result) : result;
508 }
509
510 getPageState() {
511 return this._pageState;
512 }
513
514 /**
515 * Gets the profile defined by the user or the default profile
516 * @internal
517 * @ignore
518 */
519 getProfile() {
520 return this._profile;
521 }
522
523 getRawQueryOptions() {
524 return this._queryOptions;
525 }
526
527 getReadTimeout() {
528 return ifUndefined3(this._queryOptions.readTimeout, this._profile.readTimeout,
529 this._client.options.socketOptions.readTimeout);
530 }
531
532 getRetryPolicy() {
533 return ifUndefined3(this._queryOptions.retry, this._profile.retry, this._client.options.policies.retry);
534 }
535
536 getRoutingIndexes() {
537 return this._routingIndexes;
538 }
539
540 getRoutingKey() {
541 return this._routingKey;
542 }
543
544 getRoutingNames() {
545 return this._queryOptions.routingNames;
546 }
547
548 /**
549 * Internal method to obtain the row callback, for "by row" results.
550 * @ignore
551 */
552 getRowCallback() {
553 return this._rowCallback;
554 }
555
556 getSerialConsistency() {
557 return ifUndefined3(
558 this._queryOptions.serialConsistency, this._profile.serialConsistency, this._defaultQueryOptions.serialConsistency);
559 }
560
561 getTimestamp() {
562 return this._queryOptions.timestamp;
563 }
564
565 /**
566 * Internal property to set the custom payload.
567 * @ignore
568 * @internal
569 * @param {Object} payload
570 */
571 setCustomPayload(payload) {
572 this._customPayload = payload;
573 }
574
575 /**
576 * @param {Array} hints
577 */
578 setHints(hints) {
579 this._hints = hints;
580 }
581
582 /**
583 * @param {String} keyspace
584 */
585 setKeyspace(keyspace) {
586 this._keyspace = keyspace;
587 }
588
589 /**
590 * @param {Buffer} pageState
591 */
592 setPageState(pageState) {
593 this._pageState = pageState;
594 }
595
596 /**
597 * @param {Array} routingIndexes
598 */
599 setRoutingIndexes(routingIndexes) {
600 this._routingIndexes = routingIndexes;
601 }
602
603 setRoutingKey(value) {
604 this._routingKey = value;
605 }
606}
607
608function ifUndefined(v1, v2) {
609 return v1 !== undefined ? v1 : v2;
610}
611
612function ifUndefined3(v1, v2, v3) {
613 if (v1 !== undefined) {
614 return v1;
615 }
616 return v2 !== undefined ? v2 : v3;
617}
618
619module.exports = { ExecutionOptions, DefaultExecutionOptions, proxyExecuteKey };
\No newline at end of file