Merge pull request #3430 from influxdata/bf-typescript-conversions
Start converting utils to typescriptpull/10616/head
commit
7a9fa74ed2
|
@ -3,7 +3,6 @@ import classnames from 'classnames'
|
|||
import React, {PureComponent, MouseEvent} from 'react'
|
||||
import TagList from 'src/shared/components/TagList'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
import {QueryConfig, Tag} from 'src/types'
|
||||
|
||||
interface SourceLinks {
|
||||
|
|
|
@ -9,7 +9,6 @@ import {showTagKeys, showTagValues} from 'src/shared/apis/metaQuery'
|
|||
import showTagKeysParser from 'src/shared/parsing/showTagKeys'
|
||||
import showTagValuesParser from 'src/shared/parsing/showTagValues'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
import {QueryConfig, Tag} from 'src/types'
|
||||
|
||||
const {shape} = PropTypes
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
export interface QueryConfig {
|
||||
id?: string
|
||||
database: string
|
||||
measurement: string
|
||||
retentionPolicy: string
|
||||
fields: Field[]
|
||||
database?: string
|
||||
measurement?: string
|
||||
retentionPolicy?: string
|
||||
fields?: Field[]
|
||||
tags: Tags
|
||||
groupBy: GroupBy
|
||||
groupBy?: GroupBy
|
||||
areTagsAccepted: boolean
|
||||
rawText: string
|
||||
rawText?: string
|
||||
range?: DurationRange | null
|
||||
sourceLink?: string
|
||||
fill?: string
|
||||
status?: Status
|
||||
shifts: TimeShift[]
|
||||
shifts?: TimeShift[]
|
||||
lower?: string
|
||||
upper?: string
|
||||
isQuerySupportedByExplorer?: boolean // doesn't come from server -- is set in CellEditorOverlay
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
const KMB_LABELS = ['K', 'M', 'B', 'T', 'Q']
|
||||
const KMG2_BIG_LABELS = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
|
||||
const KMG2_SMALL_LABELS = ['m', 'u', 'n', 'p', 'f', 'a', 'z', 'y']
|
||||
import _ from 'lodash'
|
||||
const KMB_LABELS: string[] = ['K', 'M', 'B', 'T', 'Q']
|
||||
const KMG2_BIG_LABELS: string[] = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
|
||||
const KMG2_SMALL_LABELS: string[] = ['m', 'u', 'n', 'p', 'f', 'a', 'z', 'y']
|
||||
|
||||
const pow = (base, exp) => {
|
||||
const pow = (base: number, exp: number): number => {
|
||||
if (exp < 0) {
|
||||
return 1.0 / Math.pow(base, -exp)
|
||||
}
|
||||
|
@ -10,12 +11,12 @@ const pow = (base, exp) => {
|
|||
return Math.pow(base, exp)
|
||||
}
|
||||
|
||||
const round_ = (num, places) => {
|
||||
const roundNum = (num, places): number => {
|
||||
const shift = Math.pow(10, places)
|
||||
return Math.round(num * shift) / shift
|
||||
}
|
||||
|
||||
const floatFormat = (x, optPrecision) => {
|
||||
const floatFormat = (x: number, optPrecision: number): string => {
|
||||
// Avoid invalid precision values; [1, 21] is the valid range.
|
||||
const p = Math.min(Math.max(1, optPrecision || 2), 21)
|
||||
|
||||
|
@ -41,7 +42,12 @@ const floatFormat = (x, optPrecision) => {
|
|||
}
|
||||
|
||||
// taken from https://github.com/danvk/dygraphs/blob/aaec6de56dba8ed712fd7b9d949de47b46a76ccd/src/dygraph-utils.js#L1103
|
||||
export const numberValueFormatter = (x, opts, prefix, suffix) => {
|
||||
export const numberValueFormatter = (
|
||||
x: number,
|
||||
opts: (name: string) => number,
|
||||
prefix: string,
|
||||
suffix: string
|
||||
): string => {
|
||||
const sigFigs = opts('sigFigs')
|
||||
|
||||
if (sigFigs !== null) {
|
||||
|
@ -65,7 +71,7 @@ export const numberValueFormatter = (x, opts, prefix, suffix) => {
|
|||
) {
|
||||
label = x.toExponential(digits)
|
||||
} else {
|
||||
label = `${round_(x, digits)}`
|
||||
label = `${roundNum(x, digits)}`
|
||||
}
|
||||
|
||||
if (kmb || kmg2) {
|
||||
|
@ -89,15 +95,17 @@ export const numberValueFormatter = (x, opts, prefix, suffix) => {
|
|||
let n = pow(k, kLabels.length)
|
||||
for (let j = kLabels.length - 1; j >= 0; j -= 1, n /= k) {
|
||||
if (absx >= n) {
|
||||
label = round_(x / n, digits) + kLabels[j]
|
||||
label = roundNum(x / n, digits) + kLabels[j]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (kmg2) {
|
||||
const xParts = String(x.toExponential()).split('e-')
|
||||
const xParts = String(x.toExponential())
|
||||
.split('e-')
|
||||
.map(Number)
|
||||
if (xParts.length === 2 && xParts[1] >= 3 && xParts[1] <= 24) {
|
||||
if (xParts[1] % 3 > 0) {
|
||||
label = round_(xParts[0] / pow(10, xParts[1] % 3), digits)
|
||||
label = roundNum(xParts[0] / pow(10, xParts[1] % 3), digits)
|
||||
} else {
|
||||
label = Number(xParts[0]).toFixed(2)
|
||||
}
|
||||
|
@ -109,7 +117,7 @@ export const numberValueFormatter = (x, opts, prefix, suffix) => {
|
|||
return `${prefix}${label}${suffix}`
|
||||
}
|
||||
|
||||
export const formatBytes = bytes => {
|
||||
export const formatBytes = (bytes: number) => {
|
||||
if (bytes === 0) {
|
||||
return '0 Bytes'
|
||||
}
|
||||
|
@ -126,7 +134,7 @@ export const formatBytes = bytes => {
|
|||
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
|
||||
}
|
||||
|
||||
export const formatRPDuration = duration => {
|
||||
export const formatRPDuration = (duration: string | null): string => {
|
||||
if (!duration) {
|
||||
return
|
||||
}
|
||||
|
@ -137,23 +145,21 @@ export const formatRPDuration = duration => {
|
|||
|
||||
let adjustedTime = duration
|
||||
const durationMatcher = /(?:(\d*)d)?(?:(\d*)h)?(?:(\d*)m)?(?:(\d*)s)?/
|
||||
const [
|
||||
_match, // eslint-disable-line no-unused-vars
|
||||
days = 0,
|
||||
hours = 0,
|
||||
minutes = 0,
|
||||
seconds = 0,
|
||||
] = duration.match(durationMatcher)
|
||||
const result = duration.match(durationMatcher)
|
||||
const days = _.get<string, string>(result, 1, '0')
|
||||
const hours = _.get<string, string>(result, 2, '0')
|
||||
const minutes = _.get<string, string>(result, 3, '0')
|
||||
const seconds = _.get<string, string>(result, 4, '0')
|
||||
|
||||
const hoursInDay = 24
|
||||
if (days) {
|
||||
if (+days) {
|
||||
adjustedTime = `${days}d`
|
||||
adjustedTime += +hours === 0 ? '' : `${hours}h`
|
||||
adjustedTime += +minutes === 0 ? '' : `${minutes}m`
|
||||
adjustedTime += +seconds === 0 ? '' : `${seconds}s`
|
||||
} else if (hours > hoursInDay) {
|
||||
const hoursRemainder = hours % hoursInDay
|
||||
const daysQuotient = (hours - hoursRemainder) / hoursInDay
|
||||
} else if (+hours > hoursInDay) {
|
||||
const hoursRemainder = +hours % hoursInDay
|
||||
const daysQuotient = (+hours - hoursRemainder) / hoursInDay
|
||||
adjustedTime = `${daysQuotient}d`
|
||||
adjustedTime += +hoursRemainder === 0 ? '' : `${hoursRemainder}h`
|
||||
adjustedTime += +minutes === 0 ? '' : `${minutes}m`
|
|
@ -1,16 +1,22 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
import {TEMP_VAR_INTERVAL, AUTO_GROUP_BY} from 'shared/constants'
|
||||
import {NULL_STRING} from 'shared/constants/queryFillOptions'
|
||||
import {TEMP_VAR_INTERVAL, AUTO_GROUP_BY} from 'src/shared/constants'
|
||||
import {NULL_STRING} from 'src/shared/constants/queryFillOptions'
|
||||
import {
|
||||
TYPE_QUERY_CONFIG,
|
||||
TYPE_SHIFTED,
|
||||
TYPE_IFQL,
|
||||
} from 'src/dashboards/constants'
|
||||
import {shiftTimeRange} from 'shared/query/helpers'
|
||||
import {shiftTimeRange} from 'src/shared/query/helpers'
|
||||
import {QueryConfig, Field, GroupBy, TimeShift} from 'src/types'
|
||||
|
||||
/* eslint-disable quotes */
|
||||
export const quoteIfTimestamp = ({lower, upper}) => {
|
||||
export const quoteIfTimestamp = ({
|
||||
lower,
|
||||
upper,
|
||||
}: {
|
||||
lower: string
|
||||
upper: string
|
||||
}): {lower: string; upper: string} => {
|
||||
if (lower && lower.includes('Z') && !lower.includes("'")) {
|
||||
lower = `'${lower}'`
|
||||
}
|
||||
|
@ -21,43 +27,53 @@ export const quoteIfTimestamp = ({lower, upper}) => {
|
|||
|
||||
return {lower, upper}
|
||||
}
|
||||
/* eslint-enable quotes */
|
||||
|
||||
export default function buildInfluxQLQuery(timeRange, config, shift) {
|
||||
export default function buildInfluxQLQuery(
|
||||
timeRange,
|
||||
config: QueryConfig,
|
||||
shift: string = ''
|
||||
): string {
|
||||
const {groupBy, fill = NULL_STRING, tags, areTagsAccepted} = config
|
||||
const {upper, lower} = quoteIfTimestamp(timeRange)
|
||||
|
||||
const select = _buildSelect(config, shift)
|
||||
const select = buildSelect(config, shift)
|
||||
if (select === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const condition = _buildWhereClause({lower, upper, tags, areTagsAccepted})
|
||||
const dimensions = _buildGroupBy(groupBy)
|
||||
const fillClause = groupBy.time ? _buildFill(fill) : ''
|
||||
const condition = buildWhereClause({lower, upper, tags, areTagsAccepted})
|
||||
const dimensions = buildGroupBy(groupBy)
|
||||
const fillClause = groupBy.time ? buildFill(fill) : ''
|
||||
|
||||
return `${select}${condition}${dimensions}${fillClause}`
|
||||
}
|
||||
|
||||
function _buildSelect({fields, database, retentionPolicy, measurement}, shift) {
|
||||
if (!database || !measurement || !fields || !fields.length) {
|
||||
function buildSelect(
|
||||
{fields, database, retentionPolicy, measurement}: QueryConfig,
|
||||
shift: string | null = null
|
||||
): string {
|
||||
if (!database || !measurement || _.isEmpty(fields)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const rpSegment = retentionPolicy ? `"${retentionPolicy}"` : ''
|
||||
const fieldsClause = _buildFields(fields, shift)
|
||||
const fieldsClause = buildFields(fields, shift)
|
||||
const fullyQualifiedMeasurement = `"${database}".${rpSegment}."${measurement}"`
|
||||
const statement = `SELECT ${fieldsClause} FROM ${fullyQualifiedMeasurement}`
|
||||
return statement
|
||||
}
|
||||
|
||||
// type arg will reason about new query types i.e. IFQL, GraphQL, or queryConfig
|
||||
export const buildQuery = (type, timeRange, config, shift) => {
|
||||
export const buildQuery = (
|
||||
type: string,
|
||||
timeRange: object,
|
||||
config: QueryConfig,
|
||||
shift: TimeShift | null = null
|
||||
): string => {
|
||||
switch (type) {
|
||||
case TYPE_QUERY_CONFIG: {
|
||||
return buildInfluxQLQuery(timeRange, config)
|
||||
}
|
||||
|
||||
case TYPE_SHIFTED: {
|
||||
const {quantity, unit} = shift
|
||||
return buildInfluxQLQuery(
|
||||
|
@ -75,11 +91,11 @@ export const buildQuery = (type, timeRange, config, shift) => {
|
|||
return buildInfluxQLQuery(timeRange, config)
|
||||
}
|
||||
|
||||
export function buildSelectStatement(config) {
|
||||
return _buildSelect(config)
|
||||
export function buildSelectStatement(config: QueryConfig): string {
|
||||
return buildSelect(config)
|
||||
}
|
||||
|
||||
function _buildFields(fieldFuncs, shift = '') {
|
||||
function buildFields(fieldFuncs: Field[], shift = ''): string {
|
||||
if (!fieldFuncs) {
|
||||
return ''
|
||||
}
|
||||
|
@ -103,7 +119,7 @@ function _buildFields(fieldFuncs, shift = '') {
|
|||
return `${f.value}`
|
||||
}
|
||||
case 'func': {
|
||||
const args = _buildFields(f.args)
|
||||
const args = buildFields(f.args)
|
||||
const alias = f.alias ? ` AS "${f.alias}${shift}"` : ''
|
||||
return `${f.value}(${args})${alias}`
|
||||
}
|
||||
|
@ -112,7 +128,12 @@ function _buildFields(fieldFuncs, shift = '') {
|
|||
.join(', ')
|
||||
}
|
||||
|
||||
function _buildWhereClause({lower, upper, tags, areTagsAccepted}) {
|
||||
function buildWhereClause({
|
||||
lower,
|
||||
upper,
|
||||
tags,
|
||||
areTagsAccepted,
|
||||
}: QueryConfig): string {
|
||||
const timeClauses = []
|
||||
|
||||
const timeClause = quoteIfTimestamp({lower, upper})
|
||||
|
@ -148,11 +169,11 @@ function _buildWhereClause({lower, upper, tags, areTagsAccepted}) {
|
|||
return ` WHERE ${subClauses.join(' AND ')}`
|
||||
}
|
||||
|
||||
function _buildGroupBy(groupBy) {
|
||||
return `${_buildGroupByTime(groupBy)}${_buildGroupByTags(groupBy)}`
|
||||
function buildGroupBy(groupBy: GroupBy): string {
|
||||
return `${buildGroupByTime(groupBy)}${buildGroupByTags(groupBy)}`
|
||||
}
|
||||
|
||||
function _buildGroupByTime(groupBy) {
|
||||
function buildGroupByTime(groupBy: GroupBy): string {
|
||||
if (!groupBy || !groupBy.time) {
|
||||
return ''
|
||||
}
|
||||
|
@ -162,7 +183,7 @@ function _buildGroupByTime(groupBy) {
|
|||
})`
|
||||
}
|
||||
|
||||
function _buildGroupByTags(groupBy) {
|
||||
function buildGroupByTags(groupBy: GroupBy): string {
|
||||
if (!groupBy || !groupBy.tags.length) {
|
||||
return ''
|
||||
}
|
||||
|
@ -176,9 +197,9 @@ function _buildGroupByTags(groupBy) {
|
|||
return ` GROUP BY ${tags}`
|
||||
}
|
||||
|
||||
function _buildFill(fill) {
|
||||
function buildFill(fill: string): string {
|
||||
return ` FILL(${fill})`
|
||||
}
|
||||
|
||||
export const buildRawText = (q, timeRange) =>
|
||||
q.rawText || buildInfluxQLQuery(timeRange, q) || ''
|
||||
export const buildRawText = (config: QueryConfig, timeRange: object): string =>
|
||||
config.rawText || buildInfluxQLQuery(timeRange, config) || ''
|
Loading…
Reference in New Issue