Browse Source

refactor PostgresQuery

Sven Klemm 7 years ago
parent
commit
fa66645b0f

+ 34 - 30
public/app/plugins/datasource/postgres/postgres_query.ts

@@ -15,7 +15,7 @@ export default class PostgresQuery {
     target.schema = target.schema || 'public';
     target.format = target.format || 'time_series';
     target.timeColumn = target.timeColumn || 'time';
-    target.metricColumn = target.metricColumn || 'None';
+    target.metricColumn = target.metricColumn || 'none';
 
     target.groupBy = target.groupBy || [];
     target.where = target.where || [];
@@ -57,6 +57,10 @@ export default class PostgresQuery {
     return _.find(this.target.groupBy, (g: any) => g.type === 'time');
   }
 
+  hasMetricColumn() {
+    return this.target.metricColumn !== 'none';
+  }
+
   interpolateQueryStr(value, variable, defaultFormatFn) {
     // if no multi or include all do not regexEscape
     if (!variable.multi && !variable.includeAll) {
@@ -83,7 +87,7 @@ export default class PostgresQuery {
       }
     }
 
-    query = this.buildQuery(target);
+    query = this.buildQuery();
     if (interpolate) {
       query = this.templateSrv.replace(query, this.scopedVars, this.interpolateQueryStr);
     }
@@ -91,7 +95,7 @@ export default class PostgresQuery {
     return query;
   }
 
-  buildTimeColumn(target) {
+  buildTimeColumn() {
     let timeGroup = this.hasGroupByTime();
     let query;
 
@@ -102,32 +106,32 @@ export default class PostgresQuery {
       } else {
         args = timeGroup.params[0];
       }
-      query = '$__timeGroup(' + target.timeColumn + ',' + args + ')';
+      query = '$__timeGroup(' + this.target.timeColumn + ',' + args + ')';
     } else {
-      query = target.timeColumn + ' AS "time"';
+      query = this.target.timeColumn + ' AS "time"';
     }
 
     return query;
   }
 
-  buildMetricColumn(target) {
-    if (target.metricColumn !== 'None') {
-      return target.metricColumn + ' AS metric';
+  buildMetricColumn() {
+    if (this.hasMetricColumn()) {
+      return this.target.metricColumn + ' AS metric';
     }
 
     return '';
   }
 
-  buildValueColumns(target) {
+  buildValueColumns() {
     let query = '';
-    for (let i = 0; i < target.select.length; i++) {
-      query += ',\n  ' + this.buildValueColumn(target, target.select[i]);
+    for (let column of this.target.select) {
+      query += ',\n  ' + this.buildValueColumn(column);
     }
 
     return query;
   }
 
-  buildValueColumn(target, column) {
+  buildValueColumn(column) {
     let query = '';
 
     let columnName = _.find(column, (g: any) => g.type === 'column');
@@ -141,15 +145,15 @@ export default class PostgresQuery {
     let special = _.find(column, (g: any) => g.type === 'special');
     if (special) {
       let over = '';
-      if (target.metricColumn !== 'None') {
-        over = 'PARTITION BY ' + target.metricColumn;
+      if (this.hasMetricColumn()) {
+        over = 'PARTITION BY ' + this.target.metricColumn;
       }
       switch (special.params[0]) {
         case 'increase':
           query = query + ' - lag(' + query + ') OVER (' + over + ')';
           break;
         case 'rate':
-          let timeColumn = target.timeColumn;
+          let timeColumn = this.target.timeColumn;
           let curr = query;
           let prev = 'lag(' + curr + ') OVER (' + over + ')';
           query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)';
@@ -166,12 +170,12 @@ export default class PostgresQuery {
     return query;
   }
 
-  buildWhereClause(target) {
+  buildWhereClause() {
     let query = '';
-    let conditions = _.map(target.where, (tag, index) => {
+    let conditions = _.map(this.target.where, (tag, index) => {
       switch (tag.type) {
         case 'macro':
-          return tag.name + '(' + target.timeColumn + ')';
+          return tag.name + '(' + this.target.timeColumn + ')';
           break;
         case 'expression':
           return tag.params.join(' ');
@@ -186,12 +190,12 @@ export default class PostgresQuery {
     return query;
   }
 
-  buildGroupByClause(target) {
+  buildGroupByClause() {
     let query = '';
     let groupBySection = '';
 
-    for (let i = 0; i < target.groupBy.length; i++) {
-      let part = target.groupBy[i];
+    for (let i = 0; i < this.target.groupBy.length; i++) {
+      let part = this.target.groupBy[i];
       if (i > 0) {
         groupBySection += ', ';
       }
@@ -204,26 +208,26 @@ export default class PostgresQuery {
 
     if (groupBySection.length) {
       query = '\nGROUP BY ' + groupBySection;
-      if (target.metricColumn !== 'None') {
+      if (this.hasMetricColumn()) {
         query += ',2';
       }
     }
     return query;
   }
 
-  buildQuery(target) {
+  buildQuery() {
     let query = 'SELECT';
 
-    query += '\n  ' + this.buildTimeColumn(target);
-    if (target.metricColumn !== 'None') {
-      query += '\n  ' + this.buildMetricColumn(target);
+    query += '\n  ' + this.buildTimeColumn();
+    if (this.hasMetricColumn()) {
+      query += '\n  ' + this.buildMetricColumn();
     }
-    query += this.buildValueColumns(target);
+    query += this.buildValueColumns();
 
-    query += '\nFROM ' + target.schema + '.' + target.table;
+    query += '\nFROM ' + this.target.schema + '.' + this.target.table;
 
-    query += this.buildWhereClause(target);
-    query += this.buildGroupByClause(target);
+    query += this.buildWhereClause();
+    query += this.buildGroupByClause();
 
     query += '\nORDER BY 1';
 

+ 1 - 1
public/app/plugins/datasource/postgres/query_ctrl.ts

@@ -214,7 +214,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
       }
 
       if (config.addNone) {
-        segments.unshift(this.uiSegmentSrv.newSegment({ type: 'template', value: 'None', expandable: true }));
+        segments.unshift(this.uiSegmentSrv.newSegment({ type: 'template', value: 'none', expandable: true }));
       }
 
       return segments;

+ 34 - 31
public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts

@@ -19,8 +19,10 @@ describe('PostgresQuery', function() {
   describe('When generating time column SQL', function() {
     let query = new PostgresQuery({}, templateSrv);
 
-    expect(query.buildTimeColumn({ timeColumn: 'time' })).toBe('time AS "time"');
-    expect(query.buildTimeColumn({ timeColumn: '"time"' })).toBe('"time" AS "time"');
+    query.target.timeColumn = 'time';
+    expect(query.buildTimeColumn()).toBe('time AS "time"');
+    query.target.timeColumn = '"time"';
+    expect(query.buildTimeColumn()).toBe('"time" AS "time"');
   });
 
   describe('When generating time column SQL with group by time', function() {
@@ -28,65 +30,66 @@ describe('PostgresQuery', function() {
       { timeColumn: 'time', groupBy: [{ type: 'time', params: ['5m', 'none'] }] },
       templateSrv
     );
-    expect(query.buildTimeColumn(query.target)).toBe('$__timeGroup(time,5m)');
+    expect(query.buildTimeColumn()).toBe('$__timeGroup(time,5m)');
 
     query = new PostgresQuery({ timeColumn: 'time', groupBy: [{ type: 'time', params: ['5m', 'NULL'] }] }, templateSrv);
-    expect(query.buildTimeColumn(query.target)).toBe('$__timeGroup(time,5m,NULL)');
+    expect(query.buildTimeColumn()).toBe('$__timeGroup(time,5m,NULL)');
   });
 
   describe('When generating metric column SQL', function() {
     let query = new PostgresQuery({}, templateSrv);
 
-    expect(query.buildMetricColumn({ metricColumn: 'host' })).toBe('host AS metric');
-    expect(query.buildMetricColumn({ metricColumn: '"host"' })).toBe('"host" AS metric');
+    query.target.metricColumn = 'host';
+    expect(query.buildMetricColumn()).toBe('host AS metric');
+    query.target.metricColumn = '"host"';
+    expect(query.buildMetricColumn()).toBe('"host" AS metric');
   });
 
   describe('When generating value column SQL', function() {
     let query = new PostgresQuery({}, templateSrv);
 
     let column = [{ type: 'column', params: ['value'] }];
-    expect(query.buildValueColumn(query.target, column)).toBe('value');
+    expect(query.buildValueColumn(column)).toBe('value');
     column = [{ type: 'column', params: ['value'] }, { type: 'alias', params: ['alias'] }];
-    expect(query.buildValueColumn(query.target, column)).toBe('value AS "alias"');
+    expect(query.buildValueColumn(column)).toBe('value AS "alias"');
     column = [
       { type: 'column', params: ['v'] },
       { type: 'alias', params: ['a'] },
       { type: 'aggregate', params: ['max'] },
     ];
-    expect(query.buildValueColumn(query.target, column)).toBe('max(v) AS "a"');
+    expect(query.buildValueColumn(column)).toBe('max(v) AS "a"');
     column = [
       { type: 'column', params: ['v'] },
       { type: 'alias', params: ['a'] },
       { type: 'special', params: ['increase'] },
     ];
-    expect(query.buildValueColumn(query.target, column)).toBe('v - lag(v) OVER () AS "a"');
+    expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER () AS "a"');
   });
 
   describe('When generating WHERE clause', function() {
     let query = new PostgresQuery({ where: [] }, templateSrv);
-    let target;
-
-    expect(query.buildWhereClause(query.target)).toBe('');
-    target = { where: [{ type: 'macro', name: '$__timeFilter' }], timeColumn: 't' };
-    expect(query.buildWhereClause(target)).toBe('\nWHERE\n  $__timeFilter(t)');
-    target = { where: [{ type: 'expression', params: ['v', '=', '1'] }], timeColumn: 't' };
-    expect(query.buildWhereClause(target)).toBe('\nWHERE\n  v = 1');
-    target = {
-      where: [{ type: 'macro', name: '$__timeFilter' }, { type: 'expression', params: ['v', '=', '1'] }],
-      timeColumn: 't',
-    };
-    expect(query.buildWhereClause(target)).toBe('\nWHERE\n  $__timeFilter(t) AND\n  v = 1');
+
+    expect(query.buildWhereClause()).toBe('');
+
+    query.target.timeColumn = 't';
+    query.target.where = [{ type: 'macro', name: '$__timeFilter' }];
+    expect(query.buildWhereClause()).toBe('\nWHERE\n  $__timeFilter(t)');
+
+    query.target.where = [{ type: 'expression', params: ['v', '=', '1'] }];
+    expect(query.buildWhereClause()).toBe('\nWHERE\n  v = 1');
+
+    query.target.where = [{ type: 'macro', name: '$__timeFilter' }, { type: 'expression', params: ['v', '=', '1'] }];
+    expect(query.buildWhereClause()).toBe('\nWHERE\n  $__timeFilter(t) AND\n  v = 1');
   });
 
   describe('When generating GROUP BY clause', function() {
-    let query = new PostgresQuery({ groupBy: [] }, templateSrv);
-    let target;
-
-    expect(query.buildGroupByClause(query.target)).toBe('');
-    target = { groupBy: [{ type: 'time', params: ['5m'] }], metricColumn: 'None' };
-    expect(query.buildGroupByClause(target)).toBe('\nGROUP BY 1');
-    target = { groupBy: [{ type: 'time', params: ['5m'] }], metricColumn: 'm' };
-    expect(query.buildGroupByClause(target)).toBe('\nGROUP BY 1,2');
+    let query = new PostgresQuery({ groupBy: [], metricColumn: 'none' }, templateSrv);
+
+    expect(query.buildGroupByClause()).toBe('');
+    query.target.groupBy = [{ type: 'time', params: ['5m'] }];
+    expect(query.buildGroupByClause()).toBe('\nGROUP BY 1');
+    query.target.metricColumn = 'm';
+    expect(query.buildGroupByClause()).toBe('\nGROUP BY 1,2');
   });
 
   describe('When generating complete statement', function() {
@@ -99,6 +102,6 @@ describe('PostgresQuery', function() {
     let result = 'SELECT\n  t AS "time",\n  value\nFROM public.table\nORDER BY 1';
     let query = new PostgresQuery(target, templateSrv);
 
-    expect(query.buildQuery(query.target)).toBe(result);
+    expect(query.buildQuery()).toBe(result);
   });
 });