@finos/legend-application-query 5.0.1 → 5.0.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.
- package/lib/components/QueryBuilderExplorerPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderExplorerPanel.js +3 -1
- package/lib/components/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.js +39 -7
- package/lib/components/QueryBuilderFetchStructurePanel.js.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.js +43 -12
- package/lib/components/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.js +12 -3
- package/lib/components/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertySearchPanel.js +2 -1
- package/lib/components/QueryBuilderPropertySearchPanel.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +11 -7
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +2 -2
- package/lib/stores/QueryBuilderExplorerState.d.ts +1 -1
- package/lib/stores/QueryBuilderExplorerState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderExplorerState.js +13 -3
- package/lib/stores/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/QueryBuilderFilterState.d.ts +7 -1
- package/lib/stores/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderFilterState.js +5 -0
- package/lib/stores/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/QueryBuilderOperatorsHelper.d.ts +1 -0
- package/lib/stores/QueryBuilderOperatorsHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderOperatorsHelper.js +28 -1
- package/lib/stores/QueryBuilderOperatorsHelper.js.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.d.ts +1 -0
- package/lib/stores/QueryBuilderProjectionState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.js +11 -0
- package/lib/stores/QueryBuilderProjectionState.js.map +1 -1
- package/lib/stores/QueryBuilderPropertySearchPanelState.js +1 -1
- package/lib/stores/QueryBuilderPropertySearchPanelState.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +5 -2
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +19 -7
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderState.d.ts +1 -0
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +3 -0
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js +5 -31
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js +5 -31
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js +5 -31
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js +5 -32
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js +5 -31
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js +3 -29
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js +4 -30
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js +4 -30
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
- package/package.json +9 -9
- package/src/components/QueryBuilderExplorerPanel.tsx +3 -1
- package/src/components/QueryBuilderFetchStructurePanel.tsx +44 -7
- package/src/components/QueryBuilderFilterPanel.tsx +70 -17
- package/src/components/QueryBuilderPostFilterPanel.tsx +22 -3
- package/src/components/QueryBuilderPropertySearchPanel.tsx +1 -0
- package/src/components/QueryBuilderResultPanel.tsx +70 -47
- package/src/stores/QueryBuilderExplorerState.ts +17 -3
- package/src/stores/QueryBuilderFilterState.ts +7 -0
- package/src/stores/QueryBuilderOperatorsHelper.ts +35 -0
- package/src/stores/QueryBuilderProjectionState.ts +15 -0
- package/src/stores/QueryBuilderPropertySearchPanelState.ts +1 -1
- package/src/stores/QueryBuilderResultState.ts +27 -9
- package/src/stores/QueryBuilderState.ts +4 -0
- package/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts +6 -35
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts +9 -35
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts +9 -35
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts +9 -36
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts +9 -35
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts +6 -33
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts +11 -36
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts +11 -36
@@ -25,6 +25,7 @@ import {
|
|
25
25
|
CaretDownIcon,
|
26
26
|
ContextMenu,
|
27
27
|
clsx,
|
28
|
+
PauseCircleIcon,
|
28
29
|
} from '@finos/legend-art';
|
29
30
|
import { observer } from 'mobx-react-lite';
|
30
31
|
import { flowResult } from 'mobx';
|
@@ -413,21 +414,25 @@ export const QueryBuilderResultPanel = observer(
|
|
413
414
|
],
|
414
415
|
});
|
415
416
|
};
|
416
|
-
const
|
417
|
+
const runQuery = (): void => {
|
417
418
|
if (queryParametersState.parameterStates.length) {
|
418
419
|
queryParametersState.parameterValuesEditorState.open(
|
419
420
|
(): Promise<void> =>
|
420
|
-
flowResult(resultState.
|
421
|
+
flowResult(resultState.runQuery()).catch(
|
421
422
|
applicationStore.alertUnhandledError,
|
422
423
|
),
|
423
424
|
PARAMETER_SUBMIT_ACTION.EXECUTE,
|
424
425
|
);
|
425
426
|
} else {
|
426
|
-
flowResult(resultState.
|
427
|
+
flowResult(resultState.runQuery()).catch(
|
427
428
|
applicationStore.alertUnhandledError,
|
428
429
|
);
|
429
430
|
}
|
430
431
|
};
|
432
|
+
const cancelQuery = (): void => {
|
433
|
+
resultState.setIsRunningQuery(false);
|
434
|
+
queryBuilderState.resultState.setQueryRunPromise(undefined);
|
435
|
+
};
|
431
436
|
const generatePlan = applicationStore.guardUnhandledError(() =>
|
432
437
|
flowResult(resultState.generatePlan(false)),
|
433
438
|
);
|
@@ -469,52 +474,65 @@ export const QueryBuilderResultPanel = observer(
|
|
469
474
|
type="number"
|
470
475
|
value={resultState.previewLimit}
|
471
476
|
onChange={changeLimit}
|
477
|
+
disabled={!queryBuilderState.isValidQueryBuilderState()}
|
472
478
|
/>
|
473
479
|
</div>
|
474
480
|
)}
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
481
|
+
{resultState.isRunningQuery ? (
|
482
|
+
<button
|
483
|
+
className="query-builder__result__stop-btn"
|
484
|
+
onClick={cancelQuery}
|
485
|
+
tabIndex={-1}
|
486
|
+
disabled={!queryBuilderState.isValidQueryBuilderState()}
|
487
|
+
>
|
488
|
+
<div className="btn--dark btn--caution query-builder__result__stop-btn__label">
|
489
|
+
<PauseCircleIcon className="query-builder__result__stop-btn__label__icon" />
|
490
|
+
<div className="query-builder__result__stop-btn__label__title">
|
491
|
+
Stop
|
492
|
+
</div>
|
487
493
|
</div>
|
488
|
-
</
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
}
|
494
|
-
|
495
|
-
<MenuContent>
|
496
|
-
<MenuContentItem
|
497
|
-
className="query-builder__result__execute-btn__option"
|
498
|
-
onClick={generatePlan}
|
499
|
-
>
|
500
|
-
Generate Plan
|
501
|
-
</MenuContentItem>
|
502
|
-
<MenuContentItem
|
503
|
-
className="query-builder__result__execute-btn__option"
|
504
|
-
onClick={debugPlanGeneration}
|
505
|
-
>
|
506
|
-
Debug
|
507
|
-
</MenuContentItem>
|
508
|
-
</MenuContent>
|
509
|
-
}
|
510
|
-
menuProps={{
|
511
|
-
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
512
|
-
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
513
|
-
}}
|
494
|
+
</button>
|
495
|
+
) : (
|
496
|
+
<button
|
497
|
+
className="query-builder__result__execute-btn"
|
498
|
+
onClick={runQuery}
|
499
|
+
tabIndex={-1}
|
500
|
+
disabled={!queryBuilderState.isValidQueryBuilderState()}
|
514
501
|
>
|
515
|
-
<
|
516
|
-
|
517
|
-
|
502
|
+
<div className="query-builder__result__execute-btn__label">
|
503
|
+
<PlayIcon className="query-builder__result__execute-btn__label__icon" />
|
504
|
+
<div className="query-builder__result__execute-btn__label__title">
|
505
|
+
Run Query
|
506
|
+
</div>
|
507
|
+
</div>
|
508
|
+
<DropdownMenu
|
509
|
+
className="query-builder__result__execute-btn__dropdown-btn"
|
510
|
+
disabled={resultState.isGeneratingPlan}
|
511
|
+
content={
|
512
|
+
<MenuContent>
|
513
|
+
<MenuContentItem
|
514
|
+
className="query-builder__result__execute-btn__option"
|
515
|
+
onClick={generatePlan}
|
516
|
+
>
|
517
|
+
Generate Plan
|
518
|
+
</MenuContentItem>
|
519
|
+
<MenuContentItem
|
520
|
+
className="query-builder__result__execute-btn__option"
|
521
|
+
onClick={debugPlanGeneration}
|
522
|
+
>
|
523
|
+
Debug
|
524
|
+
</MenuContentItem>
|
525
|
+
</MenuContent>
|
526
|
+
}
|
527
|
+
menuProps={{
|
528
|
+
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
529
|
+
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
530
|
+
}}
|
531
|
+
>
|
532
|
+
<CaretDownIcon />
|
533
|
+
</DropdownMenu>
|
534
|
+
</button>
|
535
|
+
)}
|
518
536
|
<DropdownMenu
|
519
537
|
className="query-builder__result__export__dropdown"
|
520
538
|
content={
|
@@ -542,19 +560,24 @@ export const QueryBuilderResultPanel = observer(
|
|
542
560
|
className="query-builder__result__export__dropdown__label"
|
543
561
|
tabIndex={-1}
|
544
562
|
title="Export"
|
563
|
+
disabled={!queryBuilderState.isValidQueryBuilderState()}
|
545
564
|
>
|
546
565
|
Export
|
547
566
|
</button>
|
548
|
-
<
|
567
|
+
<button
|
568
|
+
className="query-builder__result__export__dropdown__trigger"
|
569
|
+
tabIndex={-1}
|
570
|
+
disabled={!queryBuilderState.isValidQueryBuilderState()}
|
571
|
+
>
|
549
572
|
<CaretDownIcon />
|
550
|
-
</
|
573
|
+
</button>
|
551
574
|
</DropdownMenu>
|
552
575
|
</div>
|
553
576
|
</div>
|
554
577
|
<div className="panel__content">
|
555
578
|
<PanelLoadingIndicator
|
556
579
|
isLoading={
|
557
|
-
resultState.
|
580
|
+
resultState.isRunningQuery ||
|
558
581
|
resultState.isGeneratingPlan ||
|
559
582
|
resultState.exportDataState.isInProgress
|
560
583
|
}
|
@@ -50,6 +50,8 @@ import {
|
|
50
50
|
EntityMappedProperty,
|
51
51
|
Enumeration,
|
52
52
|
DerivedProperty,
|
53
|
+
Property,
|
54
|
+
Association,
|
53
55
|
} from '@finos/legend-graph';
|
54
56
|
import type { QueryBuilderState } from './QueryBuilderState.js';
|
55
57
|
import {
|
@@ -342,7 +344,7 @@ export const getQueryBuilderPropertyNodeData = (
|
|
342
344
|
property: AbstractProperty,
|
343
345
|
parentNode: QueryBuilderExplorerTreeNodeData,
|
344
346
|
modelCoverageAnalysisResult: MappingModelCoverageAnalysisResult,
|
345
|
-
): QueryBuilderExplorerTreePropertyNodeData => {
|
347
|
+
): QueryBuilderExplorerTreePropertyNodeData | undefined => {
|
346
348
|
const mappingNodeData = generatePropertyNodeMappingData(
|
347
349
|
property,
|
348
350
|
parentNode.mappingData,
|
@@ -353,6 +355,16 @@ export const getQueryBuilderPropertyNodeData = (
|
|
353
355
|
parentNode.isPartOfDerivedPropertyBranch ||
|
354
356
|
(parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
355
357
|
parentNode.property instanceof DerivedProperty);
|
358
|
+
if (
|
359
|
+
property instanceof Property &&
|
360
|
+
parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
361
|
+
parentNode.property instanceof Property &&
|
362
|
+
property._OWNER instanceof Association &&
|
363
|
+
parentNode.property._OWNER instanceof Association &&
|
364
|
+
parentNode.property._OWNER === property._OWNER
|
365
|
+
) {
|
366
|
+
return undefined;
|
367
|
+
}
|
356
368
|
const propertyNode = new QueryBuilderExplorerTreePropertyNodeData(
|
357
369
|
`${
|
358
370
|
parentNode instanceof QueryBuilderExplorerTreeRootNodeData
|
@@ -455,8 +467,10 @@ const getQueryBuilderTreeData = (
|
|
455
467
|
treeRootNode,
|
456
468
|
modelCoverageAnalysisResult,
|
457
469
|
);
|
458
|
-
|
459
|
-
|
470
|
+
if (propertyTreeNodeData) {
|
471
|
+
addUniqueEntry(treeRootNode.childrenIds, propertyTreeNodeData.id);
|
472
|
+
nodes.set(propertyTreeNodeData.id, propertyTreeNodeData);
|
473
|
+
}
|
460
474
|
});
|
461
475
|
rootClass._subclasses.forEach((subclass) => {
|
462
476
|
const subTypeTreeNodeData = getQueryBuilderSubTypeNodeData(
|
@@ -55,6 +55,7 @@ import {
|
|
55
55
|
fromGroupOperation,
|
56
56
|
QUERY_BUILDER_GROUP_OPERATION,
|
57
57
|
} from './QueryBuilderOperatorsHelper.js';
|
58
|
+
import type { QueryBuilderProjectionColumnDragSource } from './QueryBuilderProjectionState.js';
|
58
59
|
|
59
60
|
export abstract class QueryBuilderFilterOperator {
|
60
61
|
readonly uuid = uuid();
|
@@ -95,6 +96,7 @@ export interface QueryBuilderFilterConditionDragSource {
|
|
95
96
|
|
96
97
|
export type QueryBuilderFilterDropTarget =
|
97
98
|
| QueryBuilderExplorerTreeDragSource
|
99
|
+
| QueryBuilderProjectionColumnDragSource
|
98
100
|
| QueryBuilderFilterConditionDragSource;
|
99
101
|
export type QueryBuilderFilterConditionRearrangeDropTarget =
|
100
102
|
QueryBuilderFilterConditionDragSource;
|
@@ -407,6 +409,11 @@ export class QueryBuilderFilterState
|
|
407
409
|
isRearrangingConditions = false;
|
408
410
|
operators: QueryBuilderFilterOperator[] = [];
|
409
411
|
private _suppressClickawayEventListener = false;
|
412
|
+
/**
|
413
|
+
* This flag is for turning on/off dnd from projection panel to filter panel,
|
414
|
+
* and will be leveraged when the concepts of workflows are introduced into query builder.
|
415
|
+
*/
|
416
|
+
allowDnDProjectionToFilter = true;
|
410
417
|
|
411
418
|
constructor(
|
412
419
|
queryBuilderState: QueryBuilderState,
|
@@ -29,6 +29,7 @@ import {
|
|
29
29
|
EnumValueInstanceValue,
|
30
30
|
VariableExpression,
|
31
31
|
AbstractPropertyExpression,
|
32
|
+
isSuperType,
|
32
33
|
} from '@finos/legend-graph';
|
33
34
|
import {
|
34
35
|
addUniqueEntry,
|
@@ -189,3 +190,37 @@ export const isPropertyExpressionChainOptional = (
|
|
189
190
|
}
|
190
191
|
return isOptional;
|
191
192
|
};
|
193
|
+
|
194
|
+
export const isTypeCompatibleWithConditionValueType = (
|
195
|
+
type: Type | undefined,
|
196
|
+
conditionValueType: Type,
|
197
|
+
): boolean => {
|
198
|
+
const NUMERIC_PRIMITIVE_TYPES = [
|
199
|
+
PRIMITIVE_TYPE.NUMBER,
|
200
|
+
PRIMITIVE_TYPE.INTEGER,
|
201
|
+
PRIMITIVE_TYPE.DECIMAL,
|
202
|
+
PRIMITIVE_TYPE.FLOAT,
|
203
|
+
] as string[];
|
204
|
+
const DATE_PRIMITIVE_TYPES = [
|
205
|
+
PRIMITIVE_TYPE.DATE,
|
206
|
+
PRIMITIVE_TYPE.DATETIME,
|
207
|
+
PRIMITIVE_TYPE.STRICTDATE,
|
208
|
+
PRIMITIVE_TYPE.LATESTDATE,
|
209
|
+
] as string[];
|
210
|
+
|
211
|
+
// When changing the return type for LHS, the RHS value should be adjusted accordingly.
|
212
|
+
return (
|
213
|
+
type !== undefined &&
|
214
|
+
// Numeric value is handled loosely because of autoboxing
|
215
|
+
// e.g. LHS (integer) = RHS (float) is acceptable
|
216
|
+
((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
|
217
|
+
NUMERIC_PRIMITIVE_TYPES.includes(conditionValueType.path)) ||
|
218
|
+
// Date value is handled loosely as well if the LHS is of type DateTime
|
219
|
+
// This is because we would simulate auto-boxing for date by altering the
|
220
|
+
// Pure function used for the operation
|
221
|
+
// e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is()
|
222
|
+
DATE_PRIMITIVE_TYPES.includes(type.path) ||
|
223
|
+
type === conditionValueType ||
|
224
|
+
isSuperType(conditionValueType, type))
|
225
|
+
);
|
226
|
+
};
|
@@ -793,4 +793,19 @@ export class QueryBuilderProjectionState {
|
|
793
793
|
);
|
794
794
|
}
|
795
795
|
}
|
796
|
+
|
797
|
+
isValidProjectionState(): boolean {
|
798
|
+
if (this.queryBuilderState.fetchStructureState.isProjectionMode()) {
|
799
|
+
// duplicate columns check
|
800
|
+
const hasDuplicatedProjectionColumns = this.columns.some(
|
801
|
+
(column) =>
|
802
|
+
this.columns.filter((c) => c.columnName === column.columnName)
|
803
|
+
.length > 1,
|
804
|
+
);
|
805
|
+
// no columns check
|
806
|
+
const hasNoProjectionColumns = this.columns.length === 0;
|
807
|
+
return !hasDuplicatedProjectionColumns && !hasNoProjectionColumns;
|
808
|
+
}
|
809
|
+
return true;
|
810
|
+
}
|
796
811
|
}
|
@@ -262,7 +262,7 @@ export class QueryBuilderPropertySearchPanelState {
|
|
262
262
|
),
|
263
263
|
);
|
264
264
|
if (
|
265
|
-
propertyTreeNodeData
|
265
|
+
propertyTreeNodeData?.mappingData.mapped &&
|
266
266
|
!propertyTreeNodeData.isPartOfDerivedPropertyBranch
|
267
267
|
) {
|
268
268
|
nextLevelPropertyNodes.push(propertyTreeNodeData);
|
@@ -48,16 +48,18 @@ export class QueryBuilderResultState {
|
|
48
48
|
queryBuilderState: QueryBuilderState;
|
49
49
|
exportDataState = ActionState.create();
|
50
50
|
previewLimit = DEFAULT_LIMIT;
|
51
|
-
|
51
|
+
isRunningQuery = false;
|
52
52
|
isGeneratingPlan = false;
|
53
53
|
executionResult?: ExecutionResult | undefined;
|
54
54
|
executionPlanState: ExecutionPlanState;
|
55
55
|
executionDuration?: number | undefined;
|
56
|
+
queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
|
56
57
|
|
57
58
|
constructor(queryBuilderState: QueryBuilderState) {
|
58
59
|
makeAutoObservable(this, {
|
59
60
|
queryBuilderState: false,
|
60
61
|
executionPlanState: false,
|
62
|
+
setIsRunningQuery: action,
|
61
63
|
setExecutionResult: action,
|
62
64
|
});
|
63
65
|
|
@@ -68,16 +70,28 @@ export class QueryBuilderResultState {
|
|
68
70
|
);
|
69
71
|
}
|
70
72
|
|
73
|
+
setIsRunningQuery = (val: boolean): void => {
|
74
|
+
this.isRunningQuery = val;
|
75
|
+
};
|
76
|
+
|
71
77
|
setExecutionResult = (val: ExecutionResult | undefined): void => {
|
72
78
|
this.executionResult = val;
|
73
79
|
};
|
80
|
+
|
74
81
|
setExecutionDuration = (val: number | undefined): void => {
|
75
82
|
this.executionDuration = val;
|
76
83
|
};
|
84
|
+
|
77
85
|
setPreviewLimit = (val: number): void => {
|
78
86
|
this.previewLimit = Math.max(1, val);
|
79
87
|
};
|
80
88
|
|
89
|
+
setQueryRunPromise = (
|
90
|
+
promise: Promise<ExecutionResult> | undefined,
|
91
|
+
): void => {
|
92
|
+
this.queryRunPromise = promise;
|
93
|
+
};
|
94
|
+
|
81
95
|
buildExecutionRawLambda(): RawLambda {
|
82
96
|
let query: RawLambda;
|
83
97
|
if (this.queryBuilderState.isQuerySupported()) {
|
@@ -172,9 +186,9 @@ export class QueryBuilderResultState {
|
|
172
186
|
}
|
173
187
|
}
|
174
188
|
|
175
|
-
*
|
189
|
+
*runQuery(): GeneratorFn<void> {
|
176
190
|
try {
|
177
|
-
this.
|
191
|
+
this.isRunningQuery = true;
|
178
192
|
const mapping = guaranteeNonNullable(
|
179
193
|
this.queryBuilderState.querySetupState.mapping,
|
180
194
|
'Mapping is required to execute query',
|
@@ -185,15 +199,19 @@ export class QueryBuilderResultState {
|
|
185
199
|
);
|
186
200
|
const query = this.buildExecutionRawLambda();
|
187
201
|
const startTime = Date.now();
|
188
|
-
const
|
189
|
-
|
202
|
+
const promise =
|
203
|
+
this.queryBuilderState.graphManagerState.graphManager.executeMapping(
|
190
204
|
query,
|
191
205
|
mapping,
|
192
206
|
runtime,
|
193
207
|
this.queryBuilderState.graphManagerState.graph,
|
194
|
-
)
|
195
|
-
this.
|
196
|
-
|
208
|
+
);
|
209
|
+
this.setQueryRunPromise(promise);
|
210
|
+
const result = (yield promise) as ExecutionResult;
|
211
|
+
if (this.queryRunPromise === promise) {
|
212
|
+
this.setExecutionResult(result);
|
213
|
+
this.setExecutionDuration(Date.now() - startTime);
|
214
|
+
}
|
197
215
|
} catch (error) {
|
198
216
|
assertErrorThrown(error);
|
199
217
|
this.queryBuilderState.applicationStore.log.error(
|
@@ -202,7 +220,7 @@ export class QueryBuilderResultState {
|
|
202
220
|
);
|
203
221
|
this.queryBuilderState.applicationStore.notifyError(error);
|
204
222
|
} finally {
|
205
|
-
this.
|
223
|
+
this.setIsRunningQuery(false);
|
206
224
|
}
|
207
225
|
}
|
208
226
|
|
@@ -31,7 +31,6 @@ import {
|
|
31
31
|
EnumValueExplicitReference,
|
32
32
|
Enumeration,
|
33
33
|
PRIMITIVE_TYPE,
|
34
|
-
isSuperType,
|
35
34
|
SUPPORTED_FUNCTIONS,
|
36
35
|
buildPrimitiveInstanceValue,
|
37
36
|
} from '@finos/legend-graph';
|
@@ -46,6 +45,7 @@ import {
|
|
46
45
|
buildNotExpression,
|
47
46
|
unwrapNotExpression,
|
48
47
|
getNonCollectionValueSpecificationType,
|
48
|
+
isTypeCompatibleWithConditionValueType,
|
49
49
|
} from '../QueryBuilderOperatorsHelper.js';
|
50
50
|
|
51
51
|
export class QueryBuilderFilterOperator_Equal extends QueryBuilderFilterOperator {
|
@@ -81,41 +81,12 @@ export class QueryBuilderFilterOperator_Equal extends QueryBuilderFilterOperator
|
|
81
81
|
isCompatibleWithFilterConditionValue(
|
82
82
|
filterConditionState: FilterConditionState,
|
83
83
|
): boolean {
|
84
|
-
|
84
|
+
return isTypeCompatibleWithConditionValueType(
|
85
|
+
filterConditionState.value
|
86
|
+
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
87
|
+
: undefined,
|
85
88
|
filterConditionState.propertyExpressionState.propertyExpression.func
|
86
|
-
.genericType.value.rawType
|
87
|
-
const type = filterConditionState.value
|
88
|
-
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
89
|
-
: undefined;
|
90
|
-
|
91
|
-
const NUMERIC_PRIMITIVE_TYPES = [
|
92
|
-
PRIMITIVE_TYPE.NUMBER,
|
93
|
-
PRIMITIVE_TYPE.INTEGER,
|
94
|
-
PRIMITIVE_TYPE.DECIMAL,
|
95
|
-
PRIMITIVE_TYPE.FLOAT,
|
96
|
-
] as string[];
|
97
|
-
|
98
|
-
const DATE_PRIMITIVE_TYPES = [
|
99
|
-
PRIMITIVE_TYPE.DATE,
|
100
|
-
PRIMITIVE_TYPE.DATETIME,
|
101
|
-
PRIMITIVE_TYPE.STRICTDATE,
|
102
|
-
PRIMITIVE_TYPE.LATESTDATE,
|
103
|
-
] as string[];
|
104
|
-
|
105
|
-
// When changing the return type for LHS, the RHS value should be adjusted accordingly.
|
106
|
-
return (
|
107
|
-
type !== undefined &&
|
108
|
-
// Numeric value is handled loosely because of autoboxing
|
109
|
-
// e.g. LHS (integer) = RHS (float) is acceptable
|
110
|
-
((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
|
111
|
-
NUMERIC_PRIMITIVE_TYPES.includes(propertyType.path)) ||
|
112
|
-
// Date value is handled loosely as well if the LHS is of type DateTime
|
113
|
-
// This is because we would simulate auto-boxing for date by altering the
|
114
|
-
// Pure function used for the operation
|
115
|
-
// e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is()
|
116
|
-
DATE_PRIMITIVE_TYPES.includes(type.path) ||
|
117
|
-
type === propertyType ||
|
118
|
-
isSuperType(propertyType, type))
|
89
|
+
.genericType.value.rawType,
|
119
90
|
);
|
120
91
|
}
|
121
92
|
|
@@ -24,7 +24,6 @@ import {
|
|
24
24
|
type SimpleFunctionExpression,
|
25
25
|
type AbstractPropertyExpression,
|
26
26
|
PRIMITIVE_TYPE,
|
27
|
-
isSuperType,
|
28
27
|
SUPPORTED_FUNCTIONS,
|
29
28
|
buildPrimitiveInstanceValue,
|
30
29
|
} from '@finos/legend-graph';
|
@@ -35,7 +34,10 @@ import {
|
|
35
34
|
} from './QueryBuilderFilterOperatorHelper.js';
|
36
35
|
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../QueryBuilder_Const.js';
|
37
36
|
import { generateDefaultValueForPrimitiveType } from '../QueryBuilderValueSpecificationBuilderHelper.js';
|
38
|
-
import {
|
37
|
+
import {
|
38
|
+
getNonCollectionValueSpecificationType,
|
39
|
+
isTypeCompatibleWithConditionValueType,
|
40
|
+
} from '../QueryBuilderOperatorsHelper.js';
|
39
41
|
|
40
42
|
export class QueryBuilderFilterOperator_GreaterThan extends QueryBuilderFilterOperator {
|
41
43
|
getLabel(filterConditionState: FilterConditionState): string {
|
@@ -64,40 +66,12 @@ export class QueryBuilderFilterOperator_GreaterThan extends QueryBuilderFilterOp
|
|
64
66
|
isCompatibleWithFilterConditionValue(
|
65
67
|
filterConditionState: FilterConditionState,
|
66
68
|
): boolean {
|
67
|
-
|
69
|
+
return isTypeCompatibleWithConditionValueType(
|
70
|
+
filterConditionState.value
|
71
|
+
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
72
|
+
: undefined,
|
68
73
|
filterConditionState.propertyExpressionState.propertyExpression.func
|
69
|
-
.genericType.value.rawType
|
70
|
-
const type = filterConditionState.value
|
71
|
-
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
72
|
-
: undefined;
|
73
|
-
const NUMERIC_PRIMITIVE_TYPES = [
|
74
|
-
PRIMITIVE_TYPE.NUMBER,
|
75
|
-
PRIMITIVE_TYPE.INTEGER,
|
76
|
-
PRIMITIVE_TYPE.DECIMAL,
|
77
|
-
PRIMITIVE_TYPE.FLOAT,
|
78
|
-
] as string[];
|
79
|
-
|
80
|
-
const DATE_PRIMITIVE_TYPES = [
|
81
|
-
PRIMITIVE_TYPE.DATE,
|
82
|
-
PRIMITIVE_TYPE.DATETIME,
|
83
|
-
PRIMITIVE_TYPE.STRICTDATE,
|
84
|
-
PRIMITIVE_TYPE.LATESTDATE,
|
85
|
-
] as string[];
|
86
|
-
|
87
|
-
// When changing the return type for LHS, the RHS value should be adjusted accordingly.
|
88
|
-
return (
|
89
|
-
type !== undefined &&
|
90
|
-
// Numeric value is handled loosely because of autoboxing
|
91
|
-
// e.g. LHS (integer) = RHS (float) is acceptable
|
92
|
-
((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
|
93
|
-
NUMERIC_PRIMITIVE_TYPES.includes(propertyType.path)) ||
|
94
|
-
// Date value is handled loosely as well if the LHS is of type DateTime
|
95
|
-
// This is because we would simulate auto-boxing for date by altering the
|
96
|
-
// Pure function used for the operation
|
97
|
-
// e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is()
|
98
|
-
DATE_PRIMITIVE_TYPES.includes(type.path) ||
|
99
|
-
type === propertyType ||
|
100
|
-
isSuperType(propertyType, type))
|
74
|
+
.genericType.value.rawType,
|
101
75
|
);
|
102
76
|
}
|
103
77
|
|
@@ -24,7 +24,6 @@ import {
|
|
24
24
|
type ValueSpecification,
|
25
25
|
type SimpleFunctionExpression,
|
26
26
|
type AbstractPropertyExpression,
|
27
|
-
isSuperType,
|
28
27
|
SUPPORTED_FUNCTIONS,
|
29
28
|
buildPrimitiveInstanceValue,
|
30
29
|
} from '@finos/legend-graph';
|
@@ -35,7 +34,10 @@ import {
|
|
35
34
|
} from './QueryBuilderFilterOperatorHelper.js';
|
36
35
|
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../QueryBuilder_Const.js';
|
37
36
|
import { generateDefaultValueForPrimitiveType } from '../QueryBuilderValueSpecificationBuilderHelper.js';
|
38
|
-
import {
|
37
|
+
import {
|
38
|
+
getNonCollectionValueSpecificationType,
|
39
|
+
isTypeCompatibleWithConditionValueType,
|
40
|
+
} from '../QueryBuilderOperatorsHelper.js';
|
39
41
|
|
40
42
|
export class QueryBuilderFilterOperator_GreaterThanEqual extends QueryBuilderFilterOperator {
|
41
43
|
getLabel(filterConditionState: FilterConditionState): string {
|
@@ -64,40 +66,12 @@ export class QueryBuilderFilterOperator_GreaterThanEqual extends QueryBuilderFil
|
|
64
66
|
isCompatibleWithFilterConditionValue(
|
65
67
|
filterConditionState: FilterConditionState,
|
66
68
|
): boolean {
|
67
|
-
|
69
|
+
return isTypeCompatibleWithConditionValueType(
|
70
|
+
filterConditionState.value
|
71
|
+
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
72
|
+
: undefined,
|
68
73
|
filterConditionState.propertyExpressionState.propertyExpression.func
|
69
|
-
.genericType.value.rawType
|
70
|
-
const type = filterConditionState.value
|
71
|
-
? getNonCollectionValueSpecificationType(filterConditionState.value)
|
72
|
-
: undefined;
|
73
|
-
const NUMERIC_PRIMITIVE_TYPES = [
|
74
|
-
PRIMITIVE_TYPE.NUMBER,
|
75
|
-
PRIMITIVE_TYPE.INTEGER,
|
76
|
-
PRIMITIVE_TYPE.DECIMAL,
|
77
|
-
PRIMITIVE_TYPE.FLOAT,
|
78
|
-
] as string[];
|
79
|
-
|
80
|
-
const DATE_PRIMITIVE_TYPES = [
|
81
|
-
PRIMITIVE_TYPE.DATE,
|
82
|
-
PRIMITIVE_TYPE.DATETIME,
|
83
|
-
PRIMITIVE_TYPE.STRICTDATE,
|
84
|
-
PRIMITIVE_TYPE.LATESTDATE,
|
85
|
-
] as string[];
|
86
|
-
|
87
|
-
// When changing the return type for LHS, the RHS value should be adjusted accordingly.
|
88
|
-
return (
|
89
|
-
type !== undefined &&
|
90
|
-
// Numeric value is handled loosely because of autoboxing
|
91
|
-
// e.g. LHS (integer) = RHS (float) is acceptable
|
92
|
-
((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
|
93
|
-
NUMERIC_PRIMITIVE_TYPES.includes(propertyType.path)) ||
|
94
|
-
// Date value is handled loosely as well if the LHS is of type DateTime
|
95
|
-
// This is because we would simulate auto-boxing for date by altering the
|
96
|
-
// Pure function used for the operation
|
97
|
-
// e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is()
|
98
|
-
DATE_PRIMITIVE_TYPES.includes(type.path) ||
|
99
|
-
type === propertyType ||
|
100
|
-
isSuperType(propertyType, type))
|
74
|
+
.genericType.value.rawType,
|
101
75
|
);
|
102
76
|
}
|
103
77
|
|