Smalyshev has uploaded a new change for review. https://gerrit.wikimedia.org/r/316044
Change subject: Add ability to cancel queries ...................................................................... Add ability to cancel queries Change-Id: Ifc56442288c48f6c618d77c3f08ee3784dd39c5e Depends-On: I2895035e7e1d51f97f47b0f7767d51b0167bdd06 Bug: T136479 --- M i18n/en.json M i18n/qqq.json M index.html M style.css M wikibase/config.js M wikibase/queryService/api/Sparql.js M wikibase/queryService/ui/App.js M wikibase/queryService/ui/editor/hint/Sparql.js 8 files changed, 94 insertions(+), 42 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikidata/query/gui refs/changes/44/316044/1 diff --git a/i18n/en.json b/i18n/en.json index 078a21d..a107103 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -13,6 +13,7 @@ "wdqs-app-button-run": "Run", "wdqs-app-button-run-title": "Execute query (<CTRL> + <ENTER>)", "wdqs-app-button-clear": "Clear", + "wdqs-app-button-cancel": "Cancel", "wdqs-app-button-display": "Display", "wdqs-app-button-download": "Download", "wdqs-app-button-link": "Link", @@ -49,6 +50,7 @@ "wdqs-action-timeout": "Query timeout limit reached", "wdqs-action-malformed-query": "Query is malformed", "wdqs-action-server-error": "Server error", - "wdqs-action-unknow-error": "Unknown error", + "wdqs-action-cancelled": "Query was cancelled", + "wdqs-action-unknown-error": "Unknown error", "wdqs-result-map-layers-all": "All layers" } \ No newline at end of file diff --git a/i18n/qqq.json b/i18n/qqq.json index e4e709a..55466f7 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -15,6 +15,7 @@ "wdqs-app-button-run": "Button to run SPARQL query\n{{Identical|Run}}", "wdqs-app-button-run-title": "Title for button to run SPARQL query", "wdqs-app-button-clear": "Button to clear SPARQL query editor\n{{Identical|Clear}}", + "wdqs-app-button-cancel": "Button to cancel running query\n{{Identical|Cancel}}", "wdqs-app-button-display": "Button display result as table, image, ...\n{{Identical|Display}}", "wdqs-app-button-download": "Button download result\n{{Identical|Download}}", "wdqs-app-button-link": "Button get link to query\n{{Identical|Link}}", @@ -51,6 +52,7 @@ "wdqs-action-timeout": "Label for progressbar on timeout", "wdqs-action-malformed-query": "Label for progressbar on syntax error", "wdqs-action-server-error": "Label for progressbar displaying server error", - "wdqs-action-unknow-error": "Label for progressbar displaying unknown error", + "wdqs-action-cancelled": "Label for progressbar when query was cancelled", + "wdqs-action-unknown-error": "Label for progressbar displaying unknown error", "wdqs-result-map-layers-all": "Label for all layers in layer control on map view" } diff --git a/index.html b/index.html index c0acdf4..ff82419 100644 --- a/index.html +++ b/index.html @@ -112,6 +112,9 @@ <button type="button" class="btn btn-default" id="clear-button"> <span data-i18n="wdqs-app-button-clear"></span> </button> + <button type="button" class="btn btn-danger" id="cancel-button"> + <span data-i18n="wdqs-app-button-cancel"></span> + </button> <span class="query-total"> <span class="label label-default"><span id="total-results"></span> Results in <span id="query-time"></span> ms </span></span> </div> diff --git a/style.css b/style.css index a662df7..5008ee2 100644 --- a/style.css +++ b/style.css @@ -14,6 +14,7 @@ .query-total, #query-result, +#cancel-button, #hide-explorer { display: none; } diff --git a/wikibase/config.js b/wikibase/config.js index 2939722..0a78756 100644 --- a/wikibase/config.js +++ b/wikibase/config.js @@ -6,7 +6,7 @@ language: 'en', api: { sparql: { - uri: '/bigdata/namespace/wdq/sparql' + uri: '/sparql' }, wikibase: { uri: 'https://www.wikidata.org/w/api.php' @@ -17,7 +17,7 @@ var configLocal = $.extend( true, {}, configDeploy, { api: { sparql: { - uri: 'https://query.wikidata.org/bigdata/namespace/wdq/sparql' + uri: 'https://query.wikidata.org/sparql' } } } ); diff --git a/wikibase/queryService/api/Sparql.js b/wikibase/queryService/api/Sparql.js index 98bf89f..80576b7 100644 --- a/wikibase/queryService/api/Sparql.js +++ b/wikibase/queryService/api/Sparql.js @@ -5,18 +5,20 @@ wikibase.queryService.api.Sparql = ( function( $ ) { 'use strict'; - var SPARQL_SERVICE_URI = '//query.wikidata.org/bigdata/namespace/wdq/sparql'; + var SPARQL_SERVICE_URI = '//query.wikidata.org/sparql'; var ERROR_CODES = { - TIMEOUT: 10, - MALFORMED: 20, - SERVER: 30, - UNKNOWN: 100 + TIMEOUT: 10, + MALFORMED: 20, + SERVER: 30, + CANCELLED: 40, + UNKNOWN: 100 }; var ERROR_MAP = { 'QueryTimeoutException: Query deadline is expired': ERROR_CODES.TIMEOUT, - 'MalformedQueryException: ': ERROR_CODES.MALFORMED + 'MalformedQueryException: ': ERROR_CODES.MALFORMED, + 'CancellationException': ERROR_CODES.CANCELLED }; /** @@ -31,7 +33,7 @@ * * @param {string} [serviceUri] Optional URI to the SPARQL service endpoint */ - function SELF( serviceUri ) { + function SELF(serviceUri) { this._serviceUri = serviceUri || SPARQL_SERVICE_URI; } @@ -41,7 +43,7 @@ SELF.prototype.ERROR_CODES = ERROR_CODES; /** - * @property {Number} + * @property {String} * @private */ SELF.prototype._serviceUri = null; @@ -81,42 +83,55 @@ * * @return {jQuery.Promise} */ - SELF.prototype.queryDataUpdatedTime = function() { + SELF.prototype.queryDataUpdatedTime = function () { // Cache the update time only for a minute - var deferred = $.Deferred(), query = encodeURI( 'prefix schema: <http://schema.org/> ' + - 'SELECT * WHERE {<http://www.wikidata.org> schema:dateModified ?y}' ), url = this._serviceUri + - '?query=' + query + '&nocache=' + Math.floor( Date.now() / 60000 ), settings = { + var deferred = $.Deferred(), query = encodeURI('prefix schema: <http://schema.org/> ' + + 'SELECT * WHERE {<http://www.wikidata.org> schema:dateModified ?y}'), url = this._serviceUri + + '?query=' + query + '&nocache=' + Math.floor(Date.now() / 60000), settings = { headers: { Accept: 'application/sparql-results+json' } }; - $.ajax( url, settings ) + $.ajax(url, settings) .done( - function( data, textStatus, jqXHR ) { - if ( !data.results.bindings[0] ) { - deferred.reject(); - return; - } - var updateDate = new Date( - data.results.bindings[0][data.head.vars[0]].value ), dateText = updateDate - .toLocaleTimeString( navigator.language, { - timeZoneName: 'short' - } ) + - ', ' + updateDate.toLocaleDateString( navigator.language, { - month: 'short', - day: 'numeric', - year: 'numeric' - } ); - var differenceInSeconds = Math - .round( ( new Date() - updateDate ) / 1000 ); + function (data, textStatus, jqXHR) { + if (!data.results.bindings[0]) { + deferred.reject(); + return; + } + var updateDate = new Date( + data.results.bindings[0][data.head.vars[0]].value), dateText = updateDate + .toLocaleTimeString(navigator.language, { + timeZoneName: 'short' + }) + + ', ' + updateDate.toLocaleDateString(navigator.language, { + month: 'short', + day: 'numeric', + year: 'numeric' + }); + var differenceInSeconds = Math + .round(( new Date() - updateDate ) / 1000); - deferred.resolve( dateText, differenceInSeconds ); - } ).fail( function() { - deferred.reject(); - } ); + deferred.resolve(dateText, differenceInSeconds); + }).fail(function () { + deferred.reject(); + }); return deferred; + }; + + SELF.prototype.getUUID = function () { + // From http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript + var d = new Date().getTime(); + if (window.performance && typeof window.performance.now === "function") { + d += performance.now(); //use high-precision timer if available + } + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = (d + Math.random() * 16) % 16 | 0; + d = Math.floor(d / 16); + return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); }; /** @@ -132,10 +147,14 @@ } }; - this._queryUri = this._serviceUri + '?query=' + encodeURIComponent( query ); + this._queryId = this.getUUID(); + this._queryUri = this._serviceUri + '?query=' + encodeURIComponent(query) + + '&queryId=' + this._queryId; + console.log(this._queryId); this._executionTime = Date.now(); $.ajax( this._queryUri, settings ).done( function( data, textStatus, request ) { + self._queryId = null; self._executionTime = Date.now() - self._executionTime; if ( typeof data.boolean === 'boolean' ) { @@ -144,9 +163,9 @@ self._resultLength = data.results.bindings.length || 0; } self._rawData = data; - deferred.resolve(); } ).fail( function( request ) { + self._queryId = null; self._executionTime = null; self._rawData = null; self._resultLength = null; @@ -158,6 +177,13 @@ return deferred; }; + SELF.prototype.cancelQuery = function() { + if ( !this._queryId ) { + return; + } + $.post(this._serviceUri + '/cancel/' + this._queryId); + }; + /** * Get execution time in ms of the submitted query */ diff --git a/wikibase/queryService/ui/App.js b/wikibase/queryService/ui/App.js index 25e6edf..d8f70aa 100644 --- a/wikibase/queryService/ui/App.js +++ b/wikibase/queryService/ui/App.js @@ -419,6 +419,8 @@ $( '.explorer-panel' ).hide(); } ); + $( '#cancel-button' ).click( $.proxy( this._handleQueryCancel, this ) ); + $( window ).on( 'popstate', $.proxy( this._initQuery, this ) ); this._initPopovers(); @@ -597,10 +599,12 @@ $( '.query-total' ).hide(); $( '#execute-button' ).prop( 'disabled', true ); $( '#query-error' ).hide(); + $( '#clear-button' ).hide(); this._sparqlApi.query( this._editor.getValue() ) .done( $.proxy( this._handleQueryResult, this ) ) .fail( $.proxy( this._handleQueryError, this ) ); + $( '#cancel-button' ).show(); $( '.queryUri' ).attr( 'href', self._sparqlApi.getQueryUri() ); }; @@ -608,8 +612,18 @@ /** * @private */ + SELF.prototype._handleQueryCancel = function( e ) { + e.preventDefault(); + this._sparqlApi.cancelQuery(); + }; + + /** + * @private + */ SELF.prototype._handleQueryError = function() { $( '#execute-button' ).prop( 'disabled', false ); + $( '#cancel-button' ).hide(); + $( '#clear-button' ).show(); var error = this._sparqlApi.getError(), errorMessageKey = null, codes = this._sparqlApi.ERROR_CODES; @@ -623,8 +637,11 @@ case codes.SERVER: errorMessageKey = 'wdqs-action-server-error'; break; + case codes.CANCELLED: + errorMessageKey = 'wdqs-action-cancelled'; + break; default: - errorMessageKey = 'wdqs-action-unknow-error'; + errorMessageKey = 'wdqs-action-unknown-error'; break; } @@ -643,10 +660,12 @@ SELF.prototype._handleQueryResult = function() { var api = this._sparqlApi; + $( '#cancel-button' ).hide(); $( '#total-results' ).text( api.getResultLength() ); $( '#query-time' ).text( api.getExecutionTime() ); $( '.query-total' ).show(); $( '#execute-button' ).prop( 'disabled', false ); + $( '#clear-button' ).show(); var defaultBrowser = this._createResultBrowsers( api.getResultRawData() ); this._drawResult( defaultBrowser ); diff --git a/wikibase/queryService/ui/editor/hint/Sparql.js b/wikibase/queryService/ui/editor/hint/Sparql.js index 9e2f069..e9f402a 100755 --- a/wikibase/queryService/ui/editor/hint/Sparql.js +++ b/wikibase/queryService/ui/editor/hint/Sparql.js @@ -67,7 +67,6 @@ 'owl:sameAs', // prov: 'prov:wasDerivedFrom' - ]; /** -- To view, visit https://gerrit.wikimedia.org/r/316044 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifc56442288c48f6c618d77c3f08ee3784dd39c5e Gerrit-PatchSet: 1 Gerrit-Project: wikidata/query/gui Gerrit-Branch: master Gerrit-Owner: Smalyshev <smalys...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits