[SIP-5] Build metrics in query_object in the client

- Unify the metric interface (absorb the current plain string metric for built-in metric keys into the format used by adhoc metric)
- Port the logic in adhocMetric on the client and process_metrics in the backend to the new typed Metrics class
- Omit hasCustomLabel and formFromData properties from the new metric interface as their value can be inferred from label and optionName
- Expose from the Metrics class both metrics and their labels as public methods to match the all_metrics and metric_labels fields in the backend code
- Provide defaut values for filters, metrics and groupby in the backend
This commit is contained in:
Christine Chambers
2018-11-21 19:12:08 -08:00
committed by Christine Chambers
parent 2731a010ca
commit c11e9c8b67
7 changed files with 233 additions and 17 deletions

View File

@@ -0,0 +1,92 @@
import { AdhocMetric, Aggregate, ExpressionType, Metrics } from 'src/query/Metric';
describe('Metrics', () => {
let metrics: Metrics;
const formData = {
datasource: '5__table',
granularity_sqla: 'ds',
};
it('should build metrics for built-in metric keys', () => {
metrics = new Metrics({
...formData,
metric: 'sum__num',
});
expect(metrics.getMetrics()).toEqual([{label: 'sum__num'}]);
expect(metrics.getLabels()).toEqual(['sum__num']);
});
it('should build metrics for simple adhoc metrics', () => {
const adhocMetric: AdhocMetric = {
aggregate: Aggregate.AVG,
column: {
columnName: 'sum_girls',
id: 5,
type: 'BIGINT',
},
expressionType: ExpressionType.SIMPLE,
};
metrics = new Metrics({
...formData,
metric: adhocMetric,
});
expect(metrics.getMetrics()).toEqual([{
aggregate: 'AVG',
column: {
columnName: 'sum_girls',
id: 5,
type: 'BIGINT',
},
expressionType: 'SIMPLE',
label: 'AVG(sum_girls)',
}]);
expect(metrics.getLabels()).toEqual(['AVG(sum_girls)']);
});
it('should build metrics for SQL adhoc metrics', () => {
const adhocMetric: AdhocMetric = {
expressionType: ExpressionType.SQL,
sqlExpression: 'COUNT(sum_girls)',
};
metrics = new Metrics({
...formData,
metric: adhocMetric,
});
expect(metrics.getMetrics()).toEqual([{
expressionType: 'SQL',
label: 'COUNT(sum_girls)',
sqlExpression: 'COUNT(sum_girls)',
}]);
expect(metrics.getLabels()).toEqual(['COUNT(sum_girls)']);
});
it('should build metrics for adhoc metrics with custom labels', () => {
const adhocMetric: AdhocMetric = {
expressionType: ExpressionType.SQL,
label: 'foo',
sqlExpression: 'COUNT(sum_girls)',
};
metrics = new Metrics({
...formData,
metric: adhocMetric,
});
expect(metrics.getMetrics()).toEqual([{
expressionType: 'SQL',
label: 'foo',
sqlExpression: 'COUNT(sum_girls)',
}]);
expect(metrics.getLabels()).toEqual(['foo']);
});
it('should truncate labels if they are too long', () => {
const adhocMetric: AdhocMetric = {
expressionType: ExpressionType.SQL,
sqlExpression: 'COUNT(verrrrrrrrry_loooooooooooooooooooooong_string)',
};
metrics = new Metrics({
...formData,
metric: adhocMetric,
});
expect(metrics.getLabels()).toEqual(['COUNT(verrrrrrrrry_loooooooooooooooooooo...']);
});
});

View File

@@ -1,13 +1,24 @@
import build from 'src/query/buildQueryObject';
import build, { QueryObject } from 'src/query/buildQueryObject';
describe('queryObjectBuilder', () => {
let query: QueryObject;
it('should build granularity for sql alchemy datasources', () => {
const query = build({datasource: '5__table', granularity_sqla: 'ds'});
query = build({datasource: '5__table', granularity_sqla: 'ds'});
expect(query.granularity).toEqual('ds');
});
it('should build granularity for sql alchemy datasources', () => {
const query = build({datasource: '5__druid', granularity: 'ds'});
query = build({datasource: '5__druid', granularity: 'ds'});
expect(query.granularity).toEqual('ds');
});
it('should build metrics', () => {
query = build({
datasource: '5__table',
granularity_sqla: 'ds',
metric: 'sum__num',
});
expect(query.metrics).toEqual([{label: 'sum__num'}]);
});
});