Commit 0bb8b328 by Hugo Häggmark Committed by GitHub

Mysql: Support request cancellation properly (Uses new backendSrv.fetch…

Mysql: Support request cancellation properly (Uses new backendSrv.fetch Observable request API) (#27649)
parent 3ae6ba03
import _ from 'lodash';
import ResponseParser from './response_parser';
import MysqlQuery from 'app/plugins/datasource/mysql/mysql_query';
import { Observable, of } from 'rxjs';
import { catchError, map, mapTo } from 'rxjs/operators';
import { getBackendSrv } from '@grafana/runtime';
import { ScopedVars } from '@grafana/data';
import { TemplateSrv } from 'app/features/templating/template_srv';
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
//Types
import { MysqlQueryForInterpolation } from './types';
import MysqlQuery from 'app/plugins/datasource/mysql/mysql_query';
import ResponseParser, { MysqlResponse } from './response_parser';
import { MysqlMetricFindValue, MysqlQueryForInterpolation } from './types';
import { getSearchFilterScopedVar } from '../../../features/variables/utils';
export class MysqlDatasource {
......@@ -25,7 +27,7 @@ export class MysqlDatasource {
this.interval = (instanceSettings.jsonData || {}).timeInterval || '1m';
}
interpolateVariable = (value: string, variable: any) => {
interpolateVariable = (value: string | string[] | number, variable: any) => {
if (typeof value === 'string') {
if (variable.multi || variable.includeAll) {
const result = this.queryModel.quoteLiteral(value);
......@@ -64,7 +66,7 @@ export class MysqlDatasource {
return expandedQueries;
}
query(options: any) {
query(options: any): Observable<MysqlResponse> {
const queries = _.filter(options.targets, target => {
return target.hide !== true;
}).map(target => {
......@@ -81,11 +83,11 @@ export class MysqlDatasource {
});
if (queries.length === 0) {
return Promise.resolve({ data: [] });
return of({ data: [] });
}
return getBackendSrv()
.datasourceRequest({
.fetch({
url: '/api/tsdb/query',
method: 'POST',
data: {
......@@ -94,7 +96,7 @@ export class MysqlDatasource {
queries: queries,
},
})
.then(this.responseParser.processQueryResult);
.pipe(map(this.responseParser.processQueryResult));
}
annotationQuery(options: any) {
......@@ -112,7 +114,7 @@ export class MysqlDatasource {
};
return getBackendSrv()
.datasourceRequest({
.fetch({
url: '/api/tsdb/query',
method: 'POST',
data: {
......@@ -121,10 +123,11 @@ export class MysqlDatasource {
queries: [query],
},
})
.then((data: any) => this.responseParser.transformAnnotationResponse(options, data));
.pipe(map((data: any) => this.responseParser.transformAnnotationResponse(options, data)))
.toPromise();
}
metricFindQuery(query: string, optionalOptions: any) {
metricFindQuery(query: string, optionalOptions: any): Promise<MysqlMetricFindValue[]> {
let refId = 'tempvar';
if (optionalOptions && optionalOptions.variable && optionalOptions.variable.name) {
refId = optionalOptions.variable.name;
......@@ -158,17 +161,18 @@ export class MysqlDatasource {
}
return getBackendSrv()
.datasourceRequest({
.fetch({
url: '/api/tsdb/query',
method: 'POST',
data: data,
})
.then((data: any) => this.responseParser.parseMetricFindQueryResult(refId, data));
.pipe(map((data: any) => this.responseParser.parseMetricFindQueryResult(refId, data)))
.toPromise();
}
testDatasource() {
return getBackendSrv()
.datasourceRequest({
.fetch({
url: '/api/tsdb/query',
method: 'POST',
data: {
......@@ -186,17 +190,18 @@ export class MysqlDatasource {
],
},
})
.then((res: any) => {
return { status: 'success', message: 'Database Connection OK' };
})
.catch((err: any) => {
console.error(err);
if (err.data && err.data.message) {
return { status: 'error', message: err.data.message };
} else {
return { status: 'error', message: err.status };
}
});
.pipe(
mapTo({ status: 'success', message: 'Database Connection OK' }),
catchError(err => {
console.error(err);
if (err.data && err.data.message) {
return of({ status: 'error', message: err.data.message });
} else {
return of({ status: 'error', message: err.status });
}
})
)
.toPromise();
}
targetContainsTemplate(target: any) {
......
import _ from 'lodash';
import { MysqlMetricFindValue } from './types';
interface TableResponse extends Record<string, any> {
type: string;
refId: string;
meta: any;
}
interface SeriesResponse extends Record<string, any> {
target: string;
refId: string;
meta: any;
datapoints: [any[]];
}
export interface MysqlResponse {
data: Array<TableResponse | SeriesResponse>;
}
export default class ResponseParser {
processQueryResult(res: any) {
processQueryResult(res: any): MysqlResponse {
const data: any[] = [];
if (!res.data.results) {
......@@ -35,7 +53,7 @@ export default class ResponseParser {
return { data: data };
}
parseMetricFindQueryResult(refId: string, results: any) {
parseMetricFindQueryResult(refId: string, results: any): MysqlMetricFindValue[] {
if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) {
return [];
}
......@@ -117,9 +135,9 @@ export default class ResponseParser {
} else if (table.columns[i].text === 'timeend') {
timeEndColumnIndex = i;
} else if (table.columns[i].text === 'title') {
return Promise.reject({
throw {
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') {
......@@ -128,9 +146,9 @@ export default class ResponseParser {
}
if (timeColumnIndex === -1) {
return Promise.reject({
throw {
message: 'Missing mandatory time column (with time_sec column alias) in annotation query.',
});
};
}
const list = [];
......
import { MetricFindValue } from '@grafana/data';
export interface MysqlQueryForInterpolation {
alias?: any;
format?: any;
......@@ -5,3 +7,7 @@ export interface MysqlQueryForInterpolation {
refId?: any;
hide?: any;
}
export interface MysqlMetricFindValue extends MetricFindValue {
value?: string;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment