UNPKG

cloki

Version:

LogQL API with Clickhouse Backend

94 lines (89 loc) 2.44 kB
const { map, hasExtraLabels, hasStream, addStream } = require('./common') const Sql = require('@cloki/clickhouse-sql') /** * * @param token {Token} * @param query {Select} * @returns {Select} */ module.exports = (token, query) => { const label = token.Child('label').value if (hasStream(query)) { return viaStream(label, query) } if (label === '_entry') { return unwrapLine(query) } if (hasExtraLabels(query)) { return viaQueryWithExtraLabels(label, query) } return viaQuery(label, query) } /** * * @param query {Select} * @returns {Select} */ function unwrapLine (query) { return query.select([new Sql.Raw('toFloat64OrNull(string)'), 'unwrapped']) .where(Sql.Eq(new Sql.Raw('isNotNull(unwrapped)'), 1)) } /** * * @param label {string} * @param query {Select} * @returns {Select} */ function viaQuery (label, query) { query.limit(undefined, undefined) return query.select( [new Sql.Raw(`toFloat64OrNull(arrayFirst(x -> x.1 == '${label}', labels).2)`, 'unwrapped')] ).where(Sql.And( Sql.Eq(new Sql.Raw(`arrayExists(x -> x.1 == '${label}', labels)`), 1), Sql.Eq(new Sql.Raw('isNotNull(unwrapped)'), 1) )) } /** * * @param label {string} * @param query {Select} * @returns {Select} */ function viaQueryWithExtraLabels (label, query) { query.limit(undefined, undefined) return query.select( [new Sql.Raw(`toFloat64OrNull(if(arrayExists(x -> x.1 == '${label}', extra_labels), ` + `arrayFirst(x -> x.1 == '${label}', extra_labels).2, ` + `arrayFirst(x -> x.1 == '${label}', labels).2))`), 'unwrapped'] ).where(Sql.And(Sql.Or( Sql.Ne(new Sql.Raw(`arrayFirstIndex(x -> x.1 == '${label}', extra_labels)`), 0), Sql.Eq(new Sql.Raw(`arrayExists(x -> x.1 == '${label}', labels)`), 1) ), Sql.Eq(new Sql.Raw('isNotNull(unwrapped)'), 1))) } /** * * @param label {string} * @param query {Select} * @returns {Select} */ function viaStream (label, query) { query.limit(undefined, undefined) const isUnwrapString = label === '_entry' return addStream(query, (stream) => map(stream, e => { if (!e || !e.labels) { return { ...e } } if (!isUnwrapString && !e.labels[label]) { return null } try { e.unwrapped = parseFloat(isUnwrapString ? e.string : e.labels[label]) if (isNaN(e.unwrapped)) { return null } return e } catch (e) { return null } }).filter(e => e)) }