ExpressionDatasource.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { Observable, from, mergeMap } from 'rxjs';
  2. import {
  3. DataQueryRequest,
  4. DataQueryResponse,
  5. DataSourceInstanceSettings,
  6. DataSourcePluginMeta,
  7. PluginType,
  8. ScopedVars,
  9. } from '@grafana/data';
  10. import { DataSourceWithBackend, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime';
  11. import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';
  12. import { ExpressionQueryEditor } from './ExpressionQueryEditor';
  13. import { ExpressionQuery, ExpressionQueryType } from './types';
  14. /**
  15. * This is a singleton instance that just pretends to be a DataSource
  16. */
  17. export class ExpressionDatasourceApi extends DataSourceWithBackend<ExpressionQuery> {
  18. constructor(public instanceSettings: DataSourceInstanceSettings) {
  19. super(instanceSettings);
  20. }
  21. applyTemplateVariables(query: ExpressionQuery, scopedVars: ScopedVars): Record<string, any> {
  22. const templateSrv = getTemplateSrv();
  23. return {
  24. ...query,
  25. expression: templateSrv.replace(query.expression, scopedVars),
  26. window: templateSrv.replace(query.window, scopedVars),
  27. };
  28. }
  29. getCollapsedText(query: ExpressionQuery) {
  30. return `Expression: ${query.type}`;
  31. }
  32. query(request: DataQueryRequest<ExpressionQuery>): Observable<DataQueryResponse> {
  33. let targets = request.targets.map(async (query: ExpressionQuery): Promise<ExpressionQuery> => {
  34. const ds = await getDataSourceSrv().get(query.datasource);
  35. if (!ds.interpolateVariablesInQueries) {
  36. return query;
  37. }
  38. return ds?.interpolateVariablesInQueries([query], request.scopedVars)[0] as ExpressionQuery;
  39. });
  40. let sub = from(Promise.all(targets));
  41. return sub.pipe(mergeMap((t) => super.query({ ...request, targets: t })));
  42. }
  43. newQuery(query?: Partial<ExpressionQuery>): ExpressionQuery {
  44. return {
  45. refId: '--', // Replaced with query
  46. type: query?.type ?? ExpressionQueryType.math,
  47. datasource: ExpressionDatasourceRef,
  48. conditions: query?.conditions ?? undefined,
  49. };
  50. }
  51. }
  52. /**
  53. * MATCHES a constant in DataSourceWithBackend, this should be '__expr__'
  54. * @deprecated
  55. */
  56. export const ExpressionDatasourceUID = '-100';
  57. export const instanceSettings: DataSourceInstanceSettings = {
  58. id: -100,
  59. uid: ExpressionDatasourceUID,
  60. name: ExpressionDatasourceRef.name,
  61. type: ExpressionDatasourceRef.type,
  62. access: 'proxy',
  63. meta: {
  64. baseUrl: '',
  65. module: '',
  66. type: PluginType.datasource,
  67. name: ExpressionDatasourceRef.type,
  68. id: ExpressionDatasourceRef.type,
  69. info: {
  70. author: {
  71. name: 'Grafana Labs',
  72. },
  73. logos: {
  74. small: 'public/img/icn-datasource.svg',
  75. large: 'public/img/icn-datasource.svg',
  76. },
  77. description: 'Adds expression support to Grafana',
  78. screenshots: [],
  79. links: [],
  80. updated: '',
  81. version: '',
  82. },
  83. },
  84. jsonData: {},
  85. };
  86. export const dataSource = new ExpressionDatasourceApi(instanceSettings);
  87. dataSource.meta = {
  88. id: ExpressionDatasourceRef.type,
  89. info: {
  90. logos: {
  91. small: 'public/img/icn-datasource.svg',
  92. large: 'public/img/icn-datasource.svg',
  93. },
  94. },
  95. } as DataSourcePluginMeta;
  96. dataSource.components = {
  97. QueryEditor: ExpressionQueryEditor,
  98. };