|
@@ -67,10 +67,10 @@ ${ assist.assistPanel() }
|
|
|
<a href="${url('metastore:databases')}">${_('Databases')}</a><span class="divider">></span>
|
|
<a href="${url('metastore:databases')}">${_('Databases')}</a><span class="divider">></span>
|
|
|
</li>
|
|
</li>
|
|
|
<li>
|
|
<li>
|
|
|
- <a data-bind="text: activeDatabase, attr: { href: '/metastore/tables/' + activeDatabase() }"></a><span class="divider">></span>
|
|
|
|
|
|
|
+ <a data-bind="text: database.name, attr: { href: '/metastore/tables/' + name }"></a><span class="divider">></span>
|
|
|
</li>
|
|
</li>
|
|
|
<li>
|
|
<li>
|
|
|
- <span style="padding-left:12px" data-bind="text: activeTable"></span>
|
|
|
|
|
|
|
+ <span style="padding-left:12px" data-bind="text: name"></span>
|
|
|
</li>
|
|
</li>
|
|
|
</ul>
|
|
</ul>
|
|
|
</script>
|
|
</script>
|
|
@@ -98,11 +98,11 @@ ${ assist.assistPanel() }
|
|
|
alwaysActive: true,
|
|
alwaysActive: true,
|
|
|
statsVisible: true,
|
|
statsVisible: true,
|
|
|
sourceType: 'hive',
|
|
sourceType: 'hive',
|
|
|
- databaseName: $root.activeDatabase(),
|
|
|
|
|
- tableName: $root.activeTable(),
|
|
|
|
|
|
|
+ databaseName: table.database.name,
|
|
|
|
|
+ tableName: table.name,
|
|
|
columnName: name,
|
|
columnName: name,
|
|
|
fieldType: type,
|
|
fieldType: type,
|
|
|
- assistHelper: $root.assistHelper
|
|
|
|
|
|
|
+ assistHelper: table.assistHelper
|
|
|
} }"></span>
|
|
} }"></span>
|
|
|
</td>
|
|
</td>
|
|
|
<td class="pointer" data-bind="click: function() { favourite(!favourite()) }"><i style="color: #338bb8" class="fa" data-bind="css: {'fa-star': favourite, 'fa-star-o': !favourite() }"></i></td>
|
|
<td class="pointer" data-bind="click: function() { favourite(!favourite()) }"><i style="color: #338bb8" class="fa" data-bind="css: {'fa-star': favourite, 'fa-star-o': !favourite() }"></i></td>
|
|
@@ -189,11 +189,11 @@ ${ assist.assistPanel() }
|
|
|
<script type="text/html" id="metastore-table-stats">
|
|
<script type="text/html" id="metastore-table-stats">
|
|
|
<!-- ko with: tableDetails -->
|
|
<!-- ko with: tableDetails -->
|
|
|
<h4>${ _('Stats') }
|
|
<h4>${ _('Stats') }
|
|
|
- <!-- ko if: $root.refreshingTableStats -->
|
|
|
|
|
|
|
+ <!-- ko if: $parent.refreshingTableStats -->
|
|
|
<i class="fa fa-refresh fa-spin"></i>
|
|
<i class="fa fa-refresh fa-spin"></i>
|
|
|
<!-- /ko -->
|
|
<!-- /ko -->
|
|
|
- <!-- ko ifnot: $root.refreshingTableStats -->
|
|
|
|
|
- <a class="pointer" href="javascript: void(0);" data-bind="click: $root.refreshTableStats"><i class="fa fa-refresh"></i></a>
|
|
|
|
|
|
|
+ <!-- ko ifnot: $parent.refreshingTableStats -->
|
|
|
|
|
+ <a class="pointer" href="javascript: void(0);" data-bind="click: $parent.refreshTableStats"><i class="fa fa-refresh"></i></a>
|
|
|
<!-- /ko -->
|
|
<!-- /ko -->
|
|
|
<span data-bind="visible: ! details.stats.COLUMN_STATS_ACCURATE" rel="tooltip" data-placement="top" title="${ _('The column stats for this table are not accurate') }"><i class="fa fa-exclamation-triangle"></i></span>
|
|
<span data-bind="visible: ! details.stats.COLUMN_STATS_ACCURATE" rel="tooltip" data-placement="top" title="${ _('The column stats for this table are not accurate') }"><i class="fa fa-exclamation-triangle"></i></span>
|
|
|
</h4>
|
|
</h4>
|
|
@@ -211,7 +211,7 @@ ${ assist.assistPanel() }
|
|
|
|
|
|
|
|
<div class="span6">
|
|
<div class="span6">
|
|
|
<div><a data-bind="attr: {'href': hdfs_link, 'rel': path_location }"><i class="fa fa-fw fa-hdd-o"></i> ${_('Location')}</a></div>
|
|
<div><a data-bind="attr: {'href': hdfs_link, 'rel': path_location }"><i class="fa fa-fw fa-hdd-o"></i> ${_('Location')}</a></div>
|
|
|
- <!-- ko with: $root.tableStats -->
|
|
|
|
|
|
|
+ <!-- ko with: $parent.tableStats -->
|
|
|
<div title="${ _('Number of files') }"><i class="fa fa-fw fa-files-o muted"></i> <span data-bind="text: numFiles"></span></div>
|
|
<div title="${ _('Number of files') }"><i class="fa fa-fw fa-files-o muted"></i> <span data-bind="text: numFiles"></span></div>
|
|
|
<div title="${ _('Number of rows') }"><i class="fa fa-fw fa-list muted"></i> <span data-bind="text: numRows"></span></div>
|
|
<div title="${ _('Number of rows') }"><i class="fa fa-fw fa-list muted"></i> <span data-bind="text: numRows"></span></div>
|
|
|
<div title="${ _('Total size') }"><i class="fa fa-fw fa-tasks muted"></i> <span data-bind="text: totalSize"></span></div>
|
|
<div title="${ _('Total size') }"><i class="fa fa-fw fa-tasks muted"></i> <span data-bind="text: totalSize"></span></div>
|
|
@@ -252,7 +252,8 @@ ${ assist.assistPanel() }
|
|
|
</div>
|
|
</div>
|
|
|
<div class="resizer" data-bind="visible: $root.isLeftPanelVisible() && $root.assistAvailable(), splitDraggable : { appName: 'notebook', leftPanelVisible: $root.isLeftPanelVisible }"><div class="resize-bar"> </div></div>
|
|
<div class="resizer" data-bind="visible: $root.isLeftPanelVisible() && $root.assistAvailable(), splitDraggable : { appName: 'notebook', leftPanelVisible: $root.isLeftPanelVisible }"><div class="resize-bar"> </div></div>
|
|
|
<div class="right-panel">
|
|
<div class="right-panel">
|
|
|
-
|
|
|
|
|
|
|
+ <!-- ko with: database -->
|
|
|
|
|
+ <!-- ko with: table -->
|
|
|
<div class="metastore-main">
|
|
<div class="metastore-main">
|
|
|
<h3>
|
|
<h3>
|
|
|
<ul class="nav nav-pills pull-right" style="margin-top: -8px">
|
|
<ul class="nav nav-pills pull-right" style="margin-top: -8px">
|
|
@@ -271,7 +272,7 @@ ${ assist.assistPanel() }
|
|
|
</h3>
|
|
</h3>
|
|
|
<div class="clearfix"></div>
|
|
<div class="clearfix"></div>
|
|
|
|
|
|
|
|
- <span data-bind="editable: tableComment, editableOptions: {enabled: true, placement: 'right', emptytext: 'Add a description...' }" class="editable editable-click editable-empty">Add a description...</span>
|
|
|
|
|
|
|
+ <span data-bind="editable: comment, editableOptions: {enabled: true, placement: 'right', emptytext: 'Add a description...' }" class="editable editable-click editable-empty">Add a description...</span>
|
|
|
|
|
|
|
|
<ul class="nav nav-pills margin-top-30">
|
|
<ul class="nav nav-pills margin-top-30">
|
|
|
<li><a href="#overview" data-toggle="tab">${_('Overview')}</a></li>
|
|
<li><a href="#overview" data-toggle="tab">${_('Overview')}</a></li>
|
|
@@ -333,11 +334,11 @@ ${ assist.assistPanel() }
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
% if table.partition_keys:
|
|
% if table.partition_keys:
|
|
|
- <div class="tile">
|
|
|
|
|
- <h4>${ _('Partitions') }</h4>
|
|
|
|
|
|
|
+ <div class="tile">
|
|
|
|
|
+ <h4>${ _('Partitions') }</h4>
|
|
|
${ partition_column_table(table.partition_keys, "partitionTable", limit=3) }
|
|
${ partition_column_table(table.partition_keys, "partitionTable", limit=3) }
|
|
|
<a class="pointer" data-bind="click: function() { $('li a[href=\'#partitionColumns\']').click(); }">${_('View more...')}</a>
|
|
<a class="pointer" data-bind="click: function() { $('li a[href=\'#partitionColumns\']').click(); }">${_('View more...')}</a>
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div>
|
|
|
% endif
|
|
% endif
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -348,24 +349,24 @@ ${ assist.assistPanel() }
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
% if table.partition_keys:
|
|
% if table.partition_keys:
|
|
|
- <div class="tab-pane" id="partitionColumns">
|
|
|
|
|
- ${ partition_column_table(table.partition_keys, "partitionTable") }
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="tab-pane" id="partitionColumns">
|
|
|
|
|
+ ${ partition_column_table(table.partition_keys, "partitionTable") }
|
|
|
|
|
+ </div>
|
|
|
% endif
|
|
% endif
|
|
|
|
|
|
|
|
% if sample is not None:
|
|
% if sample is not None:
|
|
|
- <div class="tab-pane" id="sample">
|
|
|
|
|
- % if error_message:
|
|
|
|
|
- <div class="alert alert-error">
|
|
|
|
|
- <h3>${_('Error!')}</h3>
|
|
|
|
|
- <pre>${ error_message }</pre>
|
|
|
|
|
|
|
+ <div class="tab-pane" id="sample">
|
|
|
|
|
+ % if error_message:
|
|
|
|
|
+ <div class="alert alert-error">
|
|
|
|
|
+ <h3>${_('Error!')}</h3>
|
|
|
|
|
+ <pre>${ error_message }</pre>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ % else:
|
|
|
|
|
+ <!-- ko with: samples -->
|
|
|
|
|
+ <!-- ko template: 'metastore-samples-table' --><!-- /ko -->
|
|
|
|
|
+ <!-- /ko -->
|
|
|
|
|
+ % endif
|
|
|
</div>
|
|
</div>
|
|
|
- % else:
|
|
|
|
|
- <!-- ko with: samples -->
|
|
|
|
|
- <!-- ko template: 'metastore-samples-table' --><!-- /ko -->
|
|
|
|
|
- <!-- /ko -->
|
|
|
|
|
- % endif
|
|
|
|
|
- </div>
|
|
|
|
|
% endif
|
|
% endif
|
|
|
|
|
|
|
|
<div class="tab-pane" id="permissions">
|
|
<div class="tab-pane" id="permissions">
|
|
@@ -373,21 +374,21 @@ ${ assist.assistPanel() }
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="tab-pane" id="queries">
|
|
<div class="tab-pane" id="queries">
|
|
|
- <i class="fa fa-spinner fa-spin" data-bind="visible: loadingQueries"></i>
|
|
|
|
|
- <table data-bind="visible: !loadingQueries()" class="table table-condensed">
|
|
|
|
|
|
|
+ <i class="fa fa-spinner fa-spin" data-bind="visible: $root.loadingQueries"></i>
|
|
|
|
|
+ <table data-bind="visible: !$root.loadingQueries()" class="table table-condensed">
|
|
|
<thead>
|
|
<thead>
|
|
|
- <tr>
|
|
|
|
|
- <th width="20%">${ _('Name') }</th>
|
|
|
|
|
- <th>${ _('Query') }</th>
|
|
|
|
|
- <th width="20%">${ _('Owner') }</th>
|
|
|
|
|
- </tr>
|
|
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th width="20%">${ _('Name') }</th>
|
|
|
|
|
+ <th>${ _('Query') }</th>
|
|
|
|
|
+ <th width="20%">${ _('Owner') }</th>
|
|
|
|
|
+ </tr>
|
|
|
</thead>
|
|
</thead>
|
|
|
- <tbody data-bind="foreach: queries">
|
|
|
|
|
- <tr class="pointer" data-bind="click: function(){ location.href=doc.absoluteUrl; }">
|
|
|
|
|
- <td data-bind="text: doc.name"></td>
|
|
|
|
|
- <td><code data-bind="text: data.snippets[0].statement_raw"></code></td>
|
|
|
|
|
- <td><code data-bind="text: doc.owner"></code></td>
|
|
|
|
|
- </tr>
|
|
|
|
|
|
|
+ <tbody data-bind="foreach: $root.queries">
|
|
|
|
|
+ <tr class="pointer" data-bind="click: function(){ location.href=doc.absoluteUrl; }">
|
|
|
|
|
+ <td data-bind="text: doc.name"></td>
|
|
|
|
|
+ <td><code data-bind="text: data.snippets[0].statement_raw"></code></td>
|
|
|
|
|
+ <td><code data-bind="text: doc.owner"></code></td>
|
|
|
|
|
+ </tr>
|
|
|
</tbody>
|
|
</tbody>
|
|
|
</table>
|
|
</table>
|
|
|
</div>
|
|
</div>
|
|
@@ -403,11 +404,11 @@ ${ assist.assistPanel() }
|
|
|
<div class="tab-pane" id="properties">
|
|
<div class="tab-pane" id="properties">
|
|
|
<table class="table table-striped table-condensed">
|
|
<table class="table table-striped table-condensed">
|
|
|
<thead>
|
|
<thead>
|
|
|
- <tr>
|
|
|
|
|
- <th>${ _('Name') }</th>
|
|
|
|
|
- <th>${ _('Value') }</th>
|
|
|
|
|
- <th>${ _('Comment') }</th>
|
|
|
|
|
- </tr>
|
|
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th>${ _('Name') }</th>
|
|
|
|
|
+ <th>${ _('Value') }</th>
|
|
|
|
|
+ <th>${ _('Comment') }</th>
|
|
|
|
|
+ </tr>
|
|
|
</thead>
|
|
</thead>
|
|
|
<tbody>
|
|
<tbody>
|
|
|
% for prop in table.properties:
|
|
% for prop in table.properties:
|
|
@@ -416,14 +417,15 @@ ${ assist.assistPanel() }
|
|
|
<td>${ smart_unicode(prop['data_type']) if prop['data_type'] else '' }</td>
|
|
<td>${ smart_unicode(prop['data_type']) if prop['data_type'] else '' }</td>
|
|
|
<td>${ smart_unicode(prop['comment']) if prop['comment'] else '' } </td>
|
|
<td>${ smart_unicode(prop['comment']) if prop['comment'] else '' } </td>
|
|
|
</tr>
|
|
</tr>
|
|
|
- % endfor
|
|
|
|
|
|
|
+ % endfor
|
|
|
</tbody>
|
|
</tbody>
|
|
|
</table>
|
|
</table>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
|
|
+ <!-- /ko -->
|
|
|
|
|
+ <!-- /ko -->
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -504,55 +506,52 @@ ${ assist.assistPanel() }
|
|
|
"ko.hue-bindings"
|
|
"ko.hue-bindings"
|
|
|
], function (ko, charts, AssistHelper) {
|
|
], function (ko, charts, AssistHelper) {
|
|
|
|
|
|
|
|
- function MetastoreColumn(vm, extendedColumn) {
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param {Object} options
|
|
|
|
|
+ * @param {string} options.name
|
|
|
|
|
+ * @param {AssistHelper} options.assistHelper
|
|
|
|
|
+ * @param {string} [options.tableName]
|
|
|
|
|
+ * @param {string} [options.tableComment]
|
|
|
|
|
+ * @constructor
|
|
|
|
|
+ */
|
|
|
|
|
+ function MetastoreDatabase (options) {
|
|
|
var self = this;
|
|
var self = this;
|
|
|
- self.vm = vm;
|
|
|
|
|
- ko.mapping.fromJS(extendedColumn, {}, self);
|
|
|
|
|
-
|
|
|
|
|
- self.favourite = ko.observable(false);
|
|
|
|
|
|
|
+ self.assistHelper = options.assistHelper;
|
|
|
|
|
+ self.name = options.name;
|
|
|
|
|
+
|
|
|
|
|
+ self.table = ko.observable(options.tableName ? new MetastoreTable({
|
|
|
|
|
+ database: self,
|
|
|
|
|
+ name: options.tableName,
|
|
|
|
|
+ comment: options.tableComment,
|
|
|
|
|
+ assistHelper: self.assistHelper
|
|
|
|
|
+ }) : null);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- self.comment.subscribe(function (newValue) {
|
|
|
|
|
- $.post("${ url('metastore:alter_column', database=database, table=table.name) }", {
|
|
|
|
|
- column: self.name(),
|
|
|
|
|
- comment: newValue
|
|
|
|
|
- }, function () {
|
|
|
|
|
- self.vm.assistHelper.clearCache({
|
|
|
|
|
- sourceType: 'hive',
|
|
|
|
|
- databaseName: self.vm.activeDatabase(),
|
|
|
|
|
- tableName: self.vm.activeTable(),
|
|
|
|
|
- fields: []
|
|
|
|
|
- })
|
|
|
|
|
- });
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ MetastoreDatabase.prototype.setTable = function (name) {
|
|
|
|
|
+ var self = this;
|
|
|
|
|
+ if (!self.table() || self.table().name !== name) {
|
|
|
|
|
+ self.table(new MetastoreTable({
|
|
|
|
|
+ database: self,
|
|
|
|
|
+ name: name,
|
|
|
|
|
+ comment: '', // TODO: fetch the comment async in the table
|
|
|
|
|
+ assistHelper: self.assistHelper
|
|
|
|
|
+ }))
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @param {Object} options
|
|
* @param {Object} options
|
|
|
- * @param {Object} options.i18n
|
|
|
|
|
- * @param {string} options.i18n.errorLoadingDatabases
|
|
|
|
|
- * @param {string} options.i18n.errorLoadingTablePreview
|
|
|
|
|
- * @param {string} options.user
|
|
|
|
|
|
|
+ * @param {MetastoreDatabase} options.database
|
|
|
|
|
+ * @param {string} options.name
|
|
|
|
|
+ * @param {string} options.comment
|
|
|
|
|
+ * @param {AssistHelper} options.assistHelper
|
|
|
* @constructor
|
|
* @constructor
|
|
|
*/
|
|
*/
|
|
|
- function MetastoreViewModel(options) {
|
|
|
|
|
|
|
+ function MetastoreTable (options) {
|
|
|
var self = this;
|
|
var self = this;
|
|
|
- self.assistAvailable = ko.observable(true);
|
|
|
|
|
- self.isLeftPanelVisible = ko.observable(self.assistAvailable() && $.totalStorage('spark_left_panel_visible') != null && $.totalStorage('spark_left_panel_visible'));
|
|
|
|
|
-
|
|
|
|
|
- self.activeDatabase = ko.observable('${database}');
|
|
|
|
|
- self.activeTable = ko.observable('${table.name}');
|
|
|
|
|
- self.tableComment = ko.observable();
|
|
|
|
|
-
|
|
|
|
|
- %if table.comment:
|
|
|
|
|
- self.tableComment('${ smart_unicode(table.comment) }');
|
|
|
|
|
- %endif
|
|
|
|
|
-
|
|
|
|
|
- self.tableComment.subscribe(function (newValue) {
|
|
|
|
|
- $.post("${ url('metastore:alter_table', database=database, table=table.name) }", {
|
|
|
|
|
- comment: newValue ? newValue : ""
|
|
|
|
|
- });
|
|
|
|
|
- })
|
|
|
|
|
- self.assistHelper = new AssistHelper(options)
|
|
|
|
|
|
|
+ self.database = options.database;
|
|
|
|
|
+ self.assistHelper = options.assistHelper;
|
|
|
|
|
+ self.name = options.name;
|
|
|
|
|
|
|
|
self.columns = ko.observableArray();
|
|
self.columns = ko.observableArray();
|
|
|
self.favouriteColumns = ko.observableArray();
|
|
self.favouriteColumns = ko.observableArray();
|
|
@@ -562,48 +561,57 @@ ${ assist.assistPanel() }
|
|
|
self.tableStats = ko.observable();
|
|
self.tableStats = ko.observable();
|
|
|
self.refreshingTableStats = ko.observable(false);
|
|
self.refreshingTableStats = ko.observable(false);
|
|
|
|
|
|
|
|
- var fetchColumns = function () {
|
|
|
|
|
- self.assistHelper.fetchFields({
|
|
|
|
|
- sourceType: "hive",
|
|
|
|
|
- databaseName: self.activeDatabase(),
|
|
|
|
|
- tableName: self.activeTable(),
|
|
|
|
|
- fields: [],
|
|
|
|
|
- successCallback: function (data) {
|
|
|
|
|
- self.columns($.map(data.extended_columns, function (column) { return new MetastoreColumn(self, column) }));
|
|
|
|
|
- self.favouriteColumns(self.columns().slice(0, 3));
|
|
|
|
|
- },
|
|
|
|
|
- errorCallback: function (data) {
|
|
|
|
|
- console.log('ERRRROR!');
|
|
|
|
|
- console.log(data);
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //TODO: Fetch table comment async and don't set it from python
|
|
|
|
|
+ self.comment = ko.observable(options.comment);
|
|
|
|
|
|
|
|
- var fetchTableSample = function () {
|
|
|
|
|
- self.assistHelper.fetchTableSample({
|
|
|
|
|
- sourceType: "hive",
|
|
|
|
|
- databaseName: self.activeDatabase(),
|
|
|
|
|
- tableName: self.activeTable(),
|
|
|
|
|
- dataType: "json",
|
|
|
|
|
- successCallback: function (data) {
|
|
|
|
|
- self.samples(data);
|
|
|
|
|
- self.samplesPreview({
|
|
|
|
|
- headers: self.samples().headers,
|
|
|
|
|
- rows: self.samples().rows.slice(0, 3)
|
|
|
|
|
- });
|
|
|
|
|
- },
|
|
|
|
|
- errorCallback: function (data) {
|
|
|
|
|
- console.log('ERRRROR!');
|
|
|
|
|
- console.log(data);
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ self.comment.subscribe(function (newValue) {
|
|
|
|
|
+ // TODO: Switch to using the ko observables in the url (self.database.name() and self.name())
|
|
|
|
|
+ $.post("${ url('metastore:alter_table', database=database, table=table.name) }", {
|
|
|
|
|
+ comment: newValue ? newValue : ""
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ self.assistHelper.fetchFields({
|
|
|
|
|
+ sourceType: "hive",
|
|
|
|
|
+ databaseName: self.database.name,
|
|
|
|
|
+ tableName: self.name,
|
|
|
|
|
+ fields: [],
|
|
|
|
|
+ successCallback: function (data) {
|
|
|
|
|
+ self.columns($.map(data.extended_columns, function (column) { return new MetastoreColumn({
|
|
|
|
|
+ extendedColumn: column,
|
|
|
|
|
+ table: self
|
|
|
|
|
+ }) }));
|
|
|
|
|
+ self.favouriteColumns(self.columns().slice(0, 3));
|
|
|
|
|
+ },
|
|
|
|
|
+ errorCallback: function (data) {
|
|
|
|
|
+ console.log('ERRRROR!');
|
|
|
|
|
+ console.log(data);
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ self.assistHelper.fetchTableSample({
|
|
|
|
|
+ sourceType: "hive",
|
|
|
|
|
+ databaseName: self.database.name,
|
|
|
|
|
+ tableName: self.name,
|
|
|
|
|
+ dataType: "json",
|
|
|
|
|
+ successCallback: function (data) {
|
|
|
|
|
+ self.samples(data);
|
|
|
|
|
+ self.samplesPreview({
|
|
|
|
|
+ headers: self.samples().headers,
|
|
|
|
|
+ rows: self.samples().rows.slice(0, 3)
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ errorCallback: function (data) {
|
|
|
|
|
+ console.log('ERRRROR!');
|
|
|
|
|
+ console.log(data);
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
var fetchDetails = function () {
|
|
var fetchDetails = function () {
|
|
|
self.assistHelper.fetchTableDetails({
|
|
self.assistHelper.fetchTableDetails({
|
|
|
sourceType: "hive",
|
|
sourceType: "hive",
|
|
|
- databaseName: self.activeDatabase(),
|
|
|
|
|
- tableName: self.activeTable(),
|
|
|
|
|
|
|
+ databaseName: self.database.name,
|
|
|
|
|
+ tableName: self.name,
|
|
|
successCallback: function (data) {
|
|
successCallback: function (data) {
|
|
|
self.tableDetails(data);
|
|
self.tableDetails(data);
|
|
|
self.tableStats(data.details.stats);
|
|
self.tableStats(data.details.stats);
|
|
@@ -617,23 +625,7 @@ ${ assist.assistPanel() }
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- self.initialize = function () {
|
|
|
|
|
- fetchColumns();
|
|
|
|
|
- fetchTableSample();
|
|
|
|
|
- fetchDetails();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- self.initialize();
|
|
|
|
|
-
|
|
|
|
|
- huePubSub.subscribe("assist.table.selected", function (tableDef) {
|
|
|
|
|
- self.activeDatabase(tableDef.database);
|
|
|
|
|
- self.activeTable(tableDef.name)
|
|
|
|
|
- self.initialize();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- huePubSub.subscribe("assist.database.selected", function (databaseDef) {
|
|
|
|
|
- console.log(databaseDef);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ fetchDetails();
|
|
|
|
|
|
|
|
self.refreshTableStats = function () {
|
|
self.refreshTableStats = function () {
|
|
|
if (self.refreshingTableStats()) {
|
|
if (self.refreshingTableStats()) {
|
|
@@ -641,8 +633,8 @@ ${ assist.assistPanel() }
|
|
|
}
|
|
}
|
|
|
self.refreshingTableStats(true);
|
|
self.refreshingTableStats(true);
|
|
|
self.assistHelper.refreshTableStats({
|
|
self.assistHelper.refreshTableStats({
|
|
|
- tableName: self.activeTable(),
|
|
|
|
|
- databaseName: self.activeDatabase(),
|
|
|
|
|
|
|
+ tableName: self.name,
|
|
|
|
|
+ databaseName: self.database.name,
|
|
|
sourceType: "hive",
|
|
sourceType: "hive",
|
|
|
successCallback: function (data) {
|
|
successCallback: function (data) {
|
|
|
fetchDetails();
|
|
fetchDetails();
|
|
@@ -654,11 +646,80 @@ ${ assist.assistPanel() }
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param {Object} options
|
|
|
|
|
+ * @param {MetastoreTable} options.table
|
|
|
|
|
+ * @param {object} options.extendedColumn
|
|
|
|
|
+ * @constructor
|
|
|
|
|
+ */
|
|
|
|
|
+ function MetastoreColumn(options) {
|
|
|
|
|
+ var self = this;
|
|
|
|
|
+ self.table = options.table;
|
|
|
|
|
+ ko.mapping.fromJS(options.extendedColumn, {}, self);
|
|
|
|
|
+
|
|
|
|
|
+ self.favourite = ko.observable(false);
|
|
|
|
|
+
|
|
|
|
|
+ self.comment.subscribe(function (newValue) {
|
|
|
|
|
+ // TODO: Switch to using the ko observables in the url (self.table.name() and self.table.database.name();
|
|
|
|
|
+ $.post("${ url('metastore:alter_column', database=database, table=table.name) }", {
|
|
|
|
|
+ column: self.name(),
|
|
|
|
|
+ comment: newValue
|
|
|
|
|
+ }, function () {
|
|
|
|
|
+ self.vm.assistHelper.clearCache({
|
|
|
|
|
+ sourceType: 'hive',
|
|
|
|
|
+ databaseName: self.table.database.name,
|
|
|
|
|
+ tableName: self.table.name,
|
|
|
|
|
+ fields: []
|
|
|
|
|
+ })
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param {Object} options
|
|
|
|
|
+ * @param {Object} options.i18n
|
|
|
|
|
+ * @param {string} options.i18n.errorLoadingDatabases
|
|
|
|
|
+ * @param {string} options.i18n.errorLoadingTablePreview
|
|
|
|
|
+ * @param {string} options.user
|
|
|
|
|
+ * @constructor
|
|
|
|
|
+ */
|
|
|
|
|
+ function MetastoreViewModel(options) {
|
|
|
|
|
+ var self = this;
|
|
|
|
|
+ self.assistAvailable = ko.observable(true);
|
|
|
|
|
+ self.isLeftPanelVisible = ko.observable(self.assistAvailable() && $.totalStorage('spark_left_panel_visible') != null && $.totalStorage('spark_left_panel_visible'));
|
|
|
|
|
+
|
|
|
|
|
+ var tableComment = null;
|
|
|
|
|
+ %if table.comment:
|
|
|
|
|
+ tableComment = '${ smart_unicode(table.comment) }';
|
|
|
|
|
+ %endif
|
|
|
|
|
+
|
|
|
|
|
+ self.assistHelper = new AssistHelper(options)
|
|
|
|
|
+
|
|
|
|
|
+ self.database = ko.observable(new MetastoreDatabase({
|
|
|
|
|
+ name: '${database}',
|
|
|
|
|
+ tableName: '${table.name}',
|
|
|
|
|
+ tableComment: tableComment,
|
|
|
|
|
+ assistHelper: self.assistHelper
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ huePubSub.subscribe("assist.table.selected", function (tableDef) {
|
|
|
|
|
+ if (self.database() && self.database().name == tableDef.database) {
|
|
|
|
|
+ self.database().setTable(tableDef.name);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ huePubSub.subscribe("assist.database.selected", function (databaseDef) {
|
|
|
|
|
+ console.log(databaseDef);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
self.isLeftPanelVisible.subscribe(function(newValue) {
|
|
self.isLeftPanelVisible.subscribe(function(newValue) {
|
|
|
$.totalStorage('spark_left_panel_visible', newValue);
|
|
$.totalStorage('spark_left_panel_visible', newValue);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ // TODO: Move queries into MetastoreTable
|
|
|
self.loadingQueries = ko.observable(false);
|
|
self.loadingQueries = ko.observable(false);
|
|
|
self.queries = ko.observableArray([]);
|
|
self.queries = ko.observableArray([]);
|
|
|
}
|
|
}
|
|
@@ -676,6 +737,7 @@ ${ assist.assistPanel() }
|
|
|
|
|
|
|
|
ko.applyBindings(viewModel);
|
|
ko.applyBindings(viewModel);
|
|
|
|
|
|
|
|
|
|
+ // TODO: Use ko for this and the put the queries in the MetastoreTable
|
|
|
$('a[data-toggle="tab"]').on('shown', function (e) {
|
|
$('a[data-toggle="tab"]').on('shown', function (e) {
|
|
|
if ($(e.target).attr("href") == "#queries") {
|
|
if ($(e.target).attr("href") == "#queries") {
|
|
|
viewModel.loadingQueries(true);
|
|
viewModel.loadingQueries(true);
|