@sisense/sdk-query-client 1.0.0 → 1.2.0
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/dist/interfaces.d.ts +2 -1
- package/dist/jaql/get-jaql-query-payload.d.ts +9 -1
- package/dist/jaql/get-jaql-query-payload.js +70 -5
- package/dist/query-client.d.ts +21 -2
- package/dist/query-client.js +68 -5
- package/dist/query-task-manager/query-task-manager.d.ts +24 -3
- package/dist/query-task-manager/query-task-manager.js +45 -2
- package/dist/query-task-manager/query-task-passport.d.ts +7 -1
- package/dist/query-task-manager/query-task-passport.js +8 -0
- package/dist/types.d.ts +44 -1
- package/package.json +6 -4
package/dist/interfaces.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { DataSourceField, ExecutingCsvQueryResult, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
1
|
+
import { DataSourceField, ExecutingCsvQueryResult, ExecutingPivotQueryResult, ExecutingQueryResult, PivotQueryDescription, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
2
2
|
import { DataSource } from '@sisense/sdk-data';
|
|
3
3
|
export interface QueryClient {
|
|
4
4
|
executeQuery(params: QueryDescription, config?: QueryExecutionConfig): ExecutingQueryResult;
|
|
5
5
|
executeCsvQuery(params: QueryDescription, config?: QueryExecutionConfig): ExecutingCsvQueryResult;
|
|
6
|
+
executePivotQuery(params: PivotQueryDescription, config?: QueryExecutionConfig): ExecutingPivotQueryResult;
|
|
6
7
|
getDataSourceFields(dataSource: DataSource): Promise<DataSourceField[]>;
|
|
7
8
|
}
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
import { JaqlQueryPayload, QueryDescription } from '../types.js';
|
|
1
|
+
import { JaqlQueryPayload, QueryDescription, PivotQueryDescription } from '../types.js';
|
|
2
2
|
export declare function getJaqlQueryPayload(queryDescription: QueryDescription, shouldSkipHighlightsWithoutAttributes: boolean): JaqlQueryPayload;
|
|
3
|
+
/**
|
|
4
|
+
* Converts a pivot query description to a JAQL query payload.
|
|
5
|
+
*
|
|
6
|
+
* @param pivotQueryDescription
|
|
7
|
+
* @param shouldSkipHighlightsWithoutAttributes
|
|
8
|
+
* @returns jaql query payload
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPivotJaqlQueryPayload(pivotQueryDescription: PivotQueryDescription, shouldSkipHighlightsWithoutAttributes: boolean): JaqlQueryPayload;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
/* eslint-disable complexity */
|
|
2
|
+
/* eslint-disable max-lines */
|
|
1
3
|
import { v4 as uuid } from 'uuid';
|
|
4
|
+
import merge from 'ts-deepmerge';
|
|
5
|
+
import { isPivotAttribute, isPivotMeasure, DEFAULT_PIVOT_GRAND_TOTALS, } from '@sisense/sdk-data';
|
|
2
6
|
import { applyHighlightFilters, matchHighlightsWithAttributes } from './metadata/highlights.js';
|
|
7
|
+
const JAQL_BY_CSDK = 'ComposeSDK';
|
|
3
8
|
export function getJaqlQueryPayload(queryDescription, shouldSkipHighlightsWithoutAttributes) {
|
|
4
9
|
const { attributes, measures, filters, filterRelations, highlights, dataSource, count, offset } = queryDescription;
|
|
5
10
|
const queryPayload = Object.assign({ metadata: prepareQueryMetadata({ attributes, measures, filters, filterRelations, highlights }, shouldSkipHighlightsWithoutAttributes) }, prepareQueryOptions(dataSource, count, offset));
|
|
@@ -8,10 +13,7 @@ export function getJaqlQueryPayload(queryDescription, shouldSkipHighlightsWithou
|
|
|
8
13
|
}
|
|
9
14
|
return queryPayload;
|
|
10
15
|
}
|
|
11
|
-
function
|
|
12
|
-
const { attributes, measures, filters, filterRelations, highlights } = metadataDescription;
|
|
13
|
-
const attributesMetadata = attributes.map((d) => d.jaql());
|
|
14
|
-
const measuresMetadata = measures.map((d) => d.jaql());
|
|
16
|
+
function prepareFilterMetadata(attributesMetadata, filters, filterRelations, highlights, shouldSkipHighlightsWithoutAttributes) {
|
|
15
17
|
const [highlightsWithAttributes, highlightsWithoutAttributes] = matchHighlightsWithAttributes(attributesMetadata, highlights);
|
|
16
18
|
attributesMetadata.forEach((d) => applyHighlightFilters(d, highlightsWithAttributes));
|
|
17
19
|
const getFilterJaql = (f) => {
|
|
@@ -30,8 +32,71 @@ function prepareQueryMetadata(metadataDescription, shouldSkipHighlightsWithoutAt
|
|
|
30
32
|
.map((f) => f.attribute.name)
|
|
31
33
|
.join(', ')}].`);
|
|
32
34
|
}
|
|
35
|
+
return filtersMetadata;
|
|
36
|
+
}
|
|
37
|
+
function prepareQueryMetadata(metadataDescription, shouldSkipHighlightsWithoutAttributes) {
|
|
38
|
+
const { attributes, measures, filters, filterRelations, highlights } = metadataDescription;
|
|
39
|
+
const attributesMetadata = attributes.map((d) => d.jaql());
|
|
40
|
+
const measuresMetadata = measures.map((d) => d.jaql());
|
|
41
|
+
const filtersMetadata = prepareFilterMetadata(attributesMetadata, filters, filterRelations, highlights, shouldSkipHighlightsWithoutAttributes);
|
|
33
42
|
return [...attributesMetadata, ...measuresMetadata, ...filtersMetadata];
|
|
34
43
|
}
|
|
35
44
|
function prepareQueryOptions(dataSource, count, offset) {
|
|
36
|
-
return Object.assign(Object.assign({ datasource: dataSource, by:
|
|
45
|
+
return Object.assign(Object.assign({ datasource: dataSource, by: JAQL_BY_CSDK, queryGuid: uuid() }, (count ? { count } : {})), (offset ? { offset } : {}));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converts a pivot query description to a JAQL query payload.
|
|
49
|
+
*
|
|
50
|
+
* @param pivotQueryDescription
|
|
51
|
+
* @param shouldSkipHighlightsWithoutAttributes
|
|
52
|
+
* @returns jaql query payload
|
|
53
|
+
*/
|
|
54
|
+
export function getPivotJaqlQueryPayload(pivotQueryDescription, shouldSkipHighlightsWithoutAttributes) {
|
|
55
|
+
const { rowsAttributes, columnsAttributes, measures, filters, filterRelations, grandTotals, highlights, dataSource, count, offset, } = pivotQueryDescription;
|
|
56
|
+
const queryPayload = Object.assign({ metadata: preparePivotQueryMetadata({ rowsAttributes, columnsAttributes, measures, filters, highlights }, shouldSkipHighlightsWithoutAttributes) }, preparePivotQueryOptions(dataSource, grandTotals, count, offset));
|
|
57
|
+
if (filterRelations) {
|
|
58
|
+
return Object.assign(Object.assign({}, queryPayload), { filterRelations });
|
|
59
|
+
}
|
|
60
|
+
return queryPayload;
|
|
61
|
+
}
|
|
62
|
+
function jaqlPivotAttribute(a, panel, index) {
|
|
63
|
+
return Object.assign(Object.assign(Object.assign({}, (isPivotAttribute(a) ? a.attribute.jaql() : a.jaql())), (isPivotAttribute(a) && a.includeSubTotals ? { format: { subtotal: true } } : {})), { panel, field: { index: index, id: `${panel}-${index}` } });
|
|
64
|
+
}
|
|
65
|
+
function jaqlPivotMeasure(m, panel, index) {
|
|
66
|
+
return Object.assign(Object.assign({}, (isPivotMeasure(m)
|
|
67
|
+
? merge(m.measure.jaql(), { jaql: { subtotalAgg: m.totalsCalculation } })
|
|
68
|
+
: m.jaql())), { panel, field: { index: index, id: `${panel}-${index}` }, format: { databars: false } });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Prepares the metadata part of the JAQL payload for a pivot query.
|
|
72
|
+
*
|
|
73
|
+
* @param pivotMetadataDescription
|
|
74
|
+
* @param shouldSkipHighlightsWithoutAttributes
|
|
75
|
+
* @returns array of metadata items of the JAQL payload
|
|
76
|
+
*/
|
|
77
|
+
function preparePivotQueryMetadata(pivotMetadataDescription, shouldSkipHighlightsWithoutAttributes) {
|
|
78
|
+
const { rowsAttributes, columnsAttributes, measures, filters, filterRelations, highlights } = pivotMetadataDescription;
|
|
79
|
+
let fieldIndex = 0; // used as a global counter to build field.index in Jaql MetadataItem
|
|
80
|
+
const rowsAttributesMetadata = rowsAttributes.map((a, index) => jaqlPivotAttribute(a, 'rows', index + fieldIndex));
|
|
81
|
+
fieldIndex = fieldIndex + rowsAttributes.length;
|
|
82
|
+
const columnsAttributesMetadata = columnsAttributes.map((a, index) => jaqlPivotAttribute(a, 'columns', index + fieldIndex));
|
|
83
|
+
fieldIndex = fieldIndex + columnsAttributes.length;
|
|
84
|
+
const attributesMetadata = [
|
|
85
|
+
...rowsAttributesMetadata,
|
|
86
|
+
...columnsAttributesMetadata,
|
|
87
|
+
];
|
|
88
|
+
const measuresMetadata = measures.map((m, index) => jaqlPivotMeasure(m, 'measures', index + fieldIndex));
|
|
89
|
+
const filtersMetadata = prepareFilterMetadata(attributesMetadata, filters, filterRelations, highlights, shouldSkipHighlightsWithoutAttributes);
|
|
90
|
+
return [...attributesMetadata, ...measuresMetadata, ...filtersMetadata];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Prepares the options part of the JAQL payload for a pivot query.
|
|
94
|
+
*
|
|
95
|
+
* @param dataSource
|
|
96
|
+
* @param grandTotals
|
|
97
|
+
* @param count
|
|
98
|
+
* @param offset
|
|
99
|
+
*/
|
|
100
|
+
function preparePivotQueryOptions(dataSource, grandTotals, count, offset) {
|
|
101
|
+
return Object.assign(Object.assign(Object.assign({ datasource: dataSource, by: JAQL_BY_CSDK, queryGuid: uuid(), dashboard: JAQL_BY_CSDK, widget: JAQL_BY_CSDK, format: 'pivot' }, (count ? { count } : {})), (offset ? { offset } : {})), { grandTotals: Object.assign(Object.assign({}, DEFAULT_PIVOT_GRAND_TOTALS), grandTotals) });
|
|
37
102
|
}
|
package/dist/query-client.d.ts
CHANGED
|
@@ -1,31 +1,50 @@
|
|
|
1
|
-
import { DataSourceField, ExecutingCsvQueryResult, ExecutingQueryResult, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
1
|
+
import { DataSourceField, ExecutingCsvQueryResult, ExecutingPivotQueryResult, ExecutingQueryResult, PivotQueryDescription, QueryDescription, QueryExecutionConfig } from './types.js';
|
|
2
2
|
import { QueryClient } from './interfaces.js';
|
|
3
3
|
import { DataSource } from '@sisense/sdk-data';
|
|
4
4
|
import { HttpClient } from '@sisense/sdk-rest-client';
|
|
5
|
+
import { PivotClient } from '@sisense/sdk-pivot-client';
|
|
5
6
|
/** @internal */
|
|
6
7
|
export declare const QUERY_DEFAULT_LIMIT = 20000;
|
|
7
8
|
export declare class DimensionalQueryClient implements QueryClient {
|
|
8
9
|
private taskManager;
|
|
9
10
|
private queryApi;
|
|
10
11
|
private shouldSkipHighlightsWithoutAttributes;
|
|
11
|
-
constructor(httpClient: HttpClient, shouldSkipHighlightsWithoutAttributes?: boolean);
|
|
12
|
+
constructor(httpClient: HttpClient, pivotClient?: PivotClient, shouldSkipHighlightsWithoutAttributes?: boolean);
|
|
12
13
|
/**
|
|
13
14
|
* Executes query
|
|
14
15
|
*
|
|
15
16
|
* @param queryDescription - all options that describe query
|
|
17
|
+
* @param config - query execution configuration
|
|
16
18
|
* @returns promise that resolves to query result data and cancel function that can be used to cancel sent query
|
|
17
19
|
* @throws Error if query description is invalid
|
|
18
20
|
*/
|
|
19
21
|
executeQuery(queryDescription: QueryDescription, config?: QueryExecutionConfig): ExecutingQueryResult;
|
|
20
22
|
executeCsvQuery(queryDescription: QueryDescription, config?: QueryExecutionConfig): ExecutingCsvQueryResult;
|
|
23
|
+
/**
|
|
24
|
+
* Executes pivot query
|
|
25
|
+
*
|
|
26
|
+
* @param pivotQueryDescription - all options that describe the pivot query
|
|
27
|
+
* @param config - query execution configuration
|
|
28
|
+
* @returns promise that resolves to pivot query result data and cancel function that can be used to cancel sent query
|
|
29
|
+
* @throws Error if query description is invalid
|
|
30
|
+
*/
|
|
31
|
+
executePivotQuery(pivotQueryDescription: PivotQueryDescription, config?: QueryExecutionConfig): ExecutingPivotQueryResult;
|
|
21
32
|
getDataSourceFields(dataSource: DataSource, count?: number, offset?: number): Promise<DataSourceField[]>;
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Validates query description
|
|
25
36
|
*
|
|
26
37
|
* @param queryDescription - query description to validate
|
|
38
|
+
* @param config - query execution configuration
|
|
27
39
|
* @throws Error if query description is invalid
|
|
28
40
|
*/
|
|
29
41
|
export declare function validateQueryDescription(queryDescription: QueryDescription, config?: {
|
|
30
42
|
ignoreQueryLimit?: boolean;
|
|
31
43
|
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* Validates pivot query description
|
|
46
|
+
*
|
|
47
|
+
* @param queryDescription - pivot query description to validate
|
|
48
|
+
* @throws Error if query description is invalid
|
|
49
|
+
*/
|
|
50
|
+
export declare function validatePivotQueryDescription(queryDescription: PivotQueryDescription): void;
|
package/dist/query-client.js
CHANGED
|
@@ -8,24 +8,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { QueryTaskManager } from './query-task-manager/query-task-manager.js';
|
|
11
|
-
import { QueryTaskPassport } from './query-task-manager/query-task-passport.js';
|
|
11
|
+
import { PivotQueryTaskPassport, QueryTaskPassport, } from './query-task-manager/query-task-passport.js';
|
|
12
12
|
import { ExecutionResultStatus } from '@sisense/task-manager';
|
|
13
13
|
import { QueryApiDispatcher } from './query-api-dispatcher/query-api-dispatcher.js';
|
|
14
14
|
import { MetadataTypes } from '@sisense/sdk-data';
|
|
15
15
|
import { TranslatableError } from './translation/translatable-error.js';
|
|
16
|
+
import { PivotClient } from '@sisense/sdk-pivot-client';
|
|
16
17
|
/** @internal */
|
|
17
18
|
export const QUERY_DEFAULT_LIMIT = 20000;
|
|
19
|
+
const UNSPECIFIED_REASON = 'Unspecified reason';
|
|
18
20
|
export class DimensionalQueryClient {
|
|
19
|
-
constructor(httpClient, shouldSkipHighlightsWithoutAttributes) {
|
|
21
|
+
constructor(httpClient, pivotClient = new PivotClient(httpClient), shouldSkipHighlightsWithoutAttributes) {
|
|
20
22
|
validateHttpClient(httpClient);
|
|
21
23
|
this.queryApi = new QueryApiDispatcher(httpClient);
|
|
22
|
-
this.taskManager = new QueryTaskManager(this.queryApi);
|
|
24
|
+
this.taskManager = new QueryTaskManager(this.queryApi, pivotClient);
|
|
23
25
|
this.shouldSkipHighlightsWithoutAttributes = shouldSkipHighlightsWithoutAttributes !== null && shouldSkipHighlightsWithoutAttributes !== void 0 ? shouldSkipHighlightsWithoutAttributes : false;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Executes query
|
|
27
29
|
*
|
|
28
30
|
* @param queryDescription - all options that describe query
|
|
31
|
+
* @param config - query execution configuration
|
|
29
32
|
* @returns promise that resolves to query result data and cancel function that can be used to cancel sent query
|
|
30
33
|
* @throws Error if query description is invalid
|
|
31
34
|
*/
|
|
@@ -43,7 +46,7 @@ export class DimensionalQueryClient {
|
|
|
43
46
|
}
|
|
44
47
|
});
|
|
45
48
|
}),
|
|
46
|
-
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason ||
|
|
49
|
+
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason || UNSPECIFIED_REASON),
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
52
|
executeCsvQuery(queryDescription, config) {
|
|
@@ -60,7 +63,32 @@ export class DimensionalQueryClient {
|
|
|
60
63
|
}
|
|
61
64
|
});
|
|
62
65
|
}),
|
|
63
|
-
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason ||
|
|
66
|
+
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason || UNSPECIFIED_REASON),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Executes pivot query
|
|
71
|
+
*
|
|
72
|
+
* @param pivotQueryDescription - all options that describe the pivot query
|
|
73
|
+
* @param config - query execution configuration
|
|
74
|
+
* @returns promise that resolves to pivot query result data and cancel function that can be used to cancel sent query
|
|
75
|
+
* @throws Error if query description is invalid
|
|
76
|
+
*/
|
|
77
|
+
executePivotQuery(pivotQueryDescription, config) {
|
|
78
|
+
validatePivotQueryDescription(pivotQueryDescription);
|
|
79
|
+
const taskPassport = new PivotQueryTaskPassport('SEND_JAQL_QUERY', pivotQueryDescription, Object.assign(Object.assign({}, (config ? config : {})), { shouldSkipHighlightsWithoutAttributes: this.shouldSkipHighlightsWithoutAttributes || false }));
|
|
80
|
+
return {
|
|
81
|
+
resultPromise: new Promise((resolve, reject) => {
|
|
82
|
+
void this.taskManager.executePivotQuerySending(taskPassport).then((executionResult) => {
|
|
83
|
+
if (executionResult.status === ExecutionResultStatus.SUCCESS) {
|
|
84
|
+
resolve(executionResult.result);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
reject(executionResult.error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}),
|
|
91
|
+
cancel: (reason) => this.taskManager.cancel(taskPassport.taskId, reason || UNSPECIFIED_REASON),
|
|
64
92
|
};
|
|
65
93
|
}
|
|
66
94
|
getDataSourceFields(dataSource, count = 9999, offset = 0) {
|
|
@@ -73,6 +101,7 @@ export class DimensionalQueryClient {
|
|
|
73
101
|
* Validates query description
|
|
74
102
|
*
|
|
75
103
|
* @param queryDescription - query description to validate
|
|
104
|
+
* @param config - query execution configuration
|
|
76
105
|
* @throws Error if query description is invalid
|
|
77
106
|
*/
|
|
78
107
|
export function validateQueryDescription(queryDescription, config) {
|
|
@@ -113,6 +142,40 @@ export function validateQueryDescription(queryDescription, config) {
|
|
|
113
142
|
}
|
|
114
143
|
});
|
|
115
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Validates pivot query description
|
|
147
|
+
*
|
|
148
|
+
* @param queryDescription - pivot query description to validate
|
|
149
|
+
* @throws Error if query description is invalid
|
|
150
|
+
*/
|
|
151
|
+
export function validatePivotQueryDescription(queryDescription) {
|
|
152
|
+
const { rowsAttributes, columnsAttributes, measures, filters, highlights, count, offset } = queryDescription;
|
|
153
|
+
if (count && count < 0) {
|
|
154
|
+
throw new TranslatableError('errors.invalidCountNegative', { count: count.toString() });
|
|
155
|
+
}
|
|
156
|
+
if (count && count > QUERY_DEFAULT_LIMIT) {
|
|
157
|
+
throw new TranslatableError('errors.invalidCountLimit', {
|
|
158
|
+
count: count.toString(),
|
|
159
|
+
limit: QUERY_DEFAULT_LIMIT.toString(),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (offset && offset < 0) {
|
|
163
|
+
throw new TranslatableError('errors.invalidOffset', { offset: offset.toString() });
|
|
164
|
+
}
|
|
165
|
+
if (rowsAttributes.length + columnsAttributes.length + measures.length === 0) {
|
|
166
|
+
throw new TranslatableError('errors.noDimensionsOrMeasures');
|
|
167
|
+
}
|
|
168
|
+
filters.forEach((filter) => {
|
|
169
|
+
if (!filter.skipValidation && !MetadataTypes.isFilter(filter)) {
|
|
170
|
+
throw new TranslatableError('errors.invalidFilter', { filterName: filter.name });
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
highlights.forEach((highlight) => {
|
|
174
|
+
if (!highlight.skipValidation && !MetadataTypes.isFilter(highlight)) {
|
|
175
|
+
throw new TranslatableError('errors.invalidHighlight', { highlightName: highlight.name });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
116
179
|
/**
|
|
117
180
|
* Validates http client
|
|
118
181
|
*
|
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
import { AbstractTaskManager } from '@sisense/task-manager';
|
|
2
2
|
import { EmptyObject, JaqlResponse } from '../types.js';
|
|
3
|
-
import { QueryTaskPassport } from './query-task-passport.js';
|
|
4
|
-
import { QueryResultData } from '@sisense/sdk-data';
|
|
3
|
+
import { PivotQueryTaskPassport, QueryTaskPassport } from './query-task-passport.js';
|
|
4
|
+
import { QueryResultData, PivotQueryResultData } from '@sisense/sdk-data';
|
|
5
5
|
import { QueryApiDispatcher } from '../query-api-dispatcher/query-api-dispatcher.js';
|
|
6
|
+
import { PivotClient } from '@sisense/sdk-pivot-client';
|
|
6
7
|
export declare class QueryTaskManager extends AbstractTaskManager {
|
|
7
8
|
/** Map of aborters by task id to be able to cancel sent requests */
|
|
8
9
|
private sentRequestsAbortersMap;
|
|
9
10
|
private queryApi;
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Client for handling pivot data
|
|
13
|
+
*/
|
|
14
|
+
private pivotClient;
|
|
15
|
+
constructor(queryApi: QueryApiDispatcher, pivotClient: PivotClient);
|
|
11
16
|
private prepareJaqlPayload;
|
|
12
17
|
private sendJaqlQuery;
|
|
13
18
|
private sendCsvQuery;
|
|
14
19
|
private cancelDataRetrievalQuery;
|
|
20
|
+
/**
|
|
21
|
+
* Prepares the JAQL payload for the pivot query
|
|
22
|
+
*
|
|
23
|
+
* @param task
|
|
24
|
+
* @returns JAQL payload
|
|
25
|
+
*/
|
|
26
|
+
private preparePivotJaqlPayload;
|
|
27
|
+
/**
|
|
28
|
+
* Executes the pivot query and returns the result
|
|
29
|
+
*
|
|
30
|
+
* @param task
|
|
31
|
+
* @param jaqlPayload
|
|
32
|
+
*/
|
|
33
|
+
private sendPivotJaqlQuery;
|
|
34
|
+
private cancelPivotJaqlQuery;
|
|
15
35
|
executeQuerySending: (passport: QueryTaskPassport) => Promise<import("@sisense/task-manager").TaskExecutionResult<QueryResultData, EmptyObject>>;
|
|
16
36
|
executeDownloadCsvSending: (passport: QueryTaskPassport) => Promise<import("@sisense/task-manager").TaskExecutionResult<Blob, EmptyObject>>;
|
|
37
|
+
executePivotQuerySending: (passport: PivotQueryTaskPassport) => Promise<import("@sisense/task-manager").TaskExecutionResult<PivotQueryResultData, EmptyObject>>;
|
|
17
38
|
}
|
|
18
39
|
export declare function validateJaqlResponse(jaqlResponse: JaqlResponse): boolean;
|
|
@@ -8,10 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { AbstractTaskManager, Step } from '@sisense/task-manager';
|
|
11
|
-
import { getJaqlQueryPayload } from '../jaql/get-jaql-query-payload.js';
|
|
11
|
+
import { getJaqlQueryPayload, getPivotJaqlQueryPayload } from '../jaql/get-jaql-query-payload.js';
|
|
12
12
|
import { getDataFromQueryResult } from '../query-result/index.js';
|
|
13
|
+
import { QUERY_DEFAULT_LIMIT } from '../query-client.js';
|
|
13
14
|
export class QueryTaskManager extends AbstractTaskManager {
|
|
14
|
-
constructor(queryApi) {
|
|
15
|
+
constructor(queryApi, pivotClient) {
|
|
15
16
|
super();
|
|
16
17
|
/** Map of aborters by task id to be able to cancel sent requests */
|
|
17
18
|
this.sentRequestsAbortersMap = new Map();
|
|
@@ -23,7 +24,12 @@ export class QueryTaskManager extends AbstractTaskManager {
|
|
|
23
24
|
new Step('PREPARE_JAQL_PAYLOAD', this.prepareJaqlPayload.bind(this), () => __awaiter(this, void 0, void 0, function* () { })),
|
|
24
25
|
new Step('SEND_DOWNLOAD_CSV_QUERY', this.sendCsvQuery.bind(this), this.cancelDataRetrievalQuery.bind(this)),
|
|
25
26
|
]);
|
|
27
|
+
this.executePivotQuerySending = super.createFlow([
|
|
28
|
+
new Step('PREPARE_JAQL_PAYLOAD', this.preparePivotJaqlPayload.bind(this), () => __awaiter(this, void 0, void 0, function* () { })),
|
|
29
|
+
new Step('SEND_JAQL_QUERY', this.sendPivotJaqlQuery.bind(this), this.cancelPivotJaqlQuery.bind(this)),
|
|
30
|
+
]);
|
|
26
31
|
this.queryApi = queryApi;
|
|
32
|
+
this.pivotClient = pivotClient;
|
|
27
33
|
}
|
|
28
34
|
prepareJaqlPayload(task) {
|
|
29
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -72,6 +78,43 @@ export class QueryTaskManager extends AbstractTaskManager {
|
|
|
72
78
|
}
|
|
73
79
|
return this.queryApi.sendCancelJaqlQueryRequest(taskId, task.passport.queryDescription.dataSource);
|
|
74
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Prepares the JAQL payload for the pivot query
|
|
83
|
+
*
|
|
84
|
+
* @param task
|
|
85
|
+
* @returns JAQL payload
|
|
86
|
+
*/
|
|
87
|
+
preparePivotJaqlPayload(task) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const { pivotQueryDescription, executionConfig } = task.passport;
|
|
90
|
+
const jaqlPayload = getPivotJaqlQueryPayload(pivotQueryDescription, executionConfig.shouldSkipHighlightsWithoutAttributes);
|
|
91
|
+
const onBeforeQuery = task.passport.executionConfig.onBeforeQuery;
|
|
92
|
+
if (onBeforeQuery) {
|
|
93
|
+
return onBeforeQuery(jaqlPayload);
|
|
94
|
+
}
|
|
95
|
+
return jaqlPayload;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Executes the pivot query and returns the result
|
|
100
|
+
*
|
|
101
|
+
* @param task
|
|
102
|
+
* @param jaqlPayload
|
|
103
|
+
*/
|
|
104
|
+
sendPivotJaqlQuery(task, jaqlPayload) {
|
|
105
|
+
var _a;
|
|
106
|
+
const { pivotQueryDescription } = task.passport;
|
|
107
|
+
return this.pivotClient.queryData(jaqlPayload, true, (_a = pivotQueryDescription.count) !== null && _a !== void 0 ? _a : QUERY_DEFAULT_LIMIT, false);
|
|
108
|
+
}
|
|
109
|
+
cancelPivotJaqlQuery(task) {
|
|
110
|
+
const taskId = task.passport.taskId;
|
|
111
|
+
const abortInitialRequest = this.sentRequestsAbortersMap.get(taskId);
|
|
112
|
+
if (abortInitialRequest) {
|
|
113
|
+
abortInitialRequest();
|
|
114
|
+
this.sentRequestsAbortersMap.delete(taskId);
|
|
115
|
+
}
|
|
116
|
+
return this.queryApi.sendCancelJaqlQueryRequest(taskId, task.passport.pivotQueryDescription.dataSource);
|
|
117
|
+
}
|
|
75
118
|
}
|
|
76
119
|
export function validateJaqlResponse(jaqlResponse) {
|
|
77
120
|
var _a;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TaskPassport } from '@sisense/task-manager';
|
|
2
|
-
import { QueryDescription, QueryExecutionConfigInternal } from '../types.js';
|
|
2
|
+
import { PivotQueryDescription, QueryDescription, QueryExecutionConfigInternal } from '../types.js';
|
|
3
3
|
type TaskType = 'SEND_JAQL_QUERY' | 'SEND_DOWNLOAD_CSV_QUERY';
|
|
4
4
|
export declare class QueryTaskPassport extends TaskPassport {
|
|
5
5
|
queryDescription: QueryDescription;
|
|
@@ -7,4 +7,10 @@ export declare class QueryTaskPassport extends TaskPassport {
|
|
|
7
7
|
type: TaskType;
|
|
8
8
|
constructor(type: TaskType, queryDescription: QueryDescription, executionConfig: QueryExecutionConfigInternal);
|
|
9
9
|
}
|
|
10
|
+
export declare class PivotQueryTaskPassport extends TaskPassport {
|
|
11
|
+
pivotQueryDescription: PivotQueryDescription;
|
|
12
|
+
executionConfig: QueryExecutionConfigInternal;
|
|
13
|
+
type: TaskType;
|
|
14
|
+
constructor(type: TaskType, pivotQueryDescription: PivotQueryDescription, executionConfig: QueryExecutionConfigInternal);
|
|
15
|
+
}
|
|
10
16
|
export {};
|
|
@@ -7,3 +7,11 @@ export class QueryTaskPassport extends TaskPassport {
|
|
|
7
7
|
this.executionConfig = executionConfig;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
+
export class PivotQueryTaskPassport extends TaskPassport {
|
|
11
|
+
constructor(type, pivotQueryDescription, executionConfig) {
|
|
12
|
+
super();
|
|
13
|
+
this.pivotQueryDescription = pivotQueryDescription;
|
|
14
|
+
this.type = type;
|
|
15
|
+
this.executionConfig = executionConfig;
|
|
16
|
+
}
|
|
17
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Filter, Measure, Attribute, Cell, QueryResultData, DataSource, FilterRelation } from '@sisense/sdk-data';
|
|
1
|
+
import { Filter, Measure, Attribute, Cell, QueryResultData, DataSource, FilterRelation, PivotAttribute, PivotMeasure, PivotQueryResultData, PivotGrandTotals } from '@sisense/sdk-data';
|
|
2
2
|
/**
|
|
3
3
|
* All the properties that fully describe a query you want to send.
|
|
4
4
|
*/
|
|
@@ -12,6 +12,21 @@ export type QueryDescription = {
|
|
|
12
12
|
count?: number;
|
|
13
13
|
offset?: number;
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* All the properties that fully describe a pivot query you want to send.
|
|
17
|
+
*/
|
|
18
|
+
export type PivotQueryDescription = {
|
|
19
|
+
dataSource: DataSource;
|
|
20
|
+
rowsAttributes: (Attribute | PivotAttribute)[];
|
|
21
|
+
columnsAttributes: (Attribute | PivotAttribute)[];
|
|
22
|
+
measures: (Measure | PivotMeasure)[];
|
|
23
|
+
grandTotals: PivotGrandTotals;
|
|
24
|
+
filters: Filter[];
|
|
25
|
+
highlights: Filter[];
|
|
26
|
+
filterRelations?: FilterRelation;
|
|
27
|
+
count?: number;
|
|
28
|
+
offset?: number;
|
|
29
|
+
};
|
|
15
30
|
/**
|
|
16
31
|
* Additional configuration for query execution.
|
|
17
32
|
*/
|
|
@@ -28,6 +43,14 @@ export type QueryOptions = {
|
|
|
28
43
|
datasource: string;
|
|
29
44
|
by: string;
|
|
30
45
|
queryGuid: string;
|
|
46
|
+
dashboard?: string;
|
|
47
|
+
widget?: string;
|
|
48
|
+
format?: string;
|
|
49
|
+
grandTotals?: {
|
|
50
|
+
title?: string;
|
|
51
|
+
columns?: boolean;
|
|
52
|
+
rows?: boolean;
|
|
53
|
+
};
|
|
31
54
|
};
|
|
32
55
|
export type ExecutingQueryResult = {
|
|
33
56
|
resultPromise: Promise<QueryResultData>;
|
|
@@ -37,6 +60,10 @@ export type ExecutingCsvQueryResult = {
|
|
|
37
60
|
resultPromise: Promise<Blob>;
|
|
38
61
|
cancel: (reason?: string) => Promise<void>;
|
|
39
62
|
};
|
|
63
|
+
export type ExecutingPivotQueryResult = {
|
|
64
|
+
resultPromise: Promise<PivotQueryResultData>;
|
|
65
|
+
cancel: (reason?: string) => Promise<void>;
|
|
66
|
+
};
|
|
40
67
|
export type MetadataItem = {
|
|
41
68
|
instanceid?: string;
|
|
42
69
|
measure?: MetadataItemJaql;
|
|
@@ -48,6 +75,22 @@ export type MetadataItem = {
|
|
|
48
75
|
[level: string]: string | undefined;
|
|
49
76
|
};
|
|
50
77
|
number?: string;
|
|
78
|
+
subtotal?: boolean;
|
|
79
|
+
width?: number;
|
|
80
|
+
databars?: boolean;
|
|
81
|
+
color?: {
|
|
82
|
+
type: string;
|
|
83
|
+
color?: string;
|
|
84
|
+
conditions?: Array<{
|
|
85
|
+
color: string;
|
|
86
|
+
operator: string;
|
|
87
|
+
expression: string | Record<string, any>;
|
|
88
|
+
}>;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
field?: {
|
|
92
|
+
id?: string;
|
|
93
|
+
index?: number;
|
|
51
94
|
};
|
|
52
95
|
filter?: MetadataItem;
|
|
53
96
|
exclude?: MetadataItem;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"Sisense",
|
|
12
12
|
"Compose SDK"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.2.0",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": "./dist/index.js",
|
|
17
17
|
"main": "./dist/index.js",
|
|
@@ -20,11 +20,13 @@
|
|
|
20
20
|
"author": "Sisense",
|
|
21
21
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@sisense/sdk-common": "^1.
|
|
24
|
-
"@sisense/sdk-data": "^1.
|
|
25
|
-
"@sisense/sdk-
|
|
23
|
+
"@sisense/sdk-common": "^1.2.0",
|
|
24
|
+
"@sisense/sdk-data": "^1.2.0",
|
|
25
|
+
"@sisense/sdk-pivot-client": "^1.2.0",
|
|
26
|
+
"@sisense/sdk-rest-client": "^1.2.0",
|
|
26
27
|
"@sisense/task-manager": "^0.1.0",
|
|
27
28
|
"numeral": "^2.0.6",
|
|
29
|
+
"ts-deepmerge": "6.0.2",
|
|
28
30
|
"uuid": "^9.0.0"
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|