): void => {
if (
!queryBuilderState.class ||
- val.value === queryBuilderState.mapping ||
+ val.value === queryBuilderState.executionContextState.mapping ||
queryBuilderState.isMappingReadOnly
) {
return;
@@ -284,12 +485,15 @@ const BasicQueryBuilderSetup = observer(
new RuntimePointer(PackageableElementExplicitReference.create(rt)),
)
.map(buildRuntimeValueOption);
- const selectedRuntimeOption = queryBuilderState.runtimeValue
- ? buildRuntimeValueOption(queryBuilderState.runtimeValue)
+ const selectedRuntimeOption = queryBuilderState.executionContextState
+ .runtimeValue
+ ? buildRuntimeValueOption(
+ queryBuilderState.executionContextState.runtimeValue,
+ )
: null;
const changeRuntime = (val: { value: Runtime }): void => {
if (
- val.value === queryBuilderState.runtimeValue ||
+ val.value === queryBuilderState.executionContextState.runtimeValue ||
queryBuilderState.isRuntimeReadOnly
) {
return;
@@ -368,7 +572,7 @@ const BasicQueryBuilderSetup = observer(
disabled={
queryBuilderState.isRuntimeReadOnly ||
!queryBuilderState.class ||
- !queryBuilderState.mapping
+ !queryBuilderState.executionContextState.mapping
}
options={runtimeOptions}
onChange={changeRuntime}
diff --git a/packages/legend-query-builder/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx b/packages/legend-query-builder/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx
index f11a5131775..43f629e44fb 100644
--- a/packages/legend-query-builder/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx
+++ b/packages/legend-query-builder/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx
@@ -84,8 +84,8 @@ export const TEST__setUpQueryBuilder = async (
graphManagerState,
);
const mapping = graphManagerState.graph.getMapping(mappingPath);
- queryBuilderState.setMapping(mapping);
- queryBuilderState.setRuntimeValue(
+ queryBuilderState.executionContextState.setMapping(mapping);
+ queryBuilderState.executionContextState.setRuntimeValue(
new RuntimePointer(
PackageableElementExplicitReference.create(
graphManagerState.graph.getRuntime(runtimePath),
diff --git a/packages/legend-query-builder/src/components/explorer/QueryBuilderExplorerPanel.tsx b/packages/legend-query-builder/src/components/explorer/QueryBuilderExplorerPanel.tsx
index 72b2e27cf89..7e59fa5f46e 100644
--- a/packages/legend-query-builder/src/components/explorer/QueryBuilderExplorerPanel.tsx
+++ b/packages/legend-query-builder/src/components/explorer/QueryBuilderExplorerPanel.tsx
@@ -849,7 +849,11 @@ export const QueryBuilderExplorerPanel = observer(
flowResult(explorerState.analyzeMappingModelCoverage()).catch(
applicationStore.alertUnhandledError,
);
- }, [applicationStore, explorerState, queryBuilderState.mapping]);
+ }, [
+ applicationStore,
+ explorerState,
+ queryBuilderState.executionContextState.mapping,
+ ]);
return (
): void => {
- if (!queryBuilderState.class || val.value === queryBuilderState.mapping) {
+ if (
+ !queryBuilderState.class ||
+ val.value === queryBuilderState.executionContextState.mapping
+ ) {
return;
}
queryBuilderState.changeMapping(val.value);
@@ -90,9 +94,9 @@ const ClassQueryBuilderSetupPanelContent = observer(
// runtime
const runtimeOptions = (
- queryBuilderState.mapping
+ queryBuilderState.executionContextState.mapping
? getMappingCompatibleRuntimes(
- queryBuilderState.mapping,
+ queryBuilderState.executionContextState.mapping,
queryBuilderState.graphManagerState.usableRuntimes,
)
: []
@@ -102,11 +106,14 @@ const ClassQueryBuilderSetupPanelContent = observer(
new RuntimePointer(PackageableElementExplicitReference.create(rt)),
)
.map(buildRuntimeValueOption);
- const selectedRuntimeOption = queryBuilderState.runtimeValue
- ? buildRuntimeValueOption(queryBuilderState.runtimeValue)
+ const selectedRuntimeOption = queryBuilderState.executionContextState
+ .runtimeValue
+ ? buildRuntimeValueOption(
+ queryBuilderState.executionContextState.runtimeValue,
+ )
: null;
const changeRuntime = (val: { value: Runtime }): void => {
- if (val.value === queryBuilderState.runtimeValue) {
+ if (val.value === queryBuilderState.executionContextState.runtimeValue) {
return;
}
queryBuilderState.changeRuntime(val.value);
@@ -177,7 +184,8 @@ const ClassQueryBuilderSetupPanelContent = observer(
placeholder="Choose a runtime..."
noMatchMessage="No compatible runtime found for specified mapping"
disabled={
- !queryBuilderState.class || !queryBuilderState.mapping
+ !queryBuilderState.class ||
+ !queryBuilderState.executionContextState.mapping
}
options={runtimeOptions}
onChange={changeRuntime}
diff --git a/packages/legend-query-builder/src/components/workflows/MappingQueryBuilder.tsx b/packages/legend-query-builder/src/components/workflows/MappingQueryBuilder.tsx
index fba9cc8e225..700caf62c5a 100644
--- a/packages/legend-query-builder/src/components/workflows/MappingQueryBuilder.tsx
+++ b/packages/legend-query-builder/src/components/workflows/MappingQueryBuilder.tsx
@@ -62,11 +62,12 @@ const MappingQueryBuilderSetupPanelContent = observer(
queryBuilderState.graphManagerState.usableMappings.map(
buildElementOption,
);
- const selectedMappingOption = queryBuilderState.mapping
- ? buildElementOption(queryBuilderState.mapping)
+ const selectedMappingOption = queryBuilderState.executionContextState
+ .mapping
+ ? buildElementOption(queryBuilderState.executionContextState.mapping)
: null;
const changeMapping = (val: PackageableElementOption): void => {
- if (val.value === queryBuilderState.mapping) {
+ if (val.value === queryBuilderState.executionContextState.mapping) {
return;
}
queryBuilderState.changeMapping(val.value);
@@ -82,9 +83,9 @@ const MappingQueryBuilderSetupPanelContent = observer(
// runtime
const runtimeOptions = (
- queryBuilderState.mapping
+ queryBuilderState.executionContextState.mapping
? getMappingCompatibleRuntimes(
- queryBuilderState.mapping,
+ queryBuilderState.executionContextState.mapping,
queryBuilderState.graphManagerState.usableRuntimes,
)
: []
@@ -94,11 +95,14 @@ const MappingQueryBuilderSetupPanelContent = observer(
new RuntimePointer(PackageableElementExplicitReference.create(rt)),
)
.map(buildRuntimeValueOption);
- const selectedRuntimeOption = queryBuilderState.runtimeValue
- ? buildRuntimeValueOption(queryBuilderState.runtimeValue)
+ const selectedRuntimeOption = queryBuilderState.executionContextState
+ .runtimeValue
+ ? buildRuntimeValueOption(
+ queryBuilderState.executionContextState.runtimeValue,
+ )
: null;
const changeRuntime = (val: { value: Runtime }): void => {
- if (val.value === queryBuilderState.runtimeValue) {
+ if (val.value === queryBuilderState.executionContextState.runtimeValue) {
return;
}
queryBuilderState.changeRuntime(val.value);
@@ -113,9 +117,9 @@ const MappingQueryBuilderSetupPanelContent = observer(
});
// class
- const classes = queryBuilderState.mapping
+ const classes = queryBuilderState.executionContextState.mapping
? getMappingCompatibleClasses(
- queryBuilderState.mapping,
+ queryBuilderState.executionContextState.mapping,
queryBuilderState.graphManagerState.usableClasses,
)
: [];
@@ -170,7 +174,7 @@ const MappingQueryBuilderSetupPanelContent = observer(
className="panel__content__form__section__dropdown query-builder__setup__config-group__item__selector"
placeholder="Choose a runtime..."
noMatchMessage="No compatible runtime found for specified mapping"
- disabled={!queryBuilderState.mapping}
+ disabled={!queryBuilderState.executionContextState.mapping}
options={runtimeOptions}
onChange={changeRuntime}
value={selectedRuntimeOption}
diff --git a/packages/legend-query-builder/src/components/workflows/ServiceQueryBuilder.tsx b/packages/legend-query-builder/src/components/workflows/ServiceQueryBuilder.tsx
index c6305c5efe8..04675e244df 100644
--- a/packages/legend-query-builder/src/components/workflows/ServiceQueryBuilder.tsx
+++ b/packages/legend-query-builder/src/components/workflows/ServiceQueryBuilder.tsx
@@ -87,9 +87,9 @@ const ServiceQueryBuilderSetupPanelContent = observer(
};
// class
- const classes = queryBuilderState.mapping
+ const classes = queryBuilderState.executionContextState.mapping
? getMappingCompatibleClasses(
- queryBuilderState.mapping,
+ queryBuilderState.executionContextState.mapping,
queryBuilderState.graphManagerState.usableClasses,
)
: [];
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderExecutionContextState.ts b/packages/legend-query-builder/src/stores/QueryBuilderExecutionContextState.ts
new file mode 100644
index 00000000000..14b66f82df0
--- /dev/null
+++ b/packages/legend-query-builder/src/stores/QueryBuilderExecutionContextState.ts
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2020-present, Goldman Sachs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { Mapping, Runtime } from '@finos/legend-graph';
+import type { QueryBuilderState } from './QueryBuilderState.js';
+import { action, makeObservable, observable } from 'mobx';
+
+export abstract class QueryBuilderExecutionContextState {
+ readonly queryBuilderState: QueryBuilderState;
+ mapping: Mapping | undefined;
+ runtimeValue: Runtime | undefined;
+
+ constructor(queryBuilderState: QueryBuilderState) {
+ this.queryBuilderState = queryBuilderState;
+ }
+
+ setMapping(val: Mapping | undefined): void {
+ this.mapping = val;
+ }
+
+ setRuntimeValue(val: Runtime | undefined): void {
+ this.runtimeValue = val;
+ }
+
+ abstract isMappingReadOnly(): boolean;
+ abstract isRuntimeReadOny(): boolean;
+}
+
+export class QueryBuilderInlineFromExecutionContextState extends QueryBuilderExecutionContextState {
+ constructor(queryBuilderState: QueryBuilderState) {
+ super(queryBuilderState);
+ makeObservable(this, {
+ mapping: observable,
+ runtimeValue: observable,
+ setMapping: action,
+ setRuntimeValue: action,
+ });
+ }
+ isMappingReadOnly(): boolean {
+ return false;
+ }
+
+ isRuntimeReadOny(): boolean {
+ return false;
+ }
+}
+
+export class QueryBuilderExternalExecutionContextState extends QueryBuilderExecutionContextState {
+ constructor(queryBuilderState: QueryBuilderState) {
+ super(queryBuilderState);
+ makeObservable(this, {
+ mapping: observable,
+ runtimeValue: observable,
+ setMapping: action,
+ setRuntimeValue: action,
+ });
+ }
+
+ override setMapping(val: Mapping | undefined): void {
+ this.mapping = val;
+ }
+
+ override setRuntimeValue(val: Runtime | undefined): void {
+ this.runtimeValue = val;
+ }
+ override isMappingReadOnly(): boolean {
+ throw new Error('Method not implemented.');
+ }
+ override isRuntimeReadOny(): boolean {
+ throw new Error('Method not implemented.');
+ }
+}
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderInternalizeState.ts b/packages/legend-query-builder/src/stores/QueryBuilderInternalizeState.ts
new file mode 100644
index 00000000000..1469f647a3f
--- /dev/null
+++ b/packages/legend-query-builder/src/stores/QueryBuilderInternalizeState.ts
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2020-present, Goldman Sachs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { QueryBuilderState } from './QueryBuilderState.js';
+import type { Binding, VariableExpression } from '@finos/legend-graph';
+export class QueryBuilderInternalizeState {
+ readonly queryBuilderState: QueryBuilderState;
+ binding: Binding;
+ inputData: VariableExpression;
+
+ constructor(
+ binding: Binding,
+ inputData: VariableExpression,
+ queryBuilderState: QueryBuilderState,
+ ) {
+ this.queryBuilderState = queryBuilderState;
+ this.binding = binding;
+ this.inputData = inputData;
+ }
+}
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderResultState.ts b/packages/legend-query-builder/src/stores/QueryBuilderResultState.ts
index 6d1719450c2..e083d6407f4 100644
--- a/packages/legend-query-builder/src/stores/QueryBuilderResultState.ts
+++ b/packages/legend-query-builder/src/stores/QueryBuilderResultState.ts
@@ -217,8 +217,8 @@ export class QueryBuilderResultState {
const result =
(yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
query,
- this.queryBuilderState.mapping,
- this.queryBuilderState.runtimeValue,
+ this.queryBuilderState.executionContextState.mapping,
+ this.queryBuilderState.executionContextState.runtimeValue,
this.queryBuilderState.graphManagerState.graph,
{
serializationFormat,
@@ -260,11 +260,11 @@ export class QueryBuilderResultState {
this.setIsRunningQuery(true);
const currentHashCode = this.queryBuilderState.hashCode;
const mapping = guaranteeNonNullable(
- this.queryBuilderState.mapping,
+ this.queryBuilderState.executionContextState.mapping,
'Mapping is required to execute query',
);
const runtime = guaranteeNonNullable(
- this.queryBuilderState.runtimeValue,
+ this.queryBuilderState.executionContextState.runtimeValue,
`Runtime is required to execute query`,
);
const query = this.buildExecutionRawLambda();
@@ -350,11 +350,11 @@ export class QueryBuilderResultState {
try {
this.isGeneratingPlan = true;
const mapping = guaranteeNonNullable(
- this.queryBuilderState.mapping,
+ this.queryBuilderState.executionContextState.mapping,
'Mapping is required to execute query',
);
const runtime = guaranteeNonNullable(
- this.queryBuilderState.runtimeValue,
+ this.queryBuilderState.executionContextState.runtimeValue,
`Runtime is required to execute query`,
);
const query = this.queryBuilderState.buildQuery();
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderState.ts b/packages/legend-query-builder/src/stores/QueryBuilderState.ts
index 15630b6cb22..4557ac35dcb 100644
--- a/packages/legend-query-builder/src/stores/QueryBuilderState.ts
+++ b/packages/legend-query-builder/src/stores/QueryBuilderState.ts
@@ -51,6 +51,8 @@ import {
type Mapping,
type Runtime,
type GraphManagerState,
+ type ValueSpecification,
+ type Type,
GRAPH_MANAGER_EVENT,
CompilationError,
extractSourceInformationCoordinates,
@@ -62,9 +64,7 @@ import {
isStubbed_RawLambda,
buildLambdaVariableExpressions,
buildRawLambdaFromLambdaFunction,
- type ValueSpecification,
PrimitiveType,
- type Type,
SimpleFunctionExpression,
extractElementNameFromPath,
SUPPORTED_FUNCTIONS,
@@ -94,6 +94,11 @@ import { QueryBuilderConstantsState } from './QueryBuilderConstantsState.js';
import { QueryBuilderCheckEntitlementsState } from './entitlements/QueryBuilderCheckEntitlementsState.js';
import { QueryBuilderTDSState } from './fetch-structure/tds/QueryBuilderTDSState.js';
import { QUERY_BUILDER_PURE_PATH } from '../graph/QueryBuilderMetaModelConst.js';
+import { QueryBuilderInternalizeState } from './QueryBuilderInternalizeState.js';
+import {
+ QueryBuilderExternalExecutionContextState,
+ type QueryBuilderExecutionContextState,
+} from './QueryBuilderExecutionContextState.js';
export abstract class QueryBuilderState implements CommandRegistrar {
readonly applicationStore: GenericLegendApplicationStore;
@@ -124,8 +129,8 @@ export abstract class QueryBuilderState implements CommandRegistrar {
isCalendarEnabled = false;
class?: Class | undefined;
- mapping?: Mapping | undefined;
- runtimeValue?: Runtime | undefined;
+ executionContextState: QueryBuilderExecutionContextState;
+ internalizeState?: QueryBuilderInternalizeState | undefined;
// NOTE: this makes it so that we need to import components in stores code,
// we probably want to refactor to an extension mechanism
@@ -153,9 +158,8 @@ export abstract class QueryBuilderState implements CommandRegistrar {
isCheckingEntitlments: observable,
isCalendarEnabled: observable,
changeDetectionState: observable,
+ executionContextState: observable,
class: observable,
- mapping: observable,
- runtimeValue: observable,
sideBarClassName: computed,
isQuerySupported: computed,
@@ -167,13 +171,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
setIsCalendarEnabled: action,
setIsCheckingEntitlments: action,
setClass: action,
- setMapping: action,
- setRuntimeValue: action,
resetQueryResult: action,
resetQueryContent: action,
changeClass: action,
changeMapping: action,
+ setExecutionContextState: action,
rebuildWithQuery: action,
compileQuery: flow,
@@ -182,7 +185,9 @@ export abstract class QueryBuilderState implements CommandRegistrar {
this.applicationStore = applicationStore;
this.graphManagerState = graphManagerState;
-
+ this.executionContextState = new QueryBuilderExternalExecutionContextState(
+ this,
+ );
this.milestoningState = new QueryBuilderMilestoningState(this);
this.explorerState = new QueryBuilderExplorerState(this);
this.parametersState = new QueryBuilderParametersState(this);
@@ -243,6 +248,10 @@ export abstract class QueryBuilderState implements CommandRegistrar {
return this.allVariables.map((e) => e.name);
}
+ setInternalize(val: QueryBuilderInternalizeState | undefined): void {
+ this.internalizeState = val;
+ }
+
setShowFunctionsExplorerPanel(val: boolean): void {
this.showFunctionsExplorerPanel = val;
}
@@ -267,12 +276,8 @@ export abstract class QueryBuilderState implements CommandRegistrar {
this.class = val;
}
- setMapping(val: Mapping | undefined): void {
- this.mapping = val;
- }
-
- setRuntimeValue(val: Runtime | undefined): void {
- this.runtimeValue = val;
+ setExecutionContextState(val: QueryBuilderExecutionContextState): void {
+ this.executionContextState = val;
}
get isQuerySupported(): boolean {
@@ -366,12 +371,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
this.resetQueryContent();
this.milestoningState.updateMilestoningConfiguration();
}
- this.setMapping(val);
+ this.executionContextState.setMapping(val);
}
changeRuntime(val: Runtime): void {
this.resetQueryResult();
- this.setRuntimeValue(val);
+ this.executionContextState.setRuntimeValue(val);
}
getCurrentParameterValues(): Map | undefined {
@@ -414,11 +419,11 @@ export abstract class QueryBuilderState implements CommandRegistrar {
'Query must be supported to build from function',
);
const mapping = guaranteeNonNullable(
- this.mapping,
+ this.executionContextState.mapping,
'Mapping required to build from() function',
);
const runtime = guaranteeNonNullable(
- this.runtimeValue,
+ this.executionContextState.runtimeValue,
'Runtime required to build from query',
);
const runtimePointer = guaranteeType(
@@ -659,8 +664,10 @@ export abstract class QueryBuilderState implements CommandRegistrar {
this.graphManagerState,
);
basicState.class = this.class;
- basicState.mapping = this.mapping;
- basicState.runtimeValue = this.runtimeValue;
+ basicState.executionContextState.mapping =
+ this.executionContextState.mapping;
+ basicState.executionContextState.runtimeValue =
+ this.executionContextState.runtimeValue;
return basicState;
}
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderStateBuilder.ts b/packages/legend-query-builder/src/stores/QueryBuilderStateBuilder.ts
index 5673046fe00..6756dba56ce 100644
--- a/packages/legend-query-builder/src/stores/QueryBuilderStateBuilder.ts
+++ b/packages/legend-query-builder/src/stores/QueryBuilderStateBuilder.ts
@@ -30,7 +30,7 @@ import {
type FunctionExpression,
type GraphFetchTreeInstanceValue,
type ValueSpecificationVisitor,
- type InstanceValue,
+ InstanceValue,
type INTERNAL__UnknownValueSpecification,
type LambdaFunction,
type KeyExpressionInstanceValue,
@@ -47,6 +47,11 @@ import {
type ValueSpecification,
SUPPORTED_FUNCTIONS,
isSuperType,
+ PackageableElementReference,
+ Mapping,
+ PackageableRuntime,
+ RuntimePointer,
+ PackageableElementExplicitReference,
} from '@finos/legend-graph';
import { processTDSPostFilterExpression } from './fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js';
import { processFilterExpression } from './filter/QueryBuilderFilterStateBuilder.js';
@@ -58,6 +63,7 @@ import {
processGraphFetchExpression,
processGraphFetchExternalizeExpression,
processGraphFetchSerializeExpression,
+ processInternalizeExpression,
} from './fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeStateBuilder.js';
import {
processTDSDistinctExpression,
@@ -78,6 +84,8 @@ import { processWatermarkExpression } from './watermark/QueryBuilderWatermarkSta
import { QueryBuilderConstantExpressionState } from './QueryBuilderConstantsState.js';
import { checkIfEquivalent } from './milestoning/QueryBuilderMilestoningHelper.js';
import type { QueryBuilderParameterValue } from './QueryBuilderParametersState.js';
+import { toJS } from 'mobx';
+import { QueryBuilderInlineFromExecutionContextState } from './QueryBuilderExecutionContextState.js';
const processGetAllExpression = (
expression: SimpleFunctionExpression,
@@ -146,6 +154,51 @@ const processLetExpression = (
queryBuilderState.constantState.addConstant(constantExpression);
};
+const processFromFunction = (
+ expression: SimpleFunctionExpression,
+ queryBuilderState: QueryBuilderState,
+): void => {
+ // mapping
+ const mappingInstanceExpression = guaranteeType(
+ expression.parametersValues[1],
+ InstanceValue,
+ `Can't process internalize() expression: only support internalize() with 1st parameter as instance value`,
+ );
+ const mapping = guaranteeType(
+ guaranteeType(
+ mappingInstanceExpression.values[0],
+ PackageableElementReference,
+ `Can't process from() expression: only support from() with 1st parameter as packagableElement value`,
+ ).value,
+ Mapping,
+ `Can't process from() expression: only support from() with 1st parameter as mapping value`,
+ );
+ // runtime
+ const runtimeInstanceExpression = guaranteeType(
+ expression.parametersValues[2],
+ InstanceValue,
+ `Can't process from() expression: only support from() with 2nd parameter as instance value`,
+ );
+ const runtimeVal = guaranteeType(
+ guaranteeType(
+ runtimeInstanceExpression.values[0],
+ PackageableElementReference,
+ `Can't process from() expression: only support from() with 2nd parameter as packagableElement value`,
+ ).value,
+ PackageableRuntime,
+ `Can't process from() expression: only support from() with 2nd parameter as runtime value`,
+ );
+ const fromContext = new QueryBuilderInlineFromExecutionContextState(
+ queryBuilderState,
+ );
+ fromContext.setMapping(mapping);
+ fromContext.setRuntimeValue(
+ new RuntimePointer(PackageableElementExplicitReference.create(runtimeVal)),
+ );
+ queryBuilderState.setExecutionContextState(fromContext);
+ return;
+};
+
/**
* This is the value specification processor (a.k.a state builder) for query builder.
*
@@ -316,11 +369,24 @@ export class QueryBuilderValueSpecificationProcessor
valueSpecification: SimpleFunctionExpression,
): void {
const functionName = valueSpecification.functionName;
+ console.log('visit_SimpleFunctionExpression', functionName);
if (
matchFunctionName(functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.GET_ALL)
) {
processGetAllExpression(valueSpecification, this.queryBuilderState);
return;
+ } else if (
+ matchFunctionName(
+ functionName,
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.INTERNALIZE,
+ )
+ ) {
+ processInternalizeExpression(
+ valueSpecification,
+ this.queryBuilderState,
+ this.parentLambda,
+ );
+ return;
} else if (
matchFunctionName(functionName, [
QUERY_BUILDER_SUPPORTED_FUNCTIONS.FILTER,
@@ -545,6 +611,20 @@ export class QueryBuilderValueSpecificationProcessor
this.parentLambda,
);
return;
+ } else if (matchFunctionName(functionName, [SUPPORTED_FUNCTIONS.FROM])) {
+ const parameters = valueSpecification.parametersValues;
+ assertTrue(
+ parameters.length === 3,
+ 'From function expects 2 parameters (mapping and runtime)',
+ );
+ processFromFunction(valueSpecification, this.queryBuilderState);
+ QueryBuilderValueSpecificationProcessor.processChild(
+ guaranteeNonNullable(parameters[0]),
+ valueSpecification,
+ this.parentLambda,
+ this.queryBuilderState,
+ );
+ return;
} else if (
matchFunctionName(
functionName,
diff --git a/packages/legend-query-builder/src/stores/QueryBuilderValueSpecificationBuilder.ts b/packages/legend-query-builder/src/stores/QueryBuilderValueSpecificationBuilder.ts
index 91e3a045a29..6edc9b2e1a0 100644
--- a/packages/legend-query-builder/src/stores/QueryBuilderValueSpecificationBuilder.ts
+++ b/packages/legend-query-builder/src/stores/QueryBuilderValueSpecificationBuilder.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { guaranteeNonNullable } from '@finos/legend-shared';
+import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
import {
type Class,
Multiplicity,
@@ -31,6 +31,7 @@ import {
PrimitiveInstanceValue,
PrimitiveType,
SUPPORTED_FUNCTIONS,
+ RuntimePointer,
} from '@finos/legend-graph';
import type { QueryBuilderState } from './QueryBuilderState.js';
import { buildFilterExpression } from './filter/QueryBuilderFilterValueSpecificationBuilder.js';
@@ -40,6 +41,10 @@ import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../graph/QueryBuilderMetaMode
import { buildWatermarkExpression } from './watermark/QueryBuilderWatermarkValueSpecificationBuilder.js';
import { buildExecutionQueryFromLambdaFunction } from './shared/LambdaParameterState.js';
import type { QueryBuilderConstantExpressionState } from './QueryBuilderConstantsState.js';
+import {
+ QueryBuilderInlineFromExecutionContextState,
+ type QueryBuilderExecutionContextState,
+} from './QueryBuilderExecutionContextState.js';
export const buildGetAllFunction = (
_class: Class,
@@ -91,6 +96,46 @@ const buildLetExpression = (
return letFunc;
};
+const buildExecutionContextState = (
+ executionState: QueryBuilderExecutionContextState,
+ lambdaFunction: LambdaFunction,
+): LambdaFunction => {
+ if (executionState instanceof QueryBuilderInlineFromExecutionContextState) {
+ const precedingExpression = guaranteeNonNullable(
+ lambdaFunction.expressionSequence[0],
+ `Can't build from expression: preceding expression is not defined`,
+ );
+ const fromFunc = new SimpleFunctionExpression(
+ extractElementNameFromPath(SUPPORTED_FUNCTIONS.FROM),
+ );
+ // 1st param
+ const mapping = guaranteeNonNullable(
+ executionState.mapping,
+ 'Mapping required for building from() expression',
+ );
+ const mappingInstance = new InstanceValue(Multiplicity.ONE, undefined);
+ mappingInstance.values = [
+ PackageableElementExplicitReference.create(mapping),
+ ];
+ // 2nd parameter
+ const runtime = guaranteeType(
+ executionState.runtimeValue,
+ RuntimePointer,
+ 'Runtime Pointer required for building from() expression',
+ );
+ const runtimeInstance = new InstanceValue(Multiplicity.ONE, undefined);
+ runtimeInstance.values = [runtime.packageableRuntime];
+ // build externalize
+ fromFunc.parametersValues = [
+ precedingExpression,
+ mappingInstance,
+ runtimeInstance,
+ ];
+ lambdaFunction.expressionSequence[0] = fromFunc;
+ }
+ return lambdaFunction;
+};
+
const buildFetchStructure = (
fetchStructureState: QueryBuilderFetchStructureState,
lambdaFunction: LambdaFunction,
@@ -157,6 +202,11 @@ export const buildLambdaFunction = (
lambdaFunction,
options,
);
+ // build execution-state
+ buildExecutionContextState(
+ queryBuilderState.executionContextState,
+ lambdaFunction,
+ );
// build variable expressions
if (queryBuilderState.constantState.constants.length) {
@@ -185,5 +235,6 @@ export const buildLambdaFunction = (
);
}
}
+
return lambdaFunction;
};
diff --git a/packages/legend-query-builder/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts b/packages/legend-query-builder/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts
index e40a56aa829..664f315a226 100644
--- a/packages/legend-query-builder/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts
+++ b/packages/legend-query-builder/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts
@@ -138,9 +138,11 @@ export const TEST__setUpQueryBuilderState = async (
if (executionContext) {
const graph = queryBuilderState.graphManagerState.graph;
queryBuilderState.class = graph.getClass(executionContext._class);
- queryBuilderState.mapping = graph.getMapping(executionContext.mapping);
+ queryBuilderState.executionContextState.mapping = graph.getMapping(
+ executionContext.mapping,
+ );
if (executionContext.runtime) {
- queryBuilderState.runtimeValue = graph.getRuntime(
+ queryBuilderState.executionContextState.runtimeValue = graph.getRuntime(
executionContext.runtime,
);
}
diff --git a/packages/legend-query-builder/src/stores/entitlements/QueryBuilderCheckEntitlementsState.ts b/packages/legend-query-builder/src/stores/entitlements/QueryBuilderCheckEntitlementsState.ts
index fe9a3a12bda..183bdc1d059 100644
--- a/packages/legend-query-builder/src/stores/entitlements/QueryBuilderCheckEntitlementsState.ts
+++ b/packages/legend-query-builder/src/stores/entitlements/QueryBuilderCheckEntitlementsState.ts
@@ -53,16 +53,18 @@ export class QueryBuilderCheckEntitlementsState implements Hashable {
this.dataAccessState = undefined;
if (
- this.queryBuilderState.mapping &&
- this.queryBuilderState.runtimeValue instanceof RuntimePointer
+ this.queryBuilderState.executionContextState.mapping &&
+ this.queryBuilderState.executionContextState.runtimeValue instanceof
+ RuntimePointer
) {
this.dataAccessState = new DataAccessState(
this.queryBuilderState.applicationStore,
this.queryBuilderState.graphManagerState,
{
- mapping: this.queryBuilderState.mapping.path,
+ mapping: this.queryBuilderState.executionContextState.mapping.path,
runtime:
- this.queryBuilderState.runtimeValue.packageableRuntime.value.path,
+ this.queryBuilderState.executionContextState.runtimeValue
+ .packageableRuntime.value.path,
getQuery: async () =>
this.createExecutableQuery(
this.queryBuilderState.buildQuery(),
diff --git a/packages/legend-query-builder/src/stores/explorer/QueryBuilderExplorerState.ts b/packages/legend-query-builder/src/stores/explorer/QueryBuilderExplorerState.ts
index 0d7aa2e969a..c4262e6c621 100644
--- a/packages/legend-query-builder/src/stores/explorer/QueryBuilderExplorerState.ts
+++ b/packages/legend-query-builder/src/stores/explorer/QueryBuilderExplorerState.ts
@@ -660,7 +660,7 @@ export class QueryBuilderExplorerState {
refreshTreeData(): void {
const _class = this.queryBuilderState.class;
- const _mapping = this.queryBuilderState.mapping;
+ const _mapping = this.queryBuilderState.executionContextState.mapping;
this.setTreeData(
_class && _mapping && this.mappingModelCoverageAnalysisResult
? getQueryBuilderTreeData(
@@ -675,8 +675,8 @@ export class QueryBuilderExplorerState {
// We will only refetch if the analysis result's mapping has changed.
// This makes the assumption that the mapping has not been edited, which is a valid assumption since query is not for editing mappings
if (
- this.queryBuilderState.mapping &&
- this.queryBuilderState.mapping !==
+ this.queryBuilderState.executionContextState.mapping &&
+ this.queryBuilderState.executionContextState.mapping !==
this.mappingModelCoverageAnalysisResult?.mapping
) {
this.mappingModelCoverageAnalysisState.inProgress();
@@ -692,7 +692,7 @@ export class QueryBuilderExplorerState {
try {
this.mappingModelCoverageAnalysisResult = (yield flowResult(
this.queryBuilderState.graphManagerState.graphManager.analyzeMappingModelCoverage(
- this.queryBuilderState.mapping,
+ this.queryBuilderState.executionContextState.mapping,
this.queryBuilderState.graphManagerState.graph,
),
)) as MappingModelCoverageAnalysisResult;
@@ -720,7 +720,7 @@ export class QueryBuilderExplorerState {
*previewData(
node: QueryBuilderExplorerTreePropertyNodeData,
): GeneratorFn {
- const runtime = this.queryBuilderState.runtimeValue;
+ const runtime = this.queryBuilderState.executionContextState.runtimeValue;
if (!runtime) {
this.queryBuilderState.applicationStore.notificationService.notifyWarning(
`Can't preview data for property '${node.property.name}': runtime is not specified`,
@@ -730,7 +730,7 @@ export class QueryBuilderExplorerState {
if (
!node.mappingData.mapped ||
!this.queryBuilderState.class ||
- !this.queryBuilderState.mapping
+ !this.queryBuilderState.executionContextState.mapping
) {
return;
}
@@ -759,7 +759,7 @@ export class QueryBuilderExplorerState {
this.queryBuilderState,
propertyExpression,
),
- this.queryBuilderState.mapping,
+ this.queryBuilderState.executionContextState.mapping,
runtime,
this.queryBuilderState.graphManagerState.graph,
)) as ExecutionResult;
@@ -796,7 +796,7 @@ export class QueryBuilderExplorerState {
this.queryBuilderState,
propertyExpression,
),
- this.queryBuilderState.mapping,
+ this.queryBuilderState.executionContextState.mapping,
runtime,
this.queryBuilderState.graphManagerState.graph,
)) as ExecutionResult;
diff --git a/packages/legend-query-builder/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeStateBuilder.ts b/packages/legend-query-builder/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeStateBuilder.ts
index c3ab66a4016..57efa7eee31 100644
--- a/packages/legend-query-builder/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeStateBuilder.ts
+++ b/packages/legend-query-builder/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeStateBuilder.ts
@@ -32,11 +32,13 @@ import {
CollectionInstanceValue,
getClassProperty,
PrimitiveType,
+ VariableExpression,
} from '@finos/legend-graph';
import {
assertIsBoolean,
assertIsString,
assertTrue,
+ assertType,
guaranteeIsString,
guaranteeNonNullable,
guaranteeType,
@@ -45,7 +47,7 @@ import {
QUERY_BUILDER_PURE_PATH,
QUERY_BUILDER_SUPPORTED_FUNCTIONS,
} from '../../../graph/QueryBuilderMetaModelConst.js';
-import type { QueryBuilderState } from '../../QueryBuilderState.js';
+import { type QueryBuilderState } from '../../QueryBuilderState.js';
import { QueryBuilderValueSpecificationProcessor } from '../../QueryBuilderStateBuilder.js';
import { FETCH_STRUCTURE_IMPLEMENTATION } from '../QueryBuilderFetchStructureImplementationState.js';
import {
@@ -56,6 +58,7 @@ import {
} from './QueryBuilderGraphFetchTreeState.js';
import { buildGraphFetchTreeData } from './QueryBuilderGraphFetchTreeUtil.js';
import {} from 'mobx';
+import { QueryBuilderInternalizeState } from '../../QueryBuilderInternalizeState.js';
export const processGraphFetchExpression = (
expression: SimpleFunctionExpression,
@@ -105,6 +108,68 @@ export const processGraphFetchExpression = (
}
};
+export const processInternalizeExpression = (
+ expression: SimpleFunctionExpression,
+ queryBuilderState: QueryBuilderState,
+ parentLambda: LambdaFunction,
+): void => {
+ // update fetch-structure
+ queryBuilderState.fetchStructureState.changeImplementation(
+ FETCH_STRUCTURE_IMPLEMENTATION.GRAPH_FETCH,
+ );
+ const functionName = expression.functionName;
+ console.log(expression);
+ // check parameters
+ assertTrue(
+ expression.parametersValues.length === 3,
+ `Can't process ${functionName}() expression: ${functionName}() expects 2 argument`,
+ );
+
+ console.log('expression', expression);
+
+ // first param classs
+ const classVal = expression.parametersValues[0];
+ const _class = classVal?.genericType?.value.rawType;
+ assertType(
+ _class,
+ Class,
+ `Can't process internalize() expression: internalize() return type is missing`,
+ );
+
+ queryBuilderState.setClass(_class);
+ queryBuilderState.milestoningState.clearMilestoningDates();
+ queryBuilderState.explorerState.refreshTreeData();
+ // binding
+
+ const instanceExpression = guaranteeType(
+ expression.parametersValues[1],
+ InstanceValue,
+ `Can't process internalize() expression: only support internalize() with 1st parameter as instance value`,
+ );
+ const binding = guaranteeType(
+ guaranteeType(
+ instanceExpression.values[0],
+ PackageableElementReference,
+ `Can't process internalize() expression: only support internalize() with 1st parameter as packagableElement value`,
+ ).value,
+ Binding,
+ `Can't process internalize() expression: only support internalize() with 1st parameter as binding value`,
+ );
+
+ const variableExpression = guaranteeType(
+ expression.parametersValues[2],
+ VariableExpression,
+ );
+
+ const inernalize = new QueryBuilderInternalizeState(
+ binding,
+ variableExpression,
+ queryBuilderState,
+ );
+
+ queryBuilderState.setInternalize(inernalize);
+};
+
type PropertyValue = object | string | number | boolean;
// Dynamically sets key values of config
@@ -323,10 +388,12 @@ export const processGraphFetchExternalizeExpression = (
);
// build preceding expression
+ console.log('x', precedingExpression.functionName);
assertTrue(
matchFunctionName(precedingExpression.functionName, [
QUERY_BUILDER_SUPPORTED_FUNCTIONS.GRAPH_FETCH,
QUERY_BUILDER_SUPPORTED_FUNCTIONS.GRAPH_FETCH_CHECKED,
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.INTERNALIZE,
]),
`Can't process externalize() expression: only support externalize() in graph-fetch expression`,
);
@@ -373,7 +440,6 @@ export const processGraphFetchExternalizeExpression = (
Binding,
`Can't process externalize() expression: only support externalize() with 1st parameter as binding value`,
);
-
const externalizeState = new GraphFetchExternalFormatSerializationState(
graphFetchTreeState,
binding,
diff --git a/packages/legend-query-builder/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts b/packages/legend-query-builder/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts
index a08d85d935d..e448d255673 100644
--- a/packages/legend-query-builder/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts
+++ b/packages/legend-query-builder/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts
@@ -380,10 +380,12 @@ export class PostFilterConditionState implements Hashable {
this.value,
),
guaranteeNonNullable(
- this.postFilterState.tdsState.queryBuilderState.mapping,
+ this.postFilterState.tdsState.queryBuilderState
+ .executionContextState.mapping,
),
guaranteeNonNullable(
- this.postFilterState.tdsState.queryBuilderState.runtimeValue,
+ this.postFilterState.tdsState.queryBuilderState
+ .executionContextState.runtimeValue,
),
this.postFilterState.tdsState.queryBuilderState.graphManagerState
.graph,
diff --git a/packages/legend-query-builder/src/stores/filter/QueryBuilderFilterState.ts b/packages/legend-query-builder/src/stores/filter/QueryBuilderFilterState.ts
index 8ec55ede0d1..1e0745d8bc7 100644
--- a/packages/legend-query-builder/src/stores/filter/QueryBuilderFilterState.ts
+++ b/packages/legend-query-builder/src/stores/filter/QueryBuilderFilterState.ts
@@ -134,9 +134,12 @@ export class FilterConditionState implements Hashable {
this.propertyExpressionState.propertyExpression,
this.value,
),
- guaranteeNonNullable(this.filterState.queryBuilderState.mapping),
guaranteeNonNullable(
- this.filterState.queryBuilderState.runtimeValue,
+ this.filterState.queryBuilderState.executionContextState.mapping,
+ ),
+ guaranteeNonNullable(
+ this.filterState.queryBuilderState.executionContextState
+ .runtimeValue,
),
this.filterState.queryBuilderState.graphManagerState.graph,
)) as ExecutionResult;
diff --git a/packages/legend-query-builder/src/stores/workflows/ClassQueryBuilderState.ts b/packages/legend-query-builder/src/stores/workflows/ClassQueryBuilderState.ts
index 18822322124..ce87e8d2162 100644
--- a/packages/legend-query-builder/src/stores/workflows/ClassQueryBuilderState.ts
+++ b/packages/legend-query-builder/src/stores/workflows/ClassQueryBuilderState.ts
@@ -44,7 +44,8 @@ export class ClassQueryBuilderState extends QueryBuilderState {
);
// cascading
const isCurrentMappingCompatible =
- this.mapping && compatibleMappings.includes(this.mapping);
+ this.executionContextState.mapping &&
+ compatibleMappings.includes(this.executionContextState.mapping);
if (this.isMappingReadOnly || isCurrentMappingCompatible) {
return;
}
diff --git a/packages/legend-query-builder/src/stores/workflows/ServiceQueryBuilderState.ts b/packages/legend-query-builder/src/stores/workflows/ServiceQueryBuilderState.ts
index 403a0502a6e..af2fad385f7 100644
--- a/packages/legend-query-builder/src/stores/workflows/ServiceQueryBuilderState.ts
+++ b/packages/legend-query-builder/src/stores/workflows/ServiceQueryBuilderState.ts
@@ -78,12 +78,8 @@ export class ServiceQueryBuilderState extends QueryBuilderState {
this.onExecutionContextChange = onExecutionContextChange;
if (service.execution instanceof PureSingleExecution) {
- assertTrue(
- Boolean(service.execution.mapping && service.execution.runtime),
- 'Service queries without runtime/mapping are not supported',
- );
- this.mapping = service.execution.mapping?.value;
- this.runtimeValue = service.execution.runtime;
+ this.executionContextState.mapping = service.execution.mapping?.value;
+ this.executionContextState.runtimeValue = service.execution.runtime;
} else if (service.execution instanceof PureMultiExecution) {
this.executionContexts = service.execution.executionParameters.map(
(ep) => ({
@@ -92,7 +88,6 @@ export class ServiceQueryBuilderState extends QueryBuilderState {
runtimeValue: ep.runtime,
}),
);
-
let selectedExecutionContext: ServiceExecutionContext;
if (executionContextKey) {
const matchingExecutionContext = this.executionContexts.find(
@@ -115,8 +110,9 @@ export class ServiceQueryBuilderState extends QueryBuilderState {
}
this.setSelectedExecutionContext(selectedExecutionContext);
- this.mapping = selectedExecutionContext.mapping;
- this.runtimeValue = selectedExecutionContext.runtimeValue;
+ this.executionContextState.mapping = selectedExecutionContext.mapping;
+ this.executionContextState.runtimeValue =
+ selectedExecutionContext.runtimeValue;
}
}