/*
* Copyright 2012 OSBI Ltd
*
* 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.
*/
/**
* Workspace query
*/
var Query = Backbone.Model.extend({
formatter: Settings.CELLSET_FORMATTER,
properties: null,
initialize: function(args, options) {
// Save cube
_.extend(this, options);
// Bind `this`
_.bindAll(this, "run");
// Generate a unique query id
this.uuid = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).toUpperCase();
this.model = _.extend({ name: this.uuid }, SaikuOlapQueryTemplate);
if (args.cube) {
this.model.cube = args.cube;
}
this.helper = new SaikuOlapQueryHelper(this);
// Initialize properties, action handler, and result handler
this.action = new QueryAction({}, { query: this });
this.result = new Result({ limit: Settings.RESULT_LIMIT }, { query: this });
this.scenario = new QueryScenario({}, { query: this });
},
parse: function(response) {
// Assign id so Backbone knows to PUT instead of POST
this.id = this.uuid;
if (response.name) {
this.id = response.name;
this.uuid = response.name;
}
this.model = _.extend(this.model, response);
this.model.properties = _.extend({}, Settings.QUERY_PROPERTIES, this.model.properties);
},
setProperty: function(key, value) {
this.model.properties[key] = value;
},
getProperty: function(key) {
return this.model.properties[key];
},
run: function(force, mdx) {
var self = this;
// Check for automatic execution
Saiku.ui.unblock();
if (typeof this.model.properties != "undefined" && this.model.properties['saiku.olap.query.automatic_execution'] === false &&
(force === false || force === undefined || force === null)) {
return;
}
this.workspace.unblock();
$(this.workspace.el).find(".workspace_results_info").empty();
this.workspace.trigger('query:run');
this.result.result = null;
var validated = false;
var errorMessage = 'Query Validation failed!';
var exModel = this.helper.model();
for(var k in this.attributes) {
var att = this.attributes[k];
if(k.substring(0,5)==="PARAM"){
var p = k.substring(5, k.length);
exModel.parameters[p] = att;
}
}
if (exModel.queryType == "OLAP") {
if (exModel.type == "QUERYMODEL") {
var columnsOk = Object.keys(exModel.queryModel.axes.COLUMNS.hierarchies).length > 0;
var rowsOk = Object.keys(exModel.queryModel.axes.ROWS.hierarchies).length > 0;
var detailsOk = exModel.queryModel.details.axis == 'COLUMNS' && exModel.queryModel.details.measures.length > 0;
if (!rowsOk || !columnsOk || !detailsOk) {
errorMessage = "";
}
if (!columnsOk && !detailsOk) {
errorMessage += 'You need to include at least one measure or a level on columns for a valid query.';
}
if(!rowsOk) {
errorMessage += 'You need to include at least one level on rows for a valid query.';
}
if ( (columnsOk || detailsOk) && rowsOk) {
validated = true;
}
} else if (exModel.type == "MDX") {
validated = (exModel.mdx && exModel.mdx.length > 0);
if (!validated) {
errorMessage = 'You need to enter some MDX statement to execute.';
}
}
}
if (!validated) {
this.workspace.table.clearOut();
$(this.workspace.processing).html(errorMessage).show();
this.workspace.adjust();
Saiku.i18n.translate();
return;
}
// Run it
this.workspace.table.clearOut();
$(this.workspace.processing).html(' Running query... [ Cancel ]').show();
this.workspace.adjust();
this.workspace.trigger('query:fetch');
Saiku.i18n.translate();
var message = ' Running query... [ Cancel ]';
this.workspace.block(message);
/*
TODO: i wonder if we should clean up the model (name and captions etc.)
delete this.model.queryModel.axes['FILTER'].name;
*/
this.result.save({},{ contentType: "application/json", data: JSON.stringify(exModel), error: function() {
Saiku.ui.unblock();
var errorMessage = 'Error executing query. Please check the server logs or contact your administrator!';
self.workspace.table.clearOut();
$(self.workspace.processing).html(errorMessage).show();
self.workspace.adjust();
Saiku.i18n.translate();
} });
},
enrich: function() {
var self = this;
this.workspace.query.action.post("/../enrich", {
contentType: "application/json",
data: JSON.stringify(self.model),
async: false,
success: function(response, model) {
self.model = model;
}
});
},
url: function() {
return "api/query/" + encodeURI(this.uuid);
}
});