query_part.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. debugger;
  259. register({
  260. type: 'holt_winters_with_fit',
  261. addStrategy: addTransformationStrategy,
  262. category: categories.Predictors,
  263. params: [{ name: "number", type: "int", options: [5, 10, 20, 30, 40]}, { name: "season", type: "int", options: [0, 1, 2, 5, 10]}],
  264. defaultParams: [10, 2],
  265. renderer: functionRenderer,
  266. });
  267. // Selectors
  268. register({
  269. type: 'bottom',
  270. addStrategy: replaceAggregationAddStrategy,
  271. category: categories.Selectors,
  272. params: [{name: 'count', type: 'int'}],
  273. defaultParams: [3],
  274. renderer: functionRenderer,
  275. });
  276. register({
  277. type: 'first',
  278. addStrategy: replaceAggregationAddStrategy,
  279. category: categories.Selectors,
  280. params: [],
  281. defaultParams: [],
  282. renderer: functionRenderer,
  283. });
  284. register({
  285. type: 'last',
  286. addStrategy: replaceAggregationAddStrategy,
  287. category: categories.Selectors,
  288. params: [],
  289. defaultParams: [],
  290. renderer: functionRenderer,
  291. });
  292. register({
  293. type: 'max',
  294. addStrategy: replaceAggregationAddStrategy,
  295. category: categories.Selectors,
  296. params: [],
  297. defaultParams: [],
  298. renderer: functionRenderer,
  299. });
  300. register({
  301. type: 'min',
  302. addStrategy: replaceAggregationAddStrategy,
  303. category: categories.Selectors,
  304. params: [],
  305. defaultParams: [],
  306. renderer: functionRenderer,
  307. });
  308. register({
  309. type: 'percentile',
  310. addStrategy: replaceAggregationAddStrategy,
  311. category: categories.Selectors,
  312. params: [{name: 'nth', type: 'int'}],
  313. defaultParams: [95],
  314. renderer: functionRenderer,
  315. });
  316. register({
  317. type: 'top',
  318. addStrategy: replaceAggregationAddStrategy,
  319. category: categories.Selectors,
  320. params: [{name: 'count', type: 'int'}],
  321. defaultParams: [3],
  322. renderer: functionRenderer,
  323. });
  324. register({
  325. type: 'tag',
  326. category: groupByTimeFunctions,
  327. params: [{name: 'tag', type: 'string', dynamicLookup: true}],
  328. defaultParams: ['tag'],
  329. renderer: fieldRenderer,
  330. });
  331. register({
  332. type: 'math',
  333. addStrategy: addMathStrategy,
  334. category: categories.Math,
  335. params: [{ name: "expr", type: "string"}],
  336. defaultParams: [' / 100'],
  337. renderer: suffixRenderer,
  338. });
  339. register({
  340. type: 'alias',
  341. addStrategy: addAliasStrategy,
  342. category: categories.Aliasing,
  343. params: [{ name: "name", type: "string", quote: 'double'}],
  344. defaultParams: ['alias'],
  345. renderMode: 'suffix',
  346. renderer: aliasRenderer,
  347. });
  348. export default {
  349. create: createPart,
  350. getCategories: function() {
  351. return categories;
  352. }
  353. };