QueryResultData.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. 'use strict';
  2. /*
  3. *+------------------------------------------------------------------------+
  4. *| Licensed Materials - Property of IBM
  5. *| IBM Cognos Products: BI Dashboard
  6. *| (C) Copyright IBM Corp. 2017, 2019
  7. *|
  8. *| US Government Users Restricted Rights - Use, duplication or disclosure
  9. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10. *+------------------------------------------------------------------------+
  11. */
  12. /**
  13. * This Class encapsulates raw query result data returned from DSS and provides its accessors and iterators
  14. **/
  15. define(['../../../lib/@waca/core-client/js/core-client/ui/core/Class', 'underscore', './QueryResultDataUtils', './QueryResultDataItem'], function (BaseClass, _, Utils, DataItem) {
  16. 'use strict';
  17. var RowIterator = BaseClass.extend({
  18. _rows: null,
  19. _index: -1,
  20. _oQueryResultData: null,
  21. init: function init(rows) {
  22. this._index = -1;
  23. this._rows = rows;
  24. },
  25. setQueryResultDataRef: function setQueryResultDataRef(queryResultData) {
  26. this._oQueryResultData = queryResultData;
  27. },
  28. hasNext: function hasNext() {
  29. return this._rows && this._rows.length > 0 && this._index < this._rows.length - 1;
  30. },
  31. next: function next() {
  32. this._index++;
  33. },
  34. /**
  35. * @return the ordinal index of categorical value or the continuous value itself
  36. **/
  37. getValue: function getValue(datapointIndex) {
  38. var oDatapoint = this._getDatapoint(datapointIndex);
  39. if (_.isObject(oDatapoint) && oDatapoint.v !== undefined) {
  40. return oDatapoint.v;
  41. }
  42. return oDatapoint;
  43. },
  44. /**
  45. * @return the resolved value
  46. **/
  47. getResolvedValue: function getResolvedValue(datapointIndex) {
  48. var oDatapoint = this._getDatapoint(datapointIndex);
  49. if (_.isObject(oDatapoint) && oDatapoint.v !== undefined) {
  50. Utils.normalizeData(oDatapoint);
  51. return oDatapoint;
  52. }
  53. if (this._oQueryResultData) {
  54. return this._oQueryResultData.getResultDataItem(datapointIndex).getTuple(oDatapoint);
  55. }
  56. return null;
  57. },
  58. _getDatapoint: function _getDatapoint(datapointIndex) {
  59. if (this._index >= 0) {
  60. var oDatapoint = this._rows[this._index];
  61. if (oDatapoint && oDatapoint.pt && oDatapoint.pt.length > 0) {
  62. return oDatapoint.pt[datapointIndex];
  63. }
  64. }
  65. return null;
  66. }
  67. });
  68. var QueryResultData = BaseClass.extend({
  69. /**
  70. * Internal value that refers to the original query result data object
  71. * @private
  72. * @member {Object}
  73. **/
  74. _resultData: null,
  75. _aQueryResultDataItems: null, //Array of QueryResultDataItem Class. Init to null to indicate initial state
  76. init: function init(data) {
  77. QueryResultData.inherited('init', this, arguments);
  78. this._resultData = data;
  79. },
  80. /**
  81. * @param {Integer} rowIndex row index
  82. * @param {Integer} colIndex column index
  83. * @return The referenced tuple/value that composes the data point located by the indexes
  84. **/
  85. getCellValue: function getCellValue(rowIndex, colIndex) {
  86. var result;
  87. var value = this._getCellRefByIndexes(rowIndex, colIndex);
  88. if (Utils.isRectifyNeeded(value)) {
  89. result = Utils.getRectifiedData(value);
  90. } else if (value.v !== undefined || value.value !== undefined) {
  91. result = value;
  92. Utils.normalizeData(result);
  93. } else {
  94. result = this.getResultDataItem(colIndex).getTuple(value) || []; /*Categorical data item object*/
  95. }
  96. return result;
  97. },
  98. /**
  99. * @param {Integer} rowIndex row index
  100. * @param {Integer} colIndex column index
  101. * @return The index/value that composes the data point located by the indexes
  102. **/
  103. _getCellRefByIndexes: function _getCellRefByIndexes(rowIndex, colIndex) {
  104. var oPoint = this._getDatapointEntry(rowIndex);
  105. if (oPoint && oPoint.pt) {
  106. var aPoint = oPoint.pt;
  107. if (aPoint && aPoint.length > 0 && colIndex !== undefined && colIndex < aPoint.length) {
  108. return aPoint[colIndex];
  109. }
  110. }
  111. return null;
  112. },
  113. _getDatapointEntry: function _getDatapointEntry(rowIndex) {
  114. if (rowIndex >= 0 && this._resultData && this._resultData.data) {
  115. return this._resultData.data[rowIndex];
  116. }
  117. return null;
  118. },
  119. getDatapoints: function getDatapoints() {
  120. return this._resultData.data;
  121. },
  122. /**
  123. * @return {Integer} the count of datapoints in the query result data response
  124. **/
  125. getDatapointCount: function getDatapointCount() {
  126. if (this._resultData && this._resultData.data) {
  127. return this._resultData.data.length;
  128. }
  129. return 0;
  130. },
  131. /**
  132. * Reset the data items object array
  133. * This is called after post-processing when the data is restructured
  134. */
  135. resetDataItemArray: function resetDataItemArray() {
  136. this._generateDataItemArray();
  137. },
  138. _isValidDataItem: function _isValidDataItem(dataItem) {
  139. var _fIsValidItemClass = function _fIsValidItemClass(itemClassEntry) {
  140. return itemClassEntry.h[0].d !== null && itemClassEntry.h[0].u !== null;
  141. };
  142. //A data item could have multiple item class sections, while each item Class section could have multiple item class enties
  143. if (_.isArray(dataItem.itemClass)) {
  144. var bResult = true;
  145. _.each(dataItem.itemClass, function (itemClassEntry) {
  146. if (!_fIsValidItemClass(itemClassEntry)) {
  147. bResult = false;
  148. return;
  149. }
  150. });
  151. return bResult;
  152. } else if (_.isObject(dataItem.itemClass)) {
  153. return _fIsValidItemClass(dataItem.itemClass);
  154. }
  155. return false;
  156. },
  157. _generateDataItemArray: function _generateDataItemArray() {
  158. this._aQueryResultDataItems = [];
  159. if (this._resultData && this._resultData.dataItems && this._resultData.dataItems.length > 0) {
  160. _.each(this._resultData.dataItems, function (dataItem) {
  161. if (this._isValidDataItem(dataItem)) {
  162. this._aQueryResultDataItems.push(new DataItem(dataItem));
  163. }
  164. }.bind(this));
  165. }
  166. },
  167. /**
  168. * @return {Number} the Query result data format version
  169. **/
  170. getVersion: function getVersion() {
  171. if (this._resultData) {
  172. return this._resultData.version;
  173. }
  174. return null;
  175. },
  176. /**
  177. * @return {Integer} the count of the data items
  178. **/
  179. getResultDataItemCount: function getResultDataItemCount() {
  180. if (this._resultData) {
  181. return (_.filter(this._resultData.dataItems, function (dataItem) {
  182. return this._isValidDataItem(dataItem);
  183. }.bind(this)) || []).length;
  184. }
  185. return 0;
  186. },
  187. /**
  188. * @return {QueryResultDataItem} One QueryResultDataItem Object located at the index
  189. */
  190. getResultDataItem: function getResultDataItem(index) {
  191. if (!this._aQueryResultDataItems) {
  192. this._generateDataItemArray();
  193. }
  194. return this._aQueryResultDataItems[index];
  195. },
  196. /**
  197. * @return {Array} An array of all QueryResultDataItem objects
  198. **/
  199. getResultDataItems: function getResultDataItems() {
  200. if (this._resultData) {
  201. if (!this._aQueryResultDataItems) {
  202. this._generateDataItemArray();
  203. }
  204. return this._aQueryResultDataItems;
  205. }
  206. return [];
  207. },
  208. /**
  209. * @return {Array} An array of all QueryResultDataItem objects
  210. **/
  211. getResultDataItemsNoValidation: function getResultDataItemsNoValidation() {
  212. var aQRDataItems = [];
  213. this._resultData.dataItems.forEach(function (dataItem) {
  214. aQRDataItems.push(new DataItem(dataItem));
  215. });
  216. return aQRDataItems;
  217. },
  218. /**
  219. * @param {String} dataItemRefID Data item reference ID, Unique ID A.K.A Projection ID
  220. * @return {Integer} the index number of the DataItem
  221. **/
  222. getDataItemIndex: function getDataItemIndex(dataItemRefID) {
  223. var nIndex = -1;
  224. if (this._resultData) {
  225. _.find(this.getResultDataItems(), function (dataItem, index) {
  226. if (dataItem.getTupleHeaderId() === dataItemRefID) {
  227. nIndex = index;
  228. return true;
  229. }
  230. });
  231. }
  232. return nIndex;
  233. },
  234. /**
  235. * @param {String} dataItemRefID Data item reference ID, Unique ID A.K.A Projection ID
  236. * @return {QueryResultDataItem} QueryResultDataItem Object with data item reference ID
  237. */
  238. getDataItem: function getDataItem(dataItemRefID) {
  239. return this.getResultDataItem(this.getDataItemIndex(dataItemRefID));
  240. },
  241. /**
  242. * Create and return a data row iterator instance
  243. * @return {DataRowIterator}
  244. **/
  245. getDataRowIterator: function getDataRowIterator() {
  246. var oIterator = new RowIterator(this._resultData.data);
  247. oIterator.setQueryResultDataRef(this);
  248. return oIterator;
  249. },
  250. /**
  251. * @return {Array} two dimensions array that stores the resolved values from query result data datapoints
  252. **/
  253. getResolvedDataRows: function getResolvedDataRows() {
  254. var nDatapointCount = this.getDatapointCount();
  255. var nDataItemCount = this.getResultDataItemCount();
  256. var aResult = [];
  257. for (var i = 0; i < nDatapointCount; i++) {
  258. aResult[i] = [];
  259. for (var j = 0; j < nDataItemCount; j++) {
  260. aResult[i].push(this.getCellValue(i, j));
  261. }
  262. }
  263. return aResult;
  264. },
  265. /**
  266. * @return {boolean} true if resultData includes hasNext or hasPrev true
  267. **/
  268. hasMoreData: function hasMoreData() {
  269. if (this._resultData) {
  270. return !!(this._resultData.hasPrev || this._resultData.hasNext);
  271. }
  272. return false;
  273. }
  274. });
  275. return QueryResultData;
  276. });
  277. //# sourceMappingURL=QueryResultData.js.map