Explorar o código

HPCC-10518 Add Roxie support to ECL Playground

Signed-off-by: Gordon Smith <gordon.smith@lexisnexis.com>
Gordon Smith %!s(int64=11) %!d(string=hai) anos
pai
achega
0256bcdb83

+ 35 - 8
esp/files/scripts/ECLPlaygroundResultsWidget.js

@@ -22,7 +22,9 @@ define([
 
     "hpcc/_TabContainerWidget",
     "hpcc/ESPWorkunit",
+    "hpcc/ESPQuery",
     "hpcc/ResultWidget",
+    "hpcc/FullResultWidget",
     "hpcc/LFDetailsWidget",
     "hpcc/VizWidget",
 
@@ -31,7 +33,7 @@ define([
     "dijit/layout/TabContainer"
 ], function (declare, lang, dom, 
                 registry,
-                _TabContainerWidget, ESPWorkunit, ResultWidget, LFDetailsWidget, VizWidget,
+                _TabContainerWidget, ESPWorkunit, ESPQuery, ResultWidget, FullResultWidget, LFDetailsWidget, VizWidget,
                 template) {
     return declare("ECLPlaygroundResultsWidget", [_TabContainerWidget], {
         templateString: template,
@@ -59,6 +61,12 @@ define([
                         title: title,
                         params: params
                     });
+                } else if (lang.exists("QuerySetId", params) && lang.exists("Id", params)) {
+                    retVal = new FullResultWidget({
+                        id: id,
+                        title: title,
+                        params: params
+                    });
                 }
                 this.addChild(retVal);
             }
@@ -69,11 +77,11 @@ define([
             if (this.inherited(arguments))
                 return;
 
+            var context = this;
             if (params.Wuid) {
                 this.wu = ESPWorkunit.Get(params.Wuid);
 
                 var monitorCount = 4;
-                var context = this;
                 this.wu.monitor(function () {
                     if (context.wu.isComplete() || ++monitorCount % 5 == 0) {
                         context.wu.getInfo({
@@ -97,6 +105,23 @@ define([
                         }
                     }
                 });
+            } else if (params.QuerySetId && params.Id) {
+                this.query = ESPQuery.Get(params.QuerySetId, params.Id);
+                this.query.SubmitXML(params.RequestXml).then(function (response) {
+                    var firstTab = true;
+                    for (var key in response) {
+                        var tab = context.ensurePane(context.id + "_result" + key, key, {
+                            QuerySetId: params.QuerySetId,
+                            Id: params.Id,
+                            FullResult: response[key]
+                        });
+                        if (firstTab) {
+                            context.initTab();
+                        } else {
+                            firstTab = false;
+                        }
+                    }
+                });
             }
         },
 
@@ -106,13 +131,15 @@ define([
             this.initalized = false;
         },
 
-        refresh: function (wu) {
-            if (this.workunit != wu) {
+        refresh: function (params) {
+            if (params.Wuid) {
+                if (this.wu.Wuid != params.Wuid) {
+                    this.clear();
+                    this.init(params);
+                }
+            } else if (params.QuerySetId && params.Id) {
                 this.clear();
-                this.workunit = wu;
-                this.init({
-                    Wuid: wu.Wuid
-                });
+                this.init(params);
             }
         }
     });

+ 33 - 16
esp/files/scripts/ECLPlaygroundWidget.js

@@ -31,11 +31,12 @@ define([
     "hpcc/GraphWidget",
     "hpcc/ECLPlaygroundResultsWidget",
     "hpcc/ESPWorkunit",
+    "hpcc/ESPQuery",
 
     "dojo/text!../templates/ECLPlaygroundWidget.html"
 ], function (declare, xhr, lang, dom, query,
                 BorderContainer, TabContainer, ContentPane, registry,
-                _Widget, EclSourceWidget, TargetSelectWidget, GraphWidget, ResultsWidget, ESPWorkunit,
+                _Widget, EclSourceWidget, TargetSelectWidget, GraphWidget, ResultsWidget, ESPWorkunit, ESPQuery,
                 template) {
     return declare("ECLPlaygroundWidget", [_Widget], {
         templateString: template,
@@ -272,25 +273,41 @@ define([
             if (lang.exists("Exceptions.ECLException", this.wu)) {
                 this.editorControl.setErrors(this.wu.Exceptions.ECLException);
             }
-            this.resultsWidget.refresh(this.wu);
+            this.resultsWidget.refresh({
+                Wuid: this.wu.Wuid
+            });
         },
 
         _onSubmit: function (evt) {
             this.resetPage();
-            var context = this;
-            this.wu = ESPWorkunit.Create({
-                onCreate: function () {
-                    context.wu.update({
-                        QueryText: context.editorControl.getText()
-                    });
-                    context.watchWU();
-                },
-                onUpdate: function () {
-                    context.wu.submit(context.targetSelectWidget.getValue());
-                },
-                onSubmit: function () {
-                }
-            });
+
+            var text = this.editorControl.getText();
+            var espQuery = ESPQuery.GetFromRequestXML(this.targetSelectWidget.get("value"), text);
+
+            if (espQuery) {
+                this.stackContainer.selectChild(this.resultsWidget);
+                this.resultsWidget.set("disabled", false);
+                this.resultsWidget.refresh({
+                    QuerySetId: espQuery.QuerySetId,
+                    Id: espQuery.Id,
+                    RequestXml: text
+                });
+            } else {
+                var context = this;
+                this.wu = ESPWorkunit.Create({
+                    onCreate: function () {
+                        context.wu.update({
+                            QueryText: text
+                        });
+                        context.watchWU();
+                    },
+                    onUpdate: function () {
+                        context.wu.submit(context.targetSelectWidget.getValue());
+                    },
+                    onSubmit: function () {
+                    }
+                });
+            }
         }
     });
 });

+ 46 - 6
esp/files/scripts/ESPQuery.js

@@ -23,12 +23,16 @@ define([
     "dojo/store/Observable",
     "dojo/Stateful",
 
+    "dojox/xml/parser",
+
     "hpcc/WsWorkunits",
+    "hpcc/WsEcl",
     "hpcc/ESPRequest",
     "hpcc/ESPUtil",
     "hpcc/ESPWorkunit"
 ], function (declare, arrayUtil, lang, Deferred, ObjectStore, QueryResults, Observable, Stateful,
-        WsWorkunits, ESPRequest, ESPUtil, ESPWorkunit) {
+        parser,
+        WsWorkunits, WsEcl, ESPRequest, ESPUtil, ESPWorkunit) {
 
     var _logicalFiles = {};
 
@@ -37,14 +41,18 @@ define([
         action: "WUListQueries",
         responseQualifier: "WUListQueriesResponse.QuerysetQueries.QuerySetQuery",
         responseTotalQualifier: "WUListQueriesResponse.NumberOfQueries",
-        idProperty: "Id",
+        idProperty: "__hpcc_id",
         startProperty: "PageStartFrom",
         countProperty: "NumberOfQueries",
 
         _watched: [],
-        create: function (id) {
+
+        create: function (__hpcc_id) {
+            var tmp = __hpcc_id.split(":");
             return new Query({
-                Id: id
+                __hpcc_id: __hpcc_id,
+                QuerySetId: tmp[0],
+                Id: tmp[1]
             });
         },
         update: function (id, item) {
@@ -63,6 +71,7 @@ define([
         preProcessRow: function (item, request, query, options) {
             var ErrorCount = 0;
             var Suspended = false;
+            item[this.idProperty] = item.QuerySetId + ":" + item.Id;
             if (lang.exists("Clusters", item)) {
                 arrayUtil.forEach(item.Clusters.ClusterQueryState, function(cqs, idx){
                     if (lang.exists("Errors", cqs) && cqs.Errors != null && cqs.Errors != "" && cqs.State == "Suspended"){
@@ -84,6 +93,7 @@ define([
             if (args) {
                 declare.safeMixin(this, args);
             }
+            this.queries = {};
         },
         refresh: function (full) {
             return this.getDetails();
@@ -104,6 +114,24 @@ define([
         getWorkunit: function() {
             return ESPWorkunit.Get(this.Wuid);
         },
+        SubmitXML: function (xml) {
+            var deferred = new Deferred();
+            if (this.queries[xml]) {
+                deferred.resolve(this.queries[xml]);
+            } else {
+                var domXml = parser.parse(xml);
+                var query = {};
+                arrayUtil.forEach(domXml.firstChild.childNodes, function (item, idx) {
+                    query[item.tagName] = item.textContent;
+                });
+                var context = this;
+                WsEcl.Submit(this.QuerySetId, this.Id, query).then(function (response) {
+                    context.queries[xml] = response;
+                    deferred.resolve(response);
+                });
+            }
+            return deferred.promise;
+        },
         doAction: function (action) {
             var context = this;
             return WsWorkunits.WUQuerysetQueryAction([{
@@ -126,9 +154,21 @@ define([
     });
 
     return {
-        Get: function (Id) {
+        Get: function (QuerySetId, Id) {
             var store = new Store();
-            return store.get(Id);
+            return store.get(QuerySetId + ":" + Id);
+        },
+
+        GetFromRequestXML: function (QuerySetId, requestXml) {
+            try {
+                var domXml = parser.parse(requestXml);
+                //  Not all XML is a "Request"  ---
+                if (lang.exists("firstChild.tagName", domXml) && domXml.firstChild.tagName.indexOf("Request") === domXml.firstChild.tagName.length - 7) {
+                    return this.Get(QuerySetId, domXml.firstChild.tagName.slice(0, -7));
+                }
+            } catch (e) {
+            }
+            return null;
         },
 
         CreateQueryStore: function (options) {

+ 2 - 1
esp/files/scripts/ESPRequest.js

@@ -207,9 +207,10 @@ define([
     _StoreSingletons = [];
     return {
         getURL: function (_params) {
+            var requestHelper = new RequestHelper();
             var params = lang.mixin({
                 protocol: location.protocol,
-                hostname: location.hostname,
+                hostname: requestHelper.serverIP ? requestHelper.serverIP : location.hostname,
                 port: location.port,
                 pathname: ""
             }, _params);

+ 186 - 0
esp/files/scripts/FullResultWidget.js

@@ -0,0 +1,186 @@
+/*##############################################################################
+#    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+############################################################################## */
+define([
+    "dojo/_base/declare",
+    "dojo/_base/lang",
+    "dojo/_base/array",
+    "dojo/dom",
+    "dojo/request/iframe",
+    "dojo/store/Memory",
+    "dojo/store/Observable",
+
+    "dijit/registry",
+
+    "dgrid/OnDemandGrid",
+    "dgrid/Keyboard",
+    "dgrid/Selection",
+    "dgrid/selector",
+    "dgrid/extensions/ColumnResizer",
+    "dgrid/extensions/DijitRegistry",
+
+    "hpcc/_Widget",
+    "hpcc/ESPBase",
+    "hpcc/ESPWorkunit",
+    "hpcc/ESPLogicalFile",
+    "hpcc/ESPUtil",
+
+    "dojo/text!../templates/FullResultWidget.html",
+
+    "dijit/layout/BorderContainer",
+    "dijit/layout/ContentPane",
+    "dijit/Toolbar",
+    "dijit/form/Button",
+    "dijit/ToolbarSeparator"
+], function (declare, lang, arrayUtil, dom, iframe, Memory, Observable,
+                registry,
+                OnDemandGrid, Keyboard, Selection, selector, ColumnResizer, DijitRegistry,
+                _Widget, ESPBase, ESPWorkunit, ESPLogicalFile, ESPUtil,
+                template) {
+    return declare("FullResultWidget", [_Widget], {
+        templateString: template,
+        baseClass: "FullResultWidget",
+
+        borderContainer: null,
+        grid: null,
+
+        loaded: false,
+
+        buildRendering: function (args) {
+            this.inherited(arguments);
+        },
+
+        postCreate: function (args) {
+            this.inherited(arguments);
+            this.borderContainer = registry.byId(this.id + "BorderContainer");
+            this.grid = registry.byId(this.id + "Grid");
+        },
+
+        startup: function (args) {
+            this.inherited(arguments);
+        },
+
+        resize: function (args) {
+            this.inherited(arguments);
+            this.borderContainer.resize();
+        },
+
+        layout: function (args) {
+            this.inherited(arguments);
+        },
+
+        destroy: function (args) {
+            this.inherited(arguments);
+        },
+
+        _doDownload: function (type) {
+            //TODO Fix
+            var base = new ESPBase();
+            if (lang.exists("result.Sequence", this)) {
+                var sequence = this.result.Sequence;
+                var downloadPdfIframeName = "downloadIframe_" + sequence;
+                var frame = iframe.create(downloadPdfIframeName);
+                var url = base.getBaseURL() + "/WUResultBin?Format=" + type + "&Wuid=" + this.result.Wuid + "&Sequence=" + sequence;
+                iframe.setSrc(frame, url, true);
+            } else if (lang.exists("result.Name", this)) {
+                var logicalName = this.result.Name;
+                var downloadPdfIframeName = "downloadIframe_" + logicalName;
+                var frame = iframe.create(downloadPdfIframeName);
+                var url = base.getBaseURL() + "/WUResultBin?Format=" + type + "&Wuid=" + this.result.Wuid + "&LogicalName=" + logicalName;
+                iframe.setSrc(frame, url, true);
+            }
+        },
+
+        _onDownloadZip: function (args) {
+            this._doDownload("zip");
+        },
+
+        _onDownloadGZip: function (args) {
+            this._doDownload("gzip");
+        },
+
+        _onDownloadXLS: function (args) {
+            this._doDownload("xls");
+        },
+
+        _onFileDetails: function (args) {
+            alert("todo");
+        },
+
+        //  Implementation  ---
+        onErrorClick: function (line, col) {
+        },
+
+        init: function (params) {
+            if (this.inherited(arguments))
+                return;
+
+            if (params.FullResult) {
+                this.initResult(params.FullResult);
+            } else {
+                this.initResult(null);
+            }
+        },
+
+        initResult: function (result) {
+            if (result && result.length) {
+                var columns = [];
+                for (var key in result[0]) {
+                    if (key.indexOf("__") != 0) {
+                        columns.push({
+                            field: key,
+                            label: key
+                        });
+                    }
+                }
+                arrayUtil.forEach(result, function (item, idx) {
+                    item["__hpcc_id"] = idx;
+                });
+                var store = new Memory({
+                    idProperty: "__hpcc_id",
+                    data: result
+                });
+                this.store = Observable(store);
+                this.grid = new declare([OnDemandGrid, Keyboard, Selection, ColumnResizer, DijitRegistry, ESPUtil.GridHelper])({
+                    columns: columns,
+                    store: this.store
+                }, this.id + "Grid");
+                this.grid.startup();
+            } else {
+                this.grid = new declare([Grid, DijitRegistry])({
+                    columns: [
+                            {
+                                label: "##",
+                                width: 54
+                            }
+                    ]
+                }, this.id + "Grid");
+                this.grid.set("noDataMessage", "[undefined]");
+                this.grid.startup();
+            }
+        },
+
+        refresh: function () {
+            if (this.result && !this.result.isComplete()) {
+                this.grid.showMessage(this.result.getLoadingMessage());
+            } else if (!this.loaded) {
+                this.loaded = true;
+                this.grid.set("query", {
+                    id: "*"
+                });
+            }
+        }
+    });
+});

+ 1 - 1
esp/files/scripts/QuerySetDetailsWidget.js

@@ -120,7 +120,7 @@ define([
             if (this.inherited(arguments))
                 return;
 
-            this.query = ESPQuery.Get(params.Id);
+            this.query = ESPQuery.Get(params.QuerySetId, params.Id);
 
             var context = this;
             var data = this.query.getData();

+ 1 - 1
esp/files/scripts/QueryTestWidget.js

@@ -73,7 +73,7 @@ define([
             if (this.inherited(arguments))
                 return;
 
-            this.query = ESPQuery.Get(params.QueryId);
+            this.query = ESPQuery.Get(params.QuerySet, params.QueryId);
 
             this.selectChild(this.soapTab, true);
         },

+ 97 - 0
esp/files/scripts/WsEcl.js

@@ -0,0 +1,97 @@
+/*##############################################################################
+#    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+############################################################################## */
+define([
+    "dojo/_base/declare",
+    "dojo/_base/lang",
+    "dojo/_base/array",
+    "dojo/_base/Deferred",
+    "dojo/request",
+    "dojo/request/script",
+
+    "hpcc/WsTopology"
+], function (declare, lang, arrayUtil, Deferred, request, script,
+    WsTopology) {
+
+    return {
+        _flattenResults: function (results) {
+            if (Object.prototype.toString.call(results) === '[object Array]') {
+                for (var i = 0; i < results.length; ++i) {
+                    results[i] = this._flattenResults(results[i]);
+                }
+            } else if (Object.prototype.toString.call(results) === '[object Object]') {
+                var d = Object.prototype.toString.call(results);
+                for (var key in results) {
+                    results[key] = this._flattenResults(results[key]);
+                    if (key === "Row") {
+                        return results.Row;
+                    }
+                }
+            }
+            return results;
+        },
+        //http://192.168.1.201:8002/WsEcl/submit/query/roxie/countydeeds.1/json?year=2013&jsonp=XYZ
+        Submit: function (target, method, query) {
+            var deferred = new Deferred();
+            var context = this;
+            WsTopology.GetWsEclURL("submit").then(function (response) {
+                var url = response + target + "/" + method + "/json";
+                script.get(url, {
+                    query: query,
+                    jsonp: "jsonp"
+                }).then(function (response) {
+                    var results = response[method + "Response"] && response[method + "Response"].Results ? response[method + "Response"].Results : {};
+                    results = context._flattenResults(results);
+                    deferred.resolve(results);
+                });
+            });
+            return deferred.promise;
+        },
+        SubmitXML: function (target, domXml) {
+            domXml = domXml.firstChild;
+            var method = domXml.tagName;
+            method = method.slice(0, -7); //"Request"
+            var query = {};
+            arrayUtil.forEach(domXml.childNodes, function (item, idx) {
+                query[item.tagName] = item.textContent;
+            });
+            return this.Submit(target, method, query);
+        },
+        //http://192.168.1.201:8002/WsEcl/example/request/query/roxie/countydeeds.1
+        ExampleRequest: function(target, method) {
+            var deferred = new Deferred();
+            var context = this;
+            WsTopology.GetWsEclURL("example/request").then(function (response) {
+                var url = response + target + "/" + method;
+                //  HPCC-10488  ---
+                //  script.get(url, {
+                //    query: query,
+                //    jsonp: "jsonp"
+                request.get(url, {
+                    handleAs: "xml"
+                }).then(function (response) {
+                    var fields = [];
+                    arrayUtil.forEach(response.getElementsByTagName(method + "Request"), function (item, idx) {
+                        arrayUtil.forEach(item.childNodes, function (child_item, idx) {
+                            fields.push(child_item.tagName);
+                        });
+                    });
+                    deferred.resolve(fields);
+                });
+            });
+            return deferred.promise;
+        }
+    };
+});

+ 1 - 1
esp/files/scripts/viz/DojoD3.js

@@ -8,7 +8,7 @@
 
   "d3/d3.v3.min"
 ], function (declare, lang, dom, domConstruct, domGeom, Evented) {
-    return declare(null, {
+    return declare([Evented], {
         constructor: function () {
         },
 

+ 11 - 0
esp/files/templates/FullResultWidget.html

@@ -0,0 +1,11 @@
+<div class="${baseClass}">
+    <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%" data-dojo-props="splitter: false" data-dojo-type="dijit.layout.BorderContainer">
+        <div id="${id}Toolbar" class="topPanel" style="padding: 0px; overflow: hidden" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
+            <div id="${id}NewPage" class="right" data-dojo-attach-event="onClick:_onNewPage" data-dojo-props="iconClass:'iconNewPage', showLabel:false" data-dojo-type="dijit.form.Button">Open in New Page</div>
+        </div>
+        <div id="${id}GridCP" style="padding: 0px; border:0px; border-color:none" data-dojo-props="region: 'center'" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}Grid">
+            </div>
+        </div>
+    </div>
+</div>