import { DataTable, QueryType } from './metrics/metric'; import { QueryConfig } from './models/query_config'; import { queryDirect } from './services/direct_service'; import { queryGrafana } from './services/grafana_service'; import { BadRange } from './types'; export { QueryConfig } from './models/query_config'; export { Datasource, DatasourceType, DataTable } from './metrics/metric' export { DatasourceUnavailable } from './types'; export { GrafanaUnavailable } from './services/grafana_service'; const CHUNK_SIZE = 50000; /** * @param queryConfig * @returns { values: [time, value][], columns: string[] } */ export async function queryByConfig( // TODO: check how did we wanna use `url` field queryConfig: QueryConfig, url: string, from: number, to: number, queryType: QueryType, // TODO: we need an abstract DatasourceConfig class which will differ in direct and grafana queries apiKey?: string ): Promise { if(from > to) { throw new BadRange( `Data-kit got wrong range: from ${from} > to ${to}`, queryConfig.datasource.type, url ); } if(from === to) { console.warn(`Data-kit got from === to`); } let data: DataTable = { values: [], columns: [] }; while(true) { let query = queryConfig.datasourceConnector.getQuery(from, to, CHUNK_SIZE, data.values.length); let res: any; // TODO: use polymorphic `query` method instead switch(queryType) { case QueryType.GRAFANA: res = await queryGrafana(query, apiKey as string, queryConfig.datasource); break; case QueryType.DIRECT: res = await queryDirect(query, queryConfig.datasource); break; default: throw new Error(`Unknown query type: ${queryType}`); } let chunk = queryConfig.datasourceConnector.parseResponse(res); let values = chunk.values; data.values = data.values.concat(values); data.columns = chunk.columns; if(values.length < CHUNK_SIZE) { // because if we get less that we could, then there is nothing more break; } } return data; }