@finos/legend-query-builder 4.1.14 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts +6 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +189 -13
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/index.css +17 -1
- package/lib/index.css.map +1 -1
- package/lib/package.json +6 -6
- package/lib/stores/QueryBuilderStateHashUtils.d.ts +1 -0
- package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.js +1 -0
- package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +16 -5
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +78 -18
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +125 -2
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js +62 -3
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js +12 -192
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
- package/package.json +14 -14
- package/src/components/filter/QueryBuilderFilterPanel.tsx +355 -24
- package/src/stores/QueryBuilderStateHashUtils.ts +1 -0
- package/src/stores/filter/QueryBuilderFilterOperator.ts +1 -0
- package/src/stores/filter/QueryBuilderFilterState.ts +115 -27
- package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +244 -0
- package/src/stores/filter/QueryBuilderFilterValueSpecificationBuilder.ts +94 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.ts +37 -377
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +7 -1
@@ -19,217 +19,36 @@ import {
|
|
19
19
|
extractElementNameFromPath,
|
20
20
|
matchFunctionName,
|
21
21
|
LambdaFunctionInstanceValue,
|
22
|
-
VariableExpression,
|
23
22
|
AbstractPropertyExpression,
|
24
23
|
SimpleFunctionExpression,
|
25
|
-
|
24
|
+
LambdaFunction,
|
26
25
|
} from '@finos/legend-graph';
|
27
26
|
import {
|
28
27
|
guaranteeType,
|
29
28
|
guaranteeNonNullable,
|
30
29
|
assertTrue,
|
31
|
-
generateEnumerableNameFromToken,
|
32
30
|
} from '@finos/legend-shared';
|
33
31
|
import {
|
34
32
|
FilterConditionState,
|
35
33
|
type QueryBuilderFilterState,
|
36
34
|
} from '../QueryBuilderFilterState.js';
|
37
35
|
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../graph/QueryBuilderMetaModelConst.js';
|
38
|
-
import {
|
39
|
-
buildGenericLambdaFunctionInstanceValue,
|
40
|
-
simplifyValueExpression,
|
41
|
-
} from '../../QueryBuilderValueSpecificationHelper.js';
|
36
|
+
import { simplifyValueExpression } from '../../QueryBuilderValueSpecificationHelper.js';
|
42
37
|
import type { QueryBuilderFilterOperator } from '../QueryBuilderFilterOperator.js';
|
43
38
|
import { buildPropertyExpressionChain } from '../../QueryBuilderValueSpecificationBuilderHelper.js';
|
44
39
|
|
45
|
-
const getPropertyExpressionChainVariable = (
|
46
|
-
propertyExpression: AbstractPropertyExpression,
|
47
|
-
): VariableExpression => {
|
48
|
-
let currentExpression: ValueSpecification = propertyExpression;
|
49
|
-
while (currentExpression instanceof AbstractPropertyExpression) {
|
50
|
-
currentExpression = guaranteeNonNullable(
|
51
|
-
currentExpression.parametersValues[0],
|
52
|
-
);
|
53
|
-
// Take care of chains of subtype (a pattern that is not useful, but we want to support and rectify)
|
54
|
-
// $x.employees->subType(@Person)->subType(@Staff)
|
55
|
-
while (
|
56
|
-
currentExpression instanceof SimpleFunctionExpression &&
|
57
|
-
matchFunctionName(
|
58
|
-
currentExpression.functionName,
|
59
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
60
|
-
)
|
61
|
-
) {
|
62
|
-
currentExpression = guaranteeNonNullable(
|
63
|
-
currentExpression.parametersValues[0],
|
64
|
-
);
|
65
|
-
}
|
66
|
-
}
|
67
|
-
return guaranteeType(currentExpression, VariableExpression);
|
68
|
-
};
|
69
|
-
|
70
|
-
const buildFilterConditionExpressionWithExists = (
|
71
|
-
filterConditionState: FilterConditionState,
|
72
|
-
operatorFunctionFullPath: string,
|
73
|
-
): ValueSpecification => {
|
74
|
-
assertTrue(
|
75
|
-
filterConditionState.propertyExpressionState.requiresExistsHandling,
|
76
|
-
);
|
77
|
-
// 1. Decompose property expression
|
78
|
-
const expressions: (AbstractPropertyExpression | SimpleFunctionExpression)[] =
|
79
|
-
[];
|
80
|
-
let currentPropertyExpression: ValueSpecification =
|
81
|
-
buildPropertyExpressionChain(
|
82
|
-
filterConditionState.propertyExpressionState.propertyExpression,
|
83
|
-
filterConditionState.propertyExpressionState.queryBuilderState,
|
84
|
-
filterConditionState.filterState.lambdaParameterName,
|
85
|
-
);
|
86
|
-
while (
|
87
|
-
currentPropertyExpression instanceof AbstractPropertyExpression ||
|
88
|
-
(currentPropertyExpression instanceof SimpleFunctionExpression &&
|
89
|
-
matchFunctionName(
|
90
|
-
currentPropertyExpression.functionName,
|
91
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
92
|
-
))
|
93
|
-
) {
|
94
|
-
let exp: AbstractPropertyExpression | SimpleFunctionExpression;
|
95
|
-
if (currentPropertyExpression instanceof SimpleFunctionExpression) {
|
96
|
-
exp = new SimpleFunctionExpression(
|
97
|
-
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE),
|
98
|
-
);
|
99
|
-
} else {
|
100
|
-
exp = new AbstractPropertyExpression('');
|
101
|
-
exp.func = currentPropertyExpression.func;
|
102
|
-
}
|
103
|
-
// NOTE: we must retain the rest of the parameters as those are derived property parameters
|
104
|
-
exp.parametersValues =
|
105
|
-
currentPropertyExpression.parametersValues.length > 1
|
106
|
-
? currentPropertyExpression.parametersValues.slice(1)
|
107
|
-
: [];
|
108
|
-
expressions.push(exp);
|
109
|
-
currentPropertyExpression = guaranteeNonNullable(
|
110
|
-
currentPropertyExpression.parametersValues[0],
|
111
|
-
);
|
112
|
-
}
|
113
|
-
const rootVariable = guaranteeType(
|
114
|
-
currentPropertyExpression,
|
115
|
-
VariableExpression,
|
116
|
-
);
|
117
|
-
|
118
|
-
// 2. Traverse the list of decomposed property expression backward, every time we encounter a property of
|
119
|
-
// multiplicity many, create a new property expression and keep track of it to later form the lambda chain
|
120
|
-
const existsLambdaParamNames = [
|
121
|
-
...filterConditionState.existsLambdaParamNames,
|
122
|
-
];
|
123
|
-
const existsLambdaPropertyChains: ValueSpecification[] = [rootVariable];
|
124
|
-
let currentParamNameIndex = 0;
|
125
|
-
|
126
|
-
for (let i = expressions.length - 1; i >= 0; --i) {
|
127
|
-
const exp = expressions[i] as
|
128
|
-
| AbstractPropertyExpression
|
129
|
-
| SimpleFunctionExpression;
|
130
|
-
// just keep adding to the property chain
|
131
|
-
exp.parametersValues.unshift(
|
132
|
-
existsLambdaPropertyChains[
|
133
|
-
existsLambdaPropertyChains.length - 1
|
134
|
-
] as ValueSpecification,
|
135
|
-
);
|
136
|
-
existsLambdaPropertyChains[existsLambdaPropertyChains.length - 1] = exp;
|
137
|
-
// ... but if the property is of multiplicity multiple, start a new property chain
|
138
|
-
if (
|
139
|
-
exp instanceof AbstractPropertyExpression &&
|
140
|
-
(exp.func.value.multiplicity.upperBound === undefined ||
|
141
|
-
exp.func.value.multiplicity.upperBound > 1)
|
142
|
-
) {
|
143
|
-
// NOTE: we need to find/generate the property chain variable name
|
144
|
-
// here, by doing this, we try our best to respect original/user-input variable name
|
145
|
-
if (currentParamNameIndex > existsLambdaParamNames.length - 1) {
|
146
|
-
existsLambdaParamNames.push(
|
147
|
-
generateEnumerableNameFromToken(
|
148
|
-
existsLambdaParamNames,
|
149
|
-
filterConditionState.filterState.lambdaParameterName,
|
150
|
-
),
|
151
|
-
);
|
152
|
-
assertTrue(currentParamNameIndex === existsLambdaParamNames.length - 1);
|
153
|
-
}
|
154
|
-
existsLambdaPropertyChains.push(
|
155
|
-
new VariableExpression(
|
156
|
-
existsLambdaParamNames[currentParamNameIndex] as string,
|
157
|
-
Multiplicity.ONE,
|
158
|
-
),
|
159
|
-
);
|
160
|
-
currentParamNameIndex++;
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
// 3. Build each property chain into an exists() simple function expression
|
165
|
-
const simpleFunctionExpressions: SimpleFunctionExpression[] = [];
|
166
|
-
for (let i = 0; i < existsLambdaPropertyChains.length - 1; ++i) {
|
167
|
-
const simpleFunctionExpression = new SimpleFunctionExpression(
|
168
|
-
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS),
|
169
|
-
);
|
170
|
-
simpleFunctionExpression.parametersValues.push(
|
171
|
-
existsLambdaPropertyChains[i] as ValueSpecification,
|
172
|
-
);
|
173
|
-
simpleFunctionExpressions.push(simpleFunctionExpression);
|
174
|
-
}
|
175
|
-
// build the leaf simple function expression which uses the operator
|
176
|
-
const operatorEpression = new SimpleFunctionExpression(
|
177
|
-
extractElementNameFromPath(operatorFunctionFullPath),
|
178
|
-
);
|
179
|
-
operatorEpression.parametersValues.push(
|
180
|
-
existsLambdaPropertyChains[
|
181
|
-
existsLambdaPropertyChains.length - 1
|
182
|
-
] as ValueSpecification,
|
183
|
-
);
|
184
|
-
// NOTE: there are simple operators which do not require any params (e.g. isEmpty)
|
185
|
-
if (filterConditionState.value) {
|
186
|
-
operatorEpression.parametersValues.push(filterConditionState.value);
|
187
|
-
}
|
188
|
-
simpleFunctionExpressions.push(operatorEpression);
|
189
|
-
|
190
|
-
// 4. Build the exists() lambda chain
|
191
|
-
assertTrue(simpleFunctionExpressions.length >= 2);
|
192
|
-
for (let i = simpleFunctionExpressions.length - 2; i >= 0; --i) {
|
193
|
-
const currentSFE = simpleFunctionExpressions[i] as SimpleFunctionExpression;
|
194
|
-
const childSFE = simpleFunctionExpressions[
|
195
|
-
i + 1
|
196
|
-
] as SimpleFunctionExpression;
|
197
|
-
// build child SFE lambda
|
198
|
-
const _existsLambdaVariable = childSFE.parametersValues[0];
|
199
|
-
const existsLambdaVariable =
|
200
|
-
_existsLambdaVariable instanceof AbstractPropertyExpression
|
201
|
-
? getPropertyExpressionChainVariable(_existsLambdaVariable)
|
202
|
-
: guaranteeType(_existsLambdaVariable, VariableExpression);
|
203
|
-
const existsLambda = buildGenericLambdaFunctionInstanceValue(
|
204
|
-
existsLambdaVariable.name,
|
205
|
-
[childSFE],
|
206
|
-
filterConditionState.filterState.queryBuilderState.graphManagerState
|
207
|
-
.graph,
|
208
|
-
);
|
209
|
-
// add the child SFE lambda to the current SFE parameters
|
210
|
-
currentSFE.parametersValues.push(existsLambda);
|
211
|
-
}
|
212
|
-
|
213
|
-
return simpleFunctionExpressions[0] as SimpleFunctionExpression;
|
214
|
-
};
|
215
|
-
|
216
40
|
export const buildFilterConditionExpression = (
|
217
41
|
filterConditionState: FilterConditionState,
|
218
42
|
operatorFunctionFullPath: string,
|
43
|
+
lambdaParameterName?: string | undefined,
|
219
44
|
): ValueSpecification => {
|
220
|
-
if (filterConditionState.propertyExpressionState.requiresExistsHandling) {
|
221
|
-
return buildFilterConditionExpressionWithExists(
|
222
|
-
filterConditionState,
|
223
|
-
operatorFunctionFullPath,
|
224
|
-
);
|
225
|
-
}
|
226
45
|
const expression = new SimpleFunctionExpression(
|
227
46
|
extractElementNameFromPath(operatorFunctionFullPath),
|
228
47
|
);
|
229
48
|
const propertyExpression = buildPropertyExpressionChain(
|
230
49
|
filterConditionState.propertyExpressionState.propertyExpression,
|
231
50
|
filterConditionState.propertyExpressionState.queryBuilderState,
|
232
|
-
filterConditionState.filterState.lambdaParameterName,
|
51
|
+
lambdaParameterName ?? filterConditionState.filterState.lambdaParameterName,
|
233
52
|
);
|
234
53
|
expression.parametersValues.push(guaranteeNonNullable(propertyExpression));
|
235
54
|
// NOTE: there are simple operators which do not require any params (e.g. isEmpty)
|
@@ -239,182 +58,6 @@ export const buildFilterConditionExpression = (
|
|
239
58
|
return expression;
|
240
59
|
};
|
241
60
|
|
242
|
-
/**
|
243
|
-
* Handling exists() lambda found in the filter condition expression.
|
244
|
-
* The general approach for handling exists() is we will flat out the chain
|
245
|
-
* of exists() expressions into a normal filter condition state.
|
246
|
-
*
|
247
|
-
* When we build the condition function expression from the filter condition state,
|
248
|
-
* we walk the property expression chain, find property with multiplitiy upper bound
|
249
|
-
* other than 1 and create an exists() lambda there
|
250
|
-
*
|
251
|
-
* NOTE: to ensure we respect user's choice of variable name, as we build the state
|
252
|
-
* we record the lambda parameter names, so we can use those while re-building the function
|
253
|
-
* If for some reason, this list is stale, we can start adding our own parameter names
|
254
|
-
*/
|
255
|
-
const buildFilterConditionStateWithExists = (
|
256
|
-
filterState: QueryBuilderFilterState,
|
257
|
-
parentExpression: SimpleFunctionExpression,
|
258
|
-
operatorFunctionFullPath: string,
|
259
|
-
): [FilterConditionState | undefined, SimpleFunctionExpression | undefined] => {
|
260
|
-
if (
|
261
|
-
matchFunctionName(
|
262
|
-
parentExpression.functionName,
|
263
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
264
|
-
)
|
265
|
-
) {
|
266
|
-
// 1. Decompose the exists() lambda chain into property expression chains
|
267
|
-
const existsLambdaParameterNames: string[] = [];
|
268
|
-
|
269
|
-
// `existsLambdaExpressions` should be a list of `AbstractPropertyExpression`
|
270
|
-
// e.g. |Firm.all()->filter(x|$x.employees->exists(x_1|$x_1->subType(@Develper).id->exists(x_2|$x_2 == 1))
|
271
|
-
// In the first exists() lambda, `$x_1->subType(@Develper).id` is an `AbstractPropertyExpression`.
|
272
|
-
const existsLambdaExpressions: AbstractPropertyExpression[] = [];
|
273
|
-
let mainFilterExpression: SimpleFunctionExpression = parentExpression;
|
274
|
-
while (
|
275
|
-
matchFunctionName(
|
276
|
-
mainFilterExpression.functionName,
|
277
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
278
|
-
)
|
279
|
-
) {
|
280
|
-
const existsLambda = guaranteeNonNullable(
|
281
|
-
guaranteeType(
|
282
|
-
mainFilterExpression.parametersValues[1],
|
283
|
-
LambdaFunctionInstanceValue,
|
284
|
-
).values[0],
|
285
|
-
`Can't process exists() expression: exists() lambda is missing`,
|
286
|
-
);
|
287
|
-
assertTrue(
|
288
|
-
existsLambda.expressionSequence.length === 1,
|
289
|
-
`Can't process exists() expression: exists() lambda body should hold an expression`,
|
290
|
-
);
|
291
|
-
mainFilterExpression = guaranteeType(
|
292
|
-
existsLambda.expressionSequence[0],
|
293
|
-
SimpleFunctionExpression,
|
294
|
-
`Can't process exists() expression: exists() lambda body should hold an expression`,
|
295
|
-
);
|
296
|
-
|
297
|
-
// record the lambda parameter name
|
298
|
-
assertTrue(
|
299
|
-
existsLambda.functionType.parameters.length === 1,
|
300
|
-
`Can't process exists() expression: exists() lambda should have 1 parameter`,
|
301
|
-
);
|
302
|
-
existsLambdaParameterNames.push(
|
303
|
-
guaranteeType(
|
304
|
-
existsLambda.functionType.parameters[0],
|
305
|
-
VariableExpression,
|
306
|
-
`Can't process exists() expression: exists() lambda should have 1 parameter`,
|
307
|
-
).name,
|
308
|
-
);
|
309
|
-
|
310
|
-
// record the lambda property expression
|
311
|
-
if (
|
312
|
-
mainFilterExpression.parametersValues[0] instanceof
|
313
|
-
AbstractPropertyExpression
|
314
|
-
) {
|
315
|
-
existsLambdaExpressions.push(mainFilterExpression.parametersValues[0]);
|
316
|
-
}
|
317
|
-
}
|
318
|
-
// NOTE: make sure that the inner most function expression is the one we support
|
319
|
-
if (
|
320
|
-
!matchFunctionName(
|
321
|
-
mainFilterExpression.functionName,
|
322
|
-
operatorFunctionFullPath,
|
323
|
-
)
|
324
|
-
) {
|
325
|
-
return [undefined, undefined];
|
326
|
-
}
|
327
|
-
|
328
|
-
// 2. Build the property expression
|
329
|
-
const initialPropertyExpression = guaranteeType(
|
330
|
-
parentExpression.parametersValues[0],
|
331
|
-
AbstractPropertyExpression,
|
332
|
-
);
|
333
|
-
let flattenedPropertyExpressionChain = new AbstractPropertyExpression('');
|
334
|
-
flattenedPropertyExpressionChain.func = initialPropertyExpression.func;
|
335
|
-
flattenedPropertyExpressionChain.parametersValues = [
|
336
|
-
...initialPropertyExpression.parametersValues,
|
337
|
-
];
|
338
|
-
|
339
|
-
for (const expression of existsLambdaExpressions) {
|
340
|
-
// when rebuilding the property expression chain, disregard the initial variable that starts the chain
|
341
|
-
const expressions: (
|
342
|
-
| AbstractPropertyExpression
|
343
|
-
| SimpleFunctionExpression
|
344
|
-
)[] = [];
|
345
|
-
let currentExpression: ValueSpecification = expression;
|
346
|
-
while (
|
347
|
-
currentExpression instanceof AbstractPropertyExpression ||
|
348
|
-
(currentExpression instanceof SimpleFunctionExpression &&
|
349
|
-
matchFunctionName(
|
350
|
-
currentExpression.functionName,
|
351
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
352
|
-
))
|
353
|
-
) {
|
354
|
-
if (currentExpression instanceof SimpleFunctionExpression) {
|
355
|
-
const functionExpression = new SimpleFunctionExpression(
|
356
|
-
extractElementNameFromPath(
|
357
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
358
|
-
),
|
359
|
-
);
|
360
|
-
functionExpression.parametersValues.unshift(
|
361
|
-
guaranteeNonNullable(currentExpression.parametersValues[1]),
|
362
|
-
);
|
363
|
-
expressions.push(functionExpression);
|
364
|
-
} else if (currentExpression instanceof AbstractPropertyExpression) {
|
365
|
-
const propertyExpression = new AbstractPropertyExpression('');
|
366
|
-
propertyExpression.func = currentExpression.func;
|
367
|
-
// NOTE: we must retain the rest of the parameters as those are derived property parameters
|
368
|
-
propertyExpression.parametersValues =
|
369
|
-
currentExpression.parametersValues.length > 1
|
370
|
-
? currentExpression.parametersValues.slice(1)
|
371
|
-
: [];
|
372
|
-
expressions.push(propertyExpression);
|
373
|
-
}
|
374
|
-
currentExpression = guaranteeNonNullable(
|
375
|
-
currentExpression.parametersValues[0],
|
376
|
-
);
|
377
|
-
}
|
378
|
-
assertTrue(
|
379
|
-
expressions.length > 0,
|
380
|
-
`Can't process exists() expression: exists() usage with non-chain property expression is not supported`,
|
381
|
-
);
|
382
|
-
for (let i = 0; i < expressions.length - 1; ++i) {
|
383
|
-
(
|
384
|
-
expressions[i] as
|
385
|
-
| AbstractPropertyExpression
|
386
|
-
| SimpleFunctionExpression
|
387
|
-
).parametersValues.unshift(
|
388
|
-
expressions[i + 1] as
|
389
|
-
| AbstractPropertyExpression
|
390
|
-
| SimpleFunctionExpression,
|
391
|
-
);
|
392
|
-
}
|
393
|
-
(
|
394
|
-
expressions[expressions.length - 1] as
|
395
|
-
| AbstractPropertyExpression
|
396
|
-
| SimpleFunctionExpression
|
397
|
-
).parametersValues.unshift(flattenedPropertyExpressionChain);
|
398
|
-
flattenedPropertyExpressionChain = guaranteeType(
|
399
|
-
expressions[0],
|
400
|
-
AbstractPropertyExpression,
|
401
|
-
`Can't process exists() expression: can't flatten to a property expression`,
|
402
|
-
);
|
403
|
-
}
|
404
|
-
|
405
|
-
// 3. Build the filter condition state with the simplified property expression
|
406
|
-
const filterConditionState = new FilterConditionState(
|
407
|
-
filterState,
|
408
|
-
flattenedPropertyExpressionChain,
|
409
|
-
);
|
410
|
-
existsLambdaParameterNames.forEach((paramName) =>
|
411
|
-
filterConditionState.addExistsLambdaParamNames(paramName),
|
412
|
-
);
|
413
|
-
return [filterConditionState, mainFilterExpression];
|
414
|
-
}
|
415
|
-
return [undefined, undefined];
|
416
|
-
};
|
417
|
-
|
418
61
|
export const buildFilterConditionState = (
|
419
62
|
filterState: QueryBuilderFilterState,
|
420
63
|
expression: SimpleFunctionExpression,
|
@@ -451,17 +94,6 @@ export const buildFilterConditionState = (
|
|
451
94
|
)}() expression: expects property expression in lambda body`,
|
452
95
|
);
|
453
96
|
|
454
|
-
const variableName =
|
455
|
-
getPropertyExpressionChainVariable(propertyExpression).name;
|
456
|
-
assertTrue(
|
457
|
-
filterState.lambdaParameterName === variableName,
|
458
|
-
`Can't process ${extractElementNameFromPath(
|
459
|
-
operatorFunctionFullPath,
|
460
|
-
)}() expression: expects variable used in lambda body '${variableName}' to match lambda parameter '${
|
461
|
-
filterState.lambdaParameterName
|
462
|
-
}'`,
|
463
|
-
);
|
464
|
-
|
465
97
|
filterConditionState = new FilterConditionState(
|
466
98
|
filterState,
|
467
99
|
propertyExpression,
|
@@ -473,12 +105,40 @@ export const buildFilterConditionState = (
|
|
473
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
474
106
|
)
|
475
107
|
) {
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
108
|
+
const lambdaFunctionInstance = guaranteeType(
|
109
|
+
expression.parametersValues[1],
|
110
|
+
LambdaFunctionInstanceValue,
|
111
|
+
);
|
112
|
+
const lambdaFunction = guaranteeType(
|
113
|
+
lambdaFunctionInstance.values[0],
|
114
|
+
LambdaFunction,
|
115
|
+
);
|
116
|
+
const filterExpression = guaranteeType(
|
117
|
+
lambdaFunction.expressionSequence[0],
|
118
|
+
SimpleFunctionExpression,
|
119
|
+
);
|
120
|
+
assertTrue(
|
121
|
+
filterExpression.parametersValues.length === (hasNoValue ? 1 : 2),
|
122
|
+
`Can't process ${extractElementNameFromPath(
|
480
123
|
operatorFunctionFullPath,
|
481
|
-
)
|
124
|
+
)}() expression: ${extractElementNameFromPath(
|
125
|
+
operatorFunctionFullPath,
|
126
|
+
)}() expects ${hasNoValue ? 'no argument' : '1 argument'}`,
|
127
|
+
);
|
128
|
+
|
129
|
+
const propertyExpression = guaranteeType(
|
130
|
+
filterExpression.parametersValues[0],
|
131
|
+
AbstractPropertyExpression,
|
132
|
+
`Can't process ${extractElementNameFromPath(
|
133
|
+
operatorFunctionFullPath,
|
134
|
+
)}() expression: expects property expression in lambda body`,
|
135
|
+
);
|
136
|
+
|
137
|
+
filterConditionState = new FilterConditionState(
|
138
|
+
filterState,
|
139
|
+
propertyExpression,
|
140
|
+
);
|
141
|
+
mainExpressionWithOperator = filterExpression;
|
482
142
|
}
|
483
143
|
|
484
144
|
// Post-build check: make sure the simple filter condition LHS, RHS, and operator are compatible
|
@@ -98,10 +98,12 @@ export class QueryBuilderFilterOperator_Contain
|
|
98
98
|
|
99
99
|
buildFilterConditionExpression(
|
100
100
|
filterConditionState: FilterConditionState,
|
101
|
+
lambdaParameterName?: string | undefined,
|
101
102
|
): ValueSpecification {
|
102
103
|
return buildFilterConditionExpression(
|
103
104
|
filterConditionState,
|
104
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.CONTAINS,
|
106
|
+
lambdaParameterName,
|
105
107
|
);
|
106
108
|
}
|
107
109
|
|
@@ -131,9 +133,13 @@ export class QueryBuilderFilterOperator_NotContain extends QueryBuilderFilterOpe
|
|
131
133
|
|
132
134
|
override buildFilterConditionExpression(
|
133
135
|
filterConditionState: FilterConditionState,
|
136
|
+
lambdaParameterName?: string | undefined,
|
134
137
|
): ValueSpecification {
|
135
138
|
return buildNotExpression(
|
136
|
-
super.buildFilterConditionExpression(
|
139
|
+
super.buildFilterConditionExpression(
|
140
|
+
filterConditionState,
|
141
|
+
lambdaParameterName,
|
142
|
+
),
|
137
143
|
);
|
138
144
|
}
|
139
145
|
|
@@ -98,10 +98,12 @@ export class QueryBuilderFilterOperator_EndWith
|
|
98
98
|
|
99
99
|
buildFilterConditionExpression(
|
100
100
|
filterConditionState: FilterConditionState,
|
101
|
+
lambdaParameterName?: string | undefined,
|
101
102
|
): ValueSpecification {
|
102
103
|
return buildFilterConditionExpression(
|
103
104
|
filterConditionState,
|
104
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.ENDS_WITH,
|
106
|
+
lambdaParameterName,
|
105
107
|
);
|
106
108
|
}
|
107
109
|
|
@@ -131,9 +133,13 @@ export class QueryBuilderFilterOperator_NotEndWith extends QueryBuilderFilterOpe
|
|
131
133
|
|
132
134
|
override buildFilterConditionExpression(
|
133
135
|
filterConditionState: FilterConditionState,
|
136
|
+
lambdaParameterName?: string | undefined,
|
134
137
|
): ValueSpecification {
|
135
138
|
return buildNotExpression(
|
136
|
-
super.buildFilterConditionExpression(
|
139
|
+
super.buildFilterConditionExpression(
|
140
|
+
filterConditionState,
|
141
|
+
lambdaParameterName,
|
142
|
+
),
|
137
143
|
);
|
138
144
|
}
|
139
145
|
|
@@ -165,6 +165,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
165
165
|
|
166
166
|
buildFilterConditionExpression(
|
167
167
|
filterConditionState: FilterConditionState,
|
168
|
+
lambdaParameterName?: string | undefined,
|
168
169
|
): ValueSpecification {
|
169
170
|
return buildFilterConditionExpression(
|
170
171
|
filterConditionState,
|
@@ -174,6 +175,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
174
175
|
PRIMITIVE_TYPE.DATETIME
|
175
176
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_DAY
|
176
177
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.EQUAL,
|
178
|
+
lambdaParameterName,
|
177
179
|
);
|
178
180
|
}
|
179
181
|
|
@@ -208,9 +210,13 @@ export class QueryBuilderFilterOperator_NotEqual extends QueryBuilderFilterOpera
|
|
208
210
|
|
209
211
|
override buildFilterConditionExpression(
|
210
212
|
filterConditionState: FilterConditionState,
|
213
|
+
lambdaParameterName?: string | undefined,
|
211
214
|
): ValueSpecification {
|
212
215
|
return buildNotExpression(
|
213
|
-
super.buildFilterConditionExpression(
|
216
|
+
super.buildFilterConditionExpression(
|
217
|
+
filterConditionState,
|
218
|
+
lambdaParameterName,
|
219
|
+
),
|
214
220
|
);
|
215
221
|
}
|
216
222
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
123
123
|
|
124
124
|
buildFilterConditionExpression(
|
125
125
|
filterConditionState: FilterConditionState,
|
126
|
+
lambdaParameterName?: string | undefined,
|
126
127
|
): ValueSpecification {
|
127
128
|
return buildFilterConditionExpression(
|
128
129
|
filterConditionState,
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_AFTER_DAY
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.GREATER_THAN,
|
136
|
+
lambdaParameterName,
|
135
137
|
);
|
136
138
|
}
|
137
139
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_GreaterThanEqual
|
|
123
123
|
|
124
124
|
buildFilterConditionExpression(
|
125
125
|
filterConditionState: FilterConditionState,
|
126
|
+
lambdaParameterName?: string | undefined,
|
126
127
|
): ValueSpecification {
|
127
128
|
return buildFilterConditionExpression(
|
128
129
|
filterConditionState,
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_GreaterThanEqual
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_OR_AFTER_DAY
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.GREATER_THAN_EQUAL,
|
136
|
+
lambdaParameterName,
|
135
137
|
);
|
136
138
|
}
|
137
139
|
|
@@ -135,10 +135,12 @@ export class QueryBuilderFilterOperator_In
|
|
135
135
|
|
136
136
|
buildFilterConditionExpression(
|
137
137
|
filterConditionState: FilterConditionState,
|
138
|
+
lambdaParameterName?: string | undefined,
|
138
139
|
): ValueSpecification {
|
139
140
|
return buildFilterConditionExpression(
|
140
141
|
filterConditionState,
|
141
142
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.IN,
|
143
|
+
lambdaParameterName,
|
142
144
|
);
|
143
145
|
}
|
144
146
|
|
@@ -166,9 +168,13 @@ export class QueryBuilderFilterOperator_NotIn extends QueryBuilderFilterOperator
|
|
166
168
|
|
167
169
|
override buildFilterConditionExpression(
|
168
170
|
filterConditionState: FilterConditionState,
|
171
|
+
lambdaParameterName?: string | undefined,
|
169
172
|
): ValueSpecification {
|
170
173
|
return buildNotExpression(
|
171
|
-
super.buildFilterConditionExpression(
|
174
|
+
super.buildFilterConditionExpression(
|
175
|
+
filterConditionState,
|
176
|
+
lambdaParameterName,
|
177
|
+
),
|
172
178
|
);
|
173
179
|
}
|
174
180
|
|
@@ -80,10 +80,12 @@ export class QueryBuilderFilterOperator_IsEmpty
|
|
80
80
|
|
81
81
|
buildFilterConditionExpression(
|
82
82
|
filterConditionState: FilterConditionState,
|
83
|
+
lambdaParameterName?: string | undefined,
|
83
84
|
): ValueSpecification {
|
84
85
|
return buildFilterConditionExpression(
|
85
86
|
filterConditionState,
|
86
87
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_EMPTY,
|
88
|
+
lambdaParameterName,
|
87
89
|
);
|
88
90
|
}
|
89
91
|
|
@@ -114,9 +116,13 @@ export class QueryBuilderFilterOperator_IsNotEmpty extends QueryBuilderFilterOpe
|
|
114
116
|
|
115
117
|
override buildFilterConditionExpression(
|
116
118
|
filterConditionState: FilterConditionState,
|
119
|
+
lambdaParameterName?: string | undefined,
|
117
120
|
): ValueSpecification {
|
118
121
|
return buildNotExpression(
|
119
|
-
super.buildFilterConditionExpression(
|
122
|
+
super.buildFilterConditionExpression(
|
123
|
+
filterConditionState,
|
124
|
+
lambdaParameterName,
|
125
|
+
),
|
120
126
|
);
|
121
127
|
}
|
122
128
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_LessThan
|
|
123
123
|
|
124
124
|
buildFilterConditionExpression(
|
125
125
|
filterConditionState: FilterConditionState,
|
126
|
+
lambdaParameterName?: string | undefined,
|
126
127
|
): ValueSpecification {
|
127
128
|
return buildFilterConditionExpression(
|
128
129
|
filterConditionState,
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_LessThan
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_BEFORE_DAY
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.LESS_THAN,
|
136
|
+
lambdaParameterName,
|
135
137
|
);
|
136
138
|
}
|
137
139
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_LessThanEqual
|
|
123
123
|
|
124
124
|
buildFilterConditionExpression(
|
125
125
|
filterConditionState: FilterConditionState,
|
126
|
+
lambdaParameterName?: string | undefined,
|
126
127
|
): ValueSpecification {
|
127
128
|
return buildFilterConditionExpression(
|
128
129
|
filterConditionState,
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_LessThanEqual
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_OR_BEFORE_DAY
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.LESS_THAN_EQUAL,
|
136
|
+
lambdaParameterName,
|
135
137
|
);
|
136
138
|
}
|
137
139
|
|