Browse Source

Merge branch 'master' of code.corpglory.net:hastic/tsdb-kit

pull/13/head
rozetko 1 year ago
parent
commit
3ca05e5ca2
  1. 48
      spec/sql.jest.ts
  2. 17
      src/connectors/sql.ts
  3. 2
      src/connectors/utils.ts
  4. 20
      src/services/query_service/grafana.ts

48
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);
});
});

17
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),
};
}
}

2
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);

20
src/services/query_service/grafana.ts

@ -16,9 +16,6 @@ export class GrafanaQueryService extends QueryService {
async query(query: DatasourceQuery, apiKey: string): Promise<AxiosResponse<any>> {
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;
}

Loading…
Cancel
Save