Skip to content

Commit

Permalink
Expose data source version info in UI
Browse files Browse the repository at this point in the history
  • Loading branch information
alison985 authored and Allen Short committed Feb 22, 2018
1 parent c65b637 commit c603465
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 1 deletion.
21 changes: 21 additions & 0 deletions client/app/pages/data-sources/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,32 @@ function DataSourceCtrl(
});
}

function getDataSourceVersion(callback) {
Events.record('test', 'data_source_version', $scope.dataSource.id);

DataSource.version({ id: $scope.dataSource.id }, (httpResponse) => {
if (httpResponse.ok) {
const versionNumber = httpResponse.message;
toastr.success(`Success. Version: ${versionNumber}`);
} else {
toastr.error(httpResponse.message, 'Version Test Failed:', { timeOut: 10000 });
}
callback();
}, (httpResponse) => {
logger('Failed to get data source version: ', httpResponse.status, httpResponse.statusText, httpResponse);
toastr.error('Unknown error occurred while performing data source version test. Please try again later.', 'Data Source Version Test Failed:', { timeOut: 10000 });
callback();
});
}

$scope.actions = [
{ name: 'Delete', class: 'btn-danger', callback: deleteDataSource },
{
name: 'Test Connection', class: 'btn-default pull-right', callback: testConnection, disableWhenDirty: true,
},
{
name: 'Test Data Source Version', class: 'btn-default', callback: getDataSourceVersion, disableWhenDirty: true,
},
];
}

Expand Down
19 changes: 19 additions & 0 deletions client/app/pages/queries/get-data-source-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function GetDataSourceVersionCtrl(Events, toastr, $scope, DataSource, $route) {
'ngInject';

this.getDataSourceVersion = DataSource.version({
id: $route.current.locals.query.data_source_id,
});
}

const GetDataSourceVersionInfo = {
bindings: {
onRefresh: '&',
},
controller: GetDataSourceVersionCtrl,
template: '<span ng-if=\'!$ctrl.getDataSourceVersion.message.includes("no")\'>{{ $ctrl.getDataSourceVersion.message }}</span><span ng-if=\'$ctrl.getDataSourceVersion.message.includes("no")\' class=\'fa fa-exclamation-circle\' data-toggle=\'tooltip\' data-placement=\'right\' tooltip title=\'{{ $ctrl.getDataSourceVersion.message }}\'></span>',
};

export default function (ngModule) {
ngModule.component('getDataSourceVersion', GetDataSourceVersionInfo);
}
1 change: 1 addition & 0 deletions client/app/pages/queries/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ <h3>
{{ds.name}}
</ui-select-choices>
</ui-select>
<get-data-source-version id='data-source-version'></get-data-source-version>
</div>

<div class="editor__left__schema" ng-if="sourceMode">
Expand Down
1 change: 1 addition & 0 deletions client/app/pages/queries/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ function QueryViewCtrl(
$scope.dataSource = find($scope.dataSources, ds => ds.id === $scope.query.data_source_id);
getSchema();
$scope.executeQuery();
document.getElementById('data-source-version').innerHTML = '<span class=\'fa fa-refresh\' data-toggle=\'tooltip\' data-placement=\'right\' tooltip title=\'It seems the data source was changed since the page loaded, refresh page to get version\'></span>';
};

$scope.setVisualizationTab = (visualization) => {
Expand Down
3 changes: 3 additions & 0 deletions client/app/services/data-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ function DataSource($q, $resource, $http) {
isArray: false,
url: 'api/data_sources/:id/test',
},
version: {
method: 'GET', cache: false, isArray: false, url: 'api/data_sources/:id/version',
},
};

const DataSourceResource = $resource('api/data_sources/:id', { id: '@id' }, actions);
Expand Down
24 changes: 24 additions & 0 deletions redash/cli/data_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,30 @@ def test(name, organization='default'):
print("Couldn't find data source named: {}".format(name))
exit(1)

@manager.command()
@click.argument('name')
@click.option('--org', 'organization', default='default',
help="The organization the user belongs to "
"(leave blank for 'default').")
def get_data_source_version(name, organization='default'):
"""Get version of data source connection by issuing a trivial query."""
try:
org = models.Organization.get_by_slug(organization)
data_source = models.DataSource.query.filter(
models.DataSource.name == name,
models.DataSource.org == org).one()
print("Testing get connection data source version: {} (id={})".format(
name, data_source.id))
try:
info = data_source.query_runner.get_data_source_version()
except Exception as e:
print("Failure: {}".format(e))
exit(1)
else:
print(info)
except NoResultFound:
print("Couldn't find data source named: {}".format(name))
exit(1)

@manager.command()
@click.argument('name', default=None, required=False)
Expand Down
3 changes: 2 additions & 1 deletion redash/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from redash.handlers.permissions import ObjectPermissionsListResource, CheckPermissionResource
from redash.handlers.alerts import AlertResource, AlertListResource, AlertSubscriptionListResource, AlertSubscriptionResource
from redash.handlers.dashboards import DashboardListResource, RecentDashboardsResource, DashboardResource, DashboardShareResource, PublicDashboardResource
from redash.handlers.data_sources import DataSourceTypeListResource, DataSourceListResource, DataSourceSchemaResource, DataSourceResource, DataSourcePauseResource, DataSourceTestResource
from redash.handlers.data_sources import DataSourceTypeListResource, DataSourceListResource, DataSourceSchemaResource, DataSourceResource, DataSourcePauseResource, DataSourceTestResource, DataSourceVersionResource
from redash.handlers.events import EventsResource
from redash.handlers.queries import QueryForkResource, QueryRefreshResource, QueryListResource, QueryRecentResource, QuerySearchResource, QueryResource, MyQueriesResource
from redash.handlers.query_results import QueryResultListResource, QueryResultResource, JobResource
Expand Down Expand Up @@ -56,6 +56,7 @@ def json_representation(data, code, headers=None):
api.add_org_resource(DataSourceSchemaResource, '/api/data_sources/<data_source_id>/schema')
api.add_org_resource(DataSourcePauseResource, '/api/data_sources/<data_source_id>/pause')
api.add_org_resource(DataSourceTestResource, '/api/data_sources/<data_source_id>/test')
api.add_org_resource(DataSourceVersionResource, '/api/data_sources/<data_source_id>/version')
api.add_org_resource(DataSourceResource, '/api/data_sources/<data_source_id>', endpoint='data_source')

api.add_org_resource(GroupListResource, '/api/groups', endpoint='groups')
Expand Down
13 changes: 13 additions & 0 deletions redash/handlers/data_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,16 @@ def post(self, data_source_id):
return {"message": unicode(e), "ok": False}
else:
return {"message": "success", "ok": True}

class DataSourceVersionResource(BaseResource):
def get(self, data_source_id):
data_source = get_object_or_404(models.DataSource.get_by_id_and_org, data_source_id, self.current_org)
require_access(data_source.groups, self.current_user, view_only)
try:
version_info = data_source.query_runner.get_data_source_version()
except Exception as e:
return {"message": unicode(e), "ok": False}
else:
return {"message": version_info, "ok": True}


23 changes: 23 additions & 0 deletions redash/query_runner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class NotSupported(Exception):

class BaseQueryRunner(object):
noop_query = None
data_source_version_query = None

def __init__(self, configuration):
self.syntax = 'sql'
Expand All @@ -76,6 +77,28 @@ def annotate_query(cls):
def configuration_schema(cls):
return {}

def get_data_source_version(self):
if self.data_source_version_query is None:
raise NotImplementedError
data, error = self.run_query(self.data_source_version_query, None)

if error is not None:
raise Exception(error)

try:
version = json.loads(data)['rows'][0]['version']
except KeyError as e:
raise Exception(e)

if self.data_source_version_post_process == "split by space take second":
version = version.split(" ")[1]
elif self.data_source_version_post_process == "split by space take last":
version = version.split(" ")[-1]
elif self.data_source_version_post_process == "none":
version = version

return version

def test_connection(self):
if self.noop_query is None:
raise NotImplementedError()
Expand Down
2 changes: 2 additions & 0 deletions redash/query_runner/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

class Mysql(BaseSQLQueryRunner):
noop_query = "SELECT 1"
data_source_version_query = "select version()"
data_source_version_post_process = "none"

@classmethod
def configuration_schema(cls):
Expand Down
5 changes: 5 additions & 0 deletions redash/query_runner/pg.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def _wait(conn, timeout=None):

class PostgreSQL(BaseSQLQueryRunner):
noop_query = "SELECT 1"
data_source_version_query = "select version()"
data_source_version_post_process = "split by space take second"

@classmethod
def configuration_schema(cls):
Expand Down Expand Up @@ -179,6 +181,9 @@ def run_query(self, query, user):


class Redshift(PostgreSQL):
data_source_version_query = "select version()"
data_source_version_post_process = "split by space take last"

@classmethod
def type(cls):
return "redshift"
Expand Down

0 comments on commit c603465

Please sign in to comment.