@deephaven-enterprise/query-utils 1.20240723.62-alpha-fix-dependencies.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +136 -0
- package/dist/DraftQuery.d.ts +137 -0
- package/dist/DraftQuery.js +208 -0
- package/dist/QueryColumns.d.ts +324 -0
- package/dist/QueryColumns.js +320 -0
- package/dist/QueryScheduler.d.ts +348 -0
- package/dist/QueryScheduler.js +914 -0
- package/dist/QuerySchedulerValidation.d.ts +76 -0
- package/dist/QuerySchedulerValidation.js +306 -0
- package/dist/QueryType.d.ts +12 -0
- package/dist/QueryType.js +13 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/package.json +32 -0
|
@@ -0,0 +1,914 @@
|
|
|
1
|
+
import Log from '@deephaven/log';
|
|
2
|
+
import { TimeUtils } from '@deephaven/utils';
|
|
3
|
+
import { parseDateTime, toCalendarDate, toTime, } from '@internationalized/date';
|
|
4
|
+
const log = Log.module('QueryScheduler');
|
|
5
|
+
const DEFAULT_CALENDAR = 'USNYSE';
|
|
6
|
+
const DEFAULT_EXPIRATION_TIME_MILLIS = 24 * 60 * 60 * 1000;
|
|
7
|
+
const DEFAULT_TIME_ZONE = 'America/New_York';
|
|
8
|
+
/**
|
|
9
|
+
* QueryScheduler is the client side equivalent of the server side class IrisScheduler.
|
|
10
|
+
*
|
|
11
|
+
* The server stores scheduling data as an array of Strings. This class converts that array
|
|
12
|
+
* into an object that can be manipulated by the UI. It then converts back to an array for
|
|
13
|
+
* storage on the server.
|
|
14
|
+
*/
|
|
15
|
+
export class QueryScheduler {
|
|
16
|
+
static makeDefaultScheduling(restartQueryWhenRunningDefault, timeZone) {
|
|
17
|
+
return [
|
|
18
|
+
QueryScheduler.TOKENS.RESTART_WHEN_RUNNING +
|
|
19
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
20
|
+
restartQueryWhenRunningDefault,
|
|
21
|
+
QueryScheduler.FIELDS.TIME_ZONE +
|
|
22
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
23
|
+
timeZone,
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
static setDefaultCalendar(name) {
|
|
27
|
+
log.info('before', QueryScheduler.defaultCalendar, name);
|
|
28
|
+
QueryScheduler.defaultCalendar = name;
|
|
29
|
+
log.info('after', QueryScheduler.defaultCalendar, name);
|
|
30
|
+
}
|
|
31
|
+
static validateSplitLength(s, splitString, length) {
|
|
32
|
+
if (splitString.length !== length) {
|
|
33
|
+
throw new Error(`Unexpected error parsing scheduler string array: ${s}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creats a new QueryScheduler object.
|
|
38
|
+
*
|
|
39
|
+
* @param stringArray an array of strings representing a scheduler
|
|
40
|
+
*/
|
|
41
|
+
constructor(stringArray) {
|
|
42
|
+
// must define fields explicitly in constructor to ensure fields are properly
|
|
43
|
+
// initialized even in derived classes
|
|
44
|
+
this.type = QueryScheduler.TYPES.DAILY;
|
|
45
|
+
// Base Fields
|
|
46
|
+
this.startTimeInternal = QueryScheduler.parseLocalTime('07:55:00');
|
|
47
|
+
this.stopTimeInternal = QueryScheduler.parseLocalTime('23:55:00');
|
|
48
|
+
this.timeZone = DEFAULT_TIME_ZONE;
|
|
49
|
+
this.schedulingDisabled = false;
|
|
50
|
+
this.overnightInternal = false;
|
|
51
|
+
this.repeatEnabled = false;
|
|
52
|
+
this.stopTimeDisabledInternal = false;
|
|
53
|
+
this.repeatInterval = 0;
|
|
54
|
+
this.skipIfUnsuccessful = false;
|
|
55
|
+
this.restartErrorCount = 0;
|
|
56
|
+
this.restartDelayMinutes = 0;
|
|
57
|
+
// TODO: use queryScheduler.restartWhenRunningDefault as the default, DH-11582
|
|
58
|
+
this.restartWhenRunning = QueryScheduler.RESTART_WHEN_RUNNING_OPTION.NO;
|
|
59
|
+
// Daily Fields
|
|
60
|
+
this.businessDays = false;
|
|
61
|
+
this.dailyBusinessCalendar = DEFAULT_CALENDAR;
|
|
62
|
+
this.dailyDays = Array(QueryScheduler.DAYS_PER_WEEK).fill(true);
|
|
63
|
+
// Monthly Fields
|
|
64
|
+
this.firstBusinessDay = false;
|
|
65
|
+
this.lastBusinessDay = false;
|
|
66
|
+
this.specificDays = true;
|
|
67
|
+
this.months = Array(QueryScheduler.MONTHS_PER_YEAR).fill(true);
|
|
68
|
+
this.monthlyDays = Array(QueryScheduler.DAYS_PER_MONTH).fill(true);
|
|
69
|
+
this.monthlyBusinessCalendar = DEFAULT_CALENDAR;
|
|
70
|
+
// Continuous Fields
|
|
71
|
+
this.dailyRestart = false;
|
|
72
|
+
// Dependent Fields
|
|
73
|
+
this.runOnFailure = false;
|
|
74
|
+
this.restartOnCondition = false;
|
|
75
|
+
this.dependentOnQuerySerials = [];
|
|
76
|
+
this.useMinStartTime = false;
|
|
77
|
+
this.runOnAny = false;
|
|
78
|
+
this.deadlineStartTime = QueryScheduler.parseLocalTime('00:00:00');
|
|
79
|
+
this.deadlineEndTime = QueryScheduler.parseLocalTime('23:59:59');
|
|
80
|
+
this.runEveryTime = false;
|
|
81
|
+
// Temporary Fields
|
|
82
|
+
this.temporaryQueueName = '';
|
|
83
|
+
this.expirationTimeMillis = DEFAULT_EXPIRATION_TIME_MILLIS;
|
|
84
|
+
this.temporaryDependentOnQuerySerials = [];
|
|
85
|
+
// Range Fields
|
|
86
|
+
// Null means not set
|
|
87
|
+
this.startDateTime = null;
|
|
88
|
+
this.stopDateTime = null;
|
|
89
|
+
if (stringArray != null) {
|
|
90
|
+
this.parseFromStringArray(stringArray);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Automatically turns the overnight flag on / off based on start and stop time.
|
|
95
|
+
*/
|
|
96
|
+
checkForOvernight() {
|
|
97
|
+
const { overnightInternal, startTimeInternal, stopTimeInternal, type } = this;
|
|
98
|
+
if (type === QueryScheduler.TYPES.RANGE || this.stopTimeDisabledInternal) {
|
|
99
|
+
this.overnightInternal = false;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!overnightInternal && stopTimeInternal <= startTimeInternal) {
|
|
103
|
+
this.overnightInternal = true;
|
|
104
|
+
}
|
|
105
|
+
else if (overnightInternal && startTimeInternal <= stopTimeInternal) {
|
|
106
|
+
this.overnightInternal = false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
get startTime() {
|
|
110
|
+
return this.startTimeInternal;
|
|
111
|
+
}
|
|
112
|
+
set startTime(value) {
|
|
113
|
+
this.startTimeInternal = value;
|
|
114
|
+
this.checkForOvernight();
|
|
115
|
+
}
|
|
116
|
+
get stopTime() {
|
|
117
|
+
return this.stopTimeInternal;
|
|
118
|
+
}
|
|
119
|
+
set stopTime(value) {
|
|
120
|
+
this.stopTimeInternal = value;
|
|
121
|
+
this.checkForOvernight();
|
|
122
|
+
}
|
|
123
|
+
get overnight() {
|
|
124
|
+
return this.overnightInternal;
|
|
125
|
+
}
|
|
126
|
+
set overnight(value) {
|
|
127
|
+
const { startTimeInternal, stopTimeInternal } = this;
|
|
128
|
+
this.overnightInternal = value;
|
|
129
|
+
if ((!value && stopTimeInternal < startTimeInternal) ||
|
|
130
|
+
(value && startTimeInternal < stopTimeInternal)) {
|
|
131
|
+
this.startTimeInternal = stopTimeInternal;
|
|
132
|
+
this.stopTimeInternal = startTimeInternal;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
get stopTimeDisabled() {
|
|
136
|
+
return this.stopTimeDisabledInternal;
|
|
137
|
+
}
|
|
138
|
+
set stopTimeDisabled(value) {
|
|
139
|
+
const { overnightInternal } = this;
|
|
140
|
+
this.stopTimeDisabledInternal = value;
|
|
141
|
+
if (value && overnightInternal) {
|
|
142
|
+
this.overnight = false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Creates a deep copy of this scheduler.
|
|
147
|
+
*
|
|
148
|
+
* @returns a copy of this scheduler
|
|
149
|
+
*/
|
|
150
|
+
deepCopy() {
|
|
151
|
+
const copy = Object.assign(new QueryScheduler(), this);
|
|
152
|
+
copy.dailyDays = this.dailyDays.slice();
|
|
153
|
+
copy.months = this.months.slice();
|
|
154
|
+
copy.monthlyDays = this.monthlyDays.slice();
|
|
155
|
+
copy.dependentOnQuerySerials = this.dependentOnQuerySerials.slice();
|
|
156
|
+
copy.temporaryDependentOnQuerySerials =
|
|
157
|
+
this.temporaryDependentOnQuerySerials.slice();
|
|
158
|
+
copy.startDateTime =
|
|
159
|
+
this.startDateTime == null ? null : this.startDateTime.copy();
|
|
160
|
+
copy.stopDateTime =
|
|
161
|
+
this.stopDateTime == null ? null : this.stopDateTime.copy();
|
|
162
|
+
return copy;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Ensures that the scheduler has meaningful defaults for all fields. This allows
|
|
166
|
+
* the UI to quickly switch between scheduler types. Note that these defaults do
|
|
167
|
+
* not create valid schedulers for all types.
|
|
168
|
+
*/
|
|
169
|
+
initDefaults() {
|
|
170
|
+
this.type = QueryScheduler.TYPES.DAILY;
|
|
171
|
+
// Base Fields
|
|
172
|
+
this.startTimeInternal = QueryScheduler.parseLocalTime('07:55:00');
|
|
173
|
+
this.stopTimeInternal = QueryScheduler.parseLocalTime('23:55:00');
|
|
174
|
+
this.timeZone = DEFAULT_TIME_ZONE;
|
|
175
|
+
this.schedulingDisabled = false;
|
|
176
|
+
this.overnightInternal = false;
|
|
177
|
+
this.repeatEnabled = false;
|
|
178
|
+
this.stopTimeDisabledInternal = false;
|
|
179
|
+
this.repeatInterval = 0;
|
|
180
|
+
this.skipIfUnsuccessful = false;
|
|
181
|
+
this.restartErrorCount = 0;
|
|
182
|
+
this.restartDelayMinutes = 0;
|
|
183
|
+
// TODO: use queryScheduler.restartWhenRunningDefault as the default, DH-11582
|
|
184
|
+
this.restartWhenRunning = QueryScheduler.RESTART_WHEN_RUNNING_OPTION.NO;
|
|
185
|
+
// Daily Fields
|
|
186
|
+
this.businessDays = false;
|
|
187
|
+
this.dailyBusinessCalendar = DEFAULT_CALENDAR;
|
|
188
|
+
this.dailyDays = Array(QueryScheduler.DAYS_PER_WEEK).fill(true);
|
|
189
|
+
// Monthly Fields
|
|
190
|
+
this.firstBusinessDay = false;
|
|
191
|
+
this.lastBusinessDay = false;
|
|
192
|
+
this.specificDays = true;
|
|
193
|
+
this.months = Array(QueryScheduler.MONTHS_PER_YEAR).fill(true);
|
|
194
|
+
this.monthlyDays = Array(QueryScheduler.DAYS_PER_MONTH).fill(true);
|
|
195
|
+
this.monthlyBusinessCalendar = DEFAULT_CALENDAR;
|
|
196
|
+
// Continuous Fields
|
|
197
|
+
this.dailyRestart = false;
|
|
198
|
+
// Dependent Fields
|
|
199
|
+
this.runOnFailure = false;
|
|
200
|
+
this.restartOnCondition = false;
|
|
201
|
+
this.dependentOnQuerySerials = [];
|
|
202
|
+
this.useMinStartTime = false;
|
|
203
|
+
this.runOnAny = false;
|
|
204
|
+
this.deadlineStartTime = QueryScheduler.parseLocalTime('00:00:00');
|
|
205
|
+
this.deadlineEndTime = QueryScheduler.parseLocalTime('23:59:59');
|
|
206
|
+
this.runEveryTime = false;
|
|
207
|
+
// Temporary Fields
|
|
208
|
+
this.temporaryQueueName = '';
|
|
209
|
+
this.expirationTimeMillis = DEFAULT_EXPIRATION_TIME_MILLIS;
|
|
210
|
+
this.temporaryDependentOnQuerySerials = [];
|
|
211
|
+
// Range Fields
|
|
212
|
+
// Null means not set
|
|
213
|
+
this.startDateTime = null;
|
|
214
|
+
this.stopDateTime = null;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Parses an array of strings into a QueryScheduler object.
|
|
218
|
+
*
|
|
219
|
+
* @param stringArray an array of strings representing a scheduler
|
|
220
|
+
*/
|
|
221
|
+
parseFromStringArray(stringArray) {
|
|
222
|
+
const typeSpecificStrings = this.parseBaseScheduler(stringArray);
|
|
223
|
+
switch (this.type) {
|
|
224
|
+
case QueryScheduler.TYPES.DAILY:
|
|
225
|
+
this.parseDailyScheduler(typeSpecificStrings);
|
|
226
|
+
break;
|
|
227
|
+
case QueryScheduler.TYPES.MONTHLY:
|
|
228
|
+
this.parseMonthlyScheduler(typeSpecificStrings);
|
|
229
|
+
break;
|
|
230
|
+
case QueryScheduler.TYPES.CONTINUOUS:
|
|
231
|
+
this.parseContinuousScheduler(typeSpecificStrings);
|
|
232
|
+
break;
|
|
233
|
+
case QueryScheduler.TYPES.DEPENDENT:
|
|
234
|
+
this.parseDependentScheduler(typeSpecificStrings);
|
|
235
|
+
break;
|
|
236
|
+
case QueryScheduler.TYPES.TEMPORARY:
|
|
237
|
+
this.parseTemporaryScheduler(typeSpecificStrings);
|
|
238
|
+
break;
|
|
239
|
+
case QueryScheduler.TYPES.RANGE:
|
|
240
|
+
this.parseRangeScheduler(typeSpecificStrings);
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
throw new Error(`Unknown scheduler type: ${this.type}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Does the base parsing that is common to all scheduler types.
|
|
248
|
+
*
|
|
249
|
+
* @param stringArray an array of strings representing a scheduler
|
|
250
|
+
* @returns an array of strings fo type specific parsers
|
|
251
|
+
*/
|
|
252
|
+
parseBaseScheduler(stringArray) {
|
|
253
|
+
const typeSpecificStrings = [];
|
|
254
|
+
stringArray.forEach(s => {
|
|
255
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
256
|
+
switch (splitString[0]) {
|
|
257
|
+
case QueryScheduler.TOKENS.SCHEDULER_TYPE:
|
|
258
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
259
|
+
// eslint-disable-next-line prefer-destructuring
|
|
260
|
+
this.type = splitString[1];
|
|
261
|
+
break;
|
|
262
|
+
case QueryScheduler.TOKENS.START_TIME:
|
|
263
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
264
|
+
this.startTimeInternal = QueryScheduler.parseLocalTime(splitString[1]);
|
|
265
|
+
break;
|
|
266
|
+
case QueryScheduler.TOKENS.STOP_TIME:
|
|
267
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
268
|
+
this.stopTimeInternal = QueryScheduler.parseLocalTime(splitString[1]);
|
|
269
|
+
break;
|
|
270
|
+
case QueryScheduler.TOKENS.TIME_ZONE:
|
|
271
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
272
|
+
// eslint-disable-next-line prefer-destructuring
|
|
273
|
+
this.timeZone = splitString[1];
|
|
274
|
+
break;
|
|
275
|
+
case QueryScheduler.TOKENS.DISABLED:
|
|
276
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
277
|
+
this.schedulingDisabled = splitString[1] === 'true';
|
|
278
|
+
break;
|
|
279
|
+
case QueryScheduler.TOKENS.OVERNIGHT:
|
|
280
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
281
|
+
this.overnightInternal = splitString[1] === 'true';
|
|
282
|
+
break;
|
|
283
|
+
case QueryScheduler.TOKENS.REPEAT_ENABLED:
|
|
284
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
285
|
+
this.repeatEnabled = splitString[1] === 'true';
|
|
286
|
+
break;
|
|
287
|
+
case QueryScheduler.TOKENS.REPEAT_INTERVAL:
|
|
288
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
289
|
+
this.repeatInterval = Number(splitString[1]);
|
|
290
|
+
break;
|
|
291
|
+
case QueryScheduler.TOKENS.SKIP_IF_UNSUCCESSFUL:
|
|
292
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
293
|
+
this.skipIfUnsuccessful = splitString[1] === 'true';
|
|
294
|
+
break;
|
|
295
|
+
case QueryScheduler.TOKENS.STOP_TIME_DISABLED:
|
|
296
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
297
|
+
this.stopTimeDisabledInternal = splitString[1] === 'true';
|
|
298
|
+
break;
|
|
299
|
+
case QueryScheduler.TOKENS.RESTART_ERROR_COUNT:
|
|
300
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
301
|
+
this.restartErrorCount = Number(splitString[1]);
|
|
302
|
+
break;
|
|
303
|
+
case QueryScheduler.TOKENS.RESTART_ERROR_DELAY:
|
|
304
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
305
|
+
this.restartDelayMinutes = Number(splitString[1]);
|
|
306
|
+
break;
|
|
307
|
+
case QueryScheduler.TOKENS.RESTART_WHEN_RUNNING:
|
|
308
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
309
|
+
// eslint-disable-next-line prefer-destructuring
|
|
310
|
+
this.restartWhenRunning = splitString[1];
|
|
311
|
+
break;
|
|
312
|
+
default:
|
|
313
|
+
// Save this string for a type specific parser
|
|
314
|
+
typeSpecificStrings.push(s);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
// In legacy queries, stopTime can be null, as some queries may not have a stop time and it was not previously saved.
|
|
318
|
+
// In that case stopTimeDisabled won't have been saved or set.
|
|
319
|
+
if (this.stopTime == null) {
|
|
320
|
+
this.stopTimeDisabledInternal = true;
|
|
321
|
+
}
|
|
322
|
+
return typeSpecificStrings;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Parses the Daily scheduler type.
|
|
326
|
+
*
|
|
327
|
+
* @param stringArray an array of strings representing a scheduler
|
|
328
|
+
*/
|
|
329
|
+
parseDailyScheduler(stringArray) {
|
|
330
|
+
stringArray.forEach(s => {
|
|
331
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
332
|
+
switch (splitString[0]) {
|
|
333
|
+
case QueryScheduler.TOKENS.BUSINESS_DAYS:
|
|
334
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
335
|
+
this.businessDays = splitString[1] === 'true';
|
|
336
|
+
break;
|
|
337
|
+
case QueryScheduler.TOKENS.CALENDAR:
|
|
338
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
339
|
+
// eslint-disable-next-line prefer-destructuring
|
|
340
|
+
this.dailyBusinessCalendar = splitString[1];
|
|
341
|
+
break;
|
|
342
|
+
case QueryScheduler.TOKENS.DAYS:
|
|
343
|
+
// Should split into the token plus seven days
|
|
344
|
+
QueryScheduler.validateSplitLength(s, splitString, QueryScheduler.DAYS_PER_WEEK + 1);
|
|
345
|
+
// Remove the token from the array and convert the strings to booleans
|
|
346
|
+
this.dailyDays = splitString
|
|
347
|
+
.filter(v => v !== QueryScheduler.TOKENS.DAYS)
|
|
348
|
+
.map(b => b === 'true');
|
|
349
|
+
break;
|
|
350
|
+
default:
|
|
351
|
+
log.warn('Found unexpected token while parsing daily schedule', s);
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Parses the Monthly scheduler type.
|
|
358
|
+
*
|
|
359
|
+
* @param stringArray an array of strings representing a scheduler
|
|
360
|
+
*/
|
|
361
|
+
parseMonthlyScheduler(stringArray) {
|
|
362
|
+
stringArray.forEach(s => {
|
|
363
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
364
|
+
switch (splitString[0]) {
|
|
365
|
+
case QueryScheduler.TOKENS.FIRST_BUSINESS_DAY:
|
|
366
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
367
|
+
this.firstBusinessDay = splitString[1] === 'true';
|
|
368
|
+
break;
|
|
369
|
+
case QueryScheduler.TOKENS.LAST_BUSINESS_DAY:
|
|
370
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
371
|
+
this.lastBusinessDay = splitString[1] === 'true';
|
|
372
|
+
break;
|
|
373
|
+
case QueryScheduler.TOKENS.CALENDAR:
|
|
374
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
375
|
+
// eslint-disable-next-line prefer-destructuring
|
|
376
|
+
this.monthlyBusinessCalendar = splitString[1];
|
|
377
|
+
break;
|
|
378
|
+
case QueryScheduler.TOKENS.MONTHS:
|
|
379
|
+
// Should split into the token plus 12 months
|
|
380
|
+
QueryScheduler.validateSplitLength(s, splitString, QueryScheduler.MONTHS_PER_YEAR + 1);
|
|
381
|
+
// Remove the token from the array and convert the strings to booleans
|
|
382
|
+
this.months = splitString
|
|
383
|
+
.filter(v => v !== QueryScheduler.TOKENS.MONTHS)
|
|
384
|
+
.map(b => b === 'true');
|
|
385
|
+
break;
|
|
386
|
+
case QueryScheduler.TOKENS.SPECIFIC_DAYS:
|
|
387
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
388
|
+
this.specificDays = splitString[1] === 'true';
|
|
389
|
+
break;
|
|
390
|
+
case QueryScheduler.TOKENS.DAYS:
|
|
391
|
+
// Should split into the token plus 31 days
|
|
392
|
+
QueryScheduler.validateSplitLength(s, splitString, QueryScheduler.DAYS_PER_MONTH + 1);
|
|
393
|
+
// Remove the token from the array and convert the strings to booleans
|
|
394
|
+
this.monthlyDays = splitString
|
|
395
|
+
.filter(v => v !== QueryScheduler.TOKENS.DAYS)
|
|
396
|
+
.map(b => b === 'true');
|
|
397
|
+
break;
|
|
398
|
+
default:
|
|
399
|
+
log.warn('Found unexpected token while parsing monthly schedule', s);
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Parses the Continuous scheduler type.
|
|
406
|
+
*
|
|
407
|
+
* @param stringArray an array of strings representing a scheduler
|
|
408
|
+
*/
|
|
409
|
+
parseContinuousScheduler(stringArray) {
|
|
410
|
+
stringArray.forEach(s => {
|
|
411
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
412
|
+
switch (splitString[0]) {
|
|
413
|
+
case QueryScheduler.TOKENS.DAILY_RESTART:
|
|
414
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
415
|
+
this.dailyRestart = splitString[1] === 'true';
|
|
416
|
+
break;
|
|
417
|
+
default:
|
|
418
|
+
log.warn('Found unexpected token while parsing continuous schedule', s);
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Parses the Dependent scheduler type.
|
|
425
|
+
*
|
|
426
|
+
* @param stringArray an array of strings representing a scheduler
|
|
427
|
+
*/
|
|
428
|
+
parseDependentScheduler(stringArray) {
|
|
429
|
+
stringArray.forEach(s => {
|
|
430
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
431
|
+
switch (splitString[0]) {
|
|
432
|
+
case QueryScheduler.TOKENS.RUN_ON_FAILURE:
|
|
433
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
434
|
+
this.runOnFailure = splitString[1] === 'true';
|
|
435
|
+
break;
|
|
436
|
+
case QueryScheduler.TOKENS.RESTART_ON_CONDITION:
|
|
437
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
438
|
+
this.restartOnCondition = splitString[1] === 'true';
|
|
439
|
+
break;
|
|
440
|
+
case QueryScheduler.TOKENS.DEPENDENT_QUERY_SERIAL:
|
|
441
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
442
|
+
this.dependentOnQuerySerials = splitString[1].split(QueryScheduler.TOKENS.SERIAL_DELIMITER);
|
|
443
|
+
break;
|
|
444
|
+
case QueryScheduler.TOKENS.USE_MIN_START_TIME:
|
|
445
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
446
|
+
this.useMinStartTime = splitString[1] === 'true';
|
|
447
|
+
break;
|
|
448
|
+
case QueryScheduler.TOKENS.RUN_ON_ANY:
|
|
449
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
450
|
+
this.runOnAny = splitString[1] === 'true';
|
|
451
|
+
break;
|
|
452
|
+
case QueryScheduler.TOKENS.DEADLINE_START:
|
|
453
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
454
|
+
this.deadlineStartTime = QueryScheduler.parseLocalTime(splitString[1]);
|
|
455
|
+
break;
|
|
456
|
+
case QueryScheduler.TOKENS.DEADLINE_END:
|
|
457
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
458
|
+
this.deadlineEndTime = QueryScheduler.parseLocalTime(splitString[1]);
|
|
459
|
+
break;
|
|
460
|
+
case QueryScheduler.TOKENS.RUN_EACH_TIME:
|
|
461
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
462
|
+
this.runEveryTime = splitString[1] === 'true';
|
|
463
|
+
break;
|
|
464
|
+
default:
|
|
465
|
+
log.warn('Found unexpected token while parsing dependent schedule', s);
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Parses the Temporary scheduler type.
|
|
472
|
+
*
|
|
473
|
+
* @param stringArray an array of strings representing a scheduler
|
|
474
|
+
*/
|
|
475
|
+
parseTemporaryScheduler(stringArray) {
|
|
476
|
+
stringArray.forEach(s => {
|
|
477
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
478
|
+
switch (splitString[0]) {
|
|
479
|
+
case QueryScheduler.TOKENS.TEMPORARY_QUEUE_NAME:
|
|
480
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
481
|
+
// eslint-disable-next-line prefer-destructuring
|
|
482
|
+
this.temporaryQueueName = splitString[1];
|
|
483
|
+
break;
|
|
484
|
+
case QueryScheduler.TOKENS.TEMPORARY_EXPIRATION_TIME_MILLIS:
|
|
485
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
486
|
+
// eslint-disable-next-line prefer-destructuring
|
|
487
|
+
this.expirationTimeMillis = Number(splitString[1]);
|
|
488
|
+
break;
|
|
489
|
+
case QueryScheduler.TOKENS.TEMPORARY_DEPENDENT_QUERY_SERIAL:
|
|
490
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
491
|
+
this.temporaryDependentOnQuerySerials = splitString[1].split(QueryScheduler.TOKENS.SERIAL_DELIMITER);
|
|
492
|
+
break;
|
|
493
|
+
default:
|
|
494
|
+
log.warn('Found unexpected token while parsing tempory schedule', s);
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Parses the Range scheduler type.
|
|
501
|
+
*
|
|
502
|
+
* @param stringArray an array of strings representing a scheduler
|
|
503
|
+
*/
|
|
504
|
+
parseRangeScheduler(stringArray) {
|
|
505
|
+
// The schedule includes boolean flags for whether to use the start and stop date times.
|
|
506
|
+
// But the Web UI does not use them. Instead it sets dateTimes to null if they are not used.
|
|
507
|
+
let useStartDateTime = false;
|
|
508
|
+
let useStopDateTime = false;
|
|
509
|
+
stringArray.forEach(s => {
|
|
510
|
+
const splitString = s.split(QueryScheduler.TOKENS.DELIMITER);
|
|
511
|
+
switch (splitString[0]) {
|
|
512
|
+
case QueryScheduler.TOKENS.USE_START_DATE_TIME:
|
|
513
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
514
|
+
useStartDateTime = splitString[1] === 'true';
|
|
515
|
+
break;
|
|
516
|
+
case QueryScheduler.TOKENS.USE_STOP_DATE_TIME:
|
|
517
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
518
|
+
useStopDateTime = splitString[1] === 'true';
|
|
519
|
+
break;
|
|
520
|
+
case QueryScheduler.TOKENS.START_DATE:
|
|
521
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
522
|
+
// Combine the start date and start time
|
|
523
|
+
// Format is 'yyyy-MM-ddTHH:mm:ss'
|
|
524
|
+
// startTime will be set in base parser or this will use the default
|
|
525
|
+
this.startDateTime = parseDateTime(`${splitString[1]}T${QueryScheduler.localTimeToString(this.startTime)}`);
|
|
526
|
+
break;
|
|
527
|
+
case QueryScheduler.TOKENS.STOP_DATE:
|
|
528
|
+
QueryScheduler.validateSplitLength(s, splitString, 2);
|
|
529
|
+
// Combine the stop date and stop time
|
|
530
|
+
// Format is 'yyyy-MM-ddTHH:mm:ss'
|
|
531
|
+
// stopTime will be set in base parser or this will use the default
|
|
532
|
+
this.stopDateTime = parseDateTime(`${splitString[1]}T${QueryScheduler.localTimeToString(this.stopTime)}`);
|
|
533
|
+
break;
|
|
534
|
+
default:
|
|
535
|
+
log.warn('Found unexpected token while parsing tempory schedule', s);
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
if (!useStartDateTime) {
|
|
540
|
+
this.startDateTime = null;
|
|
541
|
+
}
|
|
542
|
+
if (!useStopDateTime) {
|
|
543
|
+
this.stopDateTime = null;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Generates an array of strings that describes the scheduler.
|
|
548
|
+
*
|
|
549
|
+
* @returns an array of strings describing the scheduler
|
|
550
|
+
*/
|
|
551
|
+
toStringArray() {
|
|
552
|
+
const arrayEntries = [];
|
|
553
|
+
switch (this.type) {
|
|
554
|
+
case QueryScheduler.TYPES.DAILY:
|
|
555
|
+
this.toStringArrayDaily(arrayEntries);
|
|
556
|
+
break;
|
|
557
|
+
case QueryScheduler.TYPES.MONTHLY:
|
|
558
|
+
this.toStringArrayMonthly(arrayEntries);
|
|
559
|
+
break;
|
|
560
|
+
case QueryScheduler.TYPES.CONTINUOUS:
|
|
561
|
+
this.toStringArrayContinuous(arrayEntries);
|
|
562
|
+
break;
|
|
563
|
+
case QueryScheduler.TYPES.DEPENDENT:
|
|
564
|
+
this.toStringArrayDependent(arrayEntries);
|
|
565
|
+
break;
|
|
566
|
+
case QueryScheduler.TYPES.TEMPORARY:
|
|
567
|
+
this.toStringArrayTemporary(arrayEntries);
|
|
568
|
+
break;
|
|
569
|
+
case QueryScheduler.TYPES.RANGE:
|
|
570
|
+
this.toStringArrayRange(arrayEntries);
|
|
571
|
+
break;
|
|
572
|
+
default:
|
|
573
|
+
throw new Error(`Unknown scheduler type: ${this.type}`);
|
|
574
|
+
}
|
|
575
|
+
this.toStringArrayBase(arrayEntries);
|
|
576
|
+
return arrayEntries;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Generates an array of strings for the Base scheduler.
|
|
580
|
+
*/
|
|
581
|
+
toStringArrayBase(arrayEntries) {
|
|
582
|
+
arrayEntries.push(QueryScheduler.TOKENS.START_TIME +
|
|
583
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
584
|
+
QueryScheduler.localTimeToString(this.startTime));
|
|
585
|
+
if (this.stopTime != null) {
|
|
586
|
+
arrayEntries.push(QueryScheduler.TOKENS.STOP_TIME +
|
|
587
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
588
|
+
QueryScheduler.localTimeToString(this.stopTime));
|
|
589
|
+
}
|
|
590
|
+
arrayEntries.push(QueryScheduler.TOKENS.TIME_ZONE +
|
|
591
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
592
|
+
this.timeZone);
|
|
593
|
+
arrayEntries.push(QueryScheduler.TOKENS.DISABLED +
|
|
594
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
595
|
+
this.schedulingDisabled);
|
|
596
|
+
arrayEntries.push(QueryScheduler.TOKENS.OVERNIGHT +
|
|
597
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
598
|
+
this.overnight);
|
|
599
|
+
arrayEntries.push(QueryScheduler.TOKENS.REPEAT_ENABLED +
|
|
600
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
601
|
+
this.repeatEnabled);
|
|
602
|
+
arrayEntries.push(QueryScheduler.TOKENS.SKIP_IF_UNSUCCESSFUL +
|
|
603
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
604
|
+
this.skipIfUnsuccessful);
|
|
605
|
+
arrayEntries.push(QueryScheduler.TOKENS.STOP_TIME_DISABLED +
|
|
606
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
607
|
+
this.stopTimeDisabled);
|
|
608
|
+
arrayEntries.push(QueryScheduler.TOKENS.RESTART_ERROR_COUNT +
|
|
609
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
610
|
+
this.restartErrorCount);
|
|
611
|
+
arrayEntries.push(QueryScheduler.TOKENS.RESTART_ERROR_DELAY +
|
|
612
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
613
|
+
this.restartDelayMinutes);
|
|
614
|
+
arrayEntries.push(QueryScheduler.TOKENS.RESTART_WHEN_RUNNING +
|
|
615
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
616
|
+
this.restartWhenRunning);
|
|
617
|
+
if (this.repeatInterval > 0) {
|
|
618
|
+
arrayEntries.push(QueryScheduler.TOKENS.REPEAT_INTERVAL +
|
|
619
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
620
|
+
this.repeatInterval);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Generates an array of strings for a Daily scheduler.
|
|
625
|
+
*/
|
|
626
|
+
toStringArrayDaily(arrayEntries) {
|
|
627
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
628
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
629
|
+
QueryScheduler.TYPES.DAILY);
|
|
630
|
+
arrayEntries.push(QueryScheduler.TOKENS.CALENDAR +
|
|
631
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
632
|
+
this.dailyBusinessCalendar);
|
|
633
|
+
arrayEntries.push(QueryScheduler.TOKENS.BUSINESS_DAYS +
|
|
634
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
635
|
+
this.businessDays);
|
|
636
|
+
arrayEntries.push(QueryScheduler.arrayToDelimitedString(QueryScheduler.TOKENS.DAYS, this.dailyDays));
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Generates an array of strings for a Monthly scheduler.
|
|
640
|
+
*/
|
|
641
|
+
toStringArrayMonthly(arrayEntries) {
|
|
642
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
643
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
644
|
+
QueryScheduler.TYPES.MONTHLY);
|
|
645
|
+
arrayEntries.push(QueryScheduler.TOKENS.CALENDAR +
|
|
646
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
647
|
+
this.monthlyBusinessCalendar);
|
|
648
|
+
arrayEntries.push(QueryScheduler.TOKENS.FIRST_BUSINESS_DAY +
|
|
649
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
650
|
+
this.firstBusinessDay);
|
|
651
|
+
arrayEntries.push(QueryScheduler.TOKENS.LAST_BUSINESS_DAY +
|
|
652
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
653
|
+
this.lastBusinessDay);
|
|
654
|
+
arrayEntries.push(QueryScheduler.arrayToDelimitedString(QueryScheduler.TOKENS.MONTHS, this.months));
|
|
655
|
+
arrayEntries.push(QueryScheduler.TOKENS.SPECIFIC_DAYS +
|
|
656
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
657
|
+
this.specificDays);
|
|
658
|
+
arrayEntries.push(QueryScheduler.arrayToDelimitedString(QueryScheduler.TOKENS.DAYS, this.monthlyDays));
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Generates an array of strings for a Continuous scheduler.
|
|
662
|
+
*/
|
|
663
|
+
toStringArrayContinuous(arrayEntries) {
|
|
664
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
665
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
666
|
+
QueryScheduler.TYPES.CONTINUOUS);
|
|
667
|
+
arrayEntries.push(QueryScheduler.TOKENS.DAILY_RESTART +
|
|
668
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
669
|
+
this.dailyRestart);
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Generates an array of strings for a Dependent scheduler.
|
|
673
|
+
*/
|
|
674
|
+
toStringArrayDependent(arrayEntries) {
|
|
675
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
676
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
677
|
+
QueryScheduler.TYPES.DEPENDENT);
|
|
678
|
+
arrayEntries.push(QueryScheduler.TOKENS.RUN_ON_FAILURE +
|
|
679
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
680
|
+
this.runOnFailure);
|
|
681
|
+
arrayEntries.push(QueryScheduler.TOKENS.RESTART_ON_CONDITION +
|
|
682
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
683
|
+
this.restartOnCondition);
|
|
684
|
+
arrayEntries.push(QueryScheduler.TOKENS.DEPENDENT_QUERY_SERIAL +
|
|
685
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
686
|
+
this.dependentOnQuerySerials.join(QueryScheduler.TOKENS.SERIAL_DELIMITER));
|
|
687
|
+
arrayEntries.push(QueryScheduler.TOKENS.USE_MIN_START_TIME +
|
|
688
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
689
|
+
this.useMinStartTime);
|
|
690
|
+
arrayEntries.push(QueryScheduler.TOKENS.RUN_ON_ANY +
|
|
691
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
692
|
+
this.runOnAny);
|
|
693
|
+
arrayEntries.push(QueryScheduler.TOKENS.DEADLINE_START +
|
|
694
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
695
|
+
QueryScheduler.localTimeToString(this.deadlineStartTime));
|
|
696
|
+
arrayEntries.push(QueryScheduler.TOKENS.DEADLINE_END +
|
|
697
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
698
|
+
QueryScheduler.localTimeToString(this.deadlineEndTime));
|
|
699
|
+
arrayEntries.push(QueryScheduler.TOKENS.RUN_EACH_TIME +
|
|
700
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
701
|
+
this.runEveryTime);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Generates an array of strings for a Temporary scheduler.
|
|
705
|
+
*/
|
|
706
|
+
toStringArrayTemporary(arrayEntries) {
|
|
707
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
708
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
709
|
+
QueryScheduler.TYPES.TEMPORARY);
|
|
710
|
+
arrayEntries.push(QueryScheduler.TOKENS.TEMPORARY_QUEUE_NAME +
|
|
711
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
712
|
+
this.temporaryQueueName);
|
|
713
|
+
arrayEntries.push(QueryScheduler.TOKENS.TEMPORARY_EXPIRATION_TIME_MILLIS +
|
|
714
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
715
|
+
this.expirationTimeMillis);
|
|
716
|
+
const { temporaryDependentOnQuerySerials } = this;
|
|
717
|
+
if (temporaryDependentOnQuerySerials != null &&
|
|
718
|
+
temporaryDependentOnQuerySerials.length > 0) {
|
|
719
|
+
arrayEntries.push(QueryScheduler.TOKENS.TEMPORARY_DEPENDENT_QUERY_SERIAL +
|
|
720
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
721
|
+
temporaryDependentOnQuerySerials.join(QueryScheduler.TOKENS.SERIAL_DELIMITER));
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Generates an array of strings for a Range scheduler.
|
|
726
|
+
*/
|
|
727
|
+
toStringArrayRange(arrayEntries) {
|
|
728
|
+
const useStartDateTime = this.startDateTime != null;
|
|
729
|
+
const useStopDateTime = this.stopDateTime != null;
|
|
730
|
+
arrayEntries.push(QueryScheduler.TOKENS.SCHEDULER_TYPE +
|
|
731
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
732
|
+
QueryScheduler.TYPES.RANGE);
|
|
733
|
+
arrayEntries.push(QueryScheduler.TOKENS.USE_START_DATE_TIME +
|
|
734
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
735
|
+
useStartDateTime);
|
|
736
|
+
arrayEntries.push(QueryScheduler.TOKENS.USE_STOP_DATE_TIME +
|
|
737
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
738
|
+
useStopDateTime);
|
|
739
|
+
if (this.startDateTime != null) {
|
|
740
|
+
// Extract the startTime from the starDateTime
|
|
741
|
+
// This will be written later in toStringArrayBase
|
|
742
|
+
this.startTime = QueryScheduler.parseLocalTime(toTime(this.startDateTime).set({ millisecond: 0 }).toString());
|
|
743
|
+
// Extract the startDate from the startDateTime
|
|
744
|
+
const startDate = toCalendarDate(this.startDateTime).toString();
|
|
745
|
+
arrayEntries.push(QueryScheduler.TOKENS.START_DATE +
|
|
746
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
747
|
+
startDate);
|
|
748
|
+
}
|
|
749
|
+
if (this.stopDateTime != null) {
|
|
750
|
+
// Extract the stopTime from the stopDateTime
|
|
751
|
+
// This will be written later in toStringArrayBase
|
|
752
|
+
this.stopTime = QueryScheduler.parseLocalTime(toTime(this.stopDateTime).set({ millisecond: 0 }).toString());
|
|
753
|
+
// Extract the stopDate from the stopDateTime
|
|
754
|
+
const stopDate = toCalendarDate(this.stopDateTime).toString();
|
|
755
|
+
arrayEntries.push(QueryScheduler.TOKENS.STOP_DATE +
|
|
756
|
+
QueryScheduler.TOKENS.DELIMITER +
|
|
757
|
+
stopDate);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Creates a Default Scheduler.
|
|
763
|
+
*/
|
|
764
|
+
QueryScheduler.createDefault = () => new QueryScheduler();
|
|
765
|
+
QueryScheduler.parseLocalTime = (string) => TimeUtils.parseTime(string);
|
|
766
|
+
QueryScheduler.localTimeToString = (timeInSeconds) => TimeUtils.formatTime(timeInSeconds);
|
|
767
|
+
QueryScheduler.MAX_LOCAL_TIME = 86399;
|
|
768
|
+
QueryScheduler.INVALID_SERIAL = '';
|
|
769
|
+
// Helper method to turn arrays into delimted strings, e.g. 'Days=true=false=true'
|
|
770
|
+
QueryScheduler.arrayToDelimitedString = (token, array) => {
|
|
771
|
+
const stringArray = [token];
|
|
772
|
+
array.forEach(item => stringArray.push(QueryScheduler.TOKENS.DELIMITER + item));
|
|
773
|
+
return stringArray.join('');
|
|
774
|
+
};
|
|
775
|
+
// The server side classes set SchedulerType to the qualified classname
|
|
776
|
+
// if the class names or packages ever change, this will break
|
|
777
|
+
QueryScheduler.TYPES = Object.freeze({
|
|
778
|
+
DAILY: 'com.illumon.iris.controller.IrisQuerySchedulerDaily',
|
|
779
|
+
MONTHLY: 'com.illumon.iris.controller.IrisQuerySchedulerMonthly',
|
|
780
|
+
CONTINUOUS: 'com.illumon.iris.controller.IrisQuerySchedulerContinuous',
|
|
781
|
+
DEPENDENT: 'com.illumon.iris.controller.IrisQuerySchedulerDependent',
|
|
782
|
+
TEMPORARY: 'com.illumon.iris.controller.IrisQuerySchedulerTemporary',
|
|
783
|
+
RANGE: 'com.illumon.iris.controller.IrisQuerySchedulerRange',
|
|
784
|
+
});
|
|
785
|
+
// These are the tokens used to parse / create the String arrays
|
|
786
|
+
QueryScheduler.TOKENS = Object.freeze({
|
|
787
|
+
// From IrisScheduler
|
|
788
|
+
SCHEDULER_TYPE: 'SchedulerType',
|
|
789
|
+
DELIMITER: '=',
|
|
790
|
+
// From IrisQueryScheduler
|
|
791
|
+
START_TIME: 'StartTime',
|
|
792
|
+
STOP_TIME: 'StopTime',
|
|
793
|
+
OVERNIGHT: 'Overnight',
|
|
794
|
+
TIME_ZONE: 'TimeZone',
|
|
795
|
+
DISABLED: 'SchedulingDisabled',
|
|
796
|
+
REPEAT_ENABLED: 'RepeatEnabled',
|
|
797
|
+
REPEAT_INTERVAL: 'RepeatInterval',
|
|
798
|
+
SKIP_IF_UNSUCCESSFUL: 'SkipIfUnsuccessful',
|
|
799
|
+
STOP_TIME_DISABLED: 'StopTimeDisabled',
|
|
800
|
+
RESTART_ERROR_COUNT: 'RestartErrorCount',
|
|
801
|
+
RESTART_ERROR_DELAY: 'RestartErrorDelay',
|
|
802
|
+
RESTART_WHEN_RUNNING: 'RestartWhenRunning',
|
|
803
|
+
// From IrisQuerySchedulerDaily
|
|
804
|
+
BUSINESS_DAYS: 'BusinessDays',
|
|
805
|
+
CALENDAR: 'Calendar',
|
|
806
|
+
DAYS: 'Days',
|
|
807
|
+
// From IrisQuerySchedulerMonthly
|
|
808
|
+
FIRST_BUSINESS_DAY: 'FirstBusinessDay',
|
|
809
|
+
LAST_BUSINESS_DAY: 'LastBusinessDay',
|
|
810
|
+
SPECIFIC_DAYS: 'SpecificDays',
|
|
811
|
+
MONTHS: 'Months',
|
|
812
|
+
// From IrisQuerySchedulerContinuous
|
|
813
|
+
DAILY_RESTART: 'DailyRestart',
|
|
814
|
+
// From IrisQuerySchedulerDependent
|
|
815
|
+
RUN_ON_FAILURE: 'RunOnFailure',
|
|
816
|
+
RESTART_ON_CONDITION: 'RestartOnCondition',
|
|
817
|
+
DEPENDENT_QUERY_SERIAL: 'DependentQuerySerial',
|
|
818
|
+
USE_MIN_START_TIME: 'UseMinStartTime',
|
|
819
|
+
RUN_ON_ANY: 'RunOnAny',
|
|
820
|
+
DEADLINE_START: 'DeadlineStart',
|
|
821
|
+
DEADLINE_END: 'DeadlineEnd',
|
|
822
|
+
RUN_EACH_TIME: 'RunEachTime',
|
|
823
|
+
// From IrisQuerySchedulerTemporary
|
|
824
|
+
TEMPORARY_QUEUE_NAME: 'TemporaryQueueName',
|
|
825
|
+
TEMPORARY_EXPIRATION_TIME_MILLIS: 'TemporaryExpirationTimeMillis',
|
|
826
|
+
TEMPORARY_DEPENDENT_QUERY_SERIAL: 'TemporaryDependentQuerySerial',
|
|
827
|
+
// From IrisQuerySchedulerRange
|
|
828
|
+
USE_START_DATE_TIME: 'UseStartDateTime',
|
|
829
|
+
USE_STOP_DATE_TIME: 'UseStopDateTime',
|
|
830
|
+
START_DATE: 'StartDate',
|
|
831
|
+
STOP_DATE: 'StopDate',
|
|
832
|
+
// Other
|
|
833
|
+
SERIAL_DELIMITER: ';',
|
|
834
|
+
});
|
|
835
|
+
QueryScheduler.FIELDS = Object.freeze({
|
|
836
|
+
TYPE: 'type',
|
|
837
|
+
// From IrisQueryScheduler
|
|
838
|
+
START_TIME: 'startTime',
|
|
839
|
+
STOP_TIME: 'stopTime',
|
|
840
|
+
TIME_ZONE: 'timeZone',
|
|
841
|
+
SCHEDULING_DISABLED: 'schedulingDisabled',
|
|
842
|
+
OVERNIGHT: 'overnight',
|
|
843
|
+
REPEAT_ENABLED: 'repeatEnabled',
|
|
844
|
+
STOP_TIME_DISABLED: 'stopTimeDisabled',
|
|
845
|
+
REPEAT_INTERVAL: 'repeatInterval',
|
|
846
|
+
SKIP_IF_UNSUCCESSFUL: 'skipIfUnsuccessful',
|
|
847
|
+
RESTART_ERROR_COUNT: 'restartErrorCount',
|
|
848
|
+
RESTART_DELAY_MINUTES: 'restartDelayMinutes',
|
|
849
|
+
RESTART_WHEN_RUNNING: 'restartWhenRunning',
|
|
850
|
+
// From IrisQuerySchedulerDaily
|
|
851
|
+
BUSINESS_DAYS: 'businessDays',
|
|
852
|
+
DAILY_BUSINESS_CALENDAR: 'dailyBusinessCalendar',
|
|
853
|
+
DAILY_DAYS: 'dailyDays',
|
|
854
|
+
// From IrisQuerySchedulerMonthly
|
|
855
|
+
FIRST_BUSINESS_DAY: 'firstBusinessDay',
|
|
856
|
+
LAST_BUSINESS_DAY: 'lastBusinessDay',
|
|
857
|
+
SPECIFIC_DAYS: 'specificDays',
|
|
858
|
+
MONTHS: 'months',
|
|
859
|
+
MONTHLY_DAYS: 'monthlyDays',
|
|
860
|
+
MONTHLY_BUSINESS_CALENDAR: 'monthlyBusinessCalendar',
|
|
861
|
+
// From IrisQuerySchedulerContinuous
|
|
862
|
+
DAILY_RESTART: 'dailyRestart',
|
|
863
|
+
// From IrisQuerySchedulerDependent
|
|
864
|
+
RUN_ON_FAILURE: 'runOnFailure',
|
|
865
|
+
RESTART_ON_CONDITION: 'restartOnCondition',
|
|
866
|
+
DEPENDENT_ON_QUERY_SERIALS: 'dependentOnQuerySerials',
|
|
867
|
+
USE_MIN_START_TIME: 'useMinStartTime',
|
|
868
|
+
RUN_ON_ANY: 'runOnAny',
|
|
869
|
+
DEADLINE_START_TIME: 'deadlineStartTime',
|
|
870
|
+
DEADLINE_END_TIME: 'deadlineEndTime',
|
|
871
|
+
RUN_EVERY_TIME: 'runEveryTime',
|
|
872
|
+
// From IrisQuerySchedulerTemporary
|
|
873
|
+
TEMPORARY_QUEUE_NAME: 'temporaryQueueName',
|
|
874
|
+
EXPIRATION_TIME_MILLIS: 'expirationTimeMillis',
|
|
875
|
+
TEMPORARY_DEPENDENT_ON_QUERY_SERIALS: 'temporaryDependentOnQuerySerials',
|
|
876
|
+
// From IrisQuerySchedulerRange
|
|
877
|
+
START_DATE_TIME: 'startDateTime',
|
|
878
|
+
STOP_DATE_TIME: 'stopDateTime',
|
|
879
|
+
});
|
|
880
|
+
QueryScheduler.DAYS_PER_WEEK = 7;
|
|
881
|
+
QueryScheduler.DAYS_PER_MONTH = 31;
|
|
882
|
+
QueryScheduler.MONTHS_PER_YEAR = 12;
|
|
883
|
+
QueryScheduler.MAX_ERROR_RESTART_COUNT = 10;
|
|
884
|
+
QueryScheduler.UNLIMITED_ERROR_RESTART_INDEX = QueryScheduler.MAX_ERROR_RESTART_COUNT + 1;
|
|
885
|
+
// Per ISO-8601 the days array is Mon - Sun
|
|
886
|
+
// This is display order which is Sun - Sat
|
|
887
|
+
QueryScheduler.DAYS = Object.freeze({
|
|
888
|
+
SUN: { text: 'Su', value: 6 },
|
|
889
|
+
MON: { text: 'Mo', value: 0 },
|
|
890
|
+
TUE: { text: 'Tu', value: 1 },
|
|
891
|
+
WED: { text: 'We', value: 2 },
|
|
892
|
+
THU: { text: 'Th', value: 3 },
|
|
893
|
+
FRI: { text: 'Fr', value: 4 },
|
|
894
|
+
SAT: { text: 'Sa', value: 5 },
|
|
895
|
+
});
|
|
896
|
+
QueryScheduler.MONTHS = Object.freeze({
|
|
897
|
+
JAN: { text: 'Jan', value: 0 },
|
|
898
|
+
FEB: { text: 'Feb', value: 1 },
|
|
899
|
+
MAR: { text: 'Mar', value: 2 },
|
|
900
|
+
APR: { text: 'Apr', value: 3 },
|
|
901
|
+
MAY: { text: 'May', value: 4 },
|
|
902
|
+
JUN: { text: 'Jun', value: 5 },
|
|
903
|
+
JUL: { text: 'Jul', value: 6 },
|
|
904
|
+
AUG: { text: 'Aug', value: 7 },
|
|
905
|
+
SEP: { text: 'Sep', value: 8 },
|
|
906
|
+
OCT: { text: 'Oct', value: 9 },
|
|
907
|
+
NOV: { text: 'Nov', value: 10 },
|
|
908
|
+
DEC: { text: 'Dec', value: 11 },
|
|
909
|
+
});
|
|
910
|
+
QueryScheduler.RESTART_WHEN_RUNNING_OPTION = Object.freeze({
|
|
911
|
+
YES: 'Yes',
|
|
912
|
+
NO: 'No',
|
|
913
|
+
});
|
|
914
|
+
export default QueryScheduler;
|