QueryService.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. 'use strict';
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2017, 2020
  5. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. *
  7. */
  8. define(['./ServiceBase', '../../../prompts/PromptManager', 'underscore'], function (Class, PromptManager, _) {
  9. 'use strict';
  10. //TODO Unify QueryManager between Legacy one and new Endor one
  11. // Declare the class
  12. var QueryService = Class.extend({
  13. init: function init(options) {
  14. QueryService.inherited('init', this, arguments);
  15. this.dashboardApi = options.dashboardApi;
  16. this.ajaxSvc = this.dashboardApi.getGlassCoreSvc('.Ajax');
  17. this.logger = this.dashboardApi.getGlassCoreSvc('.Logger');
  18. this.queryParameters = null;
  19. },
  20. _querySpecString: function _querySpecString(queryOptions, module) {
  21. if (_.isNumber(queryOptions.dataRowLimit)) {
  22. queryOptions.querySpec.limit = queryOptions.dataRowLimit;
  23. }
  24. if (this.queryParameters) {
  25. queryOptions.querySpec.parameterValues = this.queryParameters;
  26. }
  27. var metadataSubsetIds = module && module.getMetadataSubsetIds();
  28. if (metadataSubsetIds && metadataSubsetIds.length > 0) {
  29. queryOptions.querySpec.queryHints = _.extend(queryOptions.querySpec.queryHints || {}, {
  30. metadataSubsetIDs: metadataSubsetIds
  31. });
  32. }
  33. return this.isMockServer ? '\\Q' + JSON.stringify(queryOptions.querySpec) + '\\E' : JSON.stringify(queryOptions.querySpec);
  34. },
  35. /**
  36. * @public api to excute query against DSS.
  37. *
  38. * @param {Object} options.querySpec Mandatory: the query specification to be sent to DSS.
  39. * @param {Object} options.sourceIdOrModule: The sourceId or module object which we're querying
  40. * @param {Object} options.requestOptions: additional request options
  41. *
  42. * @returns a promise.
  43. */
  44. runQuery: function runQuery(options) {
  45. return this._sendRequest(options, this.getRequestId(options.sender));
  46. },
  47. runPredictQuery: function runPredictQuery(options) {
  48. var _this = this;
  49. return this._getModule(options.sourceIdOrModule).then(function (module) {
  50. var querySpec = _this._querySpecString(options);
  51. return module.queryPredictData(querySpec).then(function (response) {
  52. return response ? response.data : null;
  53. }, function (jqXHR) {
  54. return _this.handleQueryError(jqXHR, options, _this.runPredictQuery.bind(_this));
  55. });
  56. });
  57. },
  58. _sendRequest: function _sendRequest(options, requestId) {
  59. var _this2 = this;
  60. // reset the parameters for subsequent predict query
  61. if (!options.querySpec.parameterValues) {
  62. this.queryParameters = null;
  63. }
  64. return this._getModule(options.sourceIdOrModule).then(function (module) {
  65. var querySpec = _this2._querySpecString(options, module);
  66. var queryUserId = _this2.dashboardApi.getService('.UserProfile').userAccount.id;
  67. return _this2._getDataSourceModifiedTime(options.sourceIdOrModule).then(function (modTime) {
  68. return module.queryData(querySpec, {
  69. senderId: options.senderId,
  70. lastModified: modTime,
  71. queryUserId: queryUserId,
  72. qfb: options.requestOptions && options.requestOptions.qfb || 'none',
  73. qfbMode: options && options.requestOptions.qfbMode || undefined
  74. });
  75. });
  76. }).then(function (response) {
  77. var promptControlFunctions = options.promptControlFunctions;
  78. if (promptControlFunctions && promptControlFunctions.updatePromptSpecCache) {
  79. promptControlFunctions.updatePromptSpecCache(options);
  80. }
  81. var data = response ? response.data : null;
  82. var ETag = response ? response.getResponseHeader('ETag') : null;
  83. var requestTime = response ? response.getResponseHeader('x-ca-requesttime') : null;
  84. if (_this2.isActiveRequest(requestId, options.sender)) {
  85. return {
  86. data: data,
  87. requestTime: requestTime,
  88. ETag: ETag
  89. };
  90. } else {
  91. return Promise.reject(_.extend(new Error(), {
  92. reason: 'staleRequest'
  93. }));
  94. }
  95. }).catch(function (jqXHR) {
  96. return _this2.handleQueryError(jqXHR, options);
  97. });
  98. },
  99. _getModule: function _getModule(sourceIdOrModule) {
  100. var _this3 = this;
  101. var isDataModule = typeof sourceIdOrModule.queryData === 'function' || typeof sourceIdOrModule.queryPredictData === 'function';
  102. if (isDataModule) {
  103. return Promise.resolve(sourceIdOrModule);
  104. }
  105. var dataSources = this.dashboardApi.getFeature('dataSources.deprecated');
  106. return dataSources.getModule(sourceIdOrModule).then(function (module) {
  107. if (!module) {
  108. var dataSets = _this3.dashboardApi.getFeature('DataSets.internal');
  109. module = dataSets.getModule(sourceIdOrModule);
  110. }
  111. if (!module) {
  112. return Promise.reject(new Error('Data source with ID ' + sourceIdOrModule + ' not found.'));
  113. }
  114. return module;
  115. });
  116. },
  117. _getDataSourceModifiedTime: function _getDataSourceModifiedTime(sourceIdOrModule) {
  118. var datasource = this.dashboardApi.getFeature('DataSources').getDataSource(sourceIdOrModule);
  119. if (!datasource) {
  120. var dataSets = this.dashboardApi.getFeature('DataSets.internal');
  121. datasource = dataSets.getDataSource(sourceIdOrModule);
  122. if (!datasource) {
  123. return Promise.reject(new Error('Datasource with source ID: ' + sourceIdOrModule + ' not found'));
  124. }
  125. }
  126. return datasource.getModificationTime();
  127. },
  128. /**
  129. * Make the rest API call to query the map data for locations.
  130. * @param locations Array of locations to be mapped
  131. * @param useMapbox - flag to tell smarter maps to return mapbox style geojson
  132. */
  133. runGeoQuery: function runGeoQuery(payload, endpoint) {
  134. this.logger.debug('runGeoQuery');
  135. return this.ajaxSvc.ajax({
  136. url: endpoint || 'v1/geo/~',
  137. type: 'POST',
  138. headers: {
  139. 'Content-Type': 'application/json'
  140. },
  141. data: JSON.stringify(payload),
  142. processData: false
  143. }).then(function (response) {
  144. return response.data;
  145. });
  146. },
  147. /**
  148. * Make the rest API call to perform a top or bottom query the module.
  149. * @param querySpec The query specification to run
  150. */
  151. runTopBottomQuery: function runTopBottomQuery(queryOptions) {
  152. return this.runQuery(queryOptions);
  153. },
  154. handleQueryError: function handleQueryError(jqXHR, queryOptions, queryHandler) {
  155. var _this4 = this;
  156. var result = void 0;
  157. if (jqXHR && jqXHR.status && PromptManager.isPromptFault(jqXHR)) {
  158. if (!queryOptions.promptControlFunctions) {
  159. return Promise.reject(jqXHR);
  160. }
  161. var promptControlFunctions = queryOptions.promptControlFunctions;
  162. result = PromptManager.openPromptView({
  163. 'logger': this.logger,
  164. 'preferences': this.dashboardApi.getGlassCoreSvc('.UserProfile').preferences,
  165. 'promptSpec': promptControlFunctions.preparePromptSpec(jqXHR),
  166. 'whenSingleItemQueryReady': promptControlFunctions.whenSingleItemQueryReady.bind(this),
  167. 'whenColumnsMinMaxQueryReady': promptControlFunctions.whenColumnsMinMaxQueryReady.bind(this),
  168. 'getPromptSpec': promptControlFunctions.getPromptSpec.bind(this),
  169. 'isPreview': queryOptions.isPreview
  170. }).then(function (promptResponses) {
  171. var aPromptInfo = _this4._resolvePromptValues(promptResponses, promptControlFunctions);
  172. // re-send the request with resolved parameter.
  173. queryOptions.querySpec.parameterValues = aPromptInfo;
  174. // the parameters needs to be re-applied to the subsequent query (predict)
  175. _this4.queryParameters = aPromptInfo;
  176. return queryHandler ? queryHandler(queryOptions) : _this4.runQuery(queryOptions);
  177. }).catch(function (error) {
  178. if (error) {
  179. switch (error.message) {
  180. case 'cancel':
  181. case 'cancelPromptDialog':
  182. if (promptControlFunctions.onCancelPromptDialog) {
  183. promptControlFunctions.onCancelPromptDialog();
  184. }
  185. break;
  186. case 'unSupportedPromptType':
  187. if (promptControlFunctions.onUnSupportedPrompt) {
  188. promptControlFunctions.onUnSupportedPrompt();
  189. }
  190. break;
  191. }
  192. throw error;
  193. } else {
  194. return Promise.reject(jqXHR);
  195. }
  196. });
  197. } else {
  198. result = Promise.reject(jqXHR);
  199. }
  200. return result;
  201. },
  202. /**
  203. * resolve prompt values from query response and saved values.
  204. */
  205. _resolvePromptValues: function _resolvePromptValues(promptResponses, promptControlFunctions) {
  206. var aPromptInfo = [];
  207. var queryProperties = ['name', 'values', 'dataType', 'capabilities', 'modelFilterItem'];
  208. var savedPrompts = promptControlFunctions.getPromptSpec ? promptControlFunctions.getPromptSpec() : null;
  209. // push the newly resolved parameter values and save them if savePromptSpec is a function.
  210. _.each(promptResponses, function (promptResponse) {
  211. var promptResult = _.pick(promptResponse, queryProperties);
  212. aPromptInfo.push(promptResult);
  213. if (promptControlFunctions.savePromptSpec) {
  214. promptControlFunctions.savePromptSpec(promptResponse);
  215. }
  216. });
  217. // push saved parameter values when they are not in promptResponse.
  218. if (savedPrompts) {
  219. _.each(savedPrompts, function (savedPrompt) {
  220. if (!_.find(promptResponses, function (resolvedPrompt) {
  221. return savedPrompt.name === resolvedPrompt.name;
  222. })) {
  223. aPromptInfo.push(_.pick(savedPrompt, queryProperties));
  224. }
  225. });
  226. }
  227. _.each(aPromptInfo, function (promptInfo) {
  228. // MUN based dataType expect a useValue while all other types expect a displayValue for a parameter.
  229. if (promptInfo.capabilities.optional) {
  230. promptInfo.values = [promptInfo.values[0].mun];
  231. } else {
  232. // promptInfo.values
  233. if (promptInfo.dataType === 'memberUniqueName' || promptInfo.dataType === 'hierarchyUniqueName') {
  234. // use value (and not label)
  235. if (promptInfo.values[0].value) {
  236. promptInfo.values = _.pluck(promptInfo.values, 'value');
  237. } else {
  238. promptInfo.values = _.pluck(promptInfo.values, 'u');
  239. }
  240. } else {
  241. // use label
  242. if (promptInfo.values[0].label) {
  243. promptInfo.values = _.pluck(promptInfo.values, 'label');
  244. } else {
  245. promptInfo.values = _.pluck(promptInfo.values, 'd');
  246. }
  247. }
  248. }
  249. });
  250. return aPromptInfo;
  251. }
  252. });
  253. return QueryService;
  254. });
  255. //# sourceMappingURL=QueryService.js.map