sql: do not use the getTimeSrv call (#74800)

* sql: eliminate the getTimeSrv call

* adjusted tests
This commit is contained in:
Gábor Farkas 2023-09-18 10:39:05 +02:00 committed by GitHub
parent 942c4779b9
commit 1f6f866a36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 26 deletions

View File

@ -2,6 +2,7 @@ import { lastValueFrom, Observable, throwError } from 'rxjs';
import { map } from 'rxjs/operators';
import {
getDefaultTimeRange,
DataFrame,
DataFrameView,
DataQuery,
@ -15,6 +16,7 @@ import {
getSearchFilterScopedVar,
LegacyMetricFindQueryOptions,
VariableWithMultiSupport,
TimeRange,
} from '@grafana/data';
import { EditorMode } from '@grafana/experimental';
import {
@ -27,7 +29,6 @@ import {
TemplateSrv,
reportInteraction,
} from '@grafana/runtime';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { ResponseParser } from '../ResponseParser';
import { SqlQueryEditor } from '../components/QueryEditor';
@ -182,6 +183,12 @@ export abstract class SqlDatasource extends DataSourceWithBackend<SQLQuery, SQLO
}
async metricFindQuery(query: string, options?: LegacyMetricFindQueryOptions): Promise<MetricFindValue[]> {
const range = options?.range;
if (range == null) {
// i cannot create a scenario where this happens, we handle it just to be sure.
return [];
}
let refId = 'tempvar';
if (options && options.variable && options.variable.name) {
refId = options.variable.name;
@ -201,17 +208,18 @@ export abstract class SqlDatasource extends DataSourceWithBackend<SQLQuery, SQLO
format: QueryFormat.Table,
};
const response = await this.runMetaQuery(interpolatedQuery, options);
const response = await this.runMetaQuery(interpolatedQuery, range);
return this.getResponseParser().transformMetricFindResponse(response);
}
// NOTE: this always runs with the `@grafana/data/getDefaultTimeRange` time range
async runSql<T>(query: string, options?: RunSQLOptions) {
const frame = await this.runMetaQuery({ rawSql: query, format: QueryFormat.Table, refId: options?.refId }, options);
const range = getDefaultTimeRange();
const frame = await this.runMetaQuery({ rawSql: query, format: QueryFormat.Table, refId: options?.refId }, range);
return new DataFrameView<T>(frame);
}
private runMetaQuery(request: Partial<SQLQuery>, options?: LegacyMetricFindQueryOptions): Promise<DataFrame> {
const range = getTimeSrv().timeRange();
private runMetaQuery(request: Partial<SQLQuery>, range: TimeRange): Promise<DataFrame> {
const refId = request.refId || 'meta';
const queries: DataQuery[] = [{ ...request, datasource: request.datasource || this.getRef(), refId }];
@ -222,8 +230,8 @@ export abstract class SqlDatasource extends DataSourceWithBackend<SQLQuery, SQLO
method: 'POST',
headers: this.getRequestHeaders(),
data: {
from: options?.range?.from.valueOf().toString() || range.from.valueOf().toString(),
to: options?.range?.to.valueOf().toString() || range.to.valueOf().toString(),
from: range.from.valueOf().toString(),
to: range.to.valueOf().toString(),
queries,
},
requestId: refId,

View File

@ -3,6 +3,7 @@ import { createFetchResponse } from 'test/helpers/createFetchResponse';
import {
dataFrameToJSON,
getDefaultTimeRange,
DataSourceInstanceSettings,
dateTime,
FieldType,
@ -33,6 +34,7 @@ const instanceSettings = {
} as DataSourceInstanceSettings<MssqlOptions>;
describe('MSSQLDatasource', () => {
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
const fetchMock = jest.spyOn(backendSrv, 'fetch');
const ctx = {
@ -69,7 +71,7 @@ describe('MSSQLDatasource', () => {
beforeEach(() => {
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
return ctx.ds.metricFindQuery(query).then((data: MetricFindValue[]) => {
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data: MetricFindValue[]) => {
results = data;
});
});
@ -97,7 +99,7 @@ describe('MSSQLDatasource', () => {
it('should return an empty array when metricFindQuery is called', async () => {
const query = 'select * from atable';
const results = await ctx.ds.metricFindQuery(query);
const results = await ctx.ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(0);
});
@ -231,7 +233,7 @@ describe('MSSQLDatasource', () => {
beforeEach(() => {
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
return ctx.ds.metricFindQuery(query).then((data) => {
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
results = data;
});
});
@ -272,7 +274,7 @@ describe('MSSQLDatasource', () => {
beforeEach(() => {
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
return ctx.ds.metricFindQuery(query).then((data) => {
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
results = data;
});
});
@ -311,7 +313,7 @@ describe('MSSQLDatasource', () => {
beforeEach(() => {
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
return ctx.ds.metricFindQuery(query).then((data) => {
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
results = data;
});
});

View File

@ -2,6 +2,7 @@ import { of } from 'rxjs';
import {
dataFrameToJSON,
getDefaultTimeRange,
DataQueryRequest,
DataSourceInstanceSettings,
dateTime,
@ -18,6 +19,7 @@ import { MySqlDatasource } from '../MySqlDatasource';
import { MySQLOptions } from '../types';
describe('MySQLDatasource', () => {
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
const setupTestContext = (response: unknown) => {
jest.clearAllMocks();
setBackendSrv(backendSrv);
@ -82,7 +84,7 @@ describe('MySQLDatasource', () => {
it('should return an empty array when metricFindQuery is called', async () => {
const query = 'select * from atable';
const results = await ds.metricFindQuery(query);
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(0);
});
@ -216,7 +218,7 @@ describe('MySQLDatasource', () => {
it('should return list of all string field values', async () => {
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(6);
expect(results[0].text).toBe('aTitle');
@ -249,7 +251,7 @@ describe('MySQLDatasource', () => {
it('should return list of all column values', async () => {
const { ds, fetchMock } = setupTestContext(response);
const results = await ds.metricFindQuery(query, { searchFilter: 'aTit' });
const results = await ds.metricFindQuery(query, { range: defaultRange, searchFilter: 'aTit' });
expect(fetchMock).toBeCalledTimes(1);
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe(
@ -284,7 +286,7 @@ describe('MySQLDatasource', () => {
it('should return list of all column values', async () => {
const { ds, fetchMock } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(fetchMock).toBeCalledTimes(1);
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe("select title from atable where title LIKE '%'");
@ -317,7 +319,7 @@ describe('MySQLDatasource', () => {
it('should return list of as text, value', async () => {
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(3);
expect(results[0].text).toBe('aTitle');
@ -352,7 +354,7 @@ describe('MySQLDatasource', () => {
it('should return list of all field values as text', async () => {
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results).toEqual([
{ text: 1 },
@ -390,7 +392,7 @@ describe('MySQLDatasource', () => {
it('should return list of unique keys', async () => {
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(1);
expect(results[0].text).toBe('aTitle');

View File

@ -2,6 +2,7 @@ import { Observable, of } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import {
getDefaultTimeRange,
dataFrameToJSON,
DataQueryRequest,
DataQueryResponse,
@ -37,6 +38,7 @@ jest.mock('@grafana/runtime/src/services', () => ({
}));
describe('PostgreSQLDatasource', () => {
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
const fetchMock = jest.spyOn(backendSrv, 'fetch');
const setupTestContext = (data: unknown, mock?: Observable<FetchResponse<unknown>>) => {
jest.clearAllMocks();
@ -311,7 +313,7 @@ describe('PostgreSQLDatasource', () => {
it('should return an empty array when metricFindQuery is called', async () => {
const query = 'select * from atable';
const results = await ds.metricFindQuery(query);
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(0);
});
@ -474,7 +476,7 @@ describe('PostgreSQLDatasource', () => {
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results.length).toBe(6);
expect(results[0].text).toBe('aTitle');
@ -507,7 +509,7 @@ describe('PostgreSQLDatasource', () => {
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, { searchFilter: 'aTit' });
const results = await ds.metricFindQuery(query, { range: defaultRange, searchFilter: 'aTit' });
expect(fetchMock).toBeCalledTimes(1);
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe(
@ -549,7 +551,7 @@ describe('PostgreSQLDatasource', () => {
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(fetchMock).toBeCalledTimes(1);
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe("select title from atable where title LIKE '%'");
@ -588,7 +590,7 @@ describe('PostgreSQLDatasource', () => {
},
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results).toEqual([
{ text: 'aTitle', value: 'value1' },
@ -622,7 +624,7 @@ describe('PostgreSQLDatasource', () => {
},
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results).toEqual([
{ text: 1 },
@ -659,7 +661,7 @@ describe('PostgreSQLDatasource', () => {
},
};
const { ds } = setupTestContext(response);
const results = await ds.metricFindQuery(query, {});
const results = await ds.metricFindQuery(query, { range: defaultRange });
expect(results).toEqual([{ text: 'aTitle', value: 'same' }]);
});