This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-extras.git
The following commit(s) were added to refs/heads/master by this push:
new ca2d615 support object-form template variable queries (#128)
ca2d615 is described below
commit ca2d615f767cd619bfa6e3f8ce326a9a89dd72fd
Author: Zhao Xinqi <[email protected]>
AuthorDate: Tue Aug 25 17:06:11 2026 +0800
support object-form template variable queries (#128)
---
connectors/grafana-plugin/src/datasource.test.ts | 39 ++++++++++++++++++++++++
connectors/grafana-plugin/src/datasource.ts | 24 +++++++++++++--
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/connectors/grafana-plugin/src/datasource.test.ts
b/connectors/grafana-plugin/src/datasource.test.ts
index 61ee77d..6d32cfa 100644
--- a/connectors/grafana-plugin/src/datasource.test.ts
+++ b/connectors/grafana-plugin/src/datasource.test.ts
@@ -237,4 +237,43 @@ describe('DataSource', () => {
expect(result.groupBy?.step).toBe('1h');
});
});
+
+ describe('metricFindQuery', () => {
+ it('extracts and expands a standard variable query object', async () => {
+ const scopedVars: ScopedVars = { cluster: { text: 'cluster-a', value:
'cluster-a' } };
+ const sql =
+ "table:metrics_validation:SELECT DISTINCT instance FROM sys_cpu_cores
WHERE cluster IN (${cluster:sqlstring})";
+ const expandedSql =
+ "table:metrics_validation:SELECT DISTINCT instance FROM sys_cpu_cores
WHERE cluster IN ('cluster-a')";
+ const getVariablesResult = jest.spyOn(ds,
'getVariablesResult').mockResolvedValue([]);
+ mockReplace.mockReturnValue(expandedSql);
+
+ await ds.metricFindQuery({ query: sql, refId: 'StandardVariableQuery' },
{ scopedVars });
+
+ expect(mockReplace).toHaveBeenCalledWith(sql, scopedVars);
+ expect(getVariablesResult).toHaveBeenCalledWith(expandedSql);
+ });
+
+ it('keeps legacy string variable queries compatible', async () => {
+ const sql = 'show child paths root.sg';
+ const getVariablesResult = jest.spyOn(ds,
'getVariablesResult').mockResolvedValue([]);
+ mockReplace.mockReturnValue(sql);
+
+ await ds.metricFindQuery(sql);
+
+ expect(mockReplace).toHaveBeenCalledWith(sql, undefined);
+ expect(getVariablesResult).toHaveBeenCalledWith(sql);
+ });
+
+ it('rejects variable query objects without a string query field', async ()
=> {
+ const getVariablesResult = jest.spyOn(ds,
'getVariablesResult').mockResolvedValue([]);
+
+ await expect(ds.metricFindQuery({ refId: 'StandardVariableQuery'
})).rejects.toThrow(
+ 'Variable query must be a string or an object with a string query
field'
+ );
+
+ expect(mockReplace).not.toHaveBeenCalled();
+ expect(getVariablesResult).not.toHaveBeenCalled();
+ });
+ });
});
diff --git a/connectors/grafana-plugin/src/datasource.ts
b/connectors/grafana-plugin/src/datasource.ts
index 319f804..0e27c05 100644
--- a/connectors/grafana-plugin/src/datasource.ts
+++ b/connectors/grafana-plugin/src/datasource.ts
@@ -20,6 +20,21 @@ import { IoTDBOptions, IoTDBQuery } from './types';
import { toMetricFindValue } from './functions';
import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime';
+function variableQueryText(query: unknown): string | undefined {
+ if (typeof query === 'string') {
+ return query;
+ }
+
+ if (query && typeof query === 'object' && 'query' in query) {
+ const queryText = (query as { query?: unknown }).query;
+ if (typeof queryText === 'string') {
+ return queryText;
+ }
+ }
+
+ return undefined;
+}
+
export class DataSource extends DataSourceWithBackend<IoTDBQuery,
IoTDBOptions> {
username: string;
url: string;
@@ -138,8 +153,13 @@ export class DataSource extends
DataSourceWithBackend<IoTDBQuery, IoTDBOptions>
}
metricFindQuery(query: any, options?: any): Promise<MetricFindValue[]> {
- query = getTemplateSrv().replace(query, options.scopedVars);
- return this.getVariablesResult(query);
+ const queryText = variableQueryText(query);
+ if (queryText === undefined) {
+ return Promise.reject(new Error('Variable query must be a string or an
object with a string query field'));
+ }
+
+ const expandedQuery = getTemplateSrv().replace(queryText,
options?.scopedVars);
+ return this.getVariablesResult(expandedQuery);
}
nodeQuery(query: any, options?: any): Promise<MetricFindValue[]> {