Skip to content

Commit

Permalink
Merge pull request #363 from EverythingMe/feature/query_parameters
Browse files Browse the repository at this point in the history
Feature: support for query parameters
  • Loading branch information
arikfr committed Jan 27, 2015
2 parents 521a32d + 4c73e78 commit 63274db
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 32 deletions.
1 change: 1 addition & 0 deletions rd_ui/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<script src="/scripts/ui-bootstrap-tpls-0.5.0.min.js"></script>
<script src="/bower_components/bucky/bucky.js"></script>
<script src="/bower_components/pace/pace.js"></script>
<script src="/bower_components/mustache/mustache.js"></script>
<!-- endbuild -->

<!-- build:js({.tmp,app}) /scripts/scripts.js -->
Expand Down
10 changes: 6 additions & 4 deletions rd_ui/app/scripts/controllers/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
var w = new Widget(widget);

if (w.visualization) {
promises.push(w.getQuery().getQueryResultPromise());
promises.push(w.getQuery().getQueryResult().toPromise());
}

return w;
Expand Down Expand Up @@ -104,7 +104,7 @@
};
};

var WidgetCtrl = function($scope, Events, Query) {
var WidgetCtrl = function($scope, $location, Events, Query) {
$scope.deleteWidget = function() {
if (!confirm('Are you sure you want to remove "' + $scope.widget.getName() + '" from the dashboard?')) {
return;
Expand All @@ -128,7 +128,9 @@
Events.record(currentUser, "view", "visualization", $scope.widget.visualization.id);

$scope.query = $scope.widget.getQuery();
$scope.queryResult = $scope.query.getQueryResult();
var parameters = Query.collectParamsFromQueryString($location, $scope.query);
var maxAge = $location.search()['maxAge'];
$scope.queryResult = $scope.query.getQueryResult(maxAge, parameters);
$scope.nextUpdateTime = moment(new Date(($scope.query.updated_at + $scope.query.ttl + $scope.query.runtime + 300) * 1000)).fromNow();

$scope.type = 'visualization';
Expand All @@ -139,6 +141,6 @@

angular.module('redash.controllers')
.controller('DashboardCtrl', ['$scope', 'Events', 'Widget', '$routeParams', '$location', '$http', '$timeout', '$q', 'Dashboard', DashboardCtrl])
.controller('WidgetCtrl', ['$scope', 'Events', 'Query', WidgetCtrl])
.controller('WidgetCtrl', ['$scope', '$location', 'Events', 'Query', WidgetCtrl])

})();
40 changes: 17 additions & 23 deletions rd_ui/app/scripts/controllers/query_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,7 @@
var isNewQuery = !$scope.query.id,
queryText = $scope.query.query,
// ref to QueryViewCtrl.saveQuery
saveQuery = $scope.saveQuery,
shortcuts = {
'meta+s': function () {
if ($scope.canEdit) {
$scope.saveQuery();
}
},
'ctrl+s': function () {
if ($scope.canEdit) {
$scope.saveQuery();
}
},
// Cmd+Enter for Mac
'meta+enter': function () {
$scope.executeQuery();
},
// Ctrl+Enter for PC
'ctrl+enter': function () {
$scope.executeQuery();
}
};
saveQuery = $scope.saveQuery;

$scope.sourceMode = true;
$scope.canEdit = currentUser.canEdit($scope.query);
Expand All @@ -49,8 +29,22 @@
}
});


KeyboardShortcuts.bind(shortcuts);
KeyboardShortcuts.bind({
'meta+s': function () {
if ($scope.canEdit) {
$scope.saveQuery();
}
},
'ctrl+s': function () {
if ($scope.canEdit) {
$scope.saveQuery();
}
},
// Cmd+Enter for Mac
'meta+enter': $scope.executeQuery,
// Ctrl+Enter for PC
'ctrl+enter': $scope.executeQuery
});

// @override
$scope.saveQuery = function(options, data) {
Expand Down
13 changes: 11 additions & 2 deletions rd_ui/app/scripts/controllers/query_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
function QueryViewCtrl($scope, Events, $route, $location, notifications, growl, Query, DataSource) {
var DEFAULT_TAB = 'table';

var getQueryResult = function(ttl) {
// Collect params, and getQueryResult with params; getQueryResult merges it into the query
var parameters = Query.collectParamsFromQueryString($location, $scope.query);
if (ttl == undefined) {
ttl = $location.search()['maxAge'];
}
$scope.queryResult = $scope.query.getQueryResult(ttl, parameters);
}

$scope.query = $route.current.locals.query;
Events.record(currentUser, 'view', 'query', $scope.query.id);
$scope.queryResult = $scope.query.getQueryResult();
getQueryResult();
$scope.queryExecuting = false;

$scope.isQueryOwner = currentUser.id === $scope.query.user.id;
Expand Down Expand Up @@ -57,7 +66,7 @@
};

$scope.executeQuery = function() {
$scope.queryResult = $scope.query.getQueryResult(0);
getQueryResult(0);
$scope.lockButton(true);
$scope.cancelling = false;
Events.record(currentUser, 'execute', 'query', $scope.query.id);
Expand Down
55 changes: 53 additions & 2 deletions rd_ui/app/scripts/services/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,54 @@
});
};

Query.collectParamsFromQueryString = function($location, query) {
var parameterNames = query.getParameters();
var parameters = {};

var queryString = $location.search();
_.each(parameterNames, function(param, i) {
var qsName = "p_" + param;
if (qsName in queryString) {
parameters[param] = queryString[qsName];
}
});

return parameters;
};

Query.prototype.getSourceLink = function () {
return '/queries/' + this.id + '/source';
};

Query.prototype.getQueryResult = function (ttl) {
Query.prototype.getQueryResult = function (ttl, parameters) {
if (ttl == undefined) {
ttl = this.ttl;
}

var queryText = this.query;

var queryParameters = this.getParameters();
var paramsRequired = !_.isEmpty(queryParameters);

var missingParams = parameters === undefined ? queryParameters : _.difference(queryParameters, _.keys(parameters));

if (paramsRequired && missingParams.length > 0) {
var paramsWord = "parameter";
if (missingParams.length > 1) {
paramsWord = "parameters";
}

return new QueryResult({job: {error: "Missing values for " + missingParams.join(', ') + " "+paramsWord+".", status: 4}});
}

if (parameters !== undefined) {
queryText = Mustache.render(queryText, parameters);

// Need to clear latest results, to make sure we don't used results for different params.
this.latest_query_data = null;
this.latest_query_data_id = null;
}

if (this.latest_query_data && ttl != 0) {
if (!this.queryResult) {
this.queryResult = new QueryResult({'query_result': this.latest_query_data});
Expand All @@ -417,14 +456,26 @@
this.queryResult = QueryResult.getById(this.latest_query_data_id);
}
} else if (this.data_source_id) {
this.queryResult = QueryResult.get(this.data_source_id, this.query, ttl);
this.queryResult = QueryResult.get(this.data_source_id, queryText, ttl);
}

return this.queryResult;
};

Query.prototype.getQueryResultPromise = function() {
return this.getQueryResult().toPromise();
};

Query.prototype.getParameters = function() {
var parts = Mustache.parse(this.query);
var parameters = [];
_.each(parts, function(part) {
if (part[0] == 'name') {
parameters.push(part[1]);
}
});

return parameters;
}

return Query;
Expand Down
3 changes: 2 additions & 1 deletion rd_ui/bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"bucky": "~0.2.6",
"pace": "~0.5.1",
"angular-ui-select": "0.8.2",
"font-awesome": "~4.2.0"
"font-awesome": "~4.2.0",
"mustache": "~1.0.0"
},
"devDependencies": {
"angular-mocks": "1.2.18",
Expand Down
1 change: 1 addition & 0 deletions rd_ui/test/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ module.exports = function(config) {
'app/scripts/ui-bootstrap-tpls-0.5.0.min.js',
'app/bower_components/bucky/bucky.js',
'app/bower_components/pace/pace.js',
'app/bower_components/mustache/mustache.js',

'app/scripts/app.js',
'app/scripts/services/services.js',
Expand Down

0 comments on commit 63274db

Please sign in to comment.