diff --git a/public/app/plugins/datasource/mssql/datasource.ts b/public/app/plugins/datasource/mssql/datasource.ts index 35178eb575c..71779df0342 100644 --- a/public/app/plugins/datasource/mssql/datasource.ts +++ b/public/app/plugins/datasource/mssql/datasource.ts @@ -165,4 +165,9 @@ export class MssqlDatasource { } }); } + + targetContainsTemplate(target: any) { + const rawSql = target.rawSql.replace('$__', ''); + return this.templateSrv.variableExists(rawSql); + } } diff --git a/public/app/plugins/datasource/mssql/specs/datasource.test.ts b/public/app/plugins/datasource/mssql/specs/datasource.test.ts index df7b8314d0e..eb7d2e18583 100644 --- a/public/app/plugins/datasource/mssql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mssql/specs/datasource.test.ts @@ -1,15 +1,16 @@ import { MssqlDatasource } from '../datasource'; -import { TemplateSrvStub, TimeSrvStub } from 'test/specs/helpers'; +import { TimeSrvStub } from 'test/specs/helpers'; import { CustomVariable } from 'app/features/templating/custom_variable'; // @ts-ignore import q from 'q'; import { dateTime } from '@grafana/data'; +import { TemplateSrv } from 'app/features/templating/template_srv'; describe('MSSQLDatasource', () => { + const templateSrv: TemplateSrv = new TemplateSrv(); + const ctx: any = { backendSrv: {}, - // @ts-ignore - templateSrv: new TemplateSrvStub(), timeSrv: new TimeSrvStub(), }; @@ -17,7 +18,7 @@ describe('MSSQLDatasource', () => { ctx.$q = q; ctx.instanceSettings = { name: 'mssql' }; - ctx.ds = new MssqlDatasource(ctx.instanceSettings, ctx.backendSrv, ctx.$q, ctx.templateSrv, ctx.timeSrv); + ctx.ds = new MssqlDatasource(ctx.instanceSettings, ctx.backendSrv, ctx.$q, templateSrv, ctx.timeSrv); }); describe('When performing annotationQuery', () => { @@ -278,4 +279,51 @@ describe('MSSQLDatasource', () => { }); }); }); + + describe('targetContainsTemplate', () => { + it('given query that contains template variable it should return true', () => { + const rawSql = `SELECT + $__timeGroup(createdAt,'$summarize') as time, + avg(value) as value, + hostname as metric + FROM + grafana_metric + WHERE + $__timeFilter(createdAt) AND + measurement = 'logins.count' AND + hostname IN($host) + GROUP BY $__timeGroup(createdAt,'$summarize'), hostname + ORDER BY 1`; + const query = { + rawSql, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy(); + }); + + it('given query that only contains global template variable it should return false', () => { + const rawSql = `SELECT + $__timeGroup(createdAt,'$__interval') as time, + avg(value) as value, + hostname as metric + FROM + grafana_metric + WHERE + $__timeFilter(createdAt) AND + measurement = 'logins.count' + GROUP BY $__timeGroup(createdAt,'$summarize'), hostname + ORDER BY 1`; + const query = { + rawSql, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy(); + }); + }); }); diff --git a/public/app/plugins/datasource/mysql/datasource.ts b/public/app/plugins/datasource/mysql/datasource.ts index 281f8a91880..f9d6cd79d39 100644 --- a/public/app/plugins/datasource/mysql/datasource.ts +++ b/public/app/plugins/datasource/mysql/datasource.ts @@ -175,4 +175,19 @@ export class MysqlDatasource { } }); } + + targetContainsTemplate(target: any) { + let rawSql = ''; + + if (target.rawQuery) { + rawSql = target.rawSql; + } else { + const query = new MysqlQuery(target); + rawSql = query.buildQuery(); + } + + rawSql = rawSql.replace('$__', ''); + + return this.templateSrv.variableExists(rawSql); + } } diff --git a/public/app/plugins/datasource/mysql/specs/datasource.test.ts b/public/app/plugins/datasource/mysql/specs/datasource.test.ts index 6f46fc2a4c8..8aab0abe048 100644 --- a/public/app/plugins/datasource/mysql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mysql/specs/datasource.test.ts @@ -2,13 +2,12 @@ import { MysqlDatasource } from '../datasource'; import { CustomVariable } from 'app/features/templating/custom_variable'; import { toUtc, dateTime } from '@grafana/data'; import { BackendSrv } from 'app/core/services/backend_srv'; +import { TemplateSrv } from 'app/features/templating/template_srv'; describe('MySQLDatasource', () => { const instanceSettings = { name: 'mysql' }; const backendSrv = {}; - const templateSrv: any = { - replace: jest.fn(text => text), - }; + const templateSrv: TemplateSrv = new TemplateSrv(); const raw = { from: toUtc('2018-04-25 10:00'), @@ -240,4 +239,53 @@ describe('MySQLDatasource', () => { }); }); }); + + describe('targetContainsTemplate', () => { + it('given query that contains template variable it should return true', () => { + const rawSql = `SELECT + $__timeGroup(createdAt,'$summarize') as time_sec, + avg(value) as value, + hostname as metric + FROM + grafana_metric + WHERE + $__timeFilter(createdAt) AND + measurement = 'logins.count' AND + hostname IN($host) + GROUP BY 1, 3 + ORDER BY 1`; + const query = { + rawSql, + rawQuery: true, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy(); + }); + + it('given query that only contains global template variable it should return false', () => { + const rawSql = `SELECT + $__timeGroup(createdAt,'$__interval') as time_sec, + avg(value) as value, + hostname as metric + FROM + grafana_metric + WHERE + $__timeFilter(createdAt) AND + measurement = 'logins.count' + GROUP BY 1, 3 + ORDER BY 1`; + const query = { + rawSql, + rawQuery: true, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy(); + }); + }); }); diff --git a/public/app/plugins/datasource/postgres/datasource.ts b/public/app/plugins/datasource/postgres/datasource.ts index 76a6bd8da2c..360fc9f923f 100644 --- a/public/app/plugins/datasource/postgres/datasource.ts +++ b/public/app/plugins/datasource/postgres/datasource.ts @@ -160,4 +160,19 @@ export class PostgresDatasource { } }); } + + targetContainsTemplate(target: any) { + let rawSql = ''; + + if (target.rawQuery) { + rawSql = target.rawSql; + } else { + const query = new PostgresQuery(target); + rawSql = query.buildQuery(); + } + + rawSql = rawSql.replace('$__', ''); + + return this.templateSrv.variableExists(rawSql); + } } diff --git a/public/app/plugins/datasource/postgres/specs/datasource.test.ts b/public/app/plugins/datasource/postgres/specs/datasource.test.ts index b44d64e1c5c..27f448e3c2f 100644 --- a/public/app/plugins/datasource/postgres/specs/datasource.test.ts +++ b/public/app/plugins/datasource/postgres/specs/datasource.test.ts @@ -3,14 +3,13 @@ import { CustomVariable } from 'app/features/templating/custom_variable'; import { toUtc, dateTime } from '@grafana/data'; import { BackendSrv } from 'app/core/services/backend_srv'; import { IQService } from 'angular'; +import { TemplateSrv } from 'app/features/templating/template_srv'; describe('PostgreSQLDatasource', () => { const instanceSettings = { name: 'postgresql' }; const backendSrv = {}; - const templateSrv: any = { - replace: jest.fn(text => text), - }; + const templateSrv: TemplateSrv = new TemplateSrv(); const raw = { from: toUtc('2018-04-25 10:00'), to: toUtc('2018-04-25 11:00'), @@ -249,4 +248,53 @@ describe('PostgreSQLDatasource', () => { }); }); }); + + describe('targetContainsTemplate', () => { + it('given query that contains template variable it should return true', () => { + const rawSql = `SELECT + $__timeGroup("createdAt",'$summarize'), + avg(value) as "value", + hostname as "metric" + FROM + grafana_metric + WHERE + $__timeFilter("createdAt") AND + measurement = 'logins.count' AND + hostname IN($host) + GROUP BY time, metric + ORDER BY time`; + const query = { + rawSql, + rawQuery: true, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeTruthy(); + }); + + it('given query that only contains global template variable it should return false', () => { + const rawSql = `SELECT + $__timeGroup("createdAt",'$__interval'), + avg(value) as "value", + hostname as "metric" + FROM + grafana_metric + WHERE + $__timeFilter("createdAt") AND + measurement = 'logins.count' + GROUP BY time, metric + ORDER BY time`; + const query = { + rawSql, + rawQuery: true, + }; + templateSrv.init([ + { type: 'query', name: 'summarize', current: { value: '1m' } }, + { type: 'query', name: 'host', current: { value: 'a' } }, + ]); + expect(ctx.ds.targetContainsTemplate(query)).toBeFalsy(); + }); + }); });