@easyquery/enterprise 7.2.5-beta01 → 7.2.5-rc01

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.
Files changed (51) hide show
  1. package/dist/easyquery.enterprise.cjs.js +1218 -0
  2. package/dist/easyquery.enterprise.esm.js +1211 -0
  3. package/dist/types/dm/model_ex.d.ts +3 -0
  4. package/dist/types/extensions.d.ts +1 -0
  5. package/dist/{lib → types}/query/query_ex.d.ts +5 -1
  6. package/package.json +16 -36
  7. package/api-eq-enterprise.js +0 -15
  8. package/dist/browser/eq.enterprise.js +0 -37130
  9. package/dist/browser/eq.enterprise.js.map +0 -1
  10. package/dist/browser/eq.enterprise.min.js +0 -2
  11. package/dist/browser/eq.enterprise.min.js.LICENSE.txt +0 -11
  12. package/dist/browser/eq.enterprise.min.js.map +0 -1
  13. package/dist/bundles/easyquery.enterprise.js +0 -8107
  14. package/dist/bundles/easyquery.enterprise.js.map +0 -1
  15. package/dist/bundles/easyquery.enterprise.min.js +0 -3
  16. package/dist/bundles/easyquery.enterprise.min.js.LICENSE.txt +0 -1
  17. package/dist/bundles/easyquery.enterprise.min.js.map +0 -1
  18. package/dist/lib/data/data_table_aggr_calculator.js +0 -164
  19. package/dist/lib/data/data_table_aggr_calculator.js.map +0 -1
  20. package/dist/lib/data/eqs_aggr_calculator.js +0 -173
  21. package/dist/lib/data/eqs_aggr_calculator.js.map +0 -1
  22. package/dist/lib/dm/model_ex.d.ts +0 -9
  23. package/dist/lib/dm/model_ex.js +0 -152
  24. package/dist/lib/dm/model_ex.js.map +0 -1
  25. package/dist/lib/extensions.d.ts +0 -26
  26. package/dist/lib/extensions.js +0 -115
  27. package/dist/lib/extensions.js.map +0 -1
  28. package/dist/lib/license/lc-dialog.js +0 -315
  29. package/dist/lib/license/lc-dialog.js.map +0 -1
  30. package/dist/lib/main/eqs_query_storage.js +0 -106
  31. package/dist/lib/main/eqs_query_storage.js.map +0 -1
  32. package/dist/lib/public_api.js +0 -8
  33. package/dist/lib/public_api.js.map +0 -1
  34. package/dist/lib/query/condition_ex.js +0 -98
  35. package/dist/lib/query/condition_ex.js.map +0 -1
  36. package/dist/lib/query/query_column_ex.js +0 -58
  37. package/dist/lib/query/query_column_ex.js.map +0 -1
  38. package/dist/lib/query/query_ex.js +0 -78
  39. package/dist/lib/query/query_ex.js.map +0 -1
  40. package/dist/lib/utils/lcv.js +0 -103
  41. package/dist/lib/utils/lcv.js.map +0 -1
  42. package/tsconfig.json +0 -22
  43. package/webpack.config.js +0 -118
  44. /package/dist/{lib → types}/data/data_table_aggr_calculator.d.ts +0 -0
  45. /package/dist/{lib → types}/data/eqs_aggr_calculator.d.ts +0 -0
  46. /package/dist/{lib → types}/license/lc-dialog.d.ts +0 -0
  47. /package/dist/{lib → types}/main/eqs_query_storage.d.ts +0 -0
  48. /package/dist/{lib → types}/public_api.d.ts +0 -0
  49. /package/dist/{lib → types}/query/condition_ex.d.ts +0 -0
  50. /package/dist/{lib → types}/query/query_column_ex.d.ts +0 -0
  51. /package/dist/{lib → types}/utils/lcv.d.ts +0 -0
@@ -0,0 +1,1218 @@
1
+ 'use strict';
2
+
3
+ var core = require('@easyquery/core');
4
+ var core$1 = require('@easydata/core');
5
+ var ui = require('@easydata/ui');
6
+
7
+ const majVer = 7;
8
+ const minVer = 2;
9
+ const magics = [45, 128, 231];
10
+ Math.trunc = Math.trunc || function (x) {
11
+ if (isNaN(x)) {
12
+ return NaN;
13
+ }
14
+ if (x > 0) {
15
+ return Math.floor(x);
16
+ }
17
+ return Math.ceil(x);
18
+ };
19
+ const lcv = {
20
+ __kt: 0,
21
+ versionNum: '' + majVer + '.' + minVer,
22
+ ck: function (key) {
23
+ if (!key || !key.length) {
24
+ this.__kt = -3;
25
+ return;
26
+ }
27
+ try {
28
+ var part1 = key.slice(0, key.length - 12);
29
+ var infoBytes = _bs(part1);
30
+ var part2 = key.slice(key.length - 12);
31
+ let ism = false;
32
+ for (const magic of magics) {
33
+ var edc = t36(magic);
34
+ if (part2[0] === edc[0] && part2[2] === edc[1]) {
35
+ ism = true;
36
+ break;
37
+ }
38
+ }
39
+ if (!ism) {
40
+ lcv.__kt = -1;
41
+ }
42
+ var idx = minVer % 4;
43
+ var shift = majVer + minVer;
44
+ if (part2[6 + idx] != encChar(shift, 19)) {
45
+ lcv.__kt = -2;
46
+ return;
47
+ }
48
+ if (part2[1] != encChar(infoBytes[3])) {
49
+ return;
50
+ }
51
+ lcv.__kt = part2[3] != encChar(infoBytes[5]) ? 2 : 3;
52
+ if (lcv.__kt === 2) {
53
+ var eds = `${f36(part2.substring(4, 6) + part2.substring(10))}`;
54
+ var ed = new Date(2000 + Number.parseInt(eds.substring(0, 2)), Number.parseInt(eds.substring(2, 4)) - 1, Number.parseInt(eds.substring(4)), 0, 0, 0, 0);
55
+ if (Date.now() > ed.getTime()) {
56
+ lcv.__kt = 1;
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ }
62
+ }
63
+ };
64
+ function encChar(x, b = 20) {
65
+ return String.fromCharCode(65 + x % b);
66
+ }
67
+ function _bs(str) {
68
+ var binary_string = urlatob(str);
69
+ var len = binary_string.length;
70
+ var bytes = new Uint8Array(len);
71
+ for (var i = 0; i < len; i++) {
72
+ bytes[i] = binary_string.charCodeAt(i);
73
+ }
74
+ return bytes;
75
+ }
76
+ function urlatob(str) {
77
+ var s = str;
78
+ s = s.replace(/-/g, '+');
79
+ s = s.replace(/_/g, '/');
80
+ switch (s.length % 4) {
81
+ case 0:
82
+ break;
83
+ case 2:
84
+ s += "==";
85
+ break;
86
+ case 3:
87
+ s += "=";
88
+ break;
89
+ }
90
+ return window.atob(s);
91
+ }
92
+ const tokens = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
93
+ function t36(val) {
94
+ var result = "";
95
+ while (val > 0) {
96
+ result = tokens[val % tokens.length] + result;
97
+ val /= tokens.length;
98
+ }
99
+ return result;
100
+ }
101
+ function f36(val) {
102
+ var d = 0;
103
+ for (var i = 0; i < val.length; ++i)
104
+ d += tokens.indexOf(val[i]) * Math.pow(tokens.length, val.length - i - 1);
105
+ return d;
106
+ }
107
+
108
+ class ConditionEx extends core.Condition {
109
+ constructor() {
110
+ super(...arguments);
111
+ this.readOnly = false;
112
+ this.parameterized = false;
113
+ this.inJoin = false;
114
+ }
115
+ isReadOnly() {
116
+ return this.readOnly || (this.getParent() && this.getParent().isReadOnly());
117
+ }
118
+ setReadOnly(value) {
119
+ this.readOnly = value || (this.getParent() && this.getParent().isReadOnly());
120
+ this.conditions && this.conditions.forEach((cond) => {
121
+ cond.setReadOnly(value);
122
+ });
123
+ }
124
+ isParameterized() {
125
+ return this.parameterized;
126
+ }
127
+ setParameterized(value) {
128
+ this.parameterized = value;
129
+ }
130
+ isInJoin() {
131
+ return this.inJoin;
132
+ }
133
+ setInJoin(value) {
134
+ this.inJoin = value;
135
+ }
136
+ loadFromData(model, data) {
137
+ super.loadFromData(model, data);
138
+ if (lcv.__kt <= 1)
139
+ return;
140
+ if (typeof data.readOnly !== 'undefined') {
141
+ this.setReadOnly(data.readOnly);
142
+ }
143
+ if (typeof data.inJoin !== 'undefined') {
144
+ this.setInJoin(data.inJoin);
145
+ }
146
+ if (typeof data.parameterized !== 'undefined') {
147
+ this.setParameterized(data.parameterized);
148
+ }
149
+ //if condition group
150
+ //this.linkType = data.linking;
151
+ if (data.conds) {
152
+ for (let i = 0; i < data.conds.length; i++) {
153
+ let newCond = this.query.createCondition();
154
+ newCond.loadFromData(model, data.conds[i]);
155
+ this.conditions.push(newCond);
156
+ newCond.setParent(this);
157
+ }
158
+ }
159
+ }
160
+ saveToData() {
161
+ let obj = super.saveToData();
162
+ if (lcv.__kt <= 1)
163
+ return obj;
164
+ if (this.isReadOnly()) {
165
+ obj.readOnly = this.isReadOnly();
166
+ }
167
+ if (this.isParameterized()) {
168
+ obj.parameterized = this.isParameterized();
169
+ }
170
+ if (this.isInJoin()) {
171
+ obj.inJoin = this.isInJoin();
172
+ }
173
+ if (this.tag == core.CondTag.Group) {
174
+ //if condition group
175
+ //obj.linking = this.linkType;
176
+ obj.conds = [];
177
+ for (let i = 0; i < this.conditions.length; i++) {
178
+ obj.conds.push(this.conditions[i].saveToData());
179
+ }
180
+ }
181
+ return obj;
182
+ }
183
+ }
184
+
185
+ class QueryColumnEx extends core.QueryColumn {
186
+ constructor() {
187
+ super(...arguments);
188
+ this.readOnly = false;
189
+ }
190
+ isReadOnly() {
191
+ return this.readOnly;
192
+ }
193
+ setReadOnly(value) {
194
+ this.readOnly = value;
195
+ }
196
+ /**
197
+ * Loads column from its JSON representation object.
198
+ * @param model The Data Model.
199
+ * @param colData The JSON representation object.
200
+ */
201
+ loadFromData(model, colData) {
202
+ super.loadFromData(model, colData);
203
+ if (lcv.__kt <= 2)
204
+ return;
205
+ if (colData) {
206
+ if (typeof colData.readOnly != 'undefined') {
207
+ this.readOnly = colData.readOnly;
208
+ }
209
+ }
210
+ }
211
+ saveToData() {
212
+ let colData = super.saveToData();
213
+ if (lcv.__kt <= 2)
214
+ return colData;
215
+ if (this.isReadOnly()) {
216
+ colData.readOnly = this.isReadOnly();
217
+ }
218
+ return colData;
219
+ }
220
+ }
221
+
222
+ class QueryEx extends core.Query {
223
+ constructor(model, options) {
224
+ super(model, null, options);
225
+ }
226
+ isEx() {
227
+ return lcv.__kt > 1;
228
+ }
229
+ createSubQuery() {
230
+ return new QueryEx(this.model, { context: this.context });
231
+ }
232
+ createCondition(tag = core.CondTag.Simple) {
233
+ if (lcv.__kt <= 1)
234
+ return super.createCondition(tag);
235
+ return new ConditionEx(this, tag);
236
+ }
237
+ createColumn(justsorted = false) {
238
+ if (lcv.__kt <= 1)
239
+ return super.createColumn(justsorted);
240
+ return new QueryColumnEx(this, justsorted);
241
+ }
242
+ /**
243
+ * Adds a condition group - a group of simple conditions (predicates) linked by AND or OR
244
+ * @param descriptor The descriptor of the new condition group.
245
+ * @returns The new search condition.
246
+ */
247
+ addConditionGroup(descriptor, addChildCondition = true) {
248
+ if (lcv.__kt <= 1)
249
+ return super.addConditionGroup(descriptor, addChildCondition);
250
+ let parent = descriptor.parent || this.getRootCondition();
251
+ let lType = descriptor.linking || (parent.linkType === core.LinkType.All ? core.LinkType.Any : core.LinkType.All);
252
+ let group = this.createCondition(core.CondTag.Group);
253
+ group.linkType = lType;
254
+ if (addChildCondition) {
255
+ let model = this.getModel();
256
+ let attr = model.getFirstUICAttr();
257
+ if (attr) {
258
+ let op = model.getDefaultOperatorForAttr(attr);
259
+ let cond = this.createSimpleConditionObject(attr, op, "");
260
+ group.addCondition(cond);
261
+ }
262
+ }
263
+ parent.addCondition(group);
264
+ return group;
265
+ }
266
+ addExtraConditionGroup(descriptor, addChildCondition = true) {
267
+ descriptor.parent = descriptor.parent || this.extraConditions;
268
+ if (lcv.__kt <= 1)
269
+ return super.addExtraConditionGroup(descriptor, addChildCondition);
270
+ return this.addConditionGroup(descriptor);
271
+ }
272
+ buildQueryPath() {
273
+ const model = this.getModel();
274
+ if (lcv.__kt <= 1)
275
+ return this.buildQueryPath();
276
+ if (model.getMainEntity())
277
+ return this.buildQueryPath();
278
+ const entities = this.getEntitiesInQuery();
279
+ if (entities.length == 0) {
280
+ throw Error("Cannon build path. Path is empty");
281
+ }
282
+ let tree = new core.Tree(entities[0]);
283
+ for (let i = 1; i < entities.length; i++) {
284
+ const entity = entities[i];
285
+ if (tree.contains(entity)) {
286
+ continue;
287
+ }
288
+ let path = this.findPath(tree.value, entity);
289
+ if (path != null) {
290
+ //Add path to tree
291
+ tree = this.addPathToTree(tree, (path[0] === tree.value) ? path.slice(1) : path);
292
+ }
293
+ else {
294
+ throw Error("Unable to build query. Cannot build path.");
295
+ }
296
+ }
297
+ tree.setParents();
298
+ return tree;
299
+ }
300
+ addPathToTree(tree, path) {
301
+ if (path.length == 0) {
302
+ return;
303
+ }
304
+ let pathAdded = false;
305
+ for (let child of tree.childs) {
306
+ if (child.value === path[0]) {
307
+ pathAdded = true;
308
+ if (path.length > 1)
309
+ child = this.addPathToTree(child, path.slice(1));
310
+ break;
311
+ }
312
+ }
313
+ if (!pathAdded) {
314
+ let link = this.getModel().findLink(tree.value, path[0]);
315
+ if (link) {
316
+ let newNode = new core.Tree(path[0]);
317
+ tree.addChild(newNode);
318
+ if (path.length > 1)
319
+ newNode = this.addPathToTree(newNode, path.slice(1));
320
+ }
321
+ else if (!tree.parent) {
322
+ let node = new core.Tree(tree);
323
+ tree = new core.Tree(path[0]);
324
+ tree.addChild(node);
325
+ if (path.length > 1)
326
+ tree = this.addPathToTree(tree, path.slice(1));
327
+ }
328
+ else {
329
+ throw Error("Unable to build query. Cannot build path.");
330
+ }
331
+ }
332
+ return tree;
333
+ }
334
+ findPath(entityFrom, entityTo) {
335
+ let curPath = [];
336
+ let curStep = [];
337
+ let nextStep = [];
338
+ let passedEntities = [];
339
+ let pathFound = false;
340
+ curPath.push(entityFrom);
341
+ curStep.push(curPath);
342
+ passedEntities.push(entityFrom);
343
+ while (!pathFound) {
344
+ nextStep = [];
345
+ for (let path of curStep) {
346
+ pathFound = this.checkPath(path, entityTo, nextStep, passedEntities);
347
+ if (pathFound) {
348
+ path.push(entityTo);
349
+ curPath = path;
350
+ break;
351
+ }
352
+ }
353
+ curStep = [];
354
+ if (!pathFound) {
355
+ if (nextStep.length == 0)
356
+ return null;
357
+ //copy nextStep to curStep
358
+ for (let path of nextStep)
359
+ curStep.push(path);
360
+ }
361
+ }
362
+ return curPath;
363
+ }
364
+ checkPath(path, entityTo, nextStep, passedEntities) {
365
+ const endPoint = path[path.length - 1];
366
+ const entityLinks = this.getModel().getLinksByEntity(endPoint);
367
+ for (let link of entityLinks) {
368
+ let entity2 = null;
369
+ if (link.entityFrom == endPoint) {
370
+ entity2 = link.entityTo;
371
+ }
372
+ else {
373
+ entity2 = link.entityFrom;
374
+ }
375
+ if (entity2 == entityTo) { //if reach the destination
376
+ nextStep = [];
377
+ return true;
378
+ }
379
+ //if destination is not reached yet we add current node (entity2) to the path and proceed
380
+ if (path.indexOf(entity2) < 0 && passedEntities.indexOf(entity2) < 0) { //to prevent cycling
381
+ passedEntities.push(entity2);
382
+ let newPath = new Array();
383
+ newPath = newPath.concat(path);
384
+ newPath.push(entity2);
385
+ nextStep.push(newPath);
386
+ }
387
+ }
388
+ return false;
389
+ }
390
+ }
391
+
392
+ class EqServerQueryStorage {
393
+ constructor(context) {
394
+ this.context = context;
395
+ }
396
+ init() {
397
+ }
398
+ newQuery(options) {
399
+ options = options || {};
400
+ const query = options.query || this.context.getQuery();
401
+ const model = this.context.getModel();
402
+ const modelId = options.modelId || (model ? model.getId() : "");
403
+ if (options.queryId) {
404
+ query.setId(options.queryId);
405
+ }
406
+ if (options.name) {
407
+ query.setName(options.name);
408
+ }
409
+ if (options.description) {
410
+ query.setDescription(options.description);
411
+ }
412
+ let requestData = {
413
+ 'query': query.toJSONData()
414
+ };
415
+ if (options.data) {
416
+ requestData['data'] = options.data;
417
+ }
418
+ const url = this.context.resolveEndpoint('NewQuery', { modelId: modelId });
419
+ const http = this.context.getServices().getHttpClient();
420
+ return http.post(url, requestData)
421
+ .then((responseData) => {
422
+ return responseData.query;
423
+ });
424
+ }
425
+ getQueryList(options) {
426
+ options = options || {};
427
+ const modelId = options.modelId || this.context.getModel().getId();
428
+ const url = this.context.resolveEndpoint('GetQueryList', { modelId: modelId });
429
+ const http = this.context.getServices().getHttpClient();
430
+ return http.get(url)
431
+ .then((responseData) => {
432
+ if (!responseData.queries) {
433
+ return Promise.reject({
434
+ message: 'Wrong response format'
435
+ });
436
+ }
437
+ return responseData.queries;
438
+ });
439
+ }
440
+ loadQuery(options) {
441
+ options = options || {};
442
+ const model = this.context.getModel();
443
+ const query = this.context.getQuery();
444
+ const modelId = options.modelId || model.getId();
445
+ const queryId = options.queryId || query.getId();
446
+ const url = this.context.resolveEndpoint('GetQuery', { modelId: modelId, queryId: queryId });
447
+ const http = this.context.getServices().getHttpClient();
448
+ return http.get(url)
449
+ .then((responseData) => {
450
+ return responseData.query;
451
+ });
452
+ }
453
+ saveQuery(options) {
454
+ options = options || {};
455
+ const query = options.query || this.context.getQuery();
456
+ const queryId = options.queryId || query.getId();
457
+ if (options.queryId) {
458
+ query.setId(options.queryId);
459
+ }
460
+ const modelId = options.modelId || query.getModel().getId();
461
+ if (options.queryId) {
462
+ query.setId(options.queryId);
463
+ }
464
+ let requestData = {
465
+ 'query': query.toJSONData()
466
+ };
467
+ if (options.data) {
468
+ requestData['data'] = options.data;
469
+ }
470
+ const url = this.context.resolveEndpoint('SaveQuery', { modelId: modelId, queryId: queryId });
471
+ const http = this.context.getServices().getHttpClient();
472
+ return http.put(url, requestData)
473
+ .then((responseData) => {
474
+ return responseData.query;
475
+ });
476
+ }
477
+ removeQuery(options) {
478
+ options = options || {};
479
+ const context = this.context;
480
+ const query = context.getQuery();
481
+ const modelId = options.modelId || query.getModel().getId();
482
+ const queryId = options.queryId || query.getId();
483
+ let requestData = {
484
+ 'modelId': modelId,
485
+ 'queryId': queryId
486
+ };
487
+ if (options.data) {
488
+ requestData['data'] = options.data;
489
+ }
490
+ const url = this.context.resolveEndpoint('RemoveQuery', { modelId: modelId, queryId: queryId });
491
+ const http = this.context.getServices().getHttpClient();
492
+ return http.delete(url, requestData).getPromise();
493
+ }
494
+ }
495
+
496
+ class DataModelEx extends core.DataModel {
497
+ }
498
+
499
+ class DataTableAggregatesCalculator {
500
+ constructor(context) {
501
+ this.context = context;
502
+ //stores current totals by level (group) number
503
+ this.levelsTotals = [];
504
+ this.prevRow = null;
505
+ this.aggrContainer = new core.EqAggregatesContainer(context);
506
+ }
507
+ getAggrContainer() {
508
+ return this.aggrContainer;
509
+ }
510
+ initObjects() {
511
+ this.aggrSettings = this.context.getQuery().getAggregationSettings();
512
+ this.groups = this.aggrSettings.getGroups();
513
+ this.aggregates = this.aggrSettings.getAggregates();
514
+ this.aggrColIds = this.aggrSettings.getAggregates().map(a => a.colId);
515
+ this.aggrCols = this.context.resultTable.columns.getItems()
516
+ .filter(col => this.aggrColIds.indexOf(col.id) >= 0);
517
+ this.levelsTotals = [];
518
+ this.prevRow = null;
519
+ }
520
+ createColumnAggregatesObject() {
521
+ return {
522
+ sum: 0,
523
+ min: Number.MAX_VALUE,
524
+ max: Number.MIN_VALUE
525
+ };
526
+ }
527
+ calculate(options) {
528
+ this.initObjects();
529
+ this.aggrContainer.clear();
530
+ options = options || {};
531
+ options.maxLevel = options.maxLevel >= 0
532
+ ? options.maxLevel : 0;
533
+ var levelNumber = this.groups.length + 1; //number of groups plus grand totals
534
+ for (let levelIndex = 0; levelIndex < levelNumber; levelIndex++) {
535
+ let levelTotals = { count: 0, columns: {} };
536
+ this.resetLevelTotals(levelTotals);
537
+ this.levelsTotals.push(levelTotals);
538
+ }
539
+ const allRows = this.context.resultTable.getCachedRows();
540
+ if (allRows.length > 0) {
541
+ for (const row of allRows) {
542
+ this.processDataRow(row);
543
+ }
544
+ //flusing the totals for all group levels
545
+ for (let levelIndex = 1; levelIndex < levelNumber; levelIndex++) {
546
+ this.flushLevelTotals(levelIndex);
547
+ }
548
+ //flusing the grand totals (if they are turned on)
549
+ if (this.aggrSettings.hasGrandTotals()) {
550
+ this.flushLevelTotals(0);
551
+ }
552
+ }
553
+ return Promise.resolve();
554
+ }
555
+ resetLevelTotals(rowTotals) {
556
+ for (const aggrCol of this.aggrCols) {
557
+ rowTotals.columns[aggrCol.id] = this.createColumnAggregatesObject();
558
+ }
559
+ rowTotals.count = 0;
560
+ }
561
+ processDataRow(row) {
562
+ const levelIndexChanged = this.checkLevelChange(row);
563
+ if (levelIndexChanged >= 0) {
564
+ for (let levelIndex = levelIndexChanged; levelIndex < this.levelsTotals.length; levelIndex++) {
565
+ this.flushLevelTotals(levelIndex);
566
+ }
567
+ }
568
+ if (this.aggrSettings.hasGrandTotals()) {
569
+ this.updateLevelTotals(0, row);
570
+ }
571
+ let levelIndex = 1;
572
+ for (const group of this.groups) {
573
+ this.updateLevelTotals(levelIndex, row);
574
+ levelIndex++;
575
+ }
576
+ this.prevRow = row;
577
+ }
578
+ /** Checks if the values in group columns were changed
579
+ and return the level number they were */
580
+ checkLevelChange(row) {
581
+ if (this.prevRow == null)
582
+ return -1;
583
+ for (let groupIndex = 0; groupIndex < this.groups.length; groupIndex++) {
584
+ var group = this.groups[groupIndex];
585
+ for (const colId of group.columns) {
586
+ const value = row.getValue(colId);
587
+ const prevValue = this.prevRow.getValue(colId);
588
+ if (!this.aggrSettings.compareValues(prevValue, value)) {
589
+ return groupIndex + 1;
590
+ }
591
+ }
592
+ }
593
+ return -1;
594
+ }
595
+ /** Saves the current values in levelData for the specified level to AggregateContainer
596
+ and then reset the data row for that level
597
+ */
598
+ flushLevelTotals(levelIndex) {
599
+ let levelTotals = this.levelsTotals[levelIndex];
600
+ const group = levelIndex > 0 ? this.groups[levelIndex - 1] : null;
601
+ let groupKey = this.aggrSettings.buildGroupKey(group, this.prevRow);
602
+ var groupTotals = {};
603
+ for (const aggr of this.aggregates) {
604
+ const columnTotals = levelTotals.columns[aggr.colId];
605
+ groupTotals[aggr.colId] = this.applyAggrFunc(aggr.funcId, columnTotals, levelTotals);
606
+ }
607
+ if (this.aggrSettings.hasRecordCount()) {
608
+ groupTotals[this.aggrSettings.COUNT_FIELD_NAME] = levelTotals.count;
609
+ }
610
+ this.aggrContainer.updateAggregateData(levelIndex, groupKey, groupTotals);
611
+ this.resetLevelTotals(levelTotals);
612
+ }
613
+ applyAggrFunc(funcId, columnTotals, levelTotals) {
614
+ switch (funcId) {
615
+ case "SUM":
616
+ return columnTotals.sum;
617
+ case "AVG":
618
+ return columnTotals.sum / levelTotals.count;
619
+ case "COUNT":
620
+ case "CNTDST":
621
+ return levelTotals.count;
622
+ case "MIN":
623
+ return columnTotals.min;
624
+ case "MAX":
625
+ return columnTotals.max;
626
+ }
627
+ }
628
+ /** Updates the totals by values in the current DataRow
629
+ * and according to the specified aggregate
630
+ */
631
+ updateLevelTotals(levelIndex, row) {
632
+ const levelTotals = this.levelsTotals[levelIndex];
633
+ levelTotals.count += 1;
634
+ for (const aggr of this.aggregates) {
635
+ const value = row.getValue(aggr.colId);
636
+ const columnTotals = levelTotals.columns[aggr.colId];
637
+ columnTotals.sum += value;
638
+ if (value < columnTotals.min) {
639
+ columnTotals.min = value;
640
+ }
641
+ if (value > columnTotals.max) {
642
+ columnTotals.max = value;
643
+ }
644
+ }
645
+ }
646
+ needRecalculation() {
647
+ return true;
648
+ }
649
+ reset() {
650
+ }
651
+ }
652
+
653
+ function strIsEmpty(str) {
654
+ if (str) {
655
+ return str.trim() === '';
656
+ }
657
+ else
658
+ return true;
659
+ }
660
+ const baseLicApiUrl = 'https://account.korzh.com/api/license';
661
+ const eqVersion = lcv.versionNum;
662
+ class LCDialog {
663
+ constructor(context) {
664
+ this.http = new core$1.HttpClient();
665
+ this.context = context;
666
+ }
667
+ show() {
668
+ const dialogService = new ui.DefaultDialogService();
669
+ this.dialogSet = dialogService.createSet([
670
+ {
671
+ closable: false,
672
+ cancelable: false,
673
+ submitOnEnter: true,
674
+ title: 'No license key for EasyQuery',
675
+ body: this.buildStartPage(),
676
+ submitButtonText: 'Submit',
677
+ onInput: this.validateForm.bind(this),
678
+ onSubmit: this.startPageOnSubmit.bind(this)
679
+ },
680
+ {
681
+ closable: false,
682
+ cancelable: false,
683
+ submitOnEnter: true,
684
+ title: 'Please check your inbox',
685
+ body: this.buildCodePage(),
686
+ submitButtonText: 'Get License Key',
687
+ onInput: this.validateForm.bind(this),
688
+ onSubmit: this.codePageOnSubmit.bind(this)
689
+ },
690
+ {
691
+ closable: false,
692
+ cancelable: false,
693
+ submitable: false,
694
+ title: 'Success',
695
+ body: this.buildSuccessPage()
696
+ },
697
+ {
698
+ closable: false,
699
+ cancelable: false,
700
+ submitable: false,
701
+ title: 'Failure',
702
+ body: this.buildFailurePage()
703
+ },
704
+ ]);
705
+ const dialog1 = this.dialogSet.open(0);
706
+ setTimeout(() => {
707
+ this.validateForm(dialog1);
708
+ const emailInput = document.getElementById('eqAuthEmail');
709
+ if (emailInput) {
710
+ emailInput.focus();
711
+ }
712
+ }, 200);
713
+ }
714
+ isValidForm(form) {
715
+ const emailInput = form.querySelector('#eqAuthEmail'); //form.querySelector('[name="email"]') as HTMLInputElement;
716
+ if (emailInput) {
717
+ return !strIsEmpty(emailInput.value) &&
718
+ emailInput.value
719
+ .toLowerCase()
720
+ .match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
721
+ }
722
+ const codeInput = form.querySelector('#eqAuthCode'); //form.querySelector('[name="code"]') as HTMLInputElement;
723
+ if (codeInput) {
724
+ return !strIsEmpty(codeInput.value) &&
725
+ !isNaN(+codeInput.value) &&
726
+ codeInput.value == codeInput.value.trim() &&
727
+ codeInput.value.length === 6;
728
+ }
729
+ return true;
730
+ }
731
+ validateForm(dialog) {
732
+ const submitButton = dialog.getSubmitButtonElement();
733
+ submitButton.disabled = !this.isValidForm(dialog.getRootElement());
734
+ }
735
+ addInputField(parentBuilder, inputOptions) {
736
+ parentBuilder
737
+ .addChild('label', b => b
738
+ .attr('for', inputOptions.id)
739
+ .addHtml(`${inputOptions.label} ${inputOptions.required ? '<sup style="color: red">*</sup>' : ''}: `))
740
+ .addChild('input', b => {
741
+ b.id(inputOptions.id);
742
+ b.name(inputOptions.name || inputOptions.id);
743
+ b.type(inputOptions.type || 'text');
744
+ if (typeof (inputOptions.value) !== 'undefined') {
745
+ b.value(inputOptions.value);
746
+ }
747
+ if (inputOptions.onInput) {
748
+ b.on('input', inputOptions.onInput);
749
+ }
750
+ });
751
+ }
752
+ buildStartPage() {
753
+ let form;
754
+ let controlsPanelBuilder;
755
+ const formBuilder = ui.domel('div');
756
+ formBuilder.addChild('div', b => b
757
+ .html('<div style="font-size:1.2em">The EasyQuery license key is either absent, invalid or was issued for a different version of the library.</div>' +
758
+ '<div style="font-size:1.2em">Please fill out the form to obtain a valid trial license key.</div>'));
759
+ formBuilder
760
+ .addClass('kfrm-form')
761
+ .addChild('div', b => {
762
+ controlsPanelBuilder = b;
763
+ b.addClass('kfrm-fields label-above');
764
+ b.addClass('kfrm-break-20');
765
+ });
766
+ this.addInputField(controlsPanelBuilder, {
767
+ id: 'eqAuthEmail',
768
+ name: 'email',
769
+ label: 'Email',
770
+ required: true
771
+ });
772
+ this.addInputField(controlsPanelBuilder, {
773
+ id: 'eqAuthName',
774
+ name: 'contactName',
775
+ label: 'Name (optional)',
776
+ required: false
777
+ });
778
+ formBuilder.addChild('div', b => b
779
+ .html('<div style="margin-top:20px;font-size:0.9em">* By clicking Submit, you agree with Korzh.com <a href="https://korzh.com/terms-of-use">Terms of use</a>' +
780
+ ' and <a href="https://korzh.com/privacy">Privacy policy</a>.</div>' +
781
+ '<div style="font-size:0.9em">You also agree to receive email messages from Korzh.com. This consent may be revoked at any time.</div>'));
782
+ form = formBuilder.toDOM();
783
+ return form;
784
+ }
785
+ buildCodePage() {
786
+ let form;
787
+ let controlsPanelBuilder;
788
+ const formBuilder = ui.domel('div');
789
+ formBuilder.addChild('div', b => b
790
+ .html('<div style="font-size:1.2em">We sent a confirmation code to <strong>{{email}}</strong>.</div>' +
791
+ '<div style="font-size:1.2em">Please find it in the email and enter to the text box below</div>'));
792
+ formBuilder
793
+ .addClass('kfrm-form')
794
+ .addChild('div', b => {
795
+ controlsPanelBuilder = b;
796
+ b.addClass('kfrm-fields label-above');
797
+ b.addClass('kfrm-break-20');
798
+ });
799
+ this.addInputField(controlsPanelBuilder, {
800
+ id: 'eqAuthCode',
801
+ name: 'code',
802
+ label: 'Confirmation code',
803
+ required: true
804
+ });
805
+ formBuilder.addChild('div', b => b
806
+ .html('<div style="margin-top:20px;font-size:0.9em">NB: Don\'t forget to check your SPAM folder ' +
807
+ 'if the message does not arrive within the next 5 minutes, and mark it as "Not Spam" if it\'s found there.</div>'));
808
+ form = formBuilder.toDOM();
809
+ return form.outerHTML;
810
+ }
811
+ buildSuccessPage() {
812
+ let form;
813
+ const formBuilder = ui.domel('div');
814
+ formBuilder.addChild('div', b => b
815
+ .html('<div style="font-size:1.2em">You have successfully completed the registration.</div>' + '{{message}}'));
816
+ form = formBuilder.toDOM();
817
+ return form.outerHTML;
818
+ }
819
+ buildFailurePage() {
820
+ let form;
821
+ const formBuilder = ui.domel('div');
822
+ formBuilder.addChild('div', b => b
823
+ .html('{{message}}'));
824
+ form = formBuilder.toDOM();
825
+ return form.outerHTML;
826
+ }
827
+ startPageOnSubmit(dlg) {
828
+ const emailInput = document.getElementById('eqAuthEmail');
829
+ const nameInput = document.getElementById('eqAuthName');
830
+ const authEmail = emailInput.value;
831
+ const authName = nameInput.value;
832
+ dlg.disableButtons();
833
+ this.http.post(core.equtils.combinePath(baseLicApiUrl, 'get-code'), {
834
+ email: authEmail,
835
+ name: authName,
836
+ data: {
837
+ ptag: this.context.backendInfo.type,
838
+ apptype: this.context.backendInfo.subType,
839
+ }
840
+ }, { dataType: 'json' })
841
+ .then(result => {
842
+ if (result.status !== 0) {
843
+ throw new Error(result.message);
844
+ }
845
+ const dlg = this.dialogSet.openNext({ email: authEmail });
846
+ setTimeout(() => {
847
+ this.validateForm(dlg);
848
+ const codeInput = document.getElementById('eqAuthCode');
849
+ if (codeInput) {
850
+ codeInput.focus();
851
+ }
852
+ }, 200);
853
+ })
854
+ .catch(error => {
855
+ dlg.showAlert(error.message, "error", true);
856
+ dlg.enableButtons();
857
+ });
858
+ return false;
859
+ }
860
+ codePageOnSubmit(dlg) {
861
+ const codeInput = document.getElementById('eqAuthCode');
862
+ const authCode = codeInput.value;
863
+ dlg.disableButtons();
864
+ this.http.post(core.equtils.combinePath(baseLicApiUrl, 'get-key'), {
865
+ token: authCode,
866
+ ptag: this.context.backendInfo.type,
867
+ version: eqVersion
868
+ }, { dataType: 'json' })
869
+ .then(result => {
870
+ switch (result.status) {
871
+ case 0:
872
+ const url = core.equtils.combinePath(this.context.getBaseEndpoint(), 'lck');
873
+ this.http.post(url, {
874
+ version: eqVersion,
875
+ key: result.key
876
+ }, { dataType: 'json' })
877
+ .then(_ => this.dialogSet.open(2, {
878
+ message: '<div style="font-size:1.2em">Please restart your web application to get the key applied.</div>'
879
+ }), _ => this.dialogSet.open(2, {
880
+ message: '<div style="font-size:1.2em">' +
881
+ 'Please visit <a href="https://account.korzh.com">your account page on Korzh.com</a> to get the key ' +
882
+ 'and then add it to the <i>appsettings.json</i> file (in the <i>EasyQuery/LicenseKey</i> option).</div>'
883
+ }));
884
+ break;
885
+ case 2:
886
+ this.dialogSet.open(3, {
887
+ message: '<div style="font-size:1.2em">Your trial license for EasyQuery has expired.</div>' +
888
+ '<div style="font-size:1.2em">Please <a href="https://korzh.com/support">contact us</a> if you want to extend the trial period.</div>'
889
+ });
890
+ break;
891
+ case 3:
892
+ this.dialogSet.open(3, {
893
+ message: '<div style="font-size:1.2em">The maintenance subscription for your EasyQuery license has expired.</div>' +
894
+ '<div style="font-size:1.2em">You need to <a href="https://account.korzh.com">renew the subscription</a> to get a valid license.</div>'
895
+ });
896
+ break;
897
+ default:
898
+ throw new Error(result.message);
899
+ }
900
+ })
901
+ .catch(error => {
902
+ dlg.showAlert(error.message, "error", true);
903
+ dlg.enableButtons();
904
+ });
905
+ return false;
906
+ }
907
+ }
908
+ function showNoLicenseAlert(context) {
909
+ if (lcv.__kt == -3) {
910
+ const lcd = new LCDialog(context);
911
+ lcd.show();
912
+ }
913
+ else {
914
+ let title, body, buttonTitle, buttonUrl;
915
+ switch (lcv.__kt) {
916
+ case 1:
917
+ title = 'EasyQuery trial has expired';
918
+ body = `Your trial period for EasyQuery has expired.
919
+ You can <a href="https://korzh.com/support">submit a request to extend your trial</a> or <a href="https://korzh.com/easyquery#licensing">buy a license</a> to get rid of all limitations.`;
920
+ buttonTitle = 'Buy a license';
921
+ buttonUrl = '#licensing';
922
+ break;
923
+ default:
924
+ title = `Invalid key for EasyQuery!`;
925
+ body = `The EasyQuery product key is either invalid or was issued for a different version of the library.
926
+ The version you are using now is ${eqVersion},
927
+ so please <a href="https://account.korzh.com">login to your account</a> to get a proper key for version ${eqVersion}`;
928
+ buttonTitle = 'Get key';
929
+ buttonUrl = 'https://account.korzh.com';
930
+ break;
931
+ }
932
+ const ds = new ui.DefaultDialogService();
933
+ const dlg = ds.open({
934
+ closable: false,
935
+ cancelable: false,
936
+ submitable: false,
937
+ title: title,
938
+ body: body
939
+ });
940
+ const footer = dlg.getRootElement().querySelector('footer');
941
+ ui.domel(footer)
942
+ .removeClass('align-right')
943
+ .setStyle('justify-content', 'center')
944
+ .addChild('button', b => b
945
+ .addClass('kfrm-button', 'is-info')
946
+ .addText(buttonTitle)
947
+ .on('click', (e) => {
948
+ window.location.href = buttonUrl;
949
+ }));
950
+ if (lcv.__kt == 1) {
951
+ ui.domel(footer)
952
+ .addChild('button', b => b
953
+ .addClass('kfrm-button')
954
+ .addText('Extend trial')
955
+ .on('click', (e) => {
956
+ window.location.href = 'https://account.korzh.com';
957
+ }));
958
+ }
959
+ }
960
+ }
961
+
962
+ class EnterpriseEqContext extends core.EqContext {
963
+ useEnterprise(keyOrInitCallback) {
964
+ const func = (key) => {
965
+ lcv.ck(key);
966
+ if (lcv.__kt > 1) {
967
+ const services = this.getServices();
968
+ services.registerDataModelResolver(context => new DataModelEx());
969
+ services.registerQueryResolver(context => new QueryEx(context.getModel(), { context }));
970
+ services.registerQueryStorageResolver(context => new EqServerQueryStorage(context));
971
+ services.registerAggregatesCalculator(context => new DataTableAggregatesCalculator(context));
972
+ if (lcv.__kt === 2) {
973
+ console.warn('EasyQuery.JS is working in the TRIAL MODE!\n'
974
+ + 'Please order a license (https://korzh.com/eq) to get a proper product key.');
975
+ this.createTrialWM();
976
+ setTimeout(() => {
977
+ this.showTrialWM();
978
+ setTimeout(() => { this.hideTrialWM(); }, 6000);
979
+ }, 3000);
980
+ }
981
+ }
982
+ else {
983
+ showNoLicenseAlert(this);
984
+ }
985
+ };
986
+ if (typeof (keyOrInitCallback) === "string") {
987
+ func(keyOrInitCallback);
988
+ }
989
+ else if (typeof (keyOrInitCallback) === "function") {
990
+ const http = this.getServices().getHttpClient();
991
+ let url = core.equtils.combinePath(this.getBaseEndpoint(), 'lck2');
992
+ http.get(url)
993
+ .then(result => {
994
+ func(result.key.split("").reverse().join(""));
995
+ this.useBackend({
996
+ type: result.backendType,
997
+ subType: result.appType
998
+ });
999
+ keyOrInitCallback();
1000
+ })
1001
+ .catch(error => {
1002
+ url = core.equtils.combinePath(this.getBaseEndpoint(), 'lck');
1003
+ http.get(url)
1004
+ .then(result => {
1005
+ func(result.split("").reverse().join(""));
1006
+ keyOrInitCallback();
1007
+ })
1008
+ .catch(error => this.throwError({
1009
+ action: "LCK",
1010
+ sourceError: error
1011
+ }));
1012
+ });
1013
+ }
1014
+ else {
1015
+ throw new Error("Wrong type of 'keyOrInitCallback' parameter. It must be a string with a license key or a callback function.");
1016
+ }
1017
+ }
1018
+ createTrialWM() {
1019
+ // we can rewrite it using shadow dom
1020
+ // to make it impossible to hide using JS :)
1021
+ let trialDiv = document.createElement("div");
1022
+ trialDiv.style.position = "fixed";
1023
+ trialDiv.style.bottom = "0";
1024
+ trialDiv.style.right = "-400px";
1025
+ trialDiv.style.width = "400px";
1026
+ trialDiv.style.height = "100px";
1027
+ trialDiv.style.color = "grey";
1028
+ trialDiv.style.textAlign = "center";
1029
+ trialDiv.style.opacity = "0.7";
1030
+ trialDiv.style.font = "bold 1em Trebuchet MS, Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif";
1031
+ trialDiv.style.transition = "right 3s ease-out";
1032
+ const header = document.createElement("div");
1033
+ const eq = document.createElement("span");
1034
+ eq.innerText = "EasyQuery";
1035
+ eq.style.color = "#3A94D4";
1036
+ eq.style.lineHeight = "50px";
1037
+ header.appendChild(eq);
1038
+ const korzh = document.createElement("span");
1039
+ korzh.innerText = "by Korzh.com";
1040
+ korzh.style.marginLeft = "10px";
1041
+ header.appendChild(korzh);
1042
+ trialDiv.appendChild(header);
1043
+ const trialOnly = document.createElement("div");
1044
+ trialOnly.innerText = "FOR TRIAL USE ONLY";
1045
+ trialOnly.style.fontSize = "1.2em";
1046
+ trialOnly.style.fontWeight = "1000";
1047
+ trialDiv.appendChild(trialOnly);
1048
+ document.body.appendChild(trialDiv);
1049
+ this.trialDivElement = trialDiv;
1050
+ }
1051
+ showTrialWM() {
1052
+ if (this.trialDivElement) {
1053
+ this.trialDivElement.style.right = "0";
1054
+ }
1055
+ }
1056
+ hideTrialWM() {
1057
+ if (this.trialDivElement) {
1058
+ this.trialDivElement.style.right = "-400px";
1059
+ setTimeout(() => {
1060
+ this.trialDivElement.parentNode.removeChild(this.trialDivElement);
1061
+ }, 5000);
1062
+ }
1063
+ }
1064
+ }
1065
+ core.registerEqContextResolver(() => new EnterpriseEqContext());
1066
+
1067
+ class EqServerAggregatesCalculator {
1068
+ constructor(context) {
1069
+ this.context = context;
1070
+ this._needRecalculation = true;
1071
+ this.aggrContainer = new core.EqAggregatesContainer(context);
1072
+ }
1073
+ getAggrContainer() {
1074
+ return this.aggrContainer;
1075
+ }
1076
+ calculate(options) {
1077
+ this._needRecalculation = false;
1078
+ this.aggrContainer.clear();
1079
+ options = options || {};
1080
+ options.maxLevel = options.maxLevel >= 0
1081
+ ? options.maxLevel : 0;
1082
+ const levelPromises = [];
1083
+ const query = this.context.createQuery();
1084
+ query.loadFromData(this.context.getQuery().toJSONData());
1085
+ const settings = this.context.getQuery().getAggregationSettings();
1086
+ const aggregates = settings.getAggregates();
1087
+ const aggrColIds = settings.getAggregates().map(a => a.colId);
1088
+ const aggrCols = query.getColumns()
1089
+ .filter(col => aggrColIds.indexOf(col.id) >= 0);
1090
+ for (const col of aggrCols) {
1091
+ query.changeColumnType(col, core.ExprTag.AggregateFunction, { funcId: aggregates.filter(a => a.colId == col.id)[0].funcId });
1092
+ }
1093
+ //get all non-aggregate columns
1094
+ const queryCols = query.getColumns()
1095
+ .filter(c => c.expr.tag !== core.ExprTag.AggregateFunction);
1096
+ for (const col of queryCols) {
1097
+ col.setHidden(true);
1098
+ }
1099
+ if (settings.hasRecordCount()) {
1100
+ const col = query.createColumn();
1101
+ col.caption = settings.COUNT_FIELD_NAME;
1102
+ col['_id'] = settings.COUNT_FIELD_NAME;
1103
+ const sqlText = 'COUNT(*)';
1104
+ const customSqlExpr = new core.Expression(col);
1105
+ customSqlExpr.tag = core.ExprTag.CustomSql;
1106
+ customSqlExpr.sql = sqlText;
1107
+ customSqlExpr.baseAttrId = null;
1108
+ col.expr = customSqlExpr;
1109
+ query.getColumns().push(col);
1110
+ }
1111
+ if (settings.hasGrandTotals()) {
1112
+ levelPromises.push(this.processLevel({
1113
+ query: query,
1114
+ level: 0,
1115
+ groupName: 'Grand Totals',
1116
+ resultObtainedCallback: options.resultObtained,
1117
+ errorOccurredCallback: options.errorOccurred
1118
+ }));
1119
+ }
1120
+ const groups = settings.getGroups();
1121
+ for (let level = 1; level <= groups.length; level++) {
1122
+ const group = groups[level - 1];
1123
+ for (const col of queryCols) {
1124
+ col.setHidden(group.columns.indexOf(col.id) < 0);
1125
+ }
1126
+ levelPromises.push(this.processLevel({
1127
+ query: query,
1128
+ level: level,
1129
+ groupName: group.name,
1130
+ resultObtainedCallback: options.resultObtained,
1131
+ errorOccurredCallback: options.errorOccurred
1132
+ }));
1133
+ }
1134
+ return Promise.all(levelPromises)
1135
+ .then(() => {
1136
+ return;
1137
+ })
1138
+ .catch((error) => console.error(error));
1139
+ }
1140
+ processLevel(options) {
1141
+ const fetcher = this.context.getServices()
1142
+ .getDataFetcher(this.context);
1143
+ let fetchOptions = {
1144
+ aux: true,
1145
+ query: options.query
1146
+ };
1147
+ if (this.context.debugMode) {
1148
+ fetchOptions.debug = `Fetching group data. Group: '${options.groupName}', level: ${options.level}`;
1149
+ }
1150
+ const resultPromise = fetcher.fetchData(fetchOptions)
1151
+ .then((result) => {
1152
+ const dataTable = new core$1.EasyDataTable({
1153
+ elasticChunks: true
1154
+ });
1155
+ const resultSet = result.resultSet;
1156
+ for (const col of resultSet.cols) {
1157
+ dataTable.columns.add(col);
1158
+ }
1159
+ for (const row of resultSet.rows) {
1160
+ dataTable.addRow(row);
1161
+ }
1162
+ const levelData = this.buildLevelData(options.level, dataTable);
1163
+ this.aggrContainer.setAggregateData(options.level, levelData);
1164
+ if (options.resultObtainedCallback) {
1165
+ options.resultObtainedCallback(result, options.level);
1166
+ }
1167
+ })
1168
+ .catch((error) => {
1169
+ if (options.errorOccurredCallback) {
1170
+ options.errorOccurredCallback(Object.assign(Object.assign({}, error), { level: options.level }));
1171
+ }
1172
+ });
1173
+ return resultPromise;
1174
+ }
1175
+ buildLevelData(level, dataTable) {
1176
+ const aggrSettings = this.context.getQuery().getAggregationSettings();
1177
+ const keyColumns = level > 0
1178
+ ? aggrSettings.getGroups()[level - 1].columns
1179
+ : [];
1180
+ const valueColumns = aggrSettings.getAggregates().map(a => a.colId);
1181
+ if (aggrSettings.hasRecordCount()) {
1182
+ valueColumns.push(aggrSettings.COUNT_FIELD_NAME);
1183
+ }
1184
+ const data = new Map();
1185
+ for (const row of dataTable.getCachedRows()) {
1186
+ const key = {};
1187
+ const value = {};
1188
+ for (const keyCol of keyColumns) {
1189
+ const colIdx = dataTable.columns.getIndex(keyCol);
1190
+ if (colIdx >= 0) {
1191
+ let keyVal = row.getValue(keyCol);
1192
+ if (!aggrSettings.caseSensitiveGroups && typeof (keyVal) === 'string') {
1193
+ keyVal = keyVal.toLowerCase();
1194
+ }
1195
+ key[keyCol] = keyVal;
1196
+ }
1197
+ }
1198
+ for (const valueCol of valueColumns) {
1199
+ value[valueCol] = row.getValue(valueCol);
1200
+ }
1201
+ data.set(JSON.stringify(key), value);
1202
+ }
1203
+ return data;
1204
+ }
1205
+ needRecalculation() {
1206
+ return this._needRecalculation;
1207
+ }
1208
+ reset() {
1209
+ this._needRecalculation = true;
1210
+ }
1211
+ }
1212
+
1213
+ exports.ConditionEx = ConditionEx;
1214
+ exports.DataModelEx = DataModelEx;
1215
+ exports.EqServerAggregatesCalculator = EqServerAggregatesCalculator;
1216
+ exports.EqServerQueryStorage = EqServerQueryStorage;
1217
+ exports.QueryColumnEx = QueryColumnEx;
1218
+ exports.QueryEx = QueryEx;