datasource.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import _ from 'lodash';
  2. import ResponseParser from './response_parser';
  3. import PostgresQuery from 'app/plugins/datasource/postgres/postgres_query';
  4. import { IQService } from 'angular';
  5. import { BackendSrv } from 'app/core/services/backend_srv';
  6. import { TemplateSrv } from 'app/features/templating/template_srv';
  7. import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
  8. export class PostgresDatasource {
  9. id: any;
  10. name: any;
  11. jsonData: any;
  12. responseParser: ResponseParser;
  13. queryModel: PostgresQuery;
  14. interval: string;
  15. /** @ngInject */
  16. constructor(
  17. instanceSettings: { name: any; id?: any; jsonData?: any },
  18. private backendSrv: BackendSrv,
  19. private $q: IQService,
  20. private templateSrv: TemplateSrv,
  21. private timeSrv: TimeSrv
  22. ) {
  23. this.name = instanceSettings.name;
  24. this.id = instanceSettings.id;
  25. this.jsonData = instanceSettings.jsonData;
  26. this.responseParser = new ResponseParser(this.$q);
  27. this.queryModel = new PostgresQuery({});
  28. this.interval = (instanceSettings.jsonData || {}).timeInterval || '1m';
  29. }
  30. interpolateVariable = (value: string, variable: { multi: any; includeAll: any }) => {
  31. if (typeof value === 'string') {
  32. if (variable.multi || variable.includeAll) {
  33. return this.queryModel.quoteLiteral(value);
  34. } else {
  35. return value;
  36. }
  37. }
  38. if (typeof value === 'number') {
  39. return value;
  40. }
  41. const quotedValues = _.map(value, v => {
  42. return this.queryModel.quoteLiteral(v);
  43. });
  44. return quotedValues.join(',');
  45. };
  46. query(options: any) {
  47. const queries = _.filter(options.targets, target => {
  48. return target.hide !== true;
  49. }).map(target => {
  50. const queryModel = new PostgresQuery(target, this.templateSrv, options.scopedVars);
  51. return {
  52. refId: target.refId,
  53. intervalMs: options.intervalMs,
  54. maxDataPoints: options.maxDataPoints,
  55. datasourceId: this.id,
  56. rawSql: queryModel.render(this.interpolateVariable),
  57. format: target.format,
  58. };
  59. });
  60. if (queries.length === 0) {
  61. return this.$q.when({ data: [] });
  62. }
  63. return this.backendSrv
  64. .datasourceRequest({
  65. url: '/api/tsdb/query',
  66. method: 'POST',
  67. data: {
  68. from: options.range.from.valueOf().toString(),
  69. to: options.range.to.valueOf().toString(),
  70. queries: queries,
  71. },
  72. })
  73. .then(this.responseParser.processQueryResult);
  74. }
  75. annotationQuery(options: any) {
  76. if (!options.annotation.rawQuery) {
  77. return this.$q.reject({
  78. message: 'Query missing in annotation definition',
  79. });
  80. }
  81. const query = {
  82. refId: options.annotation.name,
  83. datasourceId: this.id,
  84. rawSql: this.templateSrv.replace(options.annotation.rawQuery, options.scopedVars, this.interpolateVariable),
  85. format: 'table',
  86. };
  87. return this.backendSrv
  88. .datasourceRequest({
  89. url: '/api/tsdb/query',
  90. method: 'POST',
  91. data: {
  92. from: options.range.from.valueOf().toString(),
  93. to: options.range.to.valueOf().toString(),
  94. queries: [query],
  95. },
  96. })
  97. .then((data: any) => this.responseParser.transformAnnotationResponse(options, data));
  98. }
  99. metricFindQuery(query: string, optionalOptions: { variable?: any }) {
  100. let refId = 'tempvar';
  101. if (optionalOptions && optionalOptions.variable && optionalOptions.variable.name) {
  102. refId = optionalOptions.variable.name;
  103. }
  104. const interpolatedQuery = {
  105. refId: refId,
  106. datasourceId: this.id,
  107. rawSql: this.templateSrv.replace(query, {}, this.interpolateVariable),
  108. format: 'table',
  109. };
  110. const range = this.timeSrv.timeRange();
  111. const data = {
  112. queries: [interpolatedQuery],
  113. from: range.from.valueOf().toString(),
  114. to: range.to.valueOf().toString(),
  115. };
  116. return this.backendSrv
  117. .datasourceRequest({
  118. url: '/api/tsdb/query',
  119. method: 'POST',
  120. data: data,
  121. })
  122. .then((data: any) => this.responseParser.parseMetricFindQueryResult(refId, data));
  123. }
  124. getVersion() {
  125. return this.metricFindQuery("SELECT current_setting('server_version_num')::int/100", {});
  126. }
  127. getTimescaleDBVersion() {
  128. return this.metricFindQuery("SELECT extversion FROM pg_extension WHERE extname = 'timescaledb'", {});
  129. }
  130. testDatasource() {
  131. return this.metricFindQuery('SELECT 1', {})
  132. .then((res: any) => {
  133. return { status: 'success', message: 'Database Connection OK' };
  134. })
  135. .catch((err: any) => {
  136. console.log(err);
  137. if (err.data && err.data.message) {
  138. return { status: 'error', message: err.data.message };
  139. } else {
  140. return { status: 'error', message: err.status };
  141. }
  142. });
  143. }
  144. }