ESPResult.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*##############################################################################
  2. # HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################## */
  16. define([
  17. "dojo/_base/declare",
  18. "dojo/_base/Deferred",
  19. "dojo/_base/lang",
  20. "dojo/data/ObjectStore",
  21. "dojo/store/util/QueryResults",
  22. "dojo/store/Observable",
  23. "dojo/dom-construct",
  24. "dojox/xml/parser",
  25. "dojox/xml/DomParser",
  26. "dojox/html/entities",
  27. "hpcc/ESPBase",
  28. "hpcc/WsWorkunits"
  29. ], function (declare, Deferred, lang, ObjectStore, QueryResults, Observable, domConstruct,
  30. parser, DomParser, entities,
  31. ESPBase, WsWorkunits) {
  32. var Store = declare(ESPBase, {
  33. idProperty: "myInjectedRowNum",
  34. wuid: "",
  35. sequence: 0,
  36. isComplete: false,
  37. constructor: function (args) {
  38. declare.safeMixin(this, args);
  39. },
  40. getIdentity: function (object) {
  41. return object[this.idProperty];
  42. },
  43. queryWhenComplete: function (query, options, deferredResults) {
  44. var context = this;
  45. if (this.isComplete === true) {
  46. var request = {};
  47. if (this.name) {
  48. request['LogicalName'] = this.name;
  49. } else {
  50. request['Wuid'] = this.wuid;
  51. request['Sequence'] = this.sequence;
  52. }
  53. request['Start'] = options.start;
  54. request['Count'] = options.count;
  55. var results = WsWorkunits.WUResult({
  56. request: request
  57. });
  58. Deferred.when(results, function (response) {
  59. if (lang.exists("WUResultResponse.Total", response)) {
  60. deferredResults.total.resolve(response.WUResultResponse.Total);
  61. } else {
  62. deferredResults.total.resolve(0);
  63. }
  64. var rows = [];
  65. if (lang.exists("WUResultResponse.Result", response)) {
  66. var xml = "<Result>" + response.WUResultResponse.Result + "</Result>";
  67. var domXml = parser.parse(xml);
  68. rows = context.getValues(domXml, "Row");
  69. for (var i = 0; i < rows.length; ++i) {
  70. rows[i].myInjectedRowNum = options.start + i + 1;
  71. }
  72. }
  73. deferredResults.resolve(rows);
  74. });
  75. } else {
  76. setTimeout(function () {
  77. context.queryWhenComplete(query, options, deferredResults);
  78. }, 100);
  79. }
  80. },
  81. query: function (query, options) {
  82. var deferredResults = new Deferred();
  83. deferredResults.total = new Deferred();
  84. this.queryWhenComplete(query, options, deferredResults);
  85. return QueryResults(deferredResults);
  86. }
  87. });
  88. var Result = declare(null, {
  89. store: null,
  90. Total: "-1",
  91. constructor: function (args) {
  92. declare.safeMixin(this, args);
  93. if (this.Sequence != null) {
  94. this.store = new Store({
  95. wuid: this.Wuid,
  96. sequence: this.Sequence,
  97. isComplete: this.isComplete()
  98. });
  99. } else {
  100. this.store = new Store({
  101. wuid: this.Wuid,
  102. cluster: this.Cluster,
  103. name: this.Name,
  104. isComplete: true
  105. });
  106. }
  107. },
  108. getName: function () {
  109. return this.Name;
  110. },
  111. getID: function () {
  112. if (this.Sequence != null) {
  113. return this.Sequence;
  114. }
  115. return this.Name;
  116. },
  117. isComplete: function () {
  118. return this.Total != "-1";
  119. },
  120. canShowResults: function () {
  121. if (lang.exists("Sequence", this)) { // Regular WU result
  122. return true;
  123. } else if (lang.exists("RecordCount", this) && this.RecordCount != "") { // DFU Sprayed CSV File will fail here
  124. return true;
  125. }
  126. return false;
  127. },
  128. getFirstSchemaNode: function (node, name) {
  129. if (node && node.attributes) {
  130. if ((node.baseName && node.baseName == name) || (node.localName && node.localName == name) || (typeof (node.getAttribute) != "undefined" && node.getAttribute("name") == name)) {
  131. return node;
  132. }
  133. }
  134. for (var i = 0; i < node.childNodes.length; ++i) {
  135. var retVal = this.getFirstSchemaNode(node.childNodes[i], name);
  136. if (retVal) {
  137. return retVal;
  138. }
  139. }
  140. return null;
  141. },
  142. getFirstSequenceNode: function (schemaNode) {
  143. var row = this.getFirstSchemaNode(schemaNode, "Row");
  144. if (!row)
  145. return null;
  146. var complexType = this.getFirstSchemaNode(row, "complexType");
  147. if (!complexType)
  148. return null;
  149. return this.getFirstSchemaNode(complexType, "sequence");
  150. },
  151. rowToTable: function (cell) {
  152. var table = domConstruct.create("table", { border: 1, cellspacing: 0, width: "100%" });
  153. if (cell && cell.Row) {
  154. if (!cell.Row.length) {
  155. cell.Row = [cell.Row];
  156. }
  157. for (var i = 0; i < cell.Row.length; ++i) {
  158. if (i == 0) {
  159. var tr = domConstruct.create("tr", null, table);
  160. for (key in cell.Row[i]) {
  161. var th = domConstruct.create("th", { innerHTML: entities.encode(key) }, tr);
  162. }
  163. }
  164. var tr = domConstruct.create("tr", null, table);
  165. for (var key in cell.Row[i]) {
  166. if (cell.Row[i][key]) {
  167. if (cell.Row[i][key].Row) {
  168. var td = domConstruct.create("td", null, tr);
  169. td.appendChild(this.rowToTable(cell.Row[i][key]));
  170. } else {
  171. var td = domConstruct.create("td", { innerHTML: entities.encode(cell.Row[i][key]) }, tr);
  172. }
  173. } else {
  174. var td = domConstruct.create("td", { innerHTML: "" }, tr);
  175. }
  176. }
  177. }
  178. }
  179. return table;
  180. },
  181. getRowStructureFromSchema: function (parentNode) {
  182. var retVal = [];
  183. var sequence = this.getFirstSequenceNode(parentNode, "sequence");
  184. if (!sequence)
  185. return retVal;
  186. for (var i = 0; i < sequence.childNodes.length; ++i) {
  187. var node = sequence.childNodes[i];
  188. if (typeof (node.getAttribute) != "undefined") {
  189. var name = node.getAttribute("name");
  190. var type = node.getAttribute("type");
  191. if (name && type) {
  192. retVal.push({
  193. name: name,
  194. field: name,
  195. width: this.extractWidth(type, name),
  196. classes: "resultGridCell"
  197. });
  198. }
  199. if (node.hasChildNodes()) {
  200. var context = this;
  201. retVal.push({
  202. name: name,
  203. field: name,
  204. formatter: function (cell, row, grid) {
  205. var div = document.createElement("div");
  206. div.appendChild(context.rowToTable(cell));
  207. return div.innerHTML;
  208. },
  209. width: this.getRowWidth(node),
  210. classes: "resultGridCell"
  211. });
  212. }
  213. }
  214. }
  215. return retVal;
  216. },
  217. getRowStructureFromData: function (rows) {
  218. var retVal = [];
  219. for (var key in rows[0]) {
  220. if (key != "myInjectedRowNum") {
  221. var context = this;
  222. retVal.push({
  223. name: key,
  224. field: key,
  225. formatter: function (cell, row, grid) {
  226. if (cell && cell.Row) {
  227. var div = document.createElement("div");
  228. div.appendChild(context.rowToTable(cell));
  229. return div.innerHTML;
  230. }
  231. return cell;
  232. },
  233. width: context.extractWidth("string12", key),
  234. classes: "resultGridCell"
  235. });
  236. }
  237. }
  238. return retVal;
  239. },
  240. getStructure: function () {
  241. var structure = [
  242. {
  243. cells: [
  244. [
  245. {
  246. name: "##", field: this.store.idProperty, width: "6", classes: "resultGridCell"
  247. }
  248. ]
  249. ]
  250. }
  251. ];
  252. var dom = parser.parse(this.XmlSchema);
  253. var dataset = this.getFirstSchemaNode(dom, "Dataset");
  254. var innerStruct = this.getRowStructureFromSchema(dataset);
  255. for (var i = 0; i < innerStruct.length; ++i) {
  256. structure[0].cells[structure[0].cells.length - 1].push(innerStruct[i]);
  257. }
  258. return structure;
  259. },
  260. fetchStructure: function (callback) {
  261. if (this.XmlSchema) {
  262. callback(this.getStructure());
  263. } else {
  264. var context = this;
  265. var request = {};
  266. if (this.Name) {
  267. request['LogicalName'] = this.Name;
  268. } else {
  269. request['Wuid'] = this.Wuid;
  270. request['Sequence'] = this.Sequence;
  271. }
  272. request['Start'] = 0;
  273. request['Count'] = 1;
  274. WsWorkunits.WUResult({
  275. request: request,
  276. load: function (response) {
  277. if (lang.exists("WUResultResponse.Result", response)) {
  278. context.XmlSchema = "<Result>" + response.WUResultResponse.Result + "</Result>";
  279. callback(context.getStructure());
  280. }
  281. /*
  282. if (rows.length) {
  283. var innerStruct = context.getRowStructureFromData(rows);
  284. for (var i = 0; i < innerStruct.length; ++i) {
  285. structure[0].cells[structure[0].cells.length - 1].push(innerStruct[i]);
  286. }
  287. }
  288. */
  289. }
  290. });
  291. }
  292. },
  293. getRowWidth: function (parentNode) {
  294. var retVal = 0;
  295. var sequence = this.getFirstSequenceNode(parentNode, "sequence");
  296. if (!sequence)
  297. return retVal;
  298. for (var i = 0; i < sequence.childNodes.length; ++i) {
  299. var node = sequence.childNodes[i];
  300. if (typeof (node.getAttribute) != "undefined") {
  301. var name = node.getAttribute("name");
  302. var type = node.getAttribute("type");
  303. if (name && type) {
  304. retVal += this.extractWidth(type, name);
  305. } else if (node.hasChildNodes()) {
  306. retVal += this.getRowWidth(node);
  307. }
  308. }
  309. }
  310. return retVal;
  311. },
  312. extractWidth: function (type, name) {
  313. var retVal = -1;
  314. switch (type) {
  315. case "xs:boolean":
  316. retVal = 5;
  317. break;
  318. case "xs:integer":
  319. retVal = 8;
  320. break;
  321. case "xs:nonNegativeInteger":
  322. retVal = 8;
  323. break;
  324. case "xs:double":
  325. retVal = 8;
  326. break;
  327. case "xs:string":
  328. retVal = 32;
  329. break;
  330. default:
  331. var numStr = "0123456789";
  332. var underbarPos = type.lastIndexOf("_");
  333. var length = underbarPos > 0 ? underbarPos : type.length;
  334. var i = length - 1;
  335. for (; i >= 0; --i) {
  336. if (numStr.indexOf(type.charAt(i)) == -1)
  337. break;
  338. }
  339. if (i + 1 < length) {
  340. retVal = parseInt(type.substring(i + 1, length));
  341. }
  342. if (type.indexOf("data") == 0) {
  343. retVal *= 2;
  344. }
  345. break;
  346. }
  347. if (retVal < name.length)
  348. retVal = name.length;
  349. return retVal;
  350. },
  351. getObjectStore: function () {
  352. return new ObjectStore({
  353. objectStore: this.store
  354. });
  355. },
  356. getLoadingMessage: function () {
  357. if (lang.exists("wu.state", this)) {
  358. return "<span class=\'dojoxGridWating\'>[" + this.wu.state + "]</span>";
  359. }
  360. return "<span class=\'dojoxGridWating\'>[unknown]</span>";
  361. },
  362. getECLRecord: function () {
  363. var retVal = "RECORD\n";
  364. for (var i = 0; i < this.ECLSchemas.ECLSchemaItem.length; ++i) {
  365. retVal += "\t" + this.ECLSchemas.ECLSchemaItem[i].ColumnType + "\t" + this.ECLSchemas.ECLSchemaItem[i].ColumnName + ";\n";
  366. }
  367. retVal += "END;\n";
  368. return retVal;
  369. }
  370. });
  371. return {
  372. CreateWUResultObjectStore: function (options) {
  373. var store = new Store(options);
  374. store = Observable(store);
  375. var objStore = new ObjectStore({ objectStore: store });
  376. return objStore;
  377. },
  378. Get: function (params) {
  379. return new Result(params);
  380. }
  381. }
  382. });