Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Add UDF Section #752

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/app.components.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import './scripts/services/health';
import './scripts/services/stats';
import './scripts/services/tableinfo';
import './scripts/services/shardinfo';
import './scripts/services/udfinfo';
import './scripts/services/viewinfo';
import './scripts/services/nodeinfo';
import './scripts/services/checks';
Expand All @@ -20,6 +21,7 @@ import './scripts/controllers/feed';
import './scripts/controllers/overview';
import './scripts/controllers/console';
import './scripts/controllers/tables';
import './scripts/controllers/udfs';
import './scripts/controllers/views';
import './scripts/controllers/cluster';

Expand Down
12 changes: 12 additions & 0 deletions app/app.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var MODULES = [
'console',
'tables',
'tableinfo',
'udfs',
'udfinfo',
'views',
'viewinfo',
'shardinfo',
Expand Down Expand Up @@ -53,6 +55,16 @@ var ROUTING = {
'url': '/:table_schema/:table_name',
'template': '<table-detail>',
},
'/udfs': {
'name': 'udfs',
'url': '/udfs',
'template': '<udfs>',
},
'/udfs/:schema/:name': {
'name': 'udfs.udf',
'url': '/:schema/:name',
'template': '<udf-detail>',
},
'/views': {
'name': 'views',
'url': '/views',
Expand Down
6 changes: 4 additions & 2 deletions app/scripts/controllers/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,17 @@ commons.run(function(NavigationService, $translate, $filter, $rootScope) {
NavigationService.addNavBarElement('static/assets/icon-console.svg', $filter('translate', 'NAVIGATION.CONSOLE'), '/console', 20, "console");
NavigationService.addNavBarElement('static/assets/icon-table.svg', $filter('translate', 'NAVIGATION.TABLE'), '/tables', 30, "tables");
NavigationService.addNavBarElement('static/assets/icon-view.svg', $filter('translate', 'NAVIGATION.VIEW'), '/views', 40, "views");
NavigationService.addNavBarElement('static/assets/icon-cluster.svg', $filter('translate', 'NAVIGATION.CLUSTER'), '/nodes', 50, "nodes");
NavigationService.addNavBarElement('static/assets/icon-monitoring.svg', $filter('translate', 'NAVIGATION.UDF'), '/udfs', 50, "udfs");
NavigationService.addNavBarElement('static/assets/icon-cluster.svg', $filter('translate', 'NAVIGATION.CLUSTER'), '/nodes', 60, "nodes");

// Update Navbar Elements if Language is Changed
$rootScope.$on('$translateChangeSuccess', function() {
$translate(['NAVIGATION.OVERVIEW', 'NAVIGATION.CONSOLE', 'NAVIGATION.TABLE', 'NAVIGATION.VIEW', 'NAVIGATION.CLUSTER']).then(function(i18n) {
$translate(['NAVIGATION.OVERVIEW', 'NAVIGATION.CONSOLE', 'NAVIGATION.TABLE', 'NAVIGATION.VIEWS', 'NAVIGATION.UDF', 'NAVIGATION.CLUSTER']).then(function(i18n) {
proddata marked this conversation as resolved.
Show resolved Hide resolved
NavigationService.updateNavBarElement('/', i18n['NAVIGATION.OVERVIEW']);
NavigationService.updateNavBarElement('/console', i18n['NAVIGATION.CONSOLE']);
NavigationService.updateNavBarElement('/tables', i18n['NAVIGATION.TABLE']);
NavigationService.updateNavBarElement('/views', i18n['NAVIGATION.VIEW']);
NavigationService.updateNavBarElement('/udfs', i18n['NAVIGATION.UDF']);
NavigationService.updateNavBarElement('/nodes', i18n['NAVIGATION.CLUSTER']);
});
});
Expand Down
260 changes: 260 additions & 0 deletions app/scripts/controllers/udfs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
'use strict';

angular.module('udfs', ['stats', 'sql', 'common', 'udfinfo', 'events'])
.provider('TabNavigationInfo', function () {
this.collapsed = [false, true]; // must match $scope.udfs of TablesController
this.$get = () => {
var collapsed = this.collapsed;
return {
'collapsed': collapsed,
'toggleIndex': (i) => {
collapsed[i] = !collapsed[i];
},
'collapseIndex': (i) => {
collapsed[i] = true;
},
'unCollapseIndex': (i) => {
collapsed[i] = false;
}
};
};
})
.directive('udfs', function () {
return {
restrict: 'E',
replace: true,
scope: {},
templateUrl: 'static/views/udfs.html',
controllerAs: 'UdfsController',
controller: function (ClusterState, $scope, ClusterEventsHandler) {
var hideIfEmpty = () => {
$scope.empty = ClusterState.data.udfs.length === 0;
};

// initial state
hideIfEmpty();

ClusterEventsHandler.register('STATE_REFRESHED', 'UdfsController', hideIfEmpty);

$scope.$on('$destroy', function () {
ClusterEventsHandler.remove('STATE_REFRESHED', 'UdfsController');
});
}
};
})
.directive('udfDetail', function () {
return {
restrict: 'E',
replace: true,
scope: {},
templateUrl: 'static/views/udf-detail.html',
controllerAs: 'UDFDetailController',
controller: function ($scope, $location, $log, $timeout, $state,
SQLQuery, queryResultToObjects, roundWithUnitFilter, bytesFilter, UdfList,
ClusterEventsHandler, ClusterState) {

const NESTED_COL_REGEX = /([^\s]+)(\[\'([^\s]+)\'])+/i;
const COLUMNS_QUERY = 'SELECT quote_ident(column_name) as column_name, upper(data_type) AS column_type ' +
'FROM information_schema.columns ' +
'WHERE table_schema = ? AND table_name = ?';

$scope.executeQuery = (query) => {
$location.search({'query': query});
$location.path('/console');
};

// sidebar button handler (mobile udf)
$scope.toggleSidebar = function () {
$('#page-viewport')
.toggleClass('show-sidebar');
$('.menu-toggle i.fa')
.toggleClass('fa-angle-double-right')
.toggleClass('fa-angle-double-left');
};

// bind tooltips
$('[rel=tooltip]').tooltip({
placement: 'top'
});

var isNestedColumn = (col) => col.match(NESTED_COL_REGEX);

var constructQuery = (schema, name, rows) => {
var query = 'CREATE OR REPLACE FUNCTION "' + schema + '"."' + name + '"';
query += '\nRETURNS ';
query += '\nLANGUAGE ' + 'JAVASCRIPT';
query += '\nAS ';
query += '\n\'' + 'function';
query += '\n\';';
return query;
};

var render = (schema, name) => {
$scope.nothingSelected = false;
$scope.renderSiderbar = true;

if (schema && name) {
SQLQuery.execute(COLUMNS_QUERY, [schema, name], false, false, false, false)
.then((q) => {
$scope.columns = queryResultToObjects(q, q.cols);
$scope.query = constructQuery(schema, name, $scope.columns);
}, () => {
$scope.columns = [];
});
}
};

var updateUDF = () => {
var name = $state.params.name;
var schema = $state.params.schema;
var udfs = ClusterState.data.udfs;

var hasUdfs = udfs.length > 0;
$scope.renderSidebar = hasUdfs;
$scope.nothingSelected = !hasUdfs;
if (hasUdfs) {
var current = udfs.filter((o) => o.name == name && o.schema == schema);
current = current.length ? current[0] : udfs[0];
$scope.udf = current;
$scope.udf.label = current.schema + '.' + current.name;

} else {
$scope.udf = null;
$scope.columns = [];
}
};

ClusterEventsHandler.register('STATE_REFRESHED',
'UDFDetailController',
updateUDF);

$scope.$on('$destroy', function () {
ClusterEventsHandler.remove('STATE_REFRESHED', 'UDFDetailController');
});

updateUDF();
render($state.params.schema, $state.params.name);
}
};
})
.directive('udfList', function () {
return {
restrict: 'E',
replace: true,
scope: {},
templateUrl: 'static/views/udflist.html',
controllerAs: 'UdfListController',
controller: function ($scope, $state, TabNavigationInfo, ClusterEventsHandler, ClusterState) {
$scope.collapsed = true;

$scope.udfFilter = (item) => {
return (!$scope.search || (item.fqn.toLowerCase().indexOf($scope.search) != -1));
};

$scope.clearFilter = function () {
$scope.search = '';
};

$scope.isActive = (schema, name) => {
return name === $state.params.name && schema === $state.params.schema;
};

var toggleClasses = (i) => {
$('#nav-tabs-' + i)
.collapse('toggle');
$('#nav-tabs-header-' + i + ' i.fa')
.toggleClass('fa-caret-down')
.toggleClass('fa-caret-right');
};

$scope.toggleElements = (i) => {
toggleClasses(i);
TabNavigationInfo.toggleIndex(i);
};

$scope.isCollapsed = (i) => {
return TabNavigationInfo.collapsed[i];
};

$scope.collapseAll = () => {
var idx;
for (idx in $scope.udfs) {
toggleClasses(idx);
TabNavigationInfo.collapseIndex(idx);
}
$scope.collapsed = true;
};

$scope.unCollapseAll = () => {
var idx;
for (idx in $scope.udfs) {
toggleClasses(idx);
TabNavigationInfo.unCollapseIndex(idx);
}
$scope.collapsed = false;
};

var filterBySchemaName = (schema) => (o) => o.schema === schema;

var updateUdfList = () => {
var udfs = ClusterState.data.udfs;
var hasUdfs = udfs.length > 0;
$scope.renderSidebar = hasUdfs;
$scope.udfs = [];
if (hasUdfs) {
// use name and schema from first item
if (!$scope.name || !$scope.schema) {
$scope.schema = udfs[0].schema;
$scope.name = udfs[0].name;
$state.go('udfs.udf', {
schema: $scope.schema,
name: $scope.name
});
}

var idx,
name;
var customSchemas = [];
for (idx in udfs) {
name = udfs[idx].schema;
if (name == 'doc' || name == 'blob' || customSchemas.indexOf(name) > -1) {
continue;
}
customSchemas.push(name);
}

$scope.udfs.push({
display_name: 'Doc',
udfs: udfs.filter(filterBySchemaName('doc')),
schema: 'doc'
});
for (idx in customSchemas) {
name = customSchemas[idx];
$scope.udfs.push({
display_name: name,
udfs: udfs.filter(filterBySchemaName(name)),
schema: name
});
}
}
};

var render = (schema, name) => {
$scope.name = name;
$scope.schema = schema;
$scope.renderSidebar = true;
};

ClusterEventsHandler.register('STATE_REFRESHED',
'UdfListController',
updateUdfList);

$scope.$on('$destroy', function () {
ClusterEventsHandler.remove('STATE_REFRESHED', 'UdfListController');
});

updateUdfList();
render($state.params.schema, $state.params.name);
}
};
});
9 changes: 7 additions & 2 deletions app/scripts/services/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import './clusterEventsHandler';

const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo', 'events'])
.factory('ClusterState', function ($http, $interval, $timeout, $log, $q, $rootScope,
baseURI, SQLQuery, queryResultToObjects, TableList, Health, ShardInfo, NodeInfo, ViewInfo, ViewList, ClusterEventsHandler) {
baseURI, SQLQuery, queryResultToObjects, TableList, Health, ShardInfo, NodeInfo, UdfInfo, UdfList, ViewInfo, ViewList, ClusterEventsHandler) {
var reachabilityInterval,
ClusterStateInterval;

Expand All @@ -20,6 +20,7 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo',
var data = {
online: true,
tables: [],
udfs: [],
views: [],
shards: [],
partitions: [],
Expand Down Expand Up @@ -166,6 +167,7 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo',
ShardInfo.executeRecoveryStmt(),
NodeInfo.executeClusterQuery(),
NodeInfo.executeNodeQuery(),
UdfInfo.executeUdfStmt(),
ViewInfo.executeViewStmt()
]).then(function (values) {

Expand Down Expand Up @@ -213,7 +215,10 @@ const stats = angular.module('stats', ['sql', 'health', 'tableinfo', 'nodeinfo',
data.tables = tableinfo.data.tables;
}

var viewInfo = ViewList.execute(values[6]);
var udfInfo = UdfList.execute(values[6]);
data.udfs = udfInfo.data.udfs;

var viewInfo = ViewList.execute(values[7]);
data.views = viewInfo.data.views;

ClusterEventsHandler.trigger('STATE_REFRESHED');
Expand Down
Loading