@finos/legend-query-builder 4.12.0 → 4.13.1
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +28 -2
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/graph/QueryBuilderMetaModelConst.d.ts +2 -1
- package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
- package/lib/graph/QueryBuilderMetaModelConst.js +2 -0
- package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
- package/lib/index.css +17 -1
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
- package/lib/stores/QueryBuilderStateBuilder.js +5 -1
- package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.d.ts +2 -0
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js +6 -0
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts +1 -0
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +26 -2
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +16 -0
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
- package/package.json +4 -4
- package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +84 -0
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +13 -0
- package/src/graph/QueryBuilderMetaModelConst.ts +3 -0
- package/src/stores/QueryBuilderStateBuilder.ts +10 -0
- package/src/stores/fetch-structure/tds/QueryResultSetModifierState.ts +7 -0
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +64 -0
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +27 -0
@@ -202,6 +202,40 @@ export const QueryResultModifierModal = observer(
|
|
202
202
|
);
|
203
203
|
};
|
204
204
|
|
205
|
+
const handleSliceStartChange = (start: number, end: number): void => {
|
206
|
+
const slice: [number, number] = [start, end];
|
207
|
+
resultSetModifierState.setSlice(slice);
|
208
|
+
};
|
209
|
+
|
210
|
+
const clearSlice = (): void => {
|
211
|
+
resultSetModifierState.setSlice(undefined);
|
212
|
+
};
|
213
|
+
|
214
|
+
const addSlice = (): void => {
|
215
|
+
resultSetModifierState.setSlice([0, 1]);
|
216
|
+
};
|
217
|
+
|
218
|
+
const changeSliceStart: React.ChangeEventHandler<HTMLInputElement> = (
|
219
|
+
event,
|
220
|
+
) => {
|
221
|
+
const currentSlice = resultSetModifierState.slice;
|
222
|
+
const val = event.target.value;
|
223
|
+
const start = typeof val === 'number' ? val : parseInt(val, 10);
|
224
|
+
if (currentSlice) {
|
225
|
+
handleSliceStartChange(start, currentSlice[1]);
|
226
|
+
}
|
227
|
+
};
|
228
|
+
const changeSliceEnd: React.ChangeEventHandler<HTMLInputElement> = (
|
229
|
+
event,
|
230
|
+
) => {
|
231
|
+
const currentSlice = resultSetModifierState.slice;
|
232
|
+
const val = event.target.value;
|
233
|
+
const end = typeof val === 'number' ? val : parseInt(val, 10);
|
234
|
+
if (currentSlice) {
|
235
|
+
handleSliceStartChange(currentSlice[0], end);
|
236
|
+
}
|
237
|
+
};
|
238
|
+
|
205
239
|
return (
|
206
240
|
<Dialog
|
207
241
|
open={Boolean(resultSetModifierState.showModal)}
|
@@ -258,6 +292,56 @@ export const QueryResultModifierModal = observer(
|
|
258
292
|
onChange={changeValue}
|
259
293
|
/>
|
260
294
|
</div>
|
295
|
+
<div className="panel__content__form__section">
|
296
|
+
<div className="panel__content__form__section__header__label">
|
297
|
+
Slice
|
298
|
+
</div>
|
299
|
+
<div className="panel__content__form__section__header__prompt">
|
300
|
+
Reduce the number of rows in the provided TDS, selecting the
|
301
|
+
set of rows in the specified range between start and stop
|
302
|
+
</div>
|
303
|
+
{resultSetModifierState.slice ? (
|
304
|
+
<>
|
305
|
+
<div className="query-builder__result__slice">
|
306
|
+
<input
|
307
|
+
className="input--dark query-builder__result__slice__input"
|
308
|
+
spellCheck={false}
|
309
|
+
value={resultSetModifierState.slice[0]}
|
310
|
+
onChange={changeSliceStart}
|
311
|
+
type="number"
|
312
|
+
/>
|
313
|
+
<div className="query-builder__result__slice__range">
|
314
|
+
..
|
315
|
+
</div>
|
316
|
+
<input
|
317
|
+
className="input--dark query-builder__result__slice__input"
|
318
|
+
spellCheck={false}
|
319
|
+
value={resultSetModifierState.slice[1]}
|
320
|
+
onChange={changeSliceEnd}
|
321
|
+
type="number"
|
322
|
+
/>
|
323
|
+
<button
|
324
|
+
className="query-builder__projection__options__sort__remove-btn btn--dark btn--caution"
|
325
|
+
onClick={clearSlice}
|
326
|
+
tabIndex={-1}
|
327
|
+
title="Remove"
|
328
|
+
>
|
329
|
+
<TimesIcon />
|
330
|
+
</button>
|
331
|
+
</div>
|
332
|
+
</>
|
333
|
+
) : (
|
334
|
+
<div className="panel__content__form__section__list__new-item__add">
|
335
|
+
<button
|
336
|
+
className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
|
337
|
+
onClick={addSlice}
|
338
|
+
tabIndex={-1}
|
339
|
+
>
|
340
|
+
Add Slice
|
341
|
+
</button>
|
342
|
+
</div>
|
343
|
+
)}
|
344
|
+
</div>
|
261
345
|
</div>
|
262
346
|
</ModalBody>
|
263
347
|
<ModalFooter>
|
@@ -1142,6 +1142,19 @@ export const QueryBuilderTDSPanel = observer(
|
|
1142
1142
|
)}
|
1143
1143
|
</div>
|
1144
1144
|
)}
|
1145
|
+
{tdsState.resultSetModifierState.slice && (
|
1146
|
+
<div className="query-builder__projection__result-modifier-prompt__group">
|
1147
|
+
<div className="query-builder__projection__result-modifier-prompt__group__label">
|
1148
|
+
Slice
|
1149
|
+
</div>
|
1150
|
+
<div
|
1151
|
+
className="query-builder__projection__result-modifier-prompt__group__content"
|
1152
|
+
onClick={openResultSetModifierEditor}
|
1153
|
+
>
|
1154
|
+
{`${tdsState.resultSetModifierState.slice[0]},${tdsState.resultSetModifierState.slice[1]}`}
|
1155
|
+
</div>
|
1156
|
+
</div>
|
1157
|
+
)}
|
1145
1158
|
</div>
|
1146
1159
|
<div className="query-builder__projection__toolbar__actions">
|
1147
1160
|
<button
|
@@ -158,6 +158,9 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
|
|
158
158
|
// TOTDS
|
159
159
|
TABLE_TO_TDS = 'meta::pure::tds::tableToTDS',
|
160
160
|
TABLE_REFERENCE = 'meta::relational::functions::database::tableReference',
|
161
|
+
|
162
|
+
// SLICE
|
163
|
+
SLICE = 'meta::pure::functions::collection::slice',
|
161
164
|
}
|
162
165
|
|
163
166
|
export enum TDS_COLUMN_GETTER {
|
@@ -71,6 +71,7 @@ import {
|
|
71
71
|
processTDSProjectExpression,
|
72
72
|
processTDSProjectionColumnPropertyExpression,
|
73
73
|
processTDSProjectionDerivationExpression,
|
74
|
+
processTDSSliceExpression,
|
74
75
|
processTDSSortDirectionExpression,
|
75
76
|
processTDSSortExpression,
|
76
77
|
processTDSTakeExpression,
|
@@ -641,6 +642,15 @@ export class QueryBuilderValueSpecificationProcessor
|
|
641
642
|
this.parentLambda,
|
642
643
|
);
|
643
644
|
return;
|
645
|
+
} else if (
|
646
|
+
matchFunctionName(functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.SLICE)
|
647
|
+
) {
|
648
|
+
processTDSSliceExpression(
|
649
|
+
valueSpecification,
|
650
|
+
this.queryBuilderState,
|
651
|
+
this.parentLambda,
|
652
|
+
);
|
653
|
+
return;
|
644
654
|
} else if (
|
645
655
|
matchFunctionName(functionName, [
|
646
656
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_ASC,
|
@@ -65,6 +65,7 @@ export class QueryResultSetModifierState implements Hashable {
|
|
65
65
|
limit?: number | undefined;
|
66
66
|
distinct = false;
|
67
67
|
sortColumns: SortColumnState[] = [];
|
68
|
+
slice: [number, number] | undefined;
|
68
69
|
|
69
70
|
constructor(tdsState: QueryBuilderTDSState) {
|
70
71
|
makeObservable(this, {
|
@@ -72,12 +73,14 @@ export class QueryResultSetModifierState implements Hashable {
|
|
72
73
|
limit: observable,
|
73
74
|
distinct: observable,
|
74
75
|
sortColumns: observable,
|
76
|
+
slice: observable.ref,
|
75
77
|
setShowModal: action,
|
76
78
|
setLimit: action,
|
77
79
|
toggleDistinct: action,
|
78
80
|
deleteSortColumn: action,
|
79
81
|
addSortColumn: action,
|
80
82
|
updateSortColumns: action,
|
83
|
+
setSlice: action,
|
81
84
|
reset: action,
|
82
85
|
hashCode: computed,
|
83
86
|
});
|
@@ -111,6 +114,10 @@ export class QueryResultSetModifierState implements Hashable {
|
|
111
114
|
);
|
112
115
|
}
|
113
116
|
|
117
|
+
setSlice(slice: [number, number] | undefined): void {
|
118
|
+
this.slice = slice;
|
119
|
+
}
|
120
|
+
|
114
121
|
reset(): void {
|
115
122
|
this.sortColumns = [];
|
116
123
|
this.distinct = false;
|
@@ -27,11 +27,13 @@ import {
|
|
27
27
|
V1_deserializeRawValueSpecification,
|
28
28
|
V1_RawLambda,
|
29
29
|
VariableExpression,
|
30
|
+
PrimitiveInstanceValue,
|
30
31
|
} from '@finos/legend-graph';
|
31
32
|
import {
|
32
33
|
assertNonNullable,
|
33
34
|
assertTrue,
|
34
35
|
assertType,
|
36
|
+
guaranteeIsNumber,
|
35
37
|
guaranteeNonNullable,
|
36
38
|
guaranteeType,
|
37
39
|
isNonNullable,
|
@@ -385,6 +387,68 @@ export const processTDSSortExpression = (
|
|
385
387
|
);
|
386
388
|
};
|
387
389
|
|
390
|
+
export const processTDSSliceExpression = (
|
391
|
+
exp: SimpleFunctionExpression,
|
392
|
+
queryBuilderState: QueryBuilderState,
|
393
|
+
parentLambda: LambdaFunction,
|
394
|
+
): void => {
|
395
|
+
// check parameters
|
396
|
+
assertTrue(
|
397
|
+
exp.parametersValues.length === 3,
|
398
|
+
`Can't process slice() expression: slice() expects 2 argument`,
|
399
|
+
);
|
400
|
+
|
401
|
+
// check preceding expression
|
402
|
+
const precedingExpression = guaranteeType(
|
403
|
+
exp.parametersValues[0],
|
404
|
+
SimpleFunctionExpression,
|
405
|
+
`Can't process slice() expression: only support slice() immediately following an expression`,
|
406
|
+
);
|
407
|
+
assertTrue(
|
408
|
+
matchFunctionName(precedingExpression.functionName, [
|
409
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_TAKE,
|
410
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_DISTINCT,
|
411
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_SORT,
|
412
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
|
413
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_GROUP_BY,
|
414
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_FILTER,
|
415
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.OLAP_GROUPBY,
|
416
|
+
]),
|
417
|
+
`Can't process slice() expression: only support slice() in TDS expression`,
|
418
|
+
);
|
419
|
+
QueryBuilderValueSpecificationProcessor.process(
|
420
|
+
precedingExpression,
|
421
|
+
parentLambda,
|
422
|
+
queryBuilderState,
|
423
|
+
);
|
424
|
+
|
425
|
+
// build state
|
426
|
+
if (
|
427
|
+
queryBuilderState.fetchStructureState.implementation instanceof
|
428
|
+
QueryBuilderTDSState
|
429
|
+
) {
|
430
|
+
const tdsState = queryBuilderState.fetchStructureState.implementation;
|
431
|
+
const start = guaranteeIsNumber(
|
432
|
+
guaranteeType(
|
433
|
+
exp.parametersValues[1],
|
434
|
+
PrimitiveInstanceValue,
|
435
|
+
'Can`t process slice() function: first param should be a primitive instance value',
|
436
|
+
).values[0],
|
437
|
+
'Can`t process slice() function: first param should be a number primitive instance value',
|
438
|
+
);
|
439
|
+
|
440
|
+
const end = guaranteeIsNumber(
|
441
|
+
guaranteeType(
|
442
|
+
exp.parametersValues[2],
|
443
|
+
PrimitiveInstanceValue,
|
444
|
+
'Can`t process slice() function: first param should be a primitive instance value',
|
445
|
+
).values[0],
|
446
|
+
'Can`t process slice() function: first param should be a number primitive instance value',
|
447
|
+
);
|
448
|
+
tdsState.resultSetModifierState.setSlice([start, end]);
|
449
|
+
}
|
450
|
+
};
|
451
|
+
|
388
452
|
export const processTDSSortDirectionExpression = (
|
389
453
|
expression: SimpleFunctionExpression,
|
390
454
|
parentExpression: SimpleFunctionExpression | undefined,
|
package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts
CHANGED
@@ -136,6 +136,33 @@ const appendResultSetModifier = (
|
|
136
136
|
takeFunction.parametersValues[1] = limit;
|
137
137
|
currentExpression = takeFunction;
|
138
138
|
}
|
139
|
+
// build slice()
|
140
|
+
if (resultModifierState.slice) {
|
141
|
+
const sliceStart = resultModifierState.slice[0];
|
142
|
+
const sliceEnd = resultModifierState.slice[1];
|
143
|
+
const startVal = new PrimitiveInstanceValue(
|
144
|
+
GenericTypeExplicitReference.create(
|
145
|
+
new GenericType(PrimitiveType.INTEGER),
|
146
|
+
),
|
147
|
+
);
|
148
|
+
const endVal = new PrimitiveInstanceValue(
|
149
|
+
GenericTypeExplicitReference.create(
|
150
|
+
new GenericType(PrimitiveType.INTEGER),
|
151
|
+
),
|
152
|
+
);
|
153
|
+
startVal.values = [sliceStart];
|
154
|
+
endVal.values = [sliceEnd];
|
155
|
+
const sliceFunction = new SimpleFunctionExpression(
|
156
|
+
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SLICE),
|
157
|
+
);
|
158
|
+
sliceFunction.parametersValues = [
|
159
|
+
currentExpression,
|
160
|
+
startVal,
|
161
|
+
endVal,
|
162
|
+
];
|
163
|
+
currentExpression = sliceFunction;
|
164
|
+
}
|
165
|
+
|
139
166
|
lambdaFunction.expressionSequence[0] = currentExpression;
|
140
167
|
return lambdaFunction;
|
141
168
|
}
|