import { DatasourceConnector, Datasource, DatasourceQuery, DataTable } from '.'; import { processSQLLimitOffset } from './utils'; 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; constructor(datasource: Datasource, targets: any[]) { super(datasource, targets); this.url = datasource.url; if(targets.length === 0) { throw Error('got empty targets list'); } this._targetName = targets[0].refId; } getQuery(from: number, to: number, limit: number, offset: number): DatasourceQuery { let queries = this.targets; _.forEach(queries, q => { q.rawSql = processSQLLimitOffset(q.rawSql, limit, offset); if (!q.datasourceId) { q.datasourceId = this.datasource.datasourceId; } }); return { url: this.url, method: 'POST', schema: { data: { from: String(from), to: String(to), queries: queries, } } }; } parseResponse(res): DataTable { let emptyResult = { columns: ['timestamp', 'target'], values: [] }; if(res.data === undefined || res.data.results.length < 1) { console.log('datasource return empty response, no data'); return emptyResult; } // TODO: support more than 1 metric (each res.data.results item is a metric) let results = res.data.results[this._targetName]; if (_.isEmpty(results.frames)) { return emptyResult; } const frame = results.frames[0]; return { columns: frame.schema.fields.map(field => field.name), // @ts-ignore values: _.zip(...frame.data.values), }; } }