mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
sql: do not use the getTimeSrv call (#74800)
* sql: eliminate the getTimeSrv call * adjusted tests
This commit is contained in:
parent
942c4779b9
commit
1f6f866a36
@ -2,6 +2,7 @@ import { lastValueFrom, Observable, throwError } from 'rxjs';
|
|||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getDefaultTimeRange,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataFrameView,
|
DataFrameView,
|
||||||
DataQuery,
|
DataQuery,
|
||||||
@ -15,6 +16,7 @@ import {
|
|||||||
getSearchFilterScopedVar,
|
getSearchFilterScopedVar,
|
||||||
LegacyMetricFindQueryOptions,
|
LegacyMetricFindQueryOptions,
|
||||||
VariableWithMultiSupport,
|
VariableWithMultiSupport,
|
||||||
|
TimeRange,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { EditorMode } from '@grafana/experimental';
|
import { EditorMode } from '@grafana/experimental';
|
||||||
import {
|
import {
|
||||||
@ -27,7 +29,6 @@ import {
|
|||||||
TemplateSrv,
|
TemplateSrv,
|
||||||
reportInteraction,
|
reportInteraction,
|
||||||
} from '@grafana/runtime';
|
} from '@grafana/runtime';
|
||||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
|
||||||
|
|
||||||
import { ResponseParser } from '../ResponseParser';
|
import { ResponseParser } from '../ResponseParser';
|
||||||
import { SqlQueryEditor } from '../components/QueryEditor';
|
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[]> {
|
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';
|
let refId = 'tempvar';
|
||||||
if (options && options.variable && options.variable.name) {
|
if (options && options.variable && options.variable.name) {
|
||||||
refId = options.variable.name;
|
refId = options.variable.name;
|
||||||
@ -201,17 +208,18 @@ export abstract class SqlDatasource extends DataSourceWithBackend<SQLQuery, SQLO
|
|||||||
format: QueryFormat.Table,
|
format: QueryFormat.Table,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await this.runMetaQuery(interpolatedQuery, options);
|
const response = await this.runMetaQuery(interpolatedQuery, range);
|
||||||
return this.getResponseParser().transformMetricFindResponse(response);
|
return this.getResponseParser().transformMetricFindResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: this always runs with the `@grafana/data/getDefaultTimeRange` time range
|
||||||
async runSql<T>(query: string, options?: RunSQLOptions) {
|
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);
|
return new DataFrameView<T>(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
private runMetaQuery(request: Partial<SQLQuery>, options?: LegacyMetricFindQueryOptions): Promise<DataFrame> {
|
private runMetaQuery(request: Partial<SQLQuery>, range: TimeRange): Promise<DataFrame> {
|
||||||
const range = getTimeSrv().timeRange();
|
|
||||||
const refId = request.refId || 'meta';
|
const refId = request.refId || 'meta';
|
||||||
const queries: DataQuery[] = [{ ...request, datasource: request.datasource || this.getRef(), refId }];
|
const queries: DataQuery[] = [{ ...request, datasource: request.datasource || this.getRef(), refId }];
|
||||||
|
|
||||||
@ -222,8 +230,8 @@ export abstract class SqlDatasource extends DataSourceWithBackend<SQLQuery, SQLO
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: this.getRequestHeaders(),
|
headers: this.getRequestHeaders(),
|
||||||
data: {
|
data: {
|
||||||
from: options?.range?.from.valueOf().toString() || range.from.valueOf().toString(),
|
from: range.from.valueOf().toString(),
|
||||||
to: options?.range?.to.valueOf().toString() || range.to.valueOf().toString(),
|
to: range.to.valueOf().toString(),
|
||||||
queries,
|
queries,
|
||||||
},
|
},
|
||||||
requestId: refId,
|
requestId: refId,
|
||||||
|
@ -3,6 +3,7 @@ import { createFetchResponse } from 'test/helpers/createFetchResponse';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
dataFrameToJSON,
|
dataFrameToJSON,
|
||||||
|
getDefaultTimeRange,
|
||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
dateTime,
|
dateTime,
|
||||||
FieldType,
|
FieldType,
|
||||||
@ -33,6 +34,7 @@ const instanceSettings = {
|
|||||||
} as DataSourceInstanceSettings<MssqlOptions>;
|
} as DataSourceInstanceSettings<MssqlOptions>;
|
||||||
|
|
||||||
describe('MSSQLDatasource', () => {
|
describe('MSSQLDatasource', () => {
|
||||||
|
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
|
||||||
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
@ -69,7 +71,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
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;
|
results = data;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -97,7 +99,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return an empty array when metricFindQuery is called', async () => {
|
it('should return an empty array when metricFindQuery is called', async () => {
|
||||||
const query = 'select * from atable';
|
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);
|
expect(results.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -231,7 +233,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
||||||
|
|
||||||
return ctx.ds.metricFindQuery(query).then((data) => {
|
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
|
||||||
results = data;
|
results = data;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -272,7 +274,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
||||||
|
|
||||||
return ctx.ds.metricFindQuery(query).then((data) => {
|
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
|
||||||
results = data;
|
results = data;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -311,7 +313,7 @@ describe('MSSQLDatasource', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
||||||
return ctx.ds.metricFindQuery(query).then((data) => {
|
return ctx.ds.metricFindQuery(query, { range: defaultRange }).then((data) => {
|
||||||
results = data;
|
results = data;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import { of } from 'rxjs';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
dataFrameToJSON,
|
dataFrameToJSON,
|
||||||
|
getDefaultTimeRange,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
dateTime,
|
dateTime,
|
||||||
@ -18,6 +19,7 @@ import { MySqlDatasource } from '../MySqlDatasource';
|
|||||||
import { MySQLOptions } from '../types';
|
import { MySQLOptions } from '../types';
|
||||||
|
|
||||||
describe('MySQLDatasource', () => {
|
describe('MySQLDatasource', () => {
|
||||||
|
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
|
||||||
const setupTestContext = (response: unknown) => {
|
const setupTestContext = (response: unknown) => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
setBackendSrv(backendSrv);
|
setBackendSrv(backendSrv);
|
||||||
@ -82,7 +84,7 @@ describe('MySQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return an empty array when metricFindQuery is called', async () => {
|
it('should return an empty array when metricFindQuery is called', async () => {
|
||||||
const query = 'select * from atable';
|
const query = 'select * from atable';
|
||||||
const results = await ds.metricFindQuery(query);
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
expect(results.length).toBe(0);
|
expect(results.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -216,7 +218,7 @@ describe('MySQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return list of all string field values', async () => {
|
it('should return list of all string field values', async () => {
|
||||||
const { ds } = setupTestContext(response);
|
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.length).toBe(6);
|
||||||
expect(results[0].text).toBe('aTitle');
|
expect(results[0].text).toBe('aTitle');
|
||||||
@ -249,7 +251,7 @@ describe('MySQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return list of all column values', async () => {
|
it('should return list of all column values', async () => {
|
||||||
const { ds, fetchMock } = setupTestContext(response);
|
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).toBeCalledTimes(1);
|
||||||
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe(
|
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 () => {
|
it('should return list of all column values', async () => {
|
||||||
const { ds, fetchMock } = setupTestContext(response);
|
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).toBeCalledTimes(1);
|
||||||
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe("select title from atable where title LIKE '%'");
|
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 () => {
|
it('should return list of as text, value', async () => {
|
||||||
const { ds } = setupTestContext(response);
|
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.length).toBe(3);
|
||||||
expect(results[0].text).toBe('aTitle');
|
expect(results[0].text).toBe('aTitle');
|
||||||
@ -352,7 +354,7 @@ describe('MySQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return list of all field values as text', async () => {
|
it('should return list of all field values as text', async () => {
|
||||||
const { ds } = setupTestContext(response);
|
const { ds } = setupTestContext(response);
|
||||||
const results = await ds.metricFindQuery(query, {});
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
|
|
||||||
expect(results).toEqual([
|
expect(results).toEqual([
|
||||||
{ text: 1 },
|
{ text: 1 },
|
||||||
@ -390,7 +392,7 @@ describe('MySQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return list of unique keys', async () => {
|
it('should return list of unique keys', async () => {
|
||||||
const { ds } = setupTestContext(response);
|
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.length).toBe(1);
|
||||||
expect(results[0].text).toBe('aTitle');
|
expect(results[0].text).toBe('aTitle');
|
||||||
|
@ -2,6 +2,7 @@ import { Observable, of } from 'rxjs';
|
|||||||
import { TestScheduler } from 'rxjs/testing';
|
import { TestScheduler } from 'rxjs/testing';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getDefaultTimeRange,
|
||||||
dataFrameToJSON,
|
dataFrameToJSON,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
@ -37,6 +38,7 @@ jest.mock('@grafana/runtime/src/services', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe('PostgreSQLDatasource', () => {
|
describe('PostgreSQLDatasource', () => {
|
||||||
|
const defaultRange = getDefaultTimeRange(); // it does not matter what value this has
|
||||||
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
||||||
const setupTestContext = (data: unknown, mock?: Observable<FetchResponse<unknown>>) => {
|
const setupTestContext = (data: unknown, mock?: Observable<FetchResponse<unknown>>) => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
@ -311,7 +313,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
|
|
||||||
it('should return an empty array when metricFindQuery is called', async () => {
|
it('should return an empty array when metricFindQuery is called', async () => {
|
||||||
const query = 'select * from atable';
|
const query = 'select * from atable';
|
||||||
const results = await ds.metricFindQuery(query);
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
expect(results.length).toBe(0);
|
expect(results.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -474,7 +476,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { ds } = setupTestContext(response);
|
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.length).toBe(6);
|
||||||
expect(results[0].text).toBe('aTitle');
|
expect(results[0].text).toBe('aTitle');
|
||||||
@ -507,7 +509,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { ds } = setupTestContext(response);
|
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).toBeCalledTimes(1);
|
||||||
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe(
|
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe(
|
||||||
@ -549,7 +551,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { ds } = setupTestContext(response);
|
const { ds } = setupTestContext(response);
|
||||||
const results = await ds.metricFindQuery(query, {});
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
|
|
||||||
expect(fetchMock).toBeCalledTimes(1);
|
expect(fetchMock).toBeCalledTimes(1);
|
||||||
expect(fetchMock.mock.calls[0][0].data.queries[0].rawSql).toBe("select title from atable where title LIKE '%'");
|
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 { ds } = setupTestContext(response);
|
||||||
const results = await ds.metricFindQuery(query, {});
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
|
|
||||||
expect(results).toEqual([
|
expect(results).toEqual([
|
||||||
{ text: 'aTitle', value: 'value1' },
|
{ text: 'aTitle', value: 'value1' },
|
||||||
@ -622,7 +624,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const { ds } = setupTestContext(response);
|
const { ds } = setupTestContext(response);
|
||||||
const results = await ds.metricFindQuery(query, {});
|
const results = await ds.metricFindQuery(query, { range: defaultRange });
|
||||||
|
|
||||||
expect(results).toEqual([
|
expect(results).toEqual([
|
||||||
{ text: 1 },
|
{ text: 1 },
|
||||||
@ -659,7 +661,7 @@ describe('PostgreSQLDatasource', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const { ds } = setupTestContext(response);
|
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' }]);
|
expect(results).toEqual([{ text: 'aTitle', value: 'same' }]);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user