Files
grafana/public/app/plugins/datasource/mysql/response_parser.ts
Marcus Efraimsson f5654f88e2 mysql: fix precision for the time column in table/annotation query mode
Use the ConvertSqlTimeColumnToEpochMs function to convert any native
datetime data type or epoch time (millisecond precision).
Refactored mysql implementation to make it more similar to postgres
and mssql implementations.
Added $__timeEpoch macro function with same implementation as $__time.
Added possibility to use a time column named time in addition to
the currectly supported time_sec.
Additional tests and update of existing.
Added test dashboard.
2018-03-22 15:40:46 +01:00

149 lines
3.8 KiB
TypeScript

import _ from 'lodash';
export default class ResponseParser {
constructor(private $q) {}
processQueryResult(res) {
var data = [];
if (!res.data.results) {
return { data: data };
}
for (let key in res.data.results) {
let queryRes = res.data.results[key];
if (queryRes.series) {
for (let series of queryRes.series) {
data.push({
target: series.name,
datapoints: series.points,
refId: queryRes.refId,
meta: queryRes.meta,
});
}
}
if (queryRes.tables) {
for (let table of queryRes.tables) {
table.type = 'table';
table.refId = queryRes.refId;
table.meta = queryRes.meta;
data.push(table);
}
}
}
return { data: data };
}
parseMetricFindQueryResult(refId, results) {
if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) {
return [];
}
const columns = results.data.results[refId].tables[0].columns;
const rows = results.data.results[refId].tables[0].rows;
const textColIndex = this.findColIndex(columns, '__text');
const valueColIndex = this.findColIndex(columns, '__value');
if (columns.length === 2 && textColIndex !== -1 && valueColIndex !== -1) {
return this.transformToKeyValueList(rows, textColIndex, valueColIndex);
}
return this.transformToSimpleList(rows);
}
transformToKeyValueList(rows, textColIndex, valueColIndex) {
const res = [];
for (let i = 0; i < rows.length; i++) {
if (!this.containsKey(res, rows[i][textColIndex])) {
res.push({
text: rows[i][textColIndex],
value: rows[i][valueColIndex],
});
}
}
return res;
}
transformToSimpleList(rows) {
const res = [];
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < rows[i].length; j++) {
const value = rows[i][j];
if (res.indexOf(value) === -1) {
res.push(value);
}
}
}
return _.map(res, value => {
return { text: value };
});
}
findColIndex(columns, colName) {
for (let i = 0; i < columns.length; i++) {
if (columns[i].text === colName) {
return i;
}
}
return -1;
}
containsKey(res, key) {
for (let i = 0; i < res.length; i++) {
if (res[i].text === key) {
return true;
}
}
return false;
}
transformAnnotationResponse(options, data) {
const table = data.data.results[options.annotation.name].tables[0];
let timeColumnIndex = -1;
let textColumnIndex = -1;
let tagsColumnIndex = -1;
for (let i = 0; i < table.columns.length; i++) {
if (table.columns[i].text === 'time_sec' || table.columns[i].text === 'time') {
timeColumnIndex = i;
} else if (table.columns[i].text === 'title') {
return this.$q.reject({
message: 'The title column for annotations is deprecated, now only a column named text is returned',
});
} else if (table.columns[i].text === 'text') {
textColumnIndex = i;
} else if (table.columns[i].text === 'tags') {
tagsColumnIndex = i;
}
}
if (timeColumnIndex === -1) {
return this.$q.reject({
message: 'Missing mandatory time column (with time_sec column alias) in annotation query.',
});
}
const list = [];
for (let i = 0; i < table.rows.length; i++) {
const row = table.rows[i];
list.push({
annotation: options.annotation,
time: Math.floor(row[timeColumnIndex]),
text: row[textColumnIndex] ? row[textColumnIndex].toString() : '',
tags: row[tagsColumnIndex] ? row[tagsColumnIndex].trim().split(/\s*,\s*/) : [],
});
}
return list;
}
}