@finos/legend-data-cube 0.1.32 → 0.2.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/lib/components/DataCubeStatusBar.d.ts.map +1 -1
- package/lib/components/DataCubeStatusBar.js +4 -2
- package/lib/components/DataCubeStatusBar.js.map +1 -1
- package/lib/components/view/editor/DataCubeEditor.d.ts.map +1 -1
- package/lib/components/view/editor/DataCubeEditor.js +12 -1
- package/lib/components/view/editor/DataCubeEditor.js.map +1 -1
- package/lib/components/view/grid/DataCubeMultidimensionalGrid.d.ts.map +1 -1
- package/lib/components/view/grid/DataCubeMultidimensionalGrid.js +40 -2
- package/lib/components/view/grid/DataCubeMultidimensionalGrid.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.d.ts +12 -0
- package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.js +141 -4
- package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +2 -0
- package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.js +18 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.d.ts +6 -0
- package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.js +9 -0
- package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
- package/lib/stores/core/DataCubeSnapshot.d.ts +2 -0
- package/lib/stores/core/DataCubeSnapshot.d.ts.map +1 -1
- package/lib/stores/core/DataCubeSnapshot.js.map +1 -1
- package/lib/stores/core/DataCubeSnapshotBuilder.js +1 -0
- package/lib/stores/core/DataCubeSnapshotBuilder.js.map +1 -1
- package/lib/stores/core/model/DataCubeSpecification.d.ts +2 -0
- package/lib/stores/core/model/DataCubeSpecification.d.ts.map +1 -1
- package/lib/stores/core/model/DataCubeSpecification.js +3 -0
- package/lib/stores/core/model/DataCubeSpecification.js.map +1 -1
- package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
- package/lib/stores/view/DataCubeViewState.js +1 -0
- package/lib/stores/view/DataCubeViewState.js.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.d.ts.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js +8 -4
- package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorState.d.ts.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorState.js +1 -0
- package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts +163 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.js +142 -3
- package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts +155 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +170 -2
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridControllerState.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridControllerState.js +5 -3
- package/lib/stores/view/grid/DataCubeGridControllerState.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridDimensionalTree.d.ts +54 -0
- package/lib/stores/view/grid/DataCubeGridDimensionalTree.d.ts.map +1 -0
- package/lib/stores/view/grid/DataCubeGridDimensionalTree.js +264 -0
- package/lib/stores/view/grid/DataCubeGridDimensionalTree.js.map +1 -0
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts +1 -0
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.js +207 -1
- package/lib/stores/view/grid/DataCubeGridMenuBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts +2 -0
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +7 -1
- package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.d.ts +6 -1
- package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.js +38 -2
- package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
- package/package.json +2 -2
- package/src/components/DataCubeStatusBar.tsx +9 -2
- package/src/components/view/editor/DataCubeEditor.tsx +16 -1
- package/src/components/view/grid/DataCubeMultidimensionalGrid.tsx +63 -1
- package/src/stores/core/DataCubeQueryBuilder.ts +256 -2
- package/src/stores/core/DataCubeQueryBuilderUtils.ts +22 -0
- package/src/stores/core/DataCubeQueryEngine.ts +10 -0
- package/src/stores/core/DataCubeSnapshot.ts +2 -0
- package/src/stores/core/DataCubeSnapshotBuilder.ts +1 -1
- package/src/stores/core/model/DataCubeSpecification.ts +5 -0
- package/src/stores/view/DataCubeViewState.ts +1 -0
- package/src/stores/view/editor/DataCubeEditorDimensionsPanelState.ts +9 -7
- package/src/stores/view/editor/DataCubeEditorState.tsx +1 -0
- package/src/stores/view/grid/DataCubeGridClientEngine.ts +268 -6
- package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +244 -3
- package/src/stores/view/grid/DataCubeGridControllerState.ts +10 -2
- package/src/stores/view/grid/DataCubeGridDimensionalTree.ts +438 -0
- package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +257 -0
- package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +22 -1
- package/src/stores/view/grid/DataCubeGridState.ts +92 -2
- package/tsconfig.json +1 -0
|
@@ -81,6 +81,7 @@ import {
|
|
|
81
81
|
isPivotResultColumnName,
|
|
82
82
|
getPivotResultColumnBaseColumnName,
|
|
83
83
|
DEFAULT_ROOT_AGGREGATION_COLUMN_VALUE,
|
|
84
|
+
DataCubeQueryFilterOperator,
|
|
84
85
|
} from './DataCubeQueryEngine.js';
|
|
85
86
|
import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js';
|
|
86
87
|
import type { DataCubeQueryAggregateOperation } from './aggregation/DataCubeQueryAggregateOperation.js';
|
|
@@ -88,6 +89,7 @@ import {
|
|
|
88
89
|
DataCubeColumnConfiguration,
|
|
89
90
|
type DataCubeConfiguration,
|
|
90
91
|
} from './model/DataCubeConfiguration.js';
|
|
92
|
+
import type { DataCubeDimensionalGroupByNode } from '../view/grid/DataCubeGridDimensionalTree.js';
|
|
91
93
|
|
|
92
94
|
// --------------------------------- UTILITIES ---------------------------------
|
|
93
95
|
|
|
@@ -645,3 +647,23 @@ export function _filter(
|
|
|
645
647
|
return filterCondition.not ? _not(condition) : condition;
|
|
646
648
|
}
|
|
647
649
|
}
|
|
650
|
+
|
|
651
|
+
export function _flattenFilterSnapshot(
|
|
652
|
+
groupByNodes: DataCubeDimensionalGroupByNode[],
|
|
653
|
+
): DataCubeSnapshotFilter {
|
|
654
|
+
const filterConditions = groupByNodes.map((node) => {
|
|
655
|
+
return {
|
|
656
|
+
name: node.column,
|
|
657
|
+
type: 'String', // Assuming all filters are strings — update if needed
|
|
658
|
+
operator: DataCubeQueryFilterOperator.EQUAL,
|
|
659
|
+
value: {
|
|
660
|
+
type: 'String',
|
|
661
|
+
value: node.filter,
|
|
662
|
+
} satisfies DataCubeOperationValue,
|
|
663
|
+
} satisfies DataCubeSnapshotFilterCondition;
|
|
664
|
+
});
|
|
665
|
+
return {
|
|
666
|
+
groupOperator: DataCubeQueryFilterGroupOperator.AND,
|
|
667
|
+
conditions: filterConditions,
|
|
668
|
+
} satisfies DataCubeSnapshotFilter;
|
|
669
|
+
}
|
|
@@ -273,6 +273,12 @@ export enum DataCubeGridMode {
|
|
|
273
273
|
MULTIDIMENSIONAL = 'Multidimensional',
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
export enum DataCubeClientModelOption {
|
|
277
|
+
ROW_DATA = 'rowData',
|
|
278
|
+
COLUMN_DEFS = 'columnDefs',
|
|
279
|
+
LOADING = 'loading',
|
|
280
|
+
}
|
|
281
|
+
|
|
276
282
|
export enum DataCubeTitleBarMenuItems {
|
|
277
283
|
VIEW_SOURCE = 'View Source',
|
|
278
284
|
RESET_TO_LATEST_SAVE = 'Reset to Latest Save',
|
|
@@ -409,6 +415,10 @@ export function ofDataType(
|
|
|
409
415
|
return dataTypes.includes(getDataType(type));
|
|
410
416
|
}
|
|
411
417
|
|
|
418
|
+
export function isDimensionalGridMode(gridMode: DataCubeGridMode) {
|
|
419
|
+
return gridMode === DataCubeGridMode.MULTIDIMENSIONAL;
|
|
420
|
+
}
|
|
421
|
+
|
|
412
422
|
export function isPrimitiveType(type: string) {
|
|
413
423
|
return (
|
|
414
424
|
[
|
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
DataCubeQuerySortDirection,
|
|
30
30
|
} from './DataCubeQueryEngine.js';
|
|
31
31
|
import type { DataCubeColumn } from './model/DataCubeColumn.js';
|
|
32
|
+
import type { DataCubeDimensionalTree } from '../view/grid/DataCubeGridDimensionalTree.js';
|
|
32
33
|
|
|
33
34
|
export type DataCubeSnapshotFilterCondition = DataCubeColumn & {
|
|
34
35
|
value: DataCubeOperationValue;
|
|
@@ -85,6 +86,7 @@ export type DataCubeSnapshotData = {
|
|
|
85
86
|
groupExtendedColumns: DataCubeSnapshotExtendedColumn[];
|
|
86
87
|
sortColumns: DataCubeSnapshotSortColumn[];
|
|
87
88
|
limit: number | undefined;
|
|
89
|
+
dimensionalTree?: DataCubeDimensionalTree | undefined;
|
|
88
90
|
};
|
|
89
91
|
|
|
90
92
|
export class DataCubeSnapshot {
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from '@finos/legend-shared';
|
|
22
22
|
import { createModelSchema, optional, primitive, raw } from 'serializr';
|
|
23
23
|
import { DataCubeConfiguration } from './DataCubeConfiguration.js';
|
|
24
|
+
import { DataCubeDimensionalTree } from '../../view/grid/DataCubeGridDimensionalTree.js';
|
|
24
25
|
|
|
25
26
|
export class DataCubeSpecificationOptions {
|
|
26
27
|
autoEnableCache?: boolean | undefined;
|
|
@@ -37,6 +38,7 @@ export class DataCubeSpecification {
|
|
|
37
38
|
configuration?: DataCubeConfiguration | undefined;
|
|
38
39
|
source!: PlainObject;
|
|
39
40
|
options?: DataCubeSpecificationOptions | undefined;
|
|
41
|
+
dimensionalTree?: DataCubeDimensionalTree | undefined;
|
|
40
42
|
|
|
41
43
|
static readonly serialization = new SerializationFactory(
|
|
42
44
|
createModelSchema(DataCubeSpecification, {
|
|
@@ -48,6 +50,9 @@ export class DataCubeSpecification {
|
|
|
48
50
|
),
|
|
49
51
|
query: primitive(),
|
|
50
52
|
source: raw(),
|
|
53
|
+
dimensionalTree: optional(
|
|
54
|
+
usingModelSchema(DataCubeDimensionalTree.serialization.schema),
|
|
55
|
+
),
|
|
51
56
|
}),
|
|
52
57
|
);
|
|
53
58
|
}
|
|
@@ -213,6 +213,7 @@ export class DataCubeEditorDimensionsPanelState
|
|
|
213
213
|
return _dimension;
|
|
214
214
|
}),
|
|
215
215
|
);
|
|
216
|
+
this.refreshDimensionsTreeData();
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
buildSnapshot(newSnapshot: DataCubeSnapshot, baseSnapshot: DataCubeSnapshot) {
|
|
@@ -226,13 +227,14 @@ export class DataCubeEditorDimensionsPanelState
|
|
|
226
227
|
name: dimension.name,
|
|
227
228
|
columns: dimension.columns.map((column) => column.name),
|
|
228
229
|
}));
|
|
230
|
+
newSnapshot.data.configuration = {
|
|
231
|
+
...newSnapshot.data.configuration,
|
|
232
|
+
dimensions: DataCubeDimensionsConfiguration.serialization.toJson(
|
|
233
|
+
dimensionsConfiguration,
|
|
234
|
+
),
|
|
235
|
+
};
|
|
236
|
+
} else {
|
|
237
|
+
newSnapshot = baseSnapshot;
|
|
229
238
|
}
|
|
230
|
-
|
|
231
|
-
newSnapshot.data.configuration = {
|
|
232
|
-
...newSnapshot.data.configuration,
|
|
233
|
-
dimensions: DataCubeDimensionsConfiguration.serialization.toJson(
|
|
234
|
-
dimensionsConfiguration,
|
|
235
|
-
),
|
|
236
|
-
};
|
|
237
239
|
}
|
|
238
240
|
}
|
|
@@ -147,6 +147,7 @@ export class DataCubeEditorState extends DataCubeSnapshotController {
|
|
|
147
147
|
return 'editor';
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
//TODO: for dimensional grid, we need to reload the grid when we apply changes
|
|
150
151
|
async applyChanges(options?: { closeAfterApply?: boolean | undefined }) {
|
|
151
152
|
this.finalizationState.inProgress();
|
|
152
153
|
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
IllegalStateError,
|
|
26
26
|
assertErrorThrown,
|
|
27
27
|
guaranteeNonNullable,
|
|
28
|
+
guaranteeType,
|
|
28
29
|
hashObject,
|
|
29
30
|
isBoolean,
|
|
30
31
|
isNonNullable,
|
|
@@ -35,19 +36,27 @@ import {
|
|
|
35
36
|
PRIMITIVE_TYPE,
|
|
36
37
|
PureClientVersion,
|
|
37
38
|
type TabularDataSet,
|
|
39
|
+
type TDSRow,
|
|
38
40
|
} from '@finos/legend-graph';
|
|
39
41
|
import { makeObservable, observable, runInAction } from 'mobx';
|
|
40
|
-
import
|
|
42
|
+
import {
|
|
41
43
|
DataCubeConfiguration,
|
|
42
|
-
DataCubeConfigurationColorKey,
|
|
44
|
+
type DataCubeConfigurationColorKey,
|
|
45
|
+
type DataCubeDimensionConfiguration,
|
|
43
46
|
} from '../../core/model/DataCubeConfiguration.js';
|
|
44
47
|
import { type DataCubeSnapshot } from '../../core/DataCubeSnapshot.js';
|
|
45
48
|
import { _findCol, _sortByColName } from '../../core/model/DataCubeColumn.js';
|
|
46
|
-
import {
|
|
49
|
+
import {
|
|
50
|
+
DataCubeClientModelOption,
|
|
51
|
+
isPivotResultColumnName,
|
|
52
|
+
} from '../../core/DataCubeQueryEngine.js';
|
|
47
53
|
import { buildSnapshotFromGridState } from './DataCubeGridSnapshotBuilder.js';
|
|
48
54
|
import { AlertType } from '../../services/DataCubeAlertService.js';
|
|
49
55
|
import type { DataCubeViewState } from '../DataCubeViewState.js';
|
|
50
|
-
import {
|
|
56
|
+
import {
|
|
57
|
+
buildDimensionalGridDataFetchExecutableQuery,
|
|
58
|
+
buildGridDataFetchExecutableQuery,
|
|
59
|
+
} from './DataCubeGridQueryBuilder.js';
|
|
51
60
|
import { DataCubeSettingKey } from '../../../__lib__/DataCubeSetting.js';
|
|
52
61
|
import { DEFAULT_ALERT_WINDOW_CONFIG } from '../../services/DataCubeLayoutService.js';
|
|
53
62
|
import {
|
|
@@ -57,8 +66,24 @@ import {
|
|
|
57
66
|
import { _lambda } from '../../core/DataCubeQueryBuilderUtils.js';
|
|
58
67
|
import { sum } from 'mathjs';
|
|
59
68
|
import { DataCubeEvent } from '../../../__lib__/DataCubeEvent.js';
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
import { generateColumnDefsForDimensions } from './DataCubeGridConfigurationBuilder.js';
|
|
70
|
+
import {
|
|
71
|
+
DataCubeDimensionalMetadata,
|
|
72
|
+
generateDimensionalPaths,
|
|
73
|
+
type DataCubeDimensionalNode,
|
|
74
|
+
type DataCubeDimensionalGroupByNode,
|
|
75
|
+
type DataCubeDimensionalTree,
|
|
76
|
+
DIMENSIONAL_L0_COLUMN,
|
|
77
|
+
findExtraPaths,
|
|
78
|
+
} from './DataCubeGridDimensionalTree.js';
|
|
79
|
+
|
|
80
|
+
type DataCubeGridClientCellValue =
|
|
81
|
+
| string
|
|
82
|
+
| number
|
|
83
|
+
| boolean
|
|
84
|
+
| Map<string, DataCubeDimensionalMetadata>
|
|
85
|
+
| null
|
|
86
|
+
| undefined;
|
|
62
87
|
type DataCubeGridClientRowData = {
|
|
63
88
|
[key: string]: DataCubeGridClientCellValue;
|
|
64
89
|
};
|
|
@@ -259,6 +284,136 @@ function buildRowData(
|
|
|
259
284
|
});
|
|
260
285
|
}
|
|
261
286
|
|
|
287
|
+
function buildDimensionalRowData(
|
|
288
|
+
result: TabularDataSet,
|
|
289
|
+
snapshot: DataCubeSnapshot,
|
|
290
|
+
dimensionalNodes: DataCubeDimensionalNode[],
|
|
291
|
+
rowData: DataCubeGridClientRowData[],
|
|
292
|
+
dimensions: DataCubeDimensionConfiguration[],
|
|
293
|
+
): DataCubeGridClientRowData[] {
|
|
294
|
+
const newRows = result.rows.map((rawRow) =>
|
|
295
|
+
_createClientRow(rawRow, result.columns, dimensionalNodes, dimensions),
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const updated = [...rowData];
|
|
299
|
+
for (const newRow of newRows) {
|
|
300
|
+
const insertIndex = _findInsertIndex(newRow, updated, dimensionalNodes);
|
|
301
|
+
updated.splice(insertIndex, 0, newRow);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return updated;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function _createClientRow(
|
|
308
|
+
rawRow: TDSRow,
|
|
309
|
+
columns: string[],
|
|
310
|
+
nodes: DataCubeDimensionalNode[],
|
|
311
|
+
configs: DataCubeDimensionConfiguration[],
|
|
312
|
+
): DataCubeGridClientRowData {
|
|
313
|
+
const row: DataCubeGridClientRowData = {};
|
|
314
|
+
rawRow.values.forEach((value, i) => {
|
|
315
|
+
row[guaranteeNonNullable(columns[i])] = isBoolean(value)
|
|
316
|
+
? String(value)
|
|
317
|
+
: isNonNullable(value)
|
|
318
|
+
? value
|
|
319
|
+
: INTERNAL__GRID_CLIENT_MISSING_VALUE;
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
const metadata = new Map<string, DataCubeDimensionalMetadata>();
|
|
323
|
+
for (const node of nodes) {
|
|
324
|
+
const config = guaranteeNonNullable(
|
|
325
|
+
configs.find((d) => d.name === node.dimension),
|
|
326
|
+
);
|
|
327
|
+
metadata.set(
|
|
328
|
+
node.dimension,
|
|
329
|
+
new DataCubeDimensionalMetadata(
|
|
330
|
+
node.column,
|
|
331
|
+
config.columns.indexOf(node.column),
|
|
332
|
+
node.groupByNodes,
|
|
333
|
+
),
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
row.metadata = metadata;
|
|
337
|
+
return row;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function _findInsertIndex(
|
|
341
|
+
newRow: DataCubeGridClientRowData,
|
|
342
|
+
existing: DataCubeGridClientRowData[],
|
|
343
|
+
dimensionalNodes: DataCubeDimensionalNode[],
|
|
344
|
+
): number {
|
|
345
|
+
const metadata = guaranteeType(
|
|
346
|
+
newRow.metadata,
|
|
347
|
+
Map<string, DataCubeDimensionalMetadata>,
|
|
348
|
+
);
|
|
349
|
+
const groupByNodes = [...metadata.values()].flatMap((m) => m.groupByNodes);
|
|
350
|
+
const dimensions = dimensionalNodes.map((d) => d.dimension);
|
|
351
|
+
const latest = _latestGroupByFilters(groupByNodes);
|
|
352
|
+
|
|
353
|
+
for (let i = existing.length - 1; i >= 0; i--) {
|
|
354
|
+
const existingRow = guaranteeNonNullable(existing[i]);
|
|
355
|
+
if (
|
|
356
|
+
_isParentRow(existingRow, groupByNodes.length, newRow, latest, dimensions)
|
|
357
|
+
) {
|
|
358
|
+
return i + 1;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return existing.length;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function _isParentRow(
|
|
366
|
+
existing: DataCubeGridClientRowData,
|
|
367
|
+
groupByCount: number,
|
|
368
|
+
newRow: DataCubeGridClientRowData,
|
|
369
|
+
filters: DataCubeDimensionalGroupByNode[],
|
|
370
|
+
dimensions: string[],
|
|
371
|
+
): boolean {
|
|
372
|
+
if (groupByCount === 0) {
|
|
373
|
+
let allCount = 0;
|
|
374
|
+
const match = dimensions.every((d) => {
|
|
375
|
+
const e = existing[d],
|
|
376
|
+
n = newRow[d];
|
|
377
|
+
if (e === null || n === null) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
if (String(e) === DIMENSIONAL_L0_COLUMN) {
|
|
381
|
+
allCount++;
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
return String(e) === String(n);
|
|
385
|
+
});
|
|
386
|
+
return match && allCount >= 1 && allCount <= dimensions.length;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return dimensions.every((d) => {
|
|
390
|
+
const filter = filters.find((f) => f.dimension === d);
|
|
391
|
+
const e = existing[d],
|
|
392
|
+
n = newRow[d];
|
|
393
|
+
if (e === null || n === null) {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
if (filter) {
|
|
397
|
+
return (
|
|
398
|
+
String(e) === String(filter.filter) ||
|
|
399
|
+
String(e) === String(n) ||
|
|
400
|
+
String(e) === DIMENSIONAL_L0_COLUMN
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
return String(e) === String(n);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function _latestGroupByFilters(
|
|
408
|
+
nodes: DataCubeDimensionalGroupByNode[],
|
|
409
|
+
): DataCubeDimensionalGroupByNode[] {
|
|
410
|
+
const map = new Map<string, DataCubeDimensionalGroupByNode>();
|
|
411
|
+
for (const node of nodes) {
|
|
412
|
+
map.set(node.dimension, node);
|
|
413
|
+
}
|
|
414
|
+
return [...map.values()];
|
|
415
|
+
}
|
|
416
|
+
|
|
262
417
|
async function getCastColumns(
|
|
263
418
|
currentSnapshot: DataCubeSnapshot,
|
|
264
419
|
view: DataCubeViewState,
|
|
@@ -302,6 +457,113 @@ async function getCastColumns(
|
|
|
302
457
|
});
|
|
303
458
|
}
|
|
304
459
|
|
|
460
|
+
export async function fetchDimensionalQueryRows(
|
|
461
|
+
snapshot: DataCubeSnapshot,
|
|
462
|
+
view: DataCubeViewState,
|
|
463
|
+
previousTree?: DataCubeDimensionalTree,
|
|
464
|
+
) {
|
|
465
|
+
const task = view.taskService.newTask('Fetching data...');
|
|
466
|
+
|
|
467
|
+
let rowData: DataCubeGridClientRowData[] = [];
|
|
468
|
+
|
|
469
|
+
const configuration = DataCubeConfiguration.serialization.fromJson(
|
|
470
|
+
snapshot.data.configuration,
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
// upgrade here by not shooting extra sqls
|
|
474
|
+
let paths = generateDimensionalPaths(
|
|
475
|
+
guaranteeNonNullable(snapshot.data.dimensionalTree),
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
if (previousTree) {
|
|
479
|
+
const oldPaths = generateDimensionalPaths(previousTree);
|
|
480
|
+
if (oldPaths.length <= paths.length) {
|
|
481
|
+
rowData = view.grid.client.getGridOption(
|
|
482
|
+
DataCubeClientModelOption.ROW_DATA,
|
|
483
|
+
) as DataCubeGridClientRowData[];
|
|
484
|
+
paths = findExtraPaths(oldPaths, paths);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
for (const path of paths) {
|
|
489
|
+
const executableQuery = buildDimensionalGridDataFetchExecutableQuery(
|
|
490
|
+
snapshot,
|
|
491
|
+
view.source,
|
|
492
|
+
view.engine,
|
|
493
|
+
path,
|
|
494
|
+
);
|
|
495
|
+
let result: DataCubeExecutionResult;
|
|
496
|
+
|
|
497
|
+
try {
|
|
498
|
+
result = await view.engine.executeQuery(
|
|
499
|
+
_lambda([], [executableQuery]),
|
|
500
|
+
view.source,
|
|
501
|
+
{
|
|
502
|
+
debug: view.settingService.getBooleanValue(
|
|
503
|
+
DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
|
|
504
|
+
),
|
|
505
|
+
clientVersion: view.settingService.getBooleanValue(
|
|
506
|
+
DataCubeSettingKey.DEBUGGER__USE_DEV_CLIENT_PROTOCOL_VERSION,
|
|
507
|
+
)
|
|
508
|
+
? PureClientVersion.VX_X_X
|
|
509
|
+
: undefined,
|
|
510
|
+
},
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
rowData = buildDimensionalRowData(
|
|
514
|
+
result.result.result,
|
|
515
|
+
snapshot,
|
|
516
|
+
path,
|
|
517
|
+
rowData,
|
|
518
|
+
configuration.dimensions.dimensions,
|
|
519
|
+
);
|
|
520
|
+
} catch (error) {
|
|
521
|
+
assertErrorThrown(error);
|
|
522
|
+
if (error instanceof DataCubeExecutionError) {
|
|
523
|
+
view.alertService.alertExecutionError(error, {
|
|
524
|
+
message: `Data Fetch Failure: Can't execute query.`,
|
|
525
|
+
text: `Error: ${error.message}`,
|
|
526
|
+
});
|
|
527
|
+
} else {
|
|
528
|
+
view.alertService.alertError(error, {
|
|
529
|
+
message: `Data Fetch Failure: ${error.message}`,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
view.taskService.endTask(task);
|
|
533
|
+
return {
|
|
534
|
+
rowData: [],
|
|
535
|
+
columnDefs: [],
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (
|
|
540
|
+
view.settingService.getBooleanValue(
|
|
541
|
+
DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
|
|
542
|
+
)
|
|
543
|
+
) {
|
|
544
|
+
view.engine.debugProcess(
|
|
545
|
+
`Execution`,
|
|
546
|
+
['Query', result.executedQuery],
|
|
547
|
+
[
|
|
548
|
+
'Stats',
|
|
549
|
+
`${rowData.length} rows, ${result.result.result.columns.length} columns`,
|
|
550
|
+
],
|
|
551
|
+
[
|
|
552
|
+
'SQL',
|
|
553
|
+
result.executedSQL ?? `-- Error: failed to extract executed SQL`,
|
|
554
|
+
],
|
|
555
|
+
['SQL Execution Time', result.executionTime],
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
view.taskService.endTask(task);
|
|
561
|
+
return {
|
|
562
|
+
rowData: rowData,
|
|
563
|
+
columnDefs: generateColumnDefsForDimensions(snapshot, configuration),
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
|
|
305
567
|
export type DataCubeGridClientDataFetchRequest = {
|
|
306
568
|
startRow: number | undefined;
|
|
307
569
|
endRow: number | undefined;
|