Skip to content

Commit

Permalink
Fixes + temp remove validation for Query param
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrieldutra committed Feb 20, 2020
1 parent 137aa22 commit bb0d783
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 57 deletions.
3 changes: 2 additions & 1 deletion client/app/components/QueryBasedParameterInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ export default class QueryBasedParameterInput extends React.Component {
}

componentDidUpdate(prevProps) {
if (this.props.queryId !== prevProps.queryId) {
if (this.props.queryId !== prevProps.queryId || this.props.parameter !== prevProps.parameter) {
this._loadOptions(this.props.queryId);
}

if (this.props.value !== prevProps.value) {
this.setValue(this.props.value);
}
Expand Down
32 changes: 18 additions & 14 deletions client/app/services/parameters/QueryBasedDropdownParameter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isNull, isUndefined, isArray, isEmpty, isString, get, map, join, has, toString } from "lodash";
import { isNull, isUndefined, isArray, isEmpty, get, map, join, has, toString } from "lodash";
import { Query } from "@/services/query";
import QueryResult from "@/services/query-result";
import Parameter from "./Parameter";
Expand Down Expand Up @@ -47,11 +47,7 @@ class QueryBasedDropdownParameter extends Parameter {
const parameterValues = map(this.value, v => `${prefix}${v}${suffix}`);
return join(parameterValues, separator);
}
const executionParamValues = { ...this.staticParams };
if (isString(this.searchColumn)) {
executionParamValues[this.searchColumn] = this.searchTerm;
}
return !isEmpty(executionParamValues) ? { value: this.value, executionParamValues } : this.value;
return this.value;
}

toUrlParams() {
Expand Down Expand Up @@ -99,9 +95,10 @@ class QueryBasedDropdownParameter extends Parameter {

loadDropdownValues() {
return Query.get({ id: this.queryId }).then(query => {
if (query.hasParameters()) {
const queryHasParameters = query.hasParameters();
if (queryHasParameters && this.searchColumn) {
this.searchFunction = searchTerm =>
QueryResult.getByQueryId(query.id, { ...this.staticParams, search: searchTerm }, -1)
QueryResult.getByQueryId(query.id, { ...this.staticParams, [this.searchColumn]: searchTerm }, -1)
.toPromise()
.then(result => {
this.searchTerm = searchTerm;
Expand All @@ -110,13 +107,20 @@ class QueryBasedDropdownParameter extends Parameter {
.then(mapOptionValuesToString);
return this.searchTerm ? this.searchFunction(this.searchTerm) : Promise.resolve([]);
} else {
if (this.parentQueryId) {
return Query.associatedDropdown({ queryId: this.parentQueryId, dropdownQueryId: this.queryId }).then(
mapOptionValuesToString
);
}
return Query.asDropdown({ id: this.queryId }).then(mapOptionValuesToString);
this.searchFunction = null;
}

if (queryHasParameters) {
return QueryResult.getByQueryId(query.id, { ...this.staticParams }, -1)
.toPromise()
.then(result => get(result, "query_result.data.rows"))
.then(mapOptionValuesToString);
} else if (this.parentQueryId) {
return Query.associatedDropdown({ queryId: this.parentQueryId, dropdownQueryId: this.queryId }).then(
mapOptionValuesToString
);
}
return Query.asDropdown({ id: this.queryId }).then(mapOptionValuesToString);
});
}
}
Expand Down
65 changes: 23 additions & 42 deletions redash/models/parameterized_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,43 @@ def _pluck_name_and_value(default_column, row):
return {"name": row[name_column], "value": str(row[value_column])}


def _load_result(query_id, org, parameters = None):
def _load_result(query_id, org):
from redash import models

query = models.Query.get_by_id_and_org(query_id, org)

if query.data_source:
if parameters:
param_query = query.parameterized
param_query.apply(parameters)
query_result = models.QueryResult.get_latest(query.data_source, param_query.text, -1)
else:
query_result = models.QueryResult.get_by_id_and_org(
query.latest_query_data_id, org
)
query_result = models.QueryResult.get_by_id_and_org(
query.latest_query_data_id, org
)
return query_result.data
else:
raise QueryDetachedFromDataSourceError(query_id)


def dropdown_values(query_id, org, parameters=None):
data = _load_result(query_id, org, parameters)
def dropdown_values(query_id, org):
data = _load_result(query_id, org)
first_column = data["columns"][0]["name"]
pluck = partial(_pluck_name_and_value, first_column)
return list(map(pluck, data["rows"]))


def join_parameter_list_value(value, key, schema):
definition = next(
(definition for definition in schema if definition["name"] == key), {}
)
multi_values_options = definition.get("multiValuesOptions", {})
separator = str(multi_values_options.get("separator", ","))
prefix = str(multi_values_options.get("prefix", ""))
suffix = str(multi_values_options.get("suffix", ""))
return separator.join(
[prefix + v + suffix for v in value]
)

def resolve_parameter_values(parameters, schema):
def join_parameter_list_values(parameters, schema):
updated_parameters = {}
for (key, value) in parameters.items():
if isinstance(value, dict) and "value" in value:
value = value["value"]
updated_parameters[key] = join_parameter_list_value(value, key, schema) if isinstance(value, list) else value
if isinstance(value, list):
definition = next(
(definition for definition in schema if definition["name"] == key), {}
)
multi_values_options = definition.get("multiValuesOptions", {})
separator = str(multi_values_options.get("separator", ","))
prefix = str(multi_values_options.get("prefix", ""))
suffix = str(multi_values_options.get("suffix", ""))
updated_parameters[key] = separator.join(
[prefix + v + suffix for v in value]
)
else:
updated_parameters[key] = value
return updated_parameters


Expand All @@ -83,7 +76,7 @@ def _collect_query_parameters(query):
def _parameter_names(parameter_values):
names = []
for key, value in parameter_values.items():
if isinstance(value, dict) and ("start" in value or "end" in value):
if isinstance(value, dict):
for inner_key in value.keys():
names.append("{}.{}".format(key, inner_key))
else:
Expand Down Expand Up @@ -141,7 +134,7 @@ def apply(self, parameters):
else:
self.parameters.update(parameters)
self.query = mustache_render(
self.template, resolve_parameter_values(parameters, self.schema)
self.template, join_parameter_list_values(parameters, self.schema)
)

return self
Expand All @@ -165,25 +158,13 @@ def _valid(self, name, value):
if isinstance(enum_options, str):
enum_options = enum_options.split("\n")

if definition.get("type") == "query":
if isinstance(value, dict) and "executionParamValues" in value:
query_based_with_parameter = True
dpd_values = [v["value"] for v in dropdown_values(query_id, self.org, value["executionParamValues"])]
else:
query_based_with_parameter = False
dpd_values = [v["value"] for v in dropdown_values(query_id, self.org)]

validators = {
"text": lambda value: isinstance(value, str),
"number": _is_number,
"enum": lambda value: _is_value_within_options(
value, enum_options, allow_multiple_values
),
"query": lambda value: _is_value_within_options(
value["value"] if query_based_with_parameter else value,
dpd_values,
allow_multiple_values,
),
"query": lambda value: True,
"date": _is_date,
"datetime-local": _is_date,
"datetime-with-seconds": _is_date,
Expand Down

0 comments on commit bb0d783

Please sign in to comment.