Skip to content

Commit

Permalink
Merge pull request getredash#1524 from rainforestapp/master
Browse files Browse the repository at this point in the history
Allow params once again in embeds
  • Loading branch information
arikfr authored Jun 28, 2017
2 parents 69cb5b7 + 6bc53c3 commit 70292c8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 9 deletions.
2 changes: 1 addition & 1 deletion client/app/pages/queries/visualization-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function (ngModule) {
return session($http, $route, Auth).then(() => {
const queryId = $route.current.params.queryId;
const query = $http.get(`api/queries/${queryId}`).then(response => response.data);
const queryResult = $http.get(`api/queries/${queryId}/results.json`).then(response => response.data);
const queryResult = $http.get(`api/queries/${queryId}/results.json${location.search}`).then(response => response.data);
return $q.all([query, queryResult]);
});
}
Expand Down
72 changes: 64 additions & 8 deletions redash/handlers/query_results.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import json
import time

Expand All @@ -9,14 +10,63 @@
from redash.tasks import QueryTask, record_event
from redash.permissions import require_permission, not_view_only, has_access, require_access, view_only
from redash.handlers.base import BaseResource, get_object_or_404
from redash.utils import collect_query_parameters, collect_parameters_from_request
from redash.utils import collect_query_parameters, collect_parameters_from_request, gen_query_hash
from redash.tasks.queries import enqueue_query


def error_response(message):
return {'job': {'status': 4, 'error': message}}, 400


#
# Run a parameterized query synchronously and return the result
# DISCLAIMER: Temporary solution to support parameters in queries. Should be
# removed once we refactor the query results API endpoints and handling
# on the client side. Please don't reuse in other API handlers.
#
def run_query_sync(data_source, parameter_values, query_text, max_age=0):
query_parameters = set(collect_query_parameters(query_text))
missing_params = set(query_parameters) - set(parameter_values.keys())
if missing_params:
raise Exception('Missing parameter value for: {}'.format(", ".join(missing_params)))

if query_parameters:
query_text = pystache.render(query_text, parameter_values)

if max_age <= 0:
query_result = None
else:
query_result = models.QueryResult.get_latest(data_source, query_text, max_age)

query_hash = gen_query_hash(query_text)

if query_result:
logging.info("Returning cached result for query %s" % query_hash)
return query_result

try:
started_at = time.time()
data, error = data_source.query_runner.run_query(query_text, current_user)

if error:
logging.info('got bak error')
logging.info(error)
return None

run_time = time.time() - started_at
query_result, updated_query_ids = models.QueryResult.store_result(data_source.org, data_source,
query_hash, query_text, data,
run_time, utils.utcnow())

models.db.session.commit()
return query_result
except Exception, e:
if max_age > 0:
abort(404, message="Unable to get result from the database, and no cached query result found.")
else:
abort(503, message="Unable to get result from the database.")
return None

def run_query(data_source, parameter_values, query_text, query_id, max_age=0):
query_parameters = set(collect_query_parameters(query_text))
missing_params = set(query_parameters) - set(parameter_values.keys())
Expand Down Expand Up @@ -127,15 +177,22 @@ def get(self, query_id=None, query_result_id=None, filetype='json'):
# They need to be split, as they have different logic (for example, retrieving by query id
# should check for query parameters and shouldn't cache the result).
should_cache = query_result_id is not None
if query_result_id is None and query_id is not None:
query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
if query:
query_result_id = query.latest_query_data_id

parameter_values = collect_parameters_from_request(request.args)
max_age = int(request.args.get('maxAge', 0))

query_result = None

if query_result_id:
query_result = get_object_or_404(models.QueryResult.get_by_id_and_org, query_result_id, self.current_org)
else:
query_result = None
elif query_id is not None:
query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)

if query is not None:
if settings.ALLOW_PARAMETERS_IN_EMBEDS and parameter_values:
query_result = run_query_sync(query.data_source, parameter_values, query.to_dict()['query'], max_age=max_age)
elif query.latest_query_data_id is not None:
query_result = get_object_or_404(models.QueryResult.get_by_id_and_org, query.latest_query_data_id, self.current_org)

if query_result:
require_access(query_result.data_source.groups, self.current_user, view_only)
Expand Down Expand Up @@ -209,4 +266,3 @@ def delete(self, job_id):
"""
job = QueryTask(job_id=job_id)
job.cancel()

0 comments on commit 70292c8

Please sign in to comment.