datasource.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. metricFindQuery(query, optionalOptions) {
  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. return this.backendSrv.datasourceRequest({
  111. url: '/api/tsdb/query',
  112. method: 'POST',
  113. data: {
  114. queries: [interpolatedQuery],
  115. }
  116. })
  117. .then(this.transformFindQueryResponse.bind(this, refId));
  118. }
  119. transformFindQueryResponse(refId, results) {
  120. if (!results || results.data.length === 0 || results.data.results[refId].meta.rowCount === 0) { return []; }
  121. const rows = results.data.results[refId].tables[0].rows;
  122. const res = [];
  123. for (let i = 0; i < rows.length; i++) {
  124. for (let j = 0; j < rows[i].length; j++) {
  125. const value = rows[i][j];
  126. if ( res.indexOf( value ) === -1 ) {
  127. res.push(value);
  128. }
  129. }
  130. }
  131. return _.map(res, value => {
  132. return { text: value};
  133. });
  134. }
  135. testDatasource() {
  136. return this.backendSrv.datasourceRequest({
  137. url: '/api/tsdb/query',
  138. method: 'POST',
  139. data: {
  140. from: '5m',
  141. to: 'now',
  142. queries: [{
  143. refId: 'A',
  144. intervalMs: 1,
  145. maxDataPoints: 1,
  146. datasourceId: this.id,
  147. rawSql: "SELECT 1",
  148. format: 'table',
  149. }],
  150. }
  151. }).then(res => {
  152. return { status: "success", message: "Database Connection OK", title: "Success" };
  153. }).catch(err => {
  154. console.log(err);
  155. if (err.data && err.data.message) {
  156. return { status: "error", message: err.data.message, title: "Error" };
  157. } else {
  158. return { status: "error", message: err.status, title: "Error" };
  159. }
  160. });
  161. }
  162. processQueryResult(res) {
  163. var data = [];
  164. if (!res.data.results) {
  165. return {data: data};
  166. }
  167. for (let key in res.data.results) {
  168. let queryRes = res.data.results[key];
  169. if (queryRes.series) {
  170. for (let series of queryRes.series) {
  171. data.push({
  172. target: series.name,
  173. datapoints: series.points,
  174. refId: queryRes.refId,
  175. meta: queryRes.meta,
  176. });
  177. }
  178. }
  179. if (queryRes.tables) {
  180. for (let table of queryRes.tables) {
  181. table.type = 'table';
  182. table.refId = queryRes.refId;
  183. table.meta = queryRes.meta;
  184. data.push(table);
  185. }
  186. }
  187. }
  188. return {data: data};
  189. }
  190. }