@finos/legend-query-builder 4.15.3 → 4.15.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +3 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +4 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  6. package/lib/components/QueryBuilderSideBar.js +1 -1
  7. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  8. package/lib/components/data-cube/QueryBuilderDataCube.d.ts.map +1 -1
  9. package/lib/components/data-cube/QueryBuilderDataCube.js +4 -6
  10. package/lib/components/data-cube/QueryBuilderDataCube.js.map +1 -1
  11. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
  12. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +38 -33
  13. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  15. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +12 -5
  16. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  17. package/lib/index.css +16 -0
  18. package/lib/index.d.ts +1 -2
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +0 -1
  21. package/lib/index.js.map +1 -1
  22. package/lib/package.json +1 -1
  23. package/lib/stores/QueryBuilderState.d.ts +6 -1
  24. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  25. package/lib/stores/QueryBuilderState.js +3 -0
  26. package/lib/stores/QueryBuilderState.js.map +1 -1
  27. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.d.ts +12 -21
  28. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.d.ts.map +1 -1
  29. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js +39 -57
  30. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js.map +1 -1
  31. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts +17 -6
  32. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts.map +1 -1
  33. package/lib/stores/explorer/QueryFunctionsExplorerState.js +142 -59
  34. package/lib/stores/explorer/QueryFunctionsExplorerState.js.map +1 -1
  35. package/package.json +8 -8
  36. package/src/__lib__/QueryBuilderTesting.ts +5 -0
  37. package/src/components/QueryBuilderSideBar.tsx +4 -1
  38. package/src/components/data-cube/QueryBuilderDataCube.tsx +5 -17
  39. package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +63 -70
  40. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +23 -11
  41. package/src/index.ts +1 -1
  42. package/src/stores/QueryBuilderState.ts +12 -0
  43. package/src/stores/data-cube/QueryBuilderDataCubeEngine.ts +66 -86
  44. package/src/stores/explorer/QueryFunctionsExplorerState.ts +227 -94
  45. package/tsconfig.json +0 -1
  46. package/lib/stores/data-cube/QueryBuilderDataCubeApplicationEngine.d.ts +0 -36
  47. package/lib/stores/data-cube/QueryBuilderDataCubeApplicationEngine.d.ts.map +0 -1
  48. package/lib/stores/data-cube/QueryBuilderDataCubeApplicationEngine.js +0 -65
  49. package/lib/stores/data-cube/QueryBuilderDataCubeApplicationEngine.js.map +0 -1
  50. package/src/stores/data-cube/QueryBuilderDataCubeApplicationEngine.ts +0 -98
@@ -44,16 +44,14 @@ import {
44
44
  import {
45
45
  type QueryBuilderFunctionsExplorerTreeNodeData,
46
46
  type QueryBuilderFunctionsExplorerDragSource,
47
- generateFunctionsExplorerTreeNodeData,
48
47
  getFunctionsExplorerTreeNodeChildren,
49
48
  QUERY_BUILDER_FUNCTION_DND_TYPE,
49
+ generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo,
50
50
  } from '../../stores/explorer/QueryFunctionsExplorerState.js';
51
51
  import { useDrag } from 'react-dnd';
52
52
  import {
53
- ConcreteFunctionDefinition,
54
- generateFunctionPrettyName,
53
+ type FunctionAnalysisInfo,
55
54
  getElementRootPackage,
56
- Package,
57
55
  ROOT_PACKAGE_NAME,
58
56
  getMultiplicityDescription,
59
57
  CORE_PURE_PATH,
@@ -61,20 +59,22 @@ import {
61
59
  } from '@finos/legend-graph';
62
60
  import type { QueryBuilderState } from '../../stores/QueryBuilderState.js';
63
61
  import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
62
+ import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
64
63
 
65
64
  const isDependencyTreeNode = (
66
65
  node: QueryBuilderFunctionsExplorerTreeNodeData,
67
66
  ): boolean =>
68
- getElementRootPackage(node.packageableElement).name ===
69
- ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT;
67
+ node.package !== undefined &&
68
+ getElementRootPackage(node.package).name ===
69
+ ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT;
70
70
 
71
71
  const QueryBuilderFunctionInfoTooltip: React.FC<{
72
- element: ConcreteFunctionDefinition;
73
72
  children: React.ReactElement;
74
73
  placement?: TooltipPlacement | undefined;
74
+ functionInfo: FunctionAnalysisInfo;
75
75
  }> = (props) => {
76
- const { element, children, placement } = props;
77
- const documentation = element.taggedValues
76
+ const { children, placement, functionInfo } = props;
77
+ const documentation = functionInfo.taggedValues
78
78
  .filter(
79
79
  (taggedValue) =>
80
80
  taggedValue.tag.ownerReference.value.path ===
@@ -83,6 +83,23 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
83
83
  )
84
84
  .map((taggedValue) => taggedValue.value);
85
85
 
86
+ const generateParameterCallString = (): string => {
87
+ if (
88
+ functionInfo.parameterInfoList.length &&
89
+ functionInfo.parameterInfoList.length > 0
90
+ ) {
91
+ return functionInfo.parameterInfoList
92
+ .map(
93
+ (param) =>
94
+ `${param.name}: ${
95
+ param.type
96
+ }${getMultiplicityDescription(param.multiplicity)}`,
97
+ )
98
+ .join('; ');
99
+ }
100
+ return '';
101
+ };
102
+
86
103
  return (
87
104
  <Tooltip
88
105
  arrow={true}
@@ -102,7 +119,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
102
119
  Function Name
103
120
  </div>
104
121
  <div className="query-builder__tooltip__item__value">
105
- {element.path}
122
+ {functionInfo.functionPath}
106
123
  </div>
107
124
  </div>
108
125
  <div className="query-builder__tooltip__item">
@@ -110,14 +127,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
110
127
  Parameters
111
128
  </div>
112
129
  <div className="query-builder__tooltip__item__value">
113
- {element.parameters
114
- .map(
115
- (param) =>
116
- `${param.name}: ${
117
- param.type.value.name
118
- }${getMultiplicityDescription(param.multiplicity)}`,
119
- )
120
- .join('; ')}
130
+ {generateParameterCallString()}
121
131
  </div>
122
132
  </div>
123
133
  {Boolean(documentation.length) && (
@@ -135,7 +145,7 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
135
145
  Return Type
136
146
  </div>
137
147
  <div className="query-builder__tooltip__item__value">
138
- {element.returnType.value.name}
148
+ {functionInfo.returnType}
139
149
  </div>
140
150
  </div>
141
151
  </div>
@@ -147,20 +157,10 @@ const QueryBuilderFunctionInfoTooltip: React.FC<{
147
157
  };
148
158
 
149
159
  const QueryBuilderFunctionsExplorerListEntry = observer(
150
- (props: {
151
- queryBuilderState: QueryBuilderState;
152
- element: ConcreteFunctionDefinition;
153
- rootPackageName: ROOT_PACKAGE_NAME;
154
- }) => {
155
- const { queryBuilderState, element, rootPackageName } = props;
156
- const node = generateFunctionsExplorerTreeNodeData(
157
- queryBuilderState,
158
- element,
159
- rootPackageName,
160
- );
161
- const functionPrettyName = generateFunctionPrettyName(element, {
162
- fullPath: true,
163
- });
160
+ (props: { element: FunctionAnalysisInfo }) => {
161
+ const { element } = props;
162
+ const node =
163
+ generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo(element);
164
164
  const [, dragConnector, dragPreviewConnector] = useDrag(
165
165
  () => ({
166
166
  type: QUERY_BUILDER_FUNCTION_DND_TYPE,
@@ -183,15 +183,13 @@ const QueryBuilderFunctionsExplorerListEntry = observer(
183
183
  </div>
184
184
  <div
185
185
  className="query-builder__functions-explorer__function__label"
186
- title={functionPrettyName}
186
+ title={element.functionPrettyName}
187
187
  >
188
- {functionPrettyName}
188
+ {element.functionPrettyName}
189
189
  </div>
190
190
  </div>
191
191
  <div className="query-builder__functions-explorer__function__actions">
192
- <QueryBuilderFunctionInfoTooltip
193
- element={node.packageableElement as ConcreteFunctionDefinition}
194
- >
192
+ <QueryBuilderFunctionInfoTooltip functionInfo={element}>
195
193
  <div className="query-builder__functions-explorer__function__action query-builder__functions-explorer__function__node__info">
196
194
  <InfoCircleIcon />
197
195
  </div>
@@ -212,11 +210,11 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
212
210
  >,
213
211
  ) => {
214
212
  const { node, level, stepPaddingInRem, onNodeSelect } = props;
215
- const isPackage = node.packageableElement instanceof Package;
216
- const name =
217
- node.packageableElement instanceof ConcreteFunctionDefinition
218
- ? generateFunctionPrettyName(node.packageableElement)
219
- : node.packageableElement.name;
213
+ const name = node.functionAnalysisInfo
214
+ ? node.functionAnalysisInfo.functionPrettyName.split(
215
+ `${node.functionAnalysisInfo.packagePath}::`,
216
+ )[1]
217
+ : (node.package?.name ?? '');
220
218
  const isExpandable = Boolean(node.childrenIds.length);
221
219
  const nodeExpandIcon = isExpandable ? (
222
220
  node.isOpen ? (
@@ -231,7 +229,7 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
231
229
  const iconPackageColor = isDependencyTreeNode(node)
232
230
  ? 'color--dependency'
233
231
  : '';
234
- const nodeTypeIcon = isPackage ? (
232
+ const nodeTypeIcon = node.package ? (
235
233
  node.isOpen ? (
236
234
  <FolderOpenIcon className={iconPackageColor} />
237
235
  ) : (
@@ -248,10 +246,7 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
248
246
  }>(
249
247
  () => ({
250
248
  type: QUERY_BUILDER_FUNCTION_DND_TYPE,
251
- item: () =>
252
- node.packageableElement instanceof ConcreteFunctionDefinition
253
- ? { node }
254
- : {},
249
+ item: () => (node.functionAnalysisInfo ? { node } : {}),
255
250
  }),
256
251
  [node],
257
252
  );
@@ -289,10 +284,9 @@ const QueryBuilderFunctionsExplorerTreeNodeContainer = observer(
289
284
  {name}
290
285
  </div>
291
286
  <div className="query-builder__functions-explorer__tree__node__actions">
292
- {node.packageableElement instanceof
293
- ConcreteFunctionDefinition && (
287
+ {node.functionAnalysisInfo && (
294
288
  <QueryBuilderFunctionInfoTooltip
295
- element={node.packageableElement}
289
+ functionInfo={node.functionAnalysisInfo}
296
290
  >
297
291
  <div className="query-builder__functions-explorer__tree__node__action query-builder__functions-explorer__tree__node__info">
298
292
  <InfoCircleIcon />
@@ -331,6 +325,7 @@ const QueryBuilderPackableElementExplorerTree = observer(
331
325
  const dependencyTreeData = queryFunctionsState.getTreeData(
332
326
  ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT,
333
327
  );
328
+
334
329
  const onDependencyTreeSelect = (
335
330
  node: QueryBuilderFunctionsExplorerTreeNodeData,
336
331
  ): void => {
@@ -431,6 +426,10 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
431
426
  setShowDependencyFuncions(!showDependencyFuncions);
432
427
  };
433
428
 
429
+ useEffect(() => {
430
+ queryFunctionsState.initializeTreeData();
431
+ }, [queryFunctionsState]);
432
+
434
433
  useEffect(() => {
435
434
  QueryBuilderTelemetryHelper.logEvent_RenderPanelFunctionExplorer(
436
435
  queryBuilderState.applicationStore.telemetryService,
@@ -438,7 +437,10 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
438
437
  }, [queryBuilderState.applicationStore]);
439
438
 
440
439
  return (
441
- <div className="panel query-builder__functions-explorer">
440
+ <div
441
+ data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FUNCTIONS}
442
+ className="panel query-builder__functions-explorer"
443
+ >
442
444
  <div className="panel__header">
443
445
  <div className="panel__header__title">
444
446
  <div className="panel__header__title__label">functions</div>
@@ -494,16 +496,13 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
494
496
  labelGetter={(
495
497
  item: QueryBuilderFunctionsExplorerDragSource,
496
498
  ): string =>
497
- generateFunctionPrettyName(
498
- item.node.packageableElement as ConcreteFunctionDefinition,
499
- { fullPath: true },
500
- )
499
+ item.node.functionAnalysisInfo?.functionPrettyName ?? ''
501
500
  }
502
501
  types={[QUERY_BUILDER_FUNCTION_DND_TYPE]}
503
502
  />
504
503
  {((showDependencyFuncions &&
505
- (!queryFunctionsState.dependencyTreeData ||
506
- queryFunctionsState.dependencyTreeData.rootIds.length === 0)) ||
504
+ queryFunctionsState.dependencyFunctionExplorerStates.length ===
505
+ 0) ||
507
506
  !showDependencyFuncions) &&
508
507
  queryFunctionsState.treeData?.rootIds.length === 0 && (
509
508
  <BlankPanelContent>
@@ -521,8 +520,8 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
521
520
  />
522
521
  )}
523
522
  {showDependencyFuncions &&
524
- queryFunctionsState.dependencyTreeData &&
525
- queryFunctionsState.dependencyTreeData.rootIds.length !== 0 && (
523
+ queryFunctionsState.dependencyFunctionExplorerStates.length !==
524
+ 0 && (
526
525
  <QueryBuilderPackableElementExplorerTree
527
526
  queryBuilderState={queryBuilderState}
528
527
  rootPackageName={ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT}
@@ -538,15 +537,13 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
538
537
  (funcExplorerState) => (
539
538
  <QueryBuilderFunctionsExplorerListEntry
540
539
  key={funcExplorerState.uuid}
541
- queryBuilderState={queryBuilderState}
542
- element={funcExplorerState.concreteFunctionDefinition}
543
- rootPackageName={ROOT_PACKAGE_NAME.MAIN}
540
+ element={funcExplorerState.functionAnalysisInfo}
544
541
  />
545
542
  ),
546
543
  )}
547
544
  {showDependencyFuncions &&
548
- queryFunctionsState.dependencyTreeData &&
549
- queryFunctionsState.dependencyTreeData.rootIds.length !== 0 && (
545
+ queryFunctionsState.dependencyFunctionExplorerStates.length >
546
+ 0 && (
550
547
  <>
551
548
  {queryFunctionsState.treeData?.rootIds.length !== 0 && (
552
549
  <div className="query-builder__functions-explorer__separator" />
@@ -555,11 +552,7 @@ export const QueryBuilderFunctionsExplorerPanel = observer(
555
552
  (funcExplorerState) => (
556
553
  <QueryBuilderFunctionsExplorerListEntry
557
554
  key={funcExplorerState.uuid}
558
- queryBuilderState={queryBuilderState}
559
- element={funcExplorerState.concreteFunctionDefinition}
560
- rootPackageName={
561
- ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT
562
- }
555
+ element={funcExplorerState.functionAnalysisInfo}
563
556
  />
564
557
  ),
565
558
  )}
@@ -71,8 +71,7 @@ import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
71
71
  import { flowResult } from 'mobx';
72
72
  import { useApplicationStore } from '@finos/legend-application';
73
73
  import {
74
- type ConcreteFunctionDefinition,
75
- generateFunctionCallString,
74
+ type ValueSpecification,
76
75
  LAMBDA_PIPE,
77
76
  VARIABLE_REFERENCE_TOKEN,
78
77
  AbstractPropertyExpression,
@@ -81,12 +80,12 @@ import {
81
80
  PropertyExplicitReference,
82
81
  VariableExpression,
83
82
  Multiplicity,
84
- type ValueSpecification,
85
83
  PrimitiveType,
86
84
  GenericType,
87
85
  GenericTypeExplicitReference,
88
86
  observe_PrimitiveInstanceValue,
89
87
  PrimitiveInstanceValue,
88
+ generateFunctionCallStringFromFunctionAnalysisInfo,
90
89
  } from '@finos/legend-graph';
91
90
  import {
92
91
  type QueryBuilderFunctionsExplorerDragSource,
@@ -239,13 +238,20 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
239
238
  }`,
240
239
  );
241
240
  } else if (type === QUERY_BUILDER_FUNCTION_DND_TYPE) {
241
+ const functionAnalysisInfo = (
242
+ item as QueryBuilderFunctionsExplorerDragSource
243
+ ).node.functionAnalysisInfo;
244
+ const functionPrettyName = functionAnalysisInfo
245
+ ? generateFunctionCallStringFromFunctionAnalysisInfo(
246
+ projectionColumnState.tdsState.queryBuilderState
247
+ .graphManagerState.graph,
248
+ functionAnalysisInfo,
249
+ )
250
+ : '';
242
251
  projectionColumnState.derivationLambdaEditorState.setLambdaString(
243
252
  `${
244
253
  projectionColumnState.derivationLambdaEditorState.lambdaString
245
- }${`${generateFunctionCallString(
246
- (item as QueryBuilderFunctionsExplorerDragSource).node
247
- .packageableElement as ConcreteFunctionDefinition,
248
- )}`}`,
254
+ }${functionPrettyName}`,
249
255
  );
250
256
  } else {
251
257
  projectionColumnState.derivationLambdaEditorState.setLambdaString(
@@ -1262,11 +1268,17 @@ export const QueryBuilderTDSPanel = observer(
1262
1268
  { addDummyParameter: true },
1263
1269
  ),
1264
1270
  );
1271
+ const functionAnalysisInfo = (
1272
+ item as QueryBuilderFunctionsExplorerDragSource
1273
+ ).node.functionAnalysisInfo;
1274
+ const functionPrettyName = functionAnalysisInfo
1275
+ ? generateFunctionCallStringFromFunctionAnalysisInfo(
1276
+ tdsState.queryBuilderState.graphManagerState.graph,
1277
+ functionAnalysisInfo,
1278
+ )
1279
+ : '';
1265
1280
  derivationProjectionColumn.derivationLambdaEditorState.setLambdaString(
1266
- `${DEFAULT_LAMBDA_VARIABLE_NAME}${LAMBDA_PIPE}${generateFunctionCallString(
1267
- (item as QueryBuilderFunctionsExplorerDragSource).node
1268
- .packageableElement as ConcreteFunctionDefinition,
1269
- )}`,
1281
+ `${DEFAULT_LAMBDA_VARIABLE_NAME}${LAMBDA_PIPE}${functionPrettyName} `,
1270
1282
  );
1271
1283
  tdsState.addColumn(derivationProjectionColumn);
1272
1284
  break;
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ export { QueryBuilder } from './components/QueryBuilder.js';
34
34
  export { QUERY_BUILDER_COMPONENT_ELEMENT_ID } from './components/QueryBuilderComponentElement.js';
35
35
  export {
36
36
  type QueryableSourceInfo as QuerySDLC,
37
+ type QueryBuilderExtraFunctionAnalysisInfo,
37
38
  QueryBuilderState,
38
39
  QUERY_BUILDER_LAMBDA_WRITER_MODE,
39
40
  INTERNAL__BasicQueryBuilderState,
@@ -126,5 +127,4 @@ export * from './stores/filter/QueryBuilderFilterValueSpecificationBuilder.js';
126
127
  export * from './stores/QueryBuilderValueSpecificationHelper.js';
127
128
  export * from './stores/filter/QueryBuilderFilterState.js';
128
129
  export * from './stores/filter/QueryBuilderFilterStateBuilder.js';
129
- export * from './stores/data-cube/QueryBuilderDataCubeApplicationEngine.js';
130
130
  export * from './stores/data-cube/QueryBuilderDataCubeEngine.js';
@@ -56,6 +56,7 @@ import {
56
56
  type Type,
57
57
  type QueryGridConfig,
58
58
  type QueryExecutionContext,
59
+ type FunctionAnalysisInfo,
59
60
  GRAPH_MANAGER_EVENT,
60
61
  CompilationError,
61
62
  extractSourceInformationCoordinates,
@@ -117,6 +118,11 @@ export type QueryableClassMappingRuntimeInfo = QueryableSourceInfo & {
117
118
  runtime: string;
118
119
  };
119
120
 
121
+ export type QueryBuilderExtraFunctionAnalysisInfo = {
122
+ functionInfoMap: Map<string, FunctionAnalysisInfo>;
123
+ dependencyFunctionInfoMap: Map<string, FunctionAnalysisInfo>;
124
+ };
125
+
120
126
  export enum QUERY_BUILDER_LAMBDA_WRITER_MODE {
121
127
  STANDARD = 'STANDARD',
122
128
  TYPED_FETCH_STRUCTURE = 'TYPED_FETCH_STRUCTURE',
@@ -832,6 +838,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
832
838
  );
833
839
  }
834
840
 
841
+ buildFunctionAnalysisInfo():
842
+ | QueryBuilderExtraFunctionAnalysisInfo
843
+ | undefined {
844
+ return undefined;
845
+ }
846
+
835
847
  /**
836
848
  * This method can be used to simplify the current query builder state
837
849
  * to a basic one that can be used for testing or some special operations,
@@ -33,36 +33,22 @@ import {
33
33
  import {
34
34
  _elementPtr,
35
35
  _functionName,
36
- DataCubeGetBaseQueryResult,
37
36
  DataCubeEngine,
38
- type CompletionItem,
39
- DataCubeQuerySource,
40
- type DataCubeInfrastructureInfo,
37
+ DataCubeSource,
41
38
  type RelationType,
42
39
  DataCubeQuery,
40
+ type DataCubeInitialInput,
41
+ type CompletionItem,
42
+ _function,
43
+ DataCubeFunction,
43
44
  } from '@finos/legend-data-cube';
44
- import { guaranteeType, LogService } from '@finos/legend-shared';
45
+ import { guaranteeType, isNonNullable, LogService } from '@finos/legend-shared';
45
46
 
46
- export class _DataCubeQuery {
47
- name: string;
48
- query: string;
49
- partialQuery: string;
50
- source: DataCubeQuerySource;
51
-
52
- constructor(
53
- name: string,
54
- query: string,
55
- partialQuery: string,
56
- source: DataCubeQuerySource,
57
- ) {
58
- this.name = name;
59
- this.query = query;
60
- this.partialQuery = partialQuery;
61
- this.source = source;
62
- }
47
+ class QueryBuilderDataCubeSource extends DataCubeSource {
48
+ mapping?: string | undefined;
49
+ runtime!: string;
63
50
  }
64
51
 
65
- export class QueryBuilderDataCubeQuerySource extends DataCubeQuerySource {}
66
52
  export class QueryBuilderDataCubeEngine extends DataCubeEngine {
67
53
  readonly logService = new LogService();
68
54
  readonly graphState: GraphManagerState;
@@ -90,12 +76,12 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
90
76
  get sourceLabel(): string {
91
77
  return `Query Builder Report`;
92
78
  }
93
- override getBaseQuery(): Promise<DataCubeGetBaseQueryResult> {
79
+
80
+ override getInitialInput(): Promise<DataCubeInitialInput> {
94
81
  return this.buildBaseQuery();
95
82
  }
96
83
 
97
- async buildBaseQuery(): Promise<DataCubeGetBaseQueryResult> {
98
- const timestamp = Date.now();
84
+ async buildBaseQuery(): Promise<DataCubeInitialInput> {
99
85
  let srcFuncExp = V1_deserializeValueSpecification(
100
86
  this.graphState.graphManager.serializeRawValueSpecification(
101
87
  this.selectInitialQuery,
@@ -121,60 +107,44 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
121
107
  if (this.runtimePath) {
122
108
  fromFuncExp.parameters.push(_elementPtr(this.runtimePath));
123
109
  }
124
- const [relationType, queryString, fromQuerystring] = await Promise.all([
125
- this.getRelationalType(this.selectInitialQuery),
126
- this.graphState.graphManager.valueSpecificationToPureCode(
127
- V1_serializeValueSpecification(srcFuncExp, []),
128
- ),
129
- this.graphState.graphManager.valueSpecificationToPureCode(
130
- V1_serializeValueSpecification(fromFuncExp, []),
131
- ),
132
- ]);
133
- const columns = relationType.columns;
134
- const source = new QueryBuilderDataCubeQuerySource();
135
- source.columns = columns;
110
+ const columns = (await this.getRelationalType(this.selectInitialQuery))
111
+ .columns;
112
+ const query = new DataCubeQuery();
113
+ query.query = `~[${columns.map((e) => `'${e.name}'`)}]->select()`;
114
+ const source = new QueryBuilderDataCubeSource();
115
+ source.sourceColumns = columns;
136
116
  source.mapping = this.mappingPath;
137
117
  source.runtime = this.runtimePath;
138
- source.query = queryString;
139
- const partialQuery = `~[${columns.map((e) => `'${e.name}'`)}]->select()`;
140
- const result = new DataCubeQuery(this.sourceLabel, fromQuerystring);
141
- result.partialQuery = partialQuery;
142
- result.source = source;
143
- const baseQueryResult = new DataCubeGetBaseQueryResult();
144
- baseQueryResult.timestamp = timestamp;
145
- baseQueryResult.query = result;
146
- baseQueryResult.partialQuery = await this.parseQuery(partialQuery);
147
- baseQueryResult.sourceQuery = srcFuncExp;
148
- return baseQueryResult;
118
+ source.query = srcFuncExp;
119
+ return {
120
+ query,
121
+ source,
122
+ };
149
123
  }
150
124
 
151
125
  get graph(): PureModel {
152
126
  return this.graphState.graph;
153
127
  }
154
128
 
155
- private buildRawLambdaFromValueSpec(query: V1_ValueSpecification): RawLambda {
129
+ private buildRawLambdaFromValueSpec(query: V1_Lambda): RawLambda {
156
130
  const json = guaranteeType(
157
131
  V1_deserializeRawValueSpecification(
158
- V1_serializeValueSpecification(query, []),
132
+ V1_serializeValueSpecification(
133
+ query.body[0] as V1_ValueSpecification,
134
+ [],
135
+ ),
159
136
  ),
160
137
  V1_RawLambda,
161
138
  );
162
139
  return new RawLambda(json.parameters, json.body);
163
140
  }
164
141
 
165
- override getInfrastructureInfo(): Promise<DataCubeInfrastructureInfo> {
166
- // we return undefined as we assume the grid license is set at the application level where query builder is built
167
- return Promise.resolve({
168
- gridClientLicense: undefined,
169
- simpleSampleDataTableName: '',
170
- complexSampleDataTableName: '',
171
- });
172
- }
173
- override async getQueryTypeahead(
142
+ async getQueryTypeahead(
174
143
  code: string,
175
- query: V1_ValueSpecification,
176
- ): Promise<CompletionItem[]> {
177
- const lambda = this.buildRawLambdaFromValueSpec(query);
144
+ baseQuery: V1_Lambda,
145
+ source: DataCubeSource,
146
+ ) {
147
+ const lambda = this.buildRawLambdaFromValueSpec(baseQuery);
178
148
  const queryString =
179
149
  await this.graphState.graphManager.lambdaToPureCode(lambda);
180
150
  const offset = queryString.length;
@@ -184,13 +154,13 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
184
154
  this.graph,
185
155
  offset,
186
156
  );
187
- return result.completions;
157
+ return result.completions as CompletionItem[];
188
158
  }
189
159
 
190
- override async parseQuery(
160
+ override async parseValueSpecification(
191
161
  code: string,
192
162
  returnSourceInformation?: boolean,
193
- ): Promise<V1_ValueSpecification> {
163
+ ) {
194
164
  return V1_deserializeValueSpecification(
195
165
  await this.graphState.graphManager.pureCodeToValueSpecification(
196
166
  code,
@@ -200,36 +170,35 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
200
170
  );
201
171
  }
202
172
 
203
- override getQueryCode(
204
- query: V1_ValueSpecification,
173
+ override getValueSpecificationCode(
174
+ value: V1_ValueSpecification,
205
175
  pretty?: boolean | undefined,
206
- ): Promise<string> {
176
+ ) {
207
177
  return this.graphState.graphManager.valueSpecificationToPureCode(
208
- V1_serializeValueSpecification(query, []),
178
+ V1_serializeValueSpecification(value, []),
209
179
  pretty,
210
180
  );
211
181
  }
212
182
 
213
- override getQueryRelationType(
214
- query: V1_ValueSpecification,
215
- ): Promise<RelationType> {
216
- const lambda = this.buildRawLambdaFromValueSpec(query);
217
- return this.getRelationalType(lambda);
218
- }
219
-
220
- async getRelationalType(query: RawLambda): Promise<RelationType> {
221
- const realtion_type =
183
+ private async getRelationalType(query: RawLambda): Promise<RelationType> {
184
+ const relationType =
222
185
  await this.graphState.graphManager.getLambdaRelationType(
223
186
  query,
224
187
  this.graph,
225
188
  );
226
- return realtion_type;
189
+ return relationType;
190
+ }
191
+
192
+ override getQueryRelationType(query: V1_Lambda, source: DataCubeSource) {
193
+ const lambda = this.buildRawLambdaFromValueSpec(query);
194
+ return this.getRelationalType(lambda);
227
195
  }
228
196
 
229
197
  override async getQueryCodeRelationReturnType(
230
198
  code: string,
231
199
  baseQuery: V1_ValueSpecification,
232
- ): Promise<RelationType> {
200
+ source: DataCubeSource,
201
+ ) {
233
202
  const queryString =
234
203
  await this.graphState.graphManager.valueSpecificationToPureCode(
235
204
  V1_serializeValueSpecification(baseQuery, []),
@@ -240,11 +209,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
240
209
  );
241
210
  }
242
211
 
243
- override async executeQuery(query: V1_Lambda): Promise<{
244
- result: TDSExecutionResult;
245
- executedQuery: string;
246
- executedSQL: string;
247
- }> {
212
+ override async executeQuery(query: V1_Lambda, source: DataCubeSource) {
248
213
  const lambda = this.buildRawLambdaFromValueSpec(query);
249
214
  lambda.parameters = this._parameters;
250
215
  const [executionWithMetadata, queryString] = await Promise.all([
@@ -275,4 +240,19 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
275
240
  executedSQL: sqlString,
276
241
  };
277
242
  }
243
+
244
+ override buildExecutionContext(
245
+ source: DataCubeSource,
246
+ ): V1_AppliedFunction | undefined {
247
+ if (source instanceof QueryBuilderDataCubeSource) {
248
+ return _function(
249
+ DataCubeFunction.FROM,
250
+ [
251
+ source.mapping ? _elementPtr(source.mapping) : undefined,
252
+ _elementPtr(source.runtime),
253
+ ].filter(isNonNullable),
254
+ );
255
+ }
256
+ return undefined;
257
+ }
278
258
  }