query_part.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import _ from 'lodash';
  3. import {
  4. QueryPartDef,
  5. QueryPart,
  6. functionRenderer,
  7. suffixRenderer,
  8. identityRenderer,
  9. quotedIdentityRenderer,
  10. } from 'app/core/components/query_part/query_part';
  11. var index = [];
  12. var categories = {
  13. Aggregations: [],
  14. Selectors: [],
  15. Transformations: [],
  16. Predictors: [],
  17. Math: [],
  18. Aliasing: [],
  19. Fields: [],
  20. };
  21. function createPart(part): any {
  22. var def = index[part.type];
  23. if (!def) {
  24. throw {message: 'Could not find query part ' + part.type};
  25. }
  26. return new QueryPart(part, def);
  27. }
  28. function register(options: any) {
  29. index[options.type] = new QueryPartDef(options);
  30. options.category.push(index[options.type]);
  31. }
  32. var groupByTimeFunctions = [];
  33. function aliasRenderer(part, innerExpr) {
  34. return innerExpr + ' AS ' + '"' + part.params[0] + '"';
  35. }
  36. function fieldRenderer(part, innerExpr) {
  37. if (part.params[0] === '*') {
  38. return '*';
  39. }
  40. return '"' + part.params[0] + '"';
  41. }
  42. function replaceAggregationAddStrategy(selectParts, partModel) {
  43. // look for existing aggregation
  44. for (var i = 0; i < selectParts.length; i++) {
  45. var part = selectParts[i];
  46. if (part.def.category === categories.Aggregations) {
  47. selectParts[i] = partModel;
  48. return;
  49. }
  50. if (part.def.category === categories.Selectors) {
  51. selectParts[i] = partModel;
  52. return;
  53. }
  54. }
  55. selectParts.splice(1, 0, partModel);
  56. }
  57. function addTransformationStrategy(selectParts, partModel) {
  58. var i;
  59. // look for index to add transformation
  60. for (i = 0; i < selectParts.length; i++) {
  61. var part = selectParts[i];
  62. if (part.def.category === categories.Math || part.def.category === categories.Aliasing) {
  63. break;
  64. }
  65. }
  66. selectParts.splice(i, 0, partModel);
  67. }
  68. function addMathStrategy(selectParts, partModel) {
  69. var partCount = selectParts.length;
  70. if (partCount > 0) {
  71. // if last is math, replace it
  72. if (selectParts[partCount-1].def.type === 'math') {
  73. selectParts[partCount-1] = partModel;
  74. return;
  75. }
  76. // if next to last is math, replace it
  77. if (selectParts[partCount-2].def.type === 'math') {
  78. selectParts[partCount-2] = partModel;
  79. return;
  80. } else if (selectParts[partCount-1].def.type === 'alias') { // if last is alias add it before
  81. selectParts.splice(partCount-1, 0, partModel);
  82. return;
  83. }
  84. }
  85. selectParts.push(partModel);
  86. }
  87. function addAliasStrategy(selectParts, partModel) {
  88. var partCount = selectParts.length;
  89. if (partCount > 0) {
  90. // if last is alias, replace it
  91. if (selectParts[partCount-1].def.type === 'alias') {
  92. selectParts[partCount-1] = partModel;
  93. return;
  94. }
  95. }
  96. selectParts.push(partModel);
  97. }
  98. function addFieldStrategy(selectParts, partModel, query) {
  99. // copy all parts
  100. var parts = _.map(selectParts, function(part: any) {
  101. return createPart({type: part.def.type, params: _.clone(part.params)});
  102. });
  103. query.selectModels.push(parts);
  104. }
  105. register({
  106. type: 'field',
  107. addStrategy: addFieldStrategy,
  108. category: categories.Fields,
  109. params: [{type: 'field', dynamicLookup: true}],
  110. defaultParams: ['value'],
  111. renderer: fieldRenderer,
  112. });
  113. // Aggregations
  114. register({
  115. type: 'count',
  116. addStrategy: replaceAggregationAddStrategy,
  117. category: categories.Aggregations,
  118. params: [],
  119. defaultParams: [],
  120. renderer: functionRenderer,
  121. });
  122. register({
  123. type: 'distinct',
  124. addStrategy: replaceAggregationAddStrategy,
  125. category: categories.Aggregations,
  126. params: [],
  127. defaultParams: [],
  128. renderer: functionRenderer,
  129. });
  130. register({
  131. type: 'integral',
  132. addStrategy: replaceAggregationAddStrategy,
  133. category: categories.Aggregations,
  134. params: [],
  135. defaultParams: [],
  136. renderer: functionRenderer,
  137. });
  138. register({
  139. type: 'mean',
  140. addStrategy: replaceAggregationAddStrategy,
  141. category: categories.Aggregations,
  142. params: [],
  143. defaultParams: [],
  144. renderer: functionRenderer,
  145. });
  146. register({
  147. type: 'median',
  148. addStrategy: replaceAggregationAddStrategy,
  149. category: categories.Aggregations,
  150. params: [],
  151. defaultParams: [],
  152. renderer: functionRenderer,
  153. });
  154. register({
  155. type: 'mode',
  156. addStrategy: replaceAggregationAddStrategy,
  157. category: categories.Aggregations,
  158. params: [],
  159. defaultParams: [],
  160. renderer: functionRenderer,
  161. });
  162. register({
  163. type: 'sum',
  164. addStrategy: replaceAggregationAddStrategy,
  165. category: categories.Aggregations,
  166. params: [],
  167. defaultParams: [],
  168. renderer: functionRenderer,
  169. });
  170. // transformations
  171. register({
  172. type: 'derivative',
  173. addStrategy: addTransformationStrategy,
  174. category: categories.Transformations,
  175. params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5m', '10m', '15m', '1h']}],
  176. defaultParams: ['10s'],
  177. renderer: functionRenderer,
  178. });
  179. register({
  180. type: 'spread',
  181. addStrategy: addTransformationStrategy,
  182. category: categories.Transformations,
  183. params: [],
  184. defaultParams: [],
  185. renderer: functionRenderer,
  186. });
  187. register({
  188. type: 'non_negative_derivative',
  189. addStrategy: addTransformationStrategy,
  190. category: categories.Transformations,
  191. params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5m', '10m', '15m', '1h']}],
  192. defaultParams: ['10s'],
  193. renderer: functionRenderer,
  194. });
  195. register({
  196. type: 'difference',
  197. addStrategy: addTransformationStrategy,
  198. category: categories.Transformations,
  199. params: [],
  200. defaultParams: [],
  201. renderer: functionRenderer,
  202. });
  203. register({
  204. type: 'moving_average',
  205. addStrategy: addTransformationStrategy,
  206. category: categories.Transformations,
  207. params: [{ name: "window", type: "int", options: [5, 10, 20, 30, 40]}],
  208. defaultParams: [10],
  209. renderer: functionRenderer,
  210. });
  211. register({
  212. type: 'cumulative_sum',
  213. addStrategy: addTransformationStrategy,
  214. category: categories.Transformations,
  215. params: [],
  216. defaultParams: [],
  217. renderer: functionRenderer,
  218. });
  219. register({
  220. type: 'stddev',
  221. addStrategy: addTransformationStrategy,
  222. category: categories.Transformations,
  223. params: [],
  224. defaultParams: [],
  225. renderer: functionRenderer,
  226. });
  227. register({
  228. type: 'time',
  229. category: groupByTimeFunctions,
  230. params: [{ name: "interval", type: "time", options: ['$__interval', '1s', '10s', '1m', '5m', '10m', '15m', '1h']}],
  231. defaultParams: ['$__interval'],
  232. renderer: functionRenderer,
  233. });
  234. register({
  235. type: 'fill',
  236. category: groupByTimeFunctions,
  237. params: [{ name: "fill", type: "string", options: ['none', 'null', '0', 'previous', 'linear'] }],
  238. defaultParams: ['null'],
  239. renderer: functionRenderer,
  240. });
  241. register({
  242. type: 'elapsed',
  243. addStrategy: addTransformationStrategy,
  244. category: categories.Transformations,
  245. params: [{ name: "duration", type: "interval", options: ['1s', '10s', '1m', '5m', '10m', '15m', '1h']}],
  246. defaultParams: ['10s'],
  247. renderer: functionRenderer,
  248. });
  249. // predictions
  250. register({
  251. type: 'holt_winters',
  252. addStrategy: addTransformationStrategy,
  253. category: categories.Predictors,
  254. params: [{ name: "number", type: "int", options: [5, 10, 20, 30, 40]}, { name: "season", type: "int", options: [0, 1, 2, 5, 10]}],
  255. defaultParams: [10, 2],
  256. renderer: functionRenderer,
  257. });
  258. register({
  259. type: 'holt_winters_with_fit',
  260. addStrategy: addTransformationStrategy,
  261. category: categories.Predictors,
  262. params: [{ name: "number", type: "int", options: [5, 10, 20, 30, 40]}, { name: "season", type: "int", options: [0, 1, 2, 5, 10]}],
  263. defaultParams: [10, 2],
  264. renderer: functionRenderer,
  265. });
  266. // Selectors
  267. register({
  268. type: 'bottom',
  269. addStrategy: replaceAggregationAddStrategy,
  270. category: categories.Selectors,
  271. params: [{name: 'count', type: 'int'}],
  272. defaultParams: [3],
  273. renderer: functionRenderer,
  274. });
  275. register({
  276. type: 'first',
  277. addStrategy: replaceAggregationAddStrategy,
  278. category: categories.Selectors,
  279. params: [],
  280. defaultParams: [],
  281. renderer: functionRenderer,
  282. });
  283. register({
  284. type: 'last',
  285. addStrategy: replaceAggregationAddStrategy,
  286. category: categories.Selectors,
  287. params: [],
  288. defaultParams: [],
  289. renderer: functionRenderer,
  290. });
  291. register({
  292. type: 'max',
  293. addStrategy: replaceAggregationAddStrategy,
  294. category: categories.Selectors,
  295. params: [],
  296. defaultParams: [],
  297. renderer: functionRenderer,
  298. });
  299. register({
  300. type: 'min',
  301. addStrategy: replaceAggregationAddStrategy,
  302. category: categories.Selectors,
  303. params: [],
  304. defaultParams: [],
  305. renderer: functionRenderer,
  306. });
  307. register({
  308. type: 'percentile',
  309. addStrategy: replaceAggregationAddStrategy,
  310. category: categories.Selectors,
  311. params: [{name: 'nth', type: 'int'}],
  312. defaultParams: [95],
  313. renderer: functionRenderer,
  314. });
  315. register({
  316. type: 'top',
  317. addStrategy: replaceAggregationAddStrategy,
  318. category: categories.Selectors,
  319. params: [{name: 'count', type: 'int'}],
  320. defaultParams: [3],
  321. renderer: functionRenderer,
  322. });
  323. register({
  324. type: 'tag',
  325. category: groupByTimeFunctions,
  326. params: [{name: 'tag', type: 'string', dynamicLookup: true}],
  327. defaultParams: ['tag'],
  328. renderer: fieldRenderer,
  329. });
  330. register({
  331. type: 'math',
  332. addStrategy: addMathStrategy,
  333. category: categories.Math,
  334. params: [{ name: "expr", type: "string"}],
  335. defaultParams: [' / 100'],
  336. renderer: suffixRenderer,
  337. });
  338. register({
  339. type: 'alias',
  340. addStrategy: addAliasStrategy,
  341. category: categories.Aliasing,
  342. params: [{ name: "name", type: "string", quote: 'double'}],
  343. defaultParams: ['alias'],
  344. renderMode: 'suffix',
  345. renderer: aliasRenderer,
  346. });
  347. export default {
  348. create: createPart,
  349. getCategories: function() {
  350. return categories;
  351. }
  352. };