From 7c89c455ed6da7233b5ae6271b23679f015c719e Mon Sep 17 00:00:00 2001 From: rozetko Date: Wed, 28 Dec 2022 18:29:41 +0300 Subject: [PATCH 1/2] update SQL connector to support Grafana 9 --- src/connectors/sql.ts | 17 +++++++++-------- src/connectors/utils.ts | 2 +- src/services/query_service/grafana.ts | 20 -------------------- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/connectors/sql.ts b/src/connectors/sql.ts index 7ca48d8..ab321ad 100644 --- a/src/connectors/sql.ts +++ b/src/connectors/sql.ts @@ -6,11 +6,13 @@ import * as _ from 'lodash'; // as of 26.09.2020, it works for all SQL datasources export class SqlConnector extends DatasourceConnector { private _targetName: string; //save first target name, while multi metric not implemented - private url: string = 'api/tsdb/query'; + private url: string; constructor(datasource: Datasource, targets: any[]) { super(datasource, targets); + this.url = datasource.url; + if(targets.length === 0) { throw Error('got empty targets list'); } @@ -34,7 +36,7 @@ export class SqlConnector extends DatasourceConnector { data: { from: String(from), to: String(to), - queries: queries + queries: queries, } } }; @@ -53,16 +55,15 @@ export class SqlConnector extends DatasourceConnector { // TODO: support more than 1 metric (each res.data.results item is a metric) let results = res.data.results[this._targetName]; - if (!results.series) { + if (_.isEmpty(results.frames)) { return emptyResult; } - let points = results.series[0].points; - points.forEach(p => p.reverse()); - + const frame = results.frames[0]; return { - columns: ['timestamp', results.series[0].name], - values: points + columns: frame.schema.fields.map(field => field.name), + // @ts-ignore + values: _.zip(...frame.data.values), }; } } diff --git a/src/connectors/utils.ts b/src/connectors/utils.ts index 24ceb58..3892437 100644 --- a/src/connectors/utils.ts +++ b/src/connectors/utils.ts @@ -32,7 +32,7 @@ export function processSQLLimitOffset(sql: string, limit: number, offset: number } function ensureParentheses(regex: RegExp, str: string): { index: number, length: number } { - let occurence: RegExpExecArray; + let occurence: RegExpExecArray | null; while((occurence = regex.exec(str)) !== null) { let leftPart = str.slice(0, occurence.index) let rightPart = str.slice(occurence.index + occurence[0].length); diff --git a/src/services/query_service/grafana.ts b/src/services/query_service/grafana.ts index 12f9896..260e79b 100644 --- a/src/services/query_service/grafana.ts +++ b/src/services/query_service/grafana.ts @@ -16,9 +16,6 @@ export class GrafanaQueryService extends QueryService { async query(query: DatasourceQuery, apiKey: string): Promise> { let headers = { Authorization: `Bearer ${apiKey}` }; - const grafanaUrl = getGrafanaUrl(query.url); - query.url = `${grafanaUrl}/${query.url}`; - if(query.headers !== undefined) { _.merge(headers, query.headers); } @@ -64,20 +61,3 @@ export class GrafanaQueryService extends QueryService { } } } - -export function getGrafanaUrl(url: string): string { - const parsedUrl = new URL(url); - const path = parsedUrl.pathname; - const panelUrl = path.match(/^\/*([^\/]*)\/d\//); - if(panelUrl === null) { - return url; - } - - const origin = parsedUrl.origin; - const grafanaSubPath = panelUrl[1]; - if(grafanaSubPath.length > 0) { - return `${origin}/${grafanaSubPath}`; - } - - return origin; -} -- 2.34.1 From 6bf90e69bb0beeb26e01a9a003b6b231aa2cfec9 Mon Sep 17 00:00:00 2001 From: rozetko Date: Wed, 28 Dec 2022 18:29:50 +0300 Subject: [PATCH 2/2] upd SQL test --- spec/sql.jest.ts | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/spec/sql.jest.ts b/spec/sql.jest.ts index ad828de..6c27003 100644 --- a/spec/sql.jest.ts +++ b/spec/sql.jest.ts @@ -37,22 +37,40 @@ describe('Test result parsing', function() { data: { results: { A: { - refId: 'A', - meta: { - rowCount:0, - sql: 'SELECT "time" AS "time", val FROM local ORDER BY 1' - }, - series: [ + frames: [ { - name:"val", - points: [ - [622, timestamps[0]], - [844, timestamps[1]], - [648, timestamps[2]] - ] + schema: { + refId: 'A', + meta: { + 'executedQueryString': 'SELECT\n \"time\" AS \"time\",\n eur\nFROM rate_test\nWHERE\n \"time\" >= 1669648679 AND \"time\" <= 1672240679\nORDER BY 1' + }, + fields: [ + { + name: 'Time', + type: 'time', + typeInfo: { + frame: 'time.Time', + nullable: true + } + }, + { + name: 'eur', + type: 'number', + typeInfo: { + frame: 'float64', + nullable: true + } + } + ] + }, + data: { + values: [ + [ timestamps[0], timestamps[1], timestamps[2] ], + [ 1.53, 1.17, 1.17 ], + ] + } } - ], - tables: 'null' + ] } } } @@ -61,7 +79,7 @@ describe('Test result parsing', function() { let result = connector.parseResponse(response); it('check results columns order', function() { - let timestampColumnNumber = result.columns.indexOf('timestamp'); + let timestampColumnNumber = result.columns.indexOf('Time'); expect(result.values.map(v => v[timestampColumnNumber])).toEqual(timestamps); }); }); -- 2.34.1