datasource.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import _ from 'lodash';
  3. export class MysqlDatasource {
  4. id: any;
  5. name: any;
  6. /** @ngInject **/
  7. constructor(instanceSettings, private backendSrv, private $q, private templateSrv) {
  8. this.name = instanceSettings.name;
  9. this.id = instanceSettings.id;
  10. }
  11. interpolateVariable(value) {
  12. if (typeof value === 'string') {
  13. return '\"' + value + '\"';
  14. }
  15. var quotedValues = _.map(value, function(val) {
  16. return '\"' + val + '\"';
  17. });
  18. return quotedValues.join(',');
  19. }
  20. query(options) {
  21. var queries = _.filter(options.targets, item => {
  22. return item.hide !== true;
  23. }).map(item => {
  24. return {
  25. refId: item.refId,
  26. intervalMs: options.intervalMs,
  27. maxDataPoints: options.maxDataPoints,
  28. datasourceId: this.id,
  29. rawSql: this.templateSrv.replace(item.rawSql, options.scopedVars, this.interpolateVariable),
  30. format: item.format,
  31. };
  32. });
  33. if (queries.length === 0) {
  34. return this.$q.when({data: []});
  35. }
  36. return this.backendSrv.datasourceRequest({
  37. url: '/api/tsdb/query',
  38. method: 'POST',
  39. data: {
  40. from: options.range.from.valueOf().toString(),
  41. to: options.range.to.valueOf().toString(),
  42. queries: queries,
  43. }
  44. }).then(this.processQueryResult.bind(this));
  45. }
  46. annotationQuery(options) {
  47. if (!options.annotation.rawQuery) {
  48. return this.$q.reject({message: 'Query missing in annotation definition'});
  49. }
  50. const query = {
  51. refId: options.annotation.name,
  52. datasourceId: this.id,
  53. rawSql: this.templateSrv.replace(options.annotation.rawQuery, options.scopedVars, this.interpolateVariable),
  54. format: 'table',
  55. };
  56. return this.backendSrv.datasourceRequest({
  57. url: '/api/tsdb/query',
  58. method: 'POST',
  59. data: {
  60. from: options.range.from.valueOf().toString(),
  61. to: options.range.to.valueOf().toString(),
  62. queries: [query],
  63. }
  64. }).then(this.transformAnnotationResponse.bind(this, options));
  65. }
  66. transformAnnotationResponse(options, data) {
  67. const table = data.data.results[options.annotation.name].tables[0];
  68. let timeColumnIndex = -1;
  69. let titleColumnIndex = -1;
  70. let textColumnIndex = -1;
  71. let tagsColumnIndex = -1;
  72. for (let i = 0; i < table.columns.length; i++) {
  73. if (table.columns[i].text === 'time_sec') {
  74. timeColumnIndex = i;
  75. } else if (table.columns[i].text === 'title') {
  76. titleColumnIndex = i;
  77. } else if (table.columns[i].text === 'text') {
  78. textColumnIndex = i;
  79. } else if (table.columns[i].text === 'tags') {
  80. tagsColumnIndex = i;
  81. }
  82. }
  83. if (timeColumnIndex === -1) {
  84. return this.$q.reject({message: 'Missing mandatory time column (with time_sec column alias) in annotation query.'});
  85. }
  86. const list = [];
  87. for (let i = 0; i < table.rows.length; i++) {
  88. const row = table.rows[i];
  89. list.push({
  90. annotation: options.annotation,
  91. time: Math.floor(row[timeColumnIndex]) * 1000,
  92. title: row[titleColumnIndex],
  93. text: row[textColumnIndex],
  94. tags: row[tagsColumnIndex] ? row[tagsColumnIndex].trim().split(/\s*,\s*/) : []
  95. });
  96. }
  97. return list;
  98. }
  99. testDatasource() {
  100. return this.backendSrv.datasourceRequest({
  101. url: '/api/tsdb/query',
  102. method: 'POST',
  103. data: {
  104. from: '5m',
  105. to: 'now',
  106. queries: [{
  107. refId: 'A',
  108. intervalMs: 1,
  109. maxDataPoints: 1,
  110. datasourceId: this.id,
  111. rawSql: "SELECT 1",
  112. format: 'table',
  113. }],
  114. }
  115. }).then(res => {
  116. return { status: "success", message: "Database Connection OK", title: "Success" };
  117. }).catch(err => {
  118. console.log(err);
  119. if (err.data && err.data.message) {
  120. return { status: "error", message: err.data.message, title: "Error" };
  121. } else {
  122. return { status: "error", message: err.status, title: "Error" };
  123. }
  124. });
  125. }
  126. processQueryResult(res) {
  127. var data = [];
  128. if (!res.data.results) {
  129. return {data: data};
  130. }
  131. for (let key in res.data.results) {
  132. let queryRes = res.data.results[key];
  133. if (queryRes.series) {
  134. for (let series of queryRes.series) {
  135. data.push({
  136. target: series.name,
  137. datapoints: series.points,
  138. refId: queryRes.refId,
  139. meta: queryRes.meta,
  140. });
  141. }
  142. }
  143. if (queryRes.tables) {
  144. for (let table of queryRes.tables) {
  145. table.type = 'table';
  146. table.refId = queryRes.refId;
  147. table.meta = queryRes.meta;
  148. data.push(table);
  149. }
  150. }
  151. }
  152. return {data: data};
  153. }
  154. }