@finos/legend-data-cube 0.1.0 → 0.1.2

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 (114) hide show
  1. package/lib/__lib__/DataCubeSetting.d.ts +1 -0
  2. package/lib/__lib__/DataCubeSetting.d.ts.map +1 -1
  3. package/lib/__lib__/DataCubeSetting.js +1 -0
  4. package/lib/__lib__/DataCubeSetting.js.map +1 -1
  5. package/lib/components/DataCubeStatusBar.d.ts.map +1 -1
  6. package/lib/components/DataCubeStatusBar.js +10 -3
  7. package/lib/components/DataCubeStatusBar.js.map +1 -1
  8. package/lib/components/DataCubeTitleBar.js +1 -1
  9. package/lib/components/DataCubeTitleBar.js.map +1 -1
  10. package/lib/components/core/DataCubeAlert.js +1 -1
  11. package/lib/components/core/DataCubeAlert.js.map +1 -1
  12. package/lib/components/view/grid/DataCubeGrid.d.ts.map +1 -1
  13. package/lib/components/view/grid/DataCubeGrid.js +26 -20
  14. package/lib/components/view/grid/DataCubeGrid.js.map +1 -1
  15. package/lib/index.css +1 -1
  16. package/lib/index.d.ts +2 -3
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +4 -3
  19. package/lib/index.js.map +1 -1
  20. package/lib/package.json +3 -3
  21. package/lib/stores/DataCubeAPI.d.ts +6 -0
  22. package/lib/stores/DataCubeAPI.d.ts.map +1 -1
  23. package/lib/stores/DataCubeAPI.js +3 -0
  24. package/lib/stores/DataCubeAPI.js.map +1 -1
  25. package/lib/stores/DataCubeOptions.d.ts +1 -1
  26. package/lib/stores/core/DataCubeConfigurationBuilder.js +1 -1
  27. package/lib/stores/core/DataCubeConfigurationBuilder.js.map +1 -1
  28. package/lib/stores/core/DataCubeEngine.d.ts +13 -6
  29. package/lib/stores/core/DataCubeEngine.d.ts.map +1 -1
  30. package/lib/stores/core/DataCubeEngine.js +32 -8
  31. package/lib/stores/core/DataCubeEngine.js.map +1 -1
  32. package/lib/stores/core/DataCubeQueryBuilder.d.ts +3 -4
  33. package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
  34. package/lib/stores/core/DataCubeQueryBuilder.js +19 -13
  35. package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
  36. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +2 -7
  37. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
  38. package/lib/stores/core/DataCubeQueryBuilderUtils.js +34 -46
  39. package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
  40. package/lib/stores/core/DataCubeQuerySnapshot.d.ts +11 -4
  41. package/lib/stores/core/DataCubeQuerySnapshot.d.ts.map +1 -1
  42. package/lib/stores/core/DataCubeQuerySnapshot.js +10 -0
  43. package/lib/stores/core/DataCubeQuerySnapshot.js.map +1 -1
  44. package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  45. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js +1 -2
  46. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  47. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -1
  48. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js +3 -3
  49. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -1
  50. package/lib/stores/core/model/CachedDataCubeSource.d.ts +4 -0
  51. package/lib/stores/core/model/CachedDataCubeSource.d.ts.map +1 -1
  52. package/lib/stores/core/model/CachedDataCubeSource.js +4 -0
  53. package/lib/stores/core/model/CachedDataCubeSource.js.map +1 -1
  54. package/lib/stores/services/DataCubeQuerySnapshotService.js +1 -1
  55. package/lib/stores/services/DataCubeQuerySnapshotService.js.map +1 -1
  56. package/lib/stores/services/DataCubeSettingService.d.ts.map +1 -1
  57. package/lib/stores/services/DataCubeSettingService.js +8 -0
  58. package/lib/stores/services/DataCubeSettingService.js.map +1 -1
  59. package/lib/stores/services/DataCubeTaskService.d.ts +4 -4
  60. package/lib/stores/services/DataCubeTaskService.d.ts.map +1 -1
  61. package/lib/stores/services/DataCubeTaskService.js +9 -7
  62. package/lib/stores/services/DataCubeTaskService.js.map +1 -1
  63. package/lib/stores/view/DataCubeViewState.d.ts +3 -1
  64. package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
  65. package/lib/stores/view/DataCubeViewState.js +54 -19
  66. package/lib/stores/view/DataCubeViewState.js.map +1 -1
  67. package/lib/stores/view/editor/DataCubeEditorState.js +1 -1
  68. package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
  69. package/lib/stores/view/extend/DataCubeColumnEditorState.d.ts.map +1 -1
  70. package/lib/stores/view/extend/DataCubeColumnEditorState.js +7 -5
  71. package/lib/stores/view/extend/DataCubeColumnEditorState.js.map +1 -1
  72. package/lib/stores/view/extend/DataCubeExtendManagerState.js +2 -2
  73. package/lib/stores/view/extend/DataCubeExtendManagerState.js.map +1 -1
  74. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  75. package/lib/stores/view/grid/DataCubeGridClientEngine.js +104 -108
  76. package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
  77. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  78. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +3 -3
  79. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  80. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts +3 -4
  81. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  82. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +5 -5
  83. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
  84. package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
  85. package/lib/stores/view/grid/DataCubeGridState.js +63 -8
  86. package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
  87. package/package.json +7 -7
  88. package/src/__lib__/DataCubeSetting.ts +1 -0
  89. package/src/components/DataCubeStatusBar.tsx +18 -3
  90. package/src/components/DataCubeTitleBar.tsx +3 -3
  91. package/src/components/core/DataCubeAlert.tsx +1 -1
  92. package/src/components/view/grid/DataCubeGrid.tsx +23 -7
  93. package/src/index.tsx +8 -3
  94. package/src/stores/DataCubeAPI.ts +9 -0
  95. package/src/stores/DataCubeOptions.ts +1 -1
  96. package/src/stores/core/DataCubeConfigurationBuilder.ts +1 -1
  97. package/src/stores/core/DataCubeEngine.tsx +47 -20
  98. package/src/stores/core/DataCubeQueryBuilder.ts +38 -30
  99. package/src/stores/core/DataCubeQueryBuilderUtils.ts +42 -67
  100. package/src/stores/core/DataCubeQuerySnapshot.ts +15 -4
  101. package/src/stores/core/DataCubeQuerySnapshotBuilder.ts +2 -6
  102. package/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +2 -3
  103. package/src/stores/core/model/CachedDataCubeSource.ts +4 -0
  104. package/src/stores/services/DataCubeQuerySnapshotService.ts +2 -2
  105. package/src/stores/services/DataCubeSettingService.tsx +8 -0
  106. package/src/stores/services/DataCubeTaskService.ts +9 -7
  107. package/src/stores/view/DataCubeViewState.ts +58 -27
  108. package/src/stores/view/editor/DataCubeEditorState.tsx +1 -1
  109. package/src/stores/view/extend/DataCubeColumnEditorState.tsx +7 -15
  110. package/src/stores/view/extend/DataCubeExtendManagerState.tsx +2 -2
  111. package/src/stores/view/grid/DataCubeGridClientEngine.ts +149 -168
  112. package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +6 -7
  113. package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +19 -32
  114. package/src/stores/view/grid/DataCubeGridState.ts +89 -8
@@ -133,7 +133,7 @@ export function newConfiguration(
133
133
  //
134
134
  // since we have made sure all groupBy sort columns must be of the same direction
135
135
  // we simply retrieve the direction from the one of the column provided
136
- if (groupBySortColumns.length) {
136
+ if (groupBySortColumns?.length) {
137
137
  configuration.treeColumnSortDirection = at(groupBySortColumns, 0).direction;
138
138
  }
139
139
 
@@ -20,6 +20,8 @@ import {
20
20
  type TDSExecutionResult,
21
21
  type V1_AppliedFunction,
22
22
  PRIMITIVE_TYPE,
23
+ V1_deserializeValueSpecification,
24
+ V1_serializeValueSpecification,
23
25
  } from '@finos/legend-graph';
24
26
  import {
25
27
  getFilterOperation,
@@ -65,20 +67,25 @@ import { DataCubeQueryFilterOperation__EndWithCaseInsensitive } from './filter/D
65
67
  import { DataCubeQueryFilterOperation__NotEndWith } from './filter/DataCubeQueryFilterOperation__NotEndWith.js';
66
68
  import { DataCubeQueryFilterOperation__IsNull } from './filter/DataCubeQueryFilterOperation__IsNull.js';
67
69
  import { DataCubeQueryFilterOperation__IsNotNull } from './filter/DataCubeQueryFilterOperation__IsNotNull.js';
68
- import type { DataCubeQuerySnapshot } from './DataCubeQuerySnapshot.js';
70
+ import { DataCubeQuerySnapshot } from './DataCubeQuerySnapshot.js';
69
71
  import { buildExecutableQuery } from './DataCubeQueryBuilder.js';
70
- import type { DataCubeColumn } from './model/DataCubeColumn.js';
72
+ import { _toCol, type DataCubeColumn } from './model/DataCubeColumn.js';
71
73
  import {
72
74
  type DataCubeSource,
73
75
  INTERNAL__DataCubeSource,
74
76
  } from './model/DataCubeSource.js';
75
- import { _primitiveValue } from './DataCubeQueryBuilderUtils.js';
77
+ import {
78
+ _primitiveValue,
79
+ _selectFunction,
80
+ } from './DataCubeQueryBuilderUtils.js';
76
81
  import {
77
82
  type DocumentationEntry,
78
83
  type LogEvent,
79
84
  type PlainObject,
80
85
  } from '@finos/legend-shared';
81
86
  import type { CachedDataCubeSource } from './model/CachedDataCubeSource.js';
87
+ import { DataCubeQuery } from './model/DataCubeQuery.js';
88
+ import { newConfiguration } from './DataCubeConfigurationBuilder.js';
82
89
 
83
90
  export type CompletionItem = {
84
91
  completion: string;
@@ -94,6 +101,11 @@ export type DataCubeExecutionOptions = {
94
101
  clientVersion?: string | undefined;
95
102
  };
96
103
 
104
+ export type DataCubeCacheInitializationOptions = {
105
+ debug?: boolean | undefined;
106
+ clientVersion?: string | undefined;
107
+ };
108
+
97
109
  export type DataCubeExecutionResult = {
98
110
  result: TDSExecutionResult;
99
111
  executedQuery: string;
@@ -168,6 +180,14 @@ export abstract class DataCubeEngine {
168
180
  return getAggregateOperation(value, this.aggregateOperations);
169
181
  }
170
182
 
183
+ deserializeValueSpecification(json: PlainObject<V1_ValueSpecification>) {
184
+ return V1_deserializeValueSpecification(json, []);
185
+ }
186
+
187
+ serializeValueSpecification(protocol: V1_ValueSpecification) {
188
+ return V1_serializeValueSpecification(protocol, []);
189
+ }
190
+
171
191
  /**
172
192
  * By default, for a function chain, Pure grammar composer will extract the first parameter of the first function
173
193
  * and render it as the caller of that function rather than a parameter
@@ -184,21 +204,34 @@ export abstract class DataCubeEngine {
184
204
  source.query = _primitiveValue(PRIMITIVE_TYPE.STRING, '');
185
205
  return (
186
206
  await this.getValueSpecificationCode(
187
- buildExecutableQuery(
188
- snapshot,
189
- source,
190
- () => undefined,
191
- this.filterOperations,
192
- this.aggregateOperations,
193
- ),
207
+ buildExecutableQuery(snapshot, source, this, {
208
+ skipExecutionContext: true,
209
+ }),
194
210
  pretty,
195
211
  )
196
212
  ).substring(`''->`.length);
197
213
  }
198
214
 
215
+ async generateBaseQuery(sourceData: PlainObject) {
216
+ const source = await this.processQuerySource(sourceData);
217
+ const query = new DataCubeQuery();
218
+ query.source = sourceData;
219
+ query.query = await this.getValueSpecificationCode(
220
+ _selectFunction(source.columns),
221
+ );
222
+ const snapshot = DataCubeQuerySnapshot.create({});
223
+ snapshot.data.sourceColumns = source.columns.map(_toCol);
224
+ snapshot.data.selectColumns = source.columns.map(_toCol);
225
+ const configuration = newConfiguration({
226
+ snapshot,
227
+ });
228
+ query.configuration = configuration;
229
+ return query;
230
+ }
231
+
199
232
  // ---------------------------------- PROCESSOR ----------------------------------
200
233
 
201
- abstract processQuerySource(value: PlainObject): Promise<DataCubeSource>;
234
+ abstract processQuerySource(sourceData: PlainObject): Promise<DataCubeSource>;
202
235
 
203
236
  abstract parseValueSpecification(
204
237
  code: string,
@@ -237,22 +270,16 @@ export abstract class DataCubeEngine {
237
270
  source: DataCubeSource,
238
271
  ): V1_AppliedFunction | undefined;
239
272
 
240
- processInitialSnapshot?(
241
- source: DataCubeSource,
242
- snapshot: DataCubeQuerySnapshot,
243
- ): DataCubeQuerySnapshot;
244
-
245
- // ---------------------------------- CACHING --------------------------------------
273
+ // ---------------------------------- CACHING ----------------------------------
246
274
 
247
275
  async initializeCache(
248
276
  source: DataCubeSource,
277
+ options?: DataCubeCacheInitializationOptions | undefined,
249
278
  ): Promise<CachedDataCubeSource | undefined> {
250
279
  return undefined;
251
280
  }
252
281
 
253
- async clearCache() {
254
- // do nothing
255
- }
282
+ async disposeCache(source: CachedDataCubeSource) {}
256
283
 
257
284
  // ---------------------------------- APPLICATION ----------------------------------
258
285
 
@@ -21,22 +21,24 @@
21
21
  * the query snapshot. The executable query is then used to fetch data.
22
22
  ***************************************************************************************/
23
23
 
24
- import { PRIMITIVE_TYPE, type V1_AppliedFunction } from '@finos/legend-graph';
24
+ import {
25
+ PRIMITIVE_TYPE,
26
+ V1_Lambda,
27
+ type V1_AppliedFunction,
28
+ } from '@finos/legend-graph';
25
29
  import { type DataCubeQuerySnapshot } from './DataCubeQuerySnapshot.js';
26
- import { at } from '@finos/legend-shared';
30
+ import { at, guaranteeType } from '@finos/legend-shared';
27
31
  import {
28
32
  DataCubeFunction,
29
33
  DataCubeQuerySortDirection,
30
34
  type DataCubeQueryFunctionMap,
31
35
  } from './DataCubeQueryEngine.js';
32
36
  import { DataCubeConfiguration } from './model/DataCubeConfiguration.js';
33
- import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js';
34
37
  import {
35
38
  _col,
36
39
  _collection,
37
40
  _cols,
38
41
  _colSpec,
39
- _deserializeLambda,
40
42
  _filter,
41
43
  _function,
42
44
  _groupByAggCols,
@@ -48,26 +50,21 @@ import {
48
50
  _functionCompositionProcessor,
49
51
  _extendRootAggregation,
50
52
  } from './DataCubeQueryBuilderUtils.js';
51
- import type { DataCubeQueryAggregateOperation } from './aggregation/DataCubeQueryAggregateOperation.js';
52
53
  import type { DataCubeSource } from './model/DataCubeSource.js';
53
54
  import { _findCol } from './model/DataCubeColumn.js';
55
+ import type { DataCubeEngine } from './DataCubeEngine.js';
54
56
 
55
57
  export function buildExecutableQuery(
56
58
  snapshot: DataCubeQuerySnapshot,
57
59
  source: DataCubeSource,
58
- executionContextBuilder: (
59
- source: DataCubeSource,
60
- ) => V1_AppliedFunction | undefined,
61
- filterOperations: DataCubeQueryFilterOperation[],
62
- aggregateOperations: DataCubeQueryAggregateOperation[],
60
+ engine: DataCubeEngine,
63
61
  options?: {
64
62
  postProcessor?: (
65
63
  snapshot: DataCubeQuerySnapshot,
66
64
  sequence: V1_AppliedFunction[],
67
65
  funcMap: DataCubeQueryFunctionMap,
68
66
  configuration: DataCubeConfiguration,
69
- filterOperations: DataCubeQueryFilterOperation[],
70
- aggregateOperations: DataCubeQueryAggregateOperation[],
67
+ engine: DataCubeEngine,
71
68
  ) => void;
72
69
  rootAggregation?:
73
70
  | {
@@ -101,8 +98,16 @@ export function buildExecutableQuery(
101
98
  _cols([
102
99
  _colSpec(
103
100
  col.name,
104
- _deserializeLambda(col.mapFn),
105
- col.reduceFn ? _deserializeLambda(col.reduceFn) : undefined,
101
+ guaranteeType(
102
+ engine.deserializeValueSpecification(col.mapFn),
103
+ V1_Lambda,
104
+ ),
105
+ col.reduceFn
106
+ ? guaranteeType(
107
+ engine.deserializeValueSpecification(col.reduceFn),
108
+ V1_Lambda,
109
+ )
110
+ : undefined,
106
111
  ),
107
112
  ]),
108
113
  ]),
@@ -116,7 +121,7 @@ export function buildExecutableQuery(
116
121
  _process(
117
122
  'filter',
118
123
  _function(DataCubeFunction.FILTER, [
119
- _lambda([_var()], [_filter(data.filter, filterOperations)]),
124
+ _lambda([_var()], [_filter(data.filter, engine.filterOperations)]),
120
125
  ]),
121
126
  );
122
127
  }
@@ -164,7 +169,7 @@ export function buildExecutableQuery(
164
169
  pivot.columns,
165
170
  snapshot,
166
171
  configuration,
167
- aggregateOperations,
172
+ engine.aggregateOperations,
168
173
  ),
169
174
  ),
170
175
  ]),
@@ -194,7 +199,7 @@ export function buildExecutableQuery(
194
199
  groupBy.columns,
195
200
  snapshot,
196
201
  configuration,
197
- aggregateOperations,
202
+ engine.aggregateOperations,
198
203
  ),
199
204
  ),
200
205
  ]),
@@ -227,8 +232,16 @@ export function buildExecutableQuery(
227
232
  _cols([
228
233
  _colSpec(
229
234
  col.name,
230
- _deserializeLambda(col.mapFn),
231
- col.reduceFn ? _deserializeLambda(col.reduceFn) : undefined,
235
+ guaranteeType(
236
+ engine.deserializeValueSpecification(col.mapFn),
237
+ V1_Lambda,
238
+ ),
239
+ col.reduceFn
240
+ ? guaranteeType(
241
+ engine.deserializeValueSpecification(col.reduceFn),
242
+ V1_Lambda,
243
+ )
244
+ : undefined,
232
245
  ),
233
246
  ]),
234
247
  ]),
@@ -280,19 +293,14 @@ export function buildExecutableQuery(
280
293
 
281
294
  // --------------------------------- FINALIZE ---------------------------------
282
295
 
283
- const executionContext = executionContextBuilder(source);
284
- if (executionContext) {
285
- sequence.push(executionContext);
296
+ if (!options?.skipExecutionContext) {
297
+ const executionContext = engine.buildExecutionContext(source);
298
+ if (executionContext) {
299
+ sequence.push(executionContext);
300
+ }
286
301
  }
287
302
 
288
- options?.postProcessor?.(
289
- snapshot,
290
- sequence,
291
- funcMap,
292
- configuration,
293
- filterOperations,
294
- aggregateOperations,
295
- );
303
+ options?.postProcessor?.(snapshot, sequence, funcMap, configuration, engine);
296
304
 
297
305
  if (sequence.length === 0) {
298
306
  return source.query;
@@ -43,7 +43,6 @@ import {
43
43
  V1_PackageableElementPtr,
44
44
  type V1_PrimitiveValueSpecification,
45
45
  V1_Variable,
46
- V1_deserializeValueSpecification,
47
46
  extractElementNameFromPath,
48
47
  type V1_ValueSpecification,
49
48
  extractPackagePathFromPath,
@@ -53,7 +52,6 @@ import {
53
52
  V1_createGenericTypeWithRawType,
54
53
  V1_createRelationType,
55
54
  V1_createRelationTypeColumn,
56
- V1_serializeValueSpecification,
57
55
  } from '@finos/legend-graph';
58
56
  import {
59
57
  type DataCubeQuerySnapshotFilterCondition,
@@ -67,8 +65,6 @@ import {
67
65
  guaranteeIsBoolean,
68
66
  guaranteeIsNumber,
69
67
  UnsupportedOperationError,
70
- guaranteeType,
71
- type PlainObject,
72
68
  } from '@finos/legend-shared';
73
69
  import {
74
70
  DataCubeFunction,
@@ -91,69 +87,6 @@ import {
91
87
 
92
88
  // --------------------------------- UTILITIES ---------------------------------
93
89
 
94
- export function _functionCompositionProcessor(
95
- sequence: V1_AppliedFunction[],
96
- funcMap: DataCubeQueryFunctionMap,
97
- ) {
98
- return (
99
- key: keyof DataCubeQueryFunctionMap,
100
- data: V1_AppliedFunction | V1_AppliedFunction[],
101
- ) => {
102
- switch (key) {
103
- case 'leafExtend':
104
- case 'groupExtend': {
105
- if (Array.isArray(data)) {
106
- data.forEach((func) => sequence.push(func));
107
- funcMap[key] = data;
108
- }
109
- break;
110
- }
111
- default: {
112
- funcMap[key] = data as V1_AppliedFunction;
113
- sequence.push(data as V1_AppliedFunction);
114
- }
115
- }
116
- };
117
- }
118
-
119
- export function _functionCompositionUnProcessor(
120
- sequence: V1_AppliedFunction[],
121
- funcMap: DataCubeQueryFunctionMap,
122
- ) {
123
- return (key: keyof DataCubeQueryFunctionMap) => {
124
- const data = funcMap[key];
125
- if (data) {
126
- if (Array.isArray(data)) {
127
- data.forEach((func) => sequence.splice(sequence.indexOf(func), 1));
128
- } else {
129
- sequence.splice(sequence.indexOf(data), 1);
130
- }
131
- funcMap[key] = undefined;
132
- }
133
- };
134
- }
135
-
136
- export function _deserializeLambda(json: PlainObject<V1_Lambda>) {
137
- return guaranteeType(V1_deserializeValueSpecification(json, []), V1_Lambda);
138
- }
139
-
140
- export function _deserializeValueSpecification(
141
- json: PlainObject<V1_ValueSpecification>,
142
- ) {
143
- return V1_deserializeValueSpecification(json, []);
144
- }
145
-
146
- export function _serializeValueSpecification(protocol: V1_ValueSpecification) {
147
- return V1_serializeValueSpecification(protocol, []);
148
- }
149
-
150
- export function _deserializeFunction(json: PlainObject<V1_Lambda>) {
151
- return guaranteeType(
152
- V1_deserializeValueSpecification(json, []),
153
- V1_AppliedFunction,
154
- );
155
- }
156
-
157
90
  export function _var() {
158
91
  const variable = new V1_Variable();
159
92
  // NOTE: we simplify processing logic by forcing all variable names to default value, i.e. x
@@ -356,6 +289,48 @@ export function _cols(colSpecs: V1_ColSpec[]) {
356
289
 
357
290
  // --------------------------------- BUILDING BLOCKS ---------------------------------
358
291
 
292
+ export function _functionCompositionProcessor(
293
+ sequence: V1_AppliedFunction[],
294
+ funcMap: DataCubeQueryFunctionMap,
295
+ ) {
296
+ return (
297
+ key: keyof DataCubeQueryFunctionMap,
298
+ data: V1_AppliedFunction | V1_AppliedFunction[],
299
+ ) => {
300
+ switch (key) {
301
+ case 'leafExtend':
302
+ case 'groupExtend': {
303
+ if (Array.isArray(data)) {
304
+ data.forEach((func) => sequence.push(func));
305
+ funcMap[key] = data;
306
+ }
307
+ break;
308
+ }
309
+ default: {
310
+ funcMap[key] = data as V1_AppliedFunction;
311
+ sequence.push(data as V1_AppliedFunction);
312
+ }
313
+ }
314
+ };
315
+ }
316
+
317
+ export function _functionCompositionUnProcessor(
318
+ sequence: V1_AppliedFunction[],
319
+ funcMap: DataCubeQueryFunctionMap,
320
+ ) {
321
+ return (key: keyof DataCubeQueryFunctionMap) => {
322
+ const data = funcMap[key];
323
+ if (data) {
324
+ if (Array.isArray(data)) {
325
+ data.forEach((func) => sequence.splice(sequence.indexOf(func), 1));
326
+ } else {
327
+ sequence.splice(sequence.indexOf(data), 1);
328
+ }
329
+ funcMap[key] = undefined;
330
+ }
331
+ };
332
+ }
333
+
359
334
  export function _selectFunction(columns: DataCubeColumn[]) {
360
335
  return _function(DataCubeFunction.SELECT, [
361
336
  _cols(columns.map((col) => _colSpec(col.name))),
@@ -71,10 +71,10 @@ export type DataCubeQuerySnapshotPivot = {
71
71
 
72
72
  export type DataCubeQuerySnapshotProcessingContext = {
73
73
  snapshot: DataCubeQuerySnapshot;
74
- pivotAggColumns: DataCubeQuerySnapshotAggregateColumn[];
75
- pivotSortColumns: DataCubeQuerySnapshotSortColumn[];
76
- groupByAggColumns: DataCubeQuerySnapshotAggregateColumn[];
77
- groupBySortColumns: DataCubeQuerySnapshotSortColumn[];
74
+ pivotAggColumns?: DataCubeQuerySnapshotAggregateColumn[] | undefined;
75
+ pivotSortColumns?: DataCubeQuerySnapshotSortColumn[] | undefined;
76
+ groupByAggColumns?: DataCubeQuerySnapshotAggregateColumn[] | undefined;
77
+ groupBySortColumns?: DataCubeQuerySnapshotSortColumn[] | undefined;
78
78
  };
79
79
 
80
80
  export type DataCubeQuerySnapshotData = {
@@ -185,4 +185,15 @@ export class DataCubeQuerySnapshot {
185
185
  clone._hashCode = this._hashCode;
186
186
  return clone;
187
187
  }
188
+
189
+ serialize() {
190
+ const clone = this.clone();
191
+ return {
192
+ uuid: clone.uuid,
193
+ data: clone.data,
194
+ _isPatchChange: clone._isPatchChange,
195
+ _finalized: clone._finalized,
196
+ _hashCode: clone._hashCode,
197
+ };
198
+ }
188
199
  }
@@ -73,10 +73,6 @@ import {
73
73
  } from './DataCubeQuerySnapshotBuilderUtils.js';
74
74
  import type { DataCubeSource } from './model/DataCubeSource.js';
75
75
  import type { DataCubeEngine } from './DataCubeEngine.js';
76
- import {
77
- _deserializeValueSpecification,
78
- _serializeValueSpecification,
79
- } from './DataCubeQueryBuilderUtils.js';
80
76
 
81
77
  // --------------------------------- BUILDING BLOCKS ---------------------------------
82
78
 
@@ -365,8 +361,8 @@ export async function validateAndBuildQuerySnapshot(
365
361
  // analysis more ergonomic
366
362
 
367
363
  // Clone the query since we will mutate it during the process
368
- const query = _deserializeValueSpecification(
369
- _serializeValueSpecification(partialQuery),
364
+ const query = engine.deserializeValueSpecification(
365
+ engine.serializeValueSpecification(partialQuery),
370
366
  );
371
367
  const funcMap = extractFunctionMap(query);
372
368
  const snapshot = DataCubeQuerySnapshot.create({});
@@ -79,7 +79,6 @@ import {
79
79
  _colSpec,
80
80
  _function,
81
81
  _lambda,
82
- _serializeValueSpecification,
83
82
  _synthesizeMinimalSourceQuery,
84
83
  } from './DataCubeQueryBuilderUtils.js';
85
84
  import { INTERNAL__DataCubeSource } from './model/DataCubeSource.js';
@@ -360,14 +359,14 @@ export async function _extractExtendedColumns(
360
359
  _findCol(columns, colSpec.name),
361
360
  `Can't process extend() expression: failed to retrieve type information for column '${colSpec.name}'`,
362
361
  ).type,
363
- mapFn: _serializeValueSpecification(
362
+ mapFn: engine.serializeValueSpecification(
364
363
  guaranteeNonNullable(
365
364
  colSpec.function1,
366
365
  `Can't process extend() expression: expected a transformation function expression for column '${colSpec.name}'`,
367
366
  ),
368
367
  ),
369
368
  reduceFn: colSpec.function2
370
- ? _serializeValueSpecification(colSpec.function2)
369
+ ? engine.serializeValueSpecification(colSpec.function2)
371
370
  : undefined,
372
371
  }));
373
372
  }
@@ -22,4 +22,8 @@ export const CACHED_DATA_CUBE_SOURCE_TYPE = 'cached';
22
22
  export class CachedDataCubeSource extends DataCubeSource {
23
23
  model!: V1_PureModelContextData;
24
24
  runtime!: string;
25
+ db!: string;
26
+ schema!: string;
27
+ table!: string;
28
+ count!: number;
25
29
  }
@@ -88,8 +88,8 @@ export abstract class DataCubeQuerySnapshotController
88
88
  this._engine.debugProcess(
89
89
  `New Snapshot`,
90
90
  ['Publisher', this.getSnapshotSubscriberName()],
91
- ['Snapshot', snapshot],
92
- ['Previous Snapshot', previousSnapshot],
91
+ ['Snapshot', snapshot.serialize()],
92
+ ['Previous Snapshot', previousSnapshot?.serialize()],
93
93
  ['Diff', deepDiff(previousSnapshot ?? {}, snapshot)],
94
94
  );
95
95
  }
@@ -161,6 +161,14 @@ export class DataCubeSettingService {
161
161
  action: (api) => api.reload(),
162
162
  defaultValue: undefined,
163
163
  } satisfies DataCubeSetting,
164
+ {
165
+ key: DataCubeSettingKey.GRID_CLIENT__SHOW_CACHE_PERFORMANCE_WARNING,
166
+ title: `Caching Performance Warning: Enabled`,
167
+ description: `Alerts user of potential performance and resource-related issues that caching can cause when enabled.`,
168
+ group: DataCubeSettingGroup.GRID,
169
+ type: DataCubeSettingType.BOOLEAN,
170
+ defaultValue: true,
171
+ } satisfies DataCubeSetting<boolean>,
164
172
  {
165
173
  key: DataCubeSettingKey.GRID_CLIENT__SUPPRESS_LARGE_DATASET_WARNING,
166
174
  title: `Large Dataset Warning: Disabled`,
@@ -19,14 +19,16 @@ import { action, computed, makeObservable, observable } from 'mobx';
19
19
 
20
20
  export class Task {
21
21
  readonly uuid = uuid();
22
- readonly name: string;
22
+ readonly description: string;
23
+ // use Date.now() vs. performance.now() because need to record the moment
24
+ // the task starts/ends for logging purposes.
23
25
  readonly startTime = Date.now();
24
26
  readonly ownerId?: string | undefined;
25
27
 
26
28
  endTime?: number | undefined;
27
29
 
28
- constructor(name: string, ownerId?: string | undefined) {
29
- this.name = name;
30
+ constructor(description: string, ownerId?: string | undefined) {
31
+ this.description = description;
30
32
  this.ownerId = ownerId;
31
33
  }
32
34
 
@@ -48,8 +50,8 @@ export class TaskManager {
48
50
  });
49
51
  }
50
52
 
51
- newTask(name: string, ownerId?: string | undefined) {
52
- const task = new Task(name, ownerId);
53
+ newTask(description: string, ownerId?: string | undefined) {
54
+ const task = new Task(description, ownerId);
53
55
  this.tasks.push(task);
54
56
  return task;
55
57
  }
@@ -87,8 +89,8 @@ export class DataCubeTaskService {
87
89
  return this.manager.tasks.filter((task) => task.ownerId === this.uuid);
88
90
  }
89
91
 
90
- newTask(name: string) {
91
- return this.manager.newTask(name, this.uuid);
92
+ newTask(description: string) {
93
+ return this.manager.newTask(description, this.uuid);
92
94
  }
93
95
 
94
96
  endTask(task: Task) {