all files / src/explore/ AdhocMetric.js

96.36% Statements 53/55
89.47% Branches 51/57
100% Functions 10/10
96.3% Lines 52/54
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103           55×       51×             58× 58×   47× 47× 47× 47× 11× 11× 11× 11×   58× 58× 58×   58×       40× 40×         59× 56×         22×           23×                   25× 20×                  
import { sqlaAutoGeneratedMetricRegex } from './constants';
 
export const EXPRESSION_TYPES = {
  SIMPLE: 'SIMPLE',
  SQL: 'SQL',
};
 
function inferSqlExpressionColumn(adhocMetric) {
  if (adhocMetric.sqlExpression && sqlaAutoGeneratedMetricRegex.test(adhocMetric.sqlExpression)) {
    const indexFirstCloseParen = adhocMetric.sqlExpression.indexOf(')');
    const indexPairedOpenParen =
      adhocMetric.sqlExpression.substring(0, indexFirstCloseParen).lastIndexOf('(');
    if (EindexFirstCloseParen > 0 && indexPairedOpenParen > 0) {
      return adhocMetric.sqlExpression.substring(indexPairedOpenParen + 1, indexFirstCloseParen);
    }
  }
  return null;
}
 
function inferSqlExpressionAggregate(adhocMetric) {
  if (adhocMetric.sqlExpression && sqlaAutoGeneratedMetricRegex.test(adhocMetric.sqlExpression)) {
    const indexFirstOpenParen = adhocMetric.sqlExpression.indexOf('(');
    if (EindexFirstOpenParen > 0) {
      return adhocMetric.sqlExpression.substring(0, indexFirstOpenParen);
    }
  }
  return null;
}
 
export default class AdhocMetric {
  constructor(adhocMetric) {
    this.expressionType = adhocMetric.expressionType || EXPRESSION_TYPES.SIMPLE;
    if (this.expressionType === EXPRESSION_TYPES.SIMPLE) {
      // try to be clever in the case of transitioning from Sql expression back to simple expression
      const inferredColumn = inferSqlExpressionColumn(adhocMetric);
      this.column = adhocMetric.column || (inferredColumn && { column_name: inferredColumn });
      this.aggregate = adhocMetric.aggregate || inferSqlExpressionAggregate(adhocMetric);
      this.sqlExpression = null;
    } else Eif (this.expressionType === EXPRESSION_TYPES.SQL) {
      this.sqlExpression = adhocMetric.sqlExpression;
      this.column = null;
      this.aggregate = null;
    }
    this.hasCustomLabel = !!(adhocMetric.hasCustomLabel && adhocMetric.label);
    this.fromFormData = !!adhocMetric.optionName;
    this.label = this.hasCustomLabel ? adhocMetric.label : this.getDefaultLabel();
 
    this.optionName = adhocMetric.optionName ||
      `metric_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
  }
 
  getDefaultLabel() {
    const label = this.translateToSql();
    return label.length < 43 ?
      label :
      label.substring(0, 40) + '...';
  }
 
  translateToSql() {
    if (this.expressionType === EXPRESSION_TYPES.SIMPLE) {
      return `${this.aggregate || ''}(${(this.column && this.column.column_name) || ''})`;
    } else Eif (this.expressionType === EXPRESSION_TYPES.SQL) {
      return this.sqlExpression;
    }
    return '';
  }
 
  duplicateWith(nextFields) {
    return new AdhocMetric({
      ...this,
      ...nextFields,
    });
  }
 
  equals(adhocMetric) {
    return adhocMetric.label === this.label &&
      adhocMetric.expressionType === this.expressionType &&
      adhocMetric.sqlExpression === this.sqlExpression &&
      adhocMetric.aggregate === this.aggregate &&
      (
        (adhocMetric.column && adhocMetric.column.column_name) ===
        (this.column && this.column.column_name)
      );
  }
 
  isValid() {
    if (this.expressionType === EXPRESSION_TYPES.SIMPLE) {
      return !!(this.column && this.aggregate);
    } else Eif (this.expressionType === EXPRESSION_TYPES.SQL) {
      return !!(this.sqlExpression);
    }
    return false;
  }
 
  inferSqlExpressionAggregate() {
    return inferSqlExpressionAggregate(this);
  }
 
  inferSqlExpressionColumn() {
    return inferSqlExpressionColumn(this);
  }
}