Skip to content

Commit

Permalink
Merge pull request #405 from EverythingMe/feature/syntax_highglight
Browse files Browse the repository at this point in the history
Feature: use correct syntax highlighting for Python/Mongo data sources
  • Loading branch information
arikfr committed Apr 14, 2015
2 parents d0d4101 + e32b709 commit 73de936
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions rd_ui/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<script src="/bower_components/codemirror/addon/hint/show-hint.js"></script>
<script src="/bower_components/codemirror/addon/hint/anyword-hint.js"></script>
<script src="/bower_components/codemirror/mode/sql/sql.js"></script>
<script src="/bower_components/codemirror/mode/python/python.js"></script>
<script src="/bower_components/codemirror/mode/javascript/javascript.js"></script>
<script src="/bower_components/highcharts/highcharts.js"></script>
<script src="/bower_components/highcharts/modules/exporting.js"></script>
Expand Down
3 changes: 3 additions & 0 deletions rd_ui/app/scripts/controllers/query_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
$scope.queryResult = $scope.query.getQueryResult(maxAge, parameters);
}

$scope.dataSource = {};
$scope.query = $route.current.locals.query;

var updateSchema = function() {
Expand Down Expand Up @@ -50,6 +51,7 @@
$scope.dataSources = DataSource.get(function(dataSources) {
updateSchema();
$scope.query.data_source_id = $scope.query.data_source_id || dataSources[0].id;
$scope.dataSource = _.find(dataSources, function(ds) { return ds.id == $scope.query.data_source_id; });
});

// in view mode, latest dataset is always visible
Expand Down Expand Up @@ -149,6 +151,7 @@
}

updateSchema();
$scope.dataSource = _.find($scope.dataSources, function(ds) { return ds.id == $scope.query.data_source_id; });
$scope.executeQuery();
};

Expand Down
17 changes: 15 additions & 2 deletions rd_ui/app/scripts/directives/query_directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,23 @@
scope: {
'query': '=',
'lock': '=',
'schema': '='
'schema': '=',
'syntax': '='
},
template: '<textarea></textarea>',
link: {
pre: function ($scope, element) {
$scope.syntax = $scope.syntax || 'sql';

var modes = {
'sql': 'text/x-sql',
'python': 'text/x-python',
'json': 'application/json'
};

var textarea = element.children()[0];
var editorOptions = {
mode: 'text/x-sql',
mode: modes[$scope.syntax],
lineWrapping: true,
lineNumbers: true,
readOnly: false,
Expand Down Expand Up @@ -130,6 +139,10 @@
}
});

$scope.$watch('syntax', function(syntax) {
codemirror.setOption('mode', modes[syntax]);
});

$scope.$watch('lock', function (locked) {
var readOnly = locked ? 'nocursor' : false;
codemirror.setOption('readOnly', readOnly);
Expand Down
2 changes: 1 addition & 1 deletion rd_ui/app/views/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ <h2>
</p>

<p>
<query-editor query="query" schema="schema" lock="queryFormatting"></query-editor>
<query-editor query="query" schema="schema" syntax="dataSource.syntax" lock="queryFormatting"></query-editor>
</p>
</div>
</div>
Expand Down
9 changes: 7 additions & 2 deletions redash/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ def to_dict(self):
return {
'id': self.id,
'name': self.name,
'type': self.type
'type': self.type,
'syntax': self.query_runner.syntax
}

def get_schema(self, refresh=False):
Expand All @@ -250,7 +251,7 @@ def get_schema(self, refresh=False):
cache = redis_connection.get(key)

if cache is None:
query_runner = get_query_runner(self.type, self.options)
query_runner = self.query_runner
schema = sorted(query_runner.get_schema(), key=lambda t: t['name'])

redis_connection.set(key, json.dumps(schema))
Expand All @@ -259,6 +260,10 @@ def get_schema(self, refresh=False):

return schema

@property
def query_runner(self):
return get_query_runner(self.type, self.options)

@classmethod
def all(cls):
return cls.select().order_by(cls.id.asc())
Expand Down
1 change: 1 addition & 0 deletions redash/query_runner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
class BaseQueryRunner(object):
def __init__(self, configuration):
jsonschema.validate(configuration, self.configuration_schema())
self.syntax = 'sql'
self.configuration = configuration

@classmethod
Expand Down
2 changes: 2 additions & 0 deletions redash/query_runner/mongodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ def annotate_query(cls):
def __init__(self, configuration_json):
super(MongoDB, self).__init__(configuration_json)

self.syntax = 'json'

self.db_name = self.configuration["dbName"]

self.is_replica_set = True if "replicaSetName" in self.configuration and self.configuration["replicaSetName"] else False
Expand Down
18 changes: 14 additions & 4 deletions redash/query_runner/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@

ALLOWED_MODULES = {}

# Custom hooks which controls the way objects/lists/tuples/dicts behave in
# RestrictedPython

def custom_write(obj):
"""
Custom hooks which controls the way objects/lists/tuples/dicts behave in
RestrictedPython
"""
return obj


def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
if name in ALLOWED_MODULES:
m = None
Expand All @@ -32,6 +36,7 @@ def custom_import(name, globals=None, locals=None, fromlist=(), level=0):

raise Exception("'{0}' is not configured as a supported import module".format(name))


def get_query_result(query_id):
try:
query = models.Query.get_by_id(query_id)
Expand All @@ -46,14 +51,15 @@ def get_query_result(query_id):

return json.loads(query.latest_query_data.data)


def execute_query(data_source_name_or_id, query):
try:
if type(data_source_name) == int:
if type(data_source_name_or_id) == int:
data_source = models.DataSource.get_by_id(data_source_name_or_id)
else:
data_source = models.DataSource.get(models.DataSource.name==data_source_name_or_id)
except models.DataSource.DoesNotExist:
raise Exception("Wrong data source name: %s." % data_source_name)
raise Exception("Wrong data source name/id: %s." % data_source_name_or_id)

query_runner = get_query_runner(data_source.type, data_source.options)

Expand All @@ -64,6 +70,7 @@ def execute_query(data_source_name_or_id, query):
# TODO: allow avoiding the json.dumps/loads in same process
return json.loads(data)


def add_result_column(result, column_name, friendly_name, column_type):
""" Helper function to add columns inside a Python script running in re:dash in an easier way """
if column_type not in SUPPORTED_COLUMN_TYPES:
Expand All @@ -78,6 +85,7 @@ def add_result_column(result, column_name, friendly_name, column_type):
"type" : column_type
})


def add_result_row(result, values):
if not "rows" in result:
result["rows"] = []
Expand Down Expand Up @@ -114,6 +122,8 @@ def __init__(self, configuration_json):

super(Python, self).__init__(configuration_json)

self.syntax = "python"

if self.configuration.get("allowedImportModules", None):
for item in self.configuration["allowedImportModules"].split(","):
ALLOWED_MODULES[item] = None
Expand Down

0 comments on commit 73de936

Please sign in to comment.