KYLIN-579 Unload hive table from kylin Signed-off-by: wangxianbin1987 <wangxianbin1...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/6db101ed Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/6db101ed Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/6db101ed Branch: refs/heads/1.3.x Commit: 6db101edff38f6484f805d01a06f79762da9b16a Parents: 343ce34 Author: wangxianbin1987 <wangxianbin1...@gmail.com> Authored: Mon Feb 22 17:33:23 2016 +0800 Committer: shaofengshi <shaofeng...@apache.org> Committed: Fri Feb 26 16:14:52 2016 +0800 ---------------------------------------------------------------------- .../java/org/apache/kylin/cube/CubeManager.java | 34 +++++++++ .../apache/kylin/metadata/MetadataManager.java | 18 +++-- .../kylin/metadata/project/ProjectManager.java | 31 ++++++++ .../metadata/tool/HiveSourceTableLoader.java | 6 ++ .../kylin/rest/controller/TableController.java | 67 ++++++++++++++++-- .../apache/kylin/rest/service/CubeService.java | 27 ++++++- .../kylin/rest/service/ProjectService.java | 13 ++++ .../rest/controller/TableControllerTest.java | 8 ++- webapp/app/js/controllers/sourceMeta.js | 74 ++++++++++++++++++++ webapp/app/js/services/tables.js | 1 + .../app/partials/tables/source_table_tree.html | 20 +++++- 11 files changed, 283 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/cube/src/main/java/org/apache/kylin/cube/CubeManager.java ---------------------------------------------------------------------- diff --git a/cube/src/main/java/org/apache/kylin/cube/CubeManager.java b/cube/src/main/java/org/apache/kylin/cube/CubeManager.java index d3bbf59..6fb907f 100644 --- a/cube/src/main/java/org/apache/kylin/cube/CubeManager.java +++ b/cube/src/main/java/org/apache/kylin/cube/CubeManager.java @@ -52,7 +52,9 @@ import org.apache.kylin.metadata.model.PartitionDesc; import org.apache.kylin.metadata.model.SegmentStatusEnum; import org.apache.kylin.metadata.model.TableDesc; import org.apache.kylin.metadata.model.TblColRef; +import org.apache.kylin.metadata.project.ProjectInstance; import org.apache.kylin.metadata.project.ProjectManager; +import org.apache.kylin.metadata.project.RealizationEntry; import org.apache.kylin.metadata.realization.IRealization; import org.apache.kylin.metadata.realization.IRealizationConstants; import org.apache.kylin.metadata.realization.IRealizationProvider; @@ -157,6 +159,38 @@ public class CubeManager implements IRealizationProvider { return result; } + public boolean isTableInAnyCube(String tableName) { + for(ProjectInstance projectInstance : ProjectManager.getInstance(config).listAllProjects()) { + if(isTableInCube(tableName, projectInstance.getName())) { + return true; + } + } + return false; + } + + public boolean isTableInCube(String tableName, String projectName) { + ProjectManager projectManager = ProjectManager.getInstance(config); + CubeDescManager cubeDescManager = CubeDescManager.getInstance(config); + ProjectInstance projectInstance = projectManager.getProject(projectName); + if (projectInstance == null) { + throw new IllegalStateException("Cannot find project '" + projectName + "' in project manager"); + } + + for (RealizationEntry projectDataModel : projectInstance.getRealizationEntries()) { + if (projectDataModel.getType() == RealizationType.CUBE) { + CubeDesc cubeDesc = cubeDescManager.getCubeDesc(projectDataModel.getRealization()); + if (cubeDesc == null) { + throw new IllegalStateException("Cannot find cube '" + projectDataModel.getRealization() + "' in cubeDesc manager"); + } + + if (cubeDesc.getModel().getAllTables().contains(tableName.toUpperCase())) { + return true; + } + } + } + return false; + } + public DictionaryInfo buildDictionary(CubeSegment cubeSeg, TblColRef col, String factColumnsPath) throws IOException { CubeDesc cubeDesc = cubeSeg.getCubeDesc(); if (!cubeDesc.getRowkey().isUseDictionary(col)) http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java ---------------------------------------------------------------------- diff --git a/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java b/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java index 800ea44..71e6649 100644 --- a/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java +++ b/metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java @@ -22,11 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; @@ -191,6 +187,12 @@ public class MetadataManager { srcTableMap.put(srcTable.getIdentity(), srcTable); } + public void removeSourceTable(String tableIdentity) throws IOException { + String path = TableDesc.concatResourcePath(tableIdentity); + getStore().deleteResource(path); + srcTableMap.remove(tableIdentity); + } + private void init(KylinConfig config) throws IOException { this.config = config; reloadAllSourceTable(); @@ -394,6 +396,12 @@ public class MetadataManager { srcTableExdMap.putLocal(tableId, tableExdProperties); } + public void removeTableExd(String tableIdentity) throws IOException { + String path = TableDesc.concatExdResourcePath(tableIdentity); + getStore().deleteResource(path); + srcTableExdMap.remove(tableIdentity); + } + public String appendDBName(String table) { if (table.indexOf(".") > 0) http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java ---------------------------------------------------------------------- diff --git a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java index a05128a..8bdfb51 100644 --- a/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java +++ b/metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java @@ -255,6 +255,18 @@ public class ProjectManager { return projectInstance; } + public void removeTableDescFromProject(String tableIdentities, String projectName) throws IOException { + MetadataManager metaMgr = getMetadataManager(); + ProjectInstance projectInstance = getProject(projectName); + TableDesc table = metaMgr.getTableDesc(tableIdentities); + if (table == null) { + throw new IllegalStateException("Cannot find table '" + table + "' in metadata manager"); + } + + projectInstance.removeTable(table.getIdentity()); + saveResource(projectInstance); + } + private void saveResource(ProjectInstance prj) throws IOException { ResourceStore store = getStore(); store.putResource(prj.getResourcePath(), prj, PROJECT_SERIALIZER); @@ -271,6 +283,25 @@ public class ProjectManager { clearL2Cache(); } + public boolean isTableInAnyProject(String tableName) { + for(ProjectInstance projectInstance : ProjectManager.getInstance(config).listAllProjects()) { + if(projectInstance.containsTable(tableName.toUpperCase())) { + return true; + } + } + return false; + } + + public boolean isTableInProject(String projectName, String tableName) { + ProjectInstance projectInstance = ProjectManager.getInstance(config).getProject(projectName); + if(projectInstance != null) { + if(projectInstance.containsTable(tableName.toUpperCase())) { + return true; + } + } + return false; + } + public List<ProjectInstance> findProjects(RealizationType type, String realizationName) { List<ProjectInstance> result = Lists.newArrayList(); for (ProjectInstance prj : projectMap.values()) { http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/metadata/src/main/java/org/apache/kylin/metadata/tool/HiveSourceTableLoader.java ---------------------------------------------------------------------- diff --git a/metadata/src/main/java/org/apache/kylin/metadata/tool/HiveSourceTableLoader.java b/metadata/src/main/java/org/apache/kylin/metadata/tool/HiveSourceTableLoader.java index 5e64068..39b4f93 100644 --- a/metadata/src/main/java/org/apache/kylin/metadata/tool/HiveSourceTableLoader.java +++ b/metadata/src/main/java/org/apache/kylin/metadata/tool/HiveSourceTableLoader.java @@ -79,6 +79,12 @@ public class HiveSourceTableLoader { return loadedTables; } + public static void unLoadHiveTable(String hiveTable) throws IOException { + MetadataManager metaMgr = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv()); + metaMgr.removeSourceTable(hiveTable); + metaMgr.removeTableExd(hiveTable); + } + private static List<String> extractHiveTables(String database, Set<String> tables, KylinConfig config) throws IOException { List<String> loadedTables = Lists.newArrayList(); http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/server/src/main/java/org/apache/kylin/rest/controller/TableController.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/kylin/rest/controller/TableController.java b/server/src/main/java/org/apache/kylin/rest/controller/TableController.java index f899d99..a4d172f 100644 --- a/server/src/main/java/org/apache/kylin/rest/controller/TableController.java +++ b/server/src/main/java/org/apache/kylin/rest/controller/TableController.java @@ -19,13 +19,9 @@ package org.apache.kylin.rest.controller; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; +import com.google.common.collect.Sets; import org.apache.commons.lang.StringUtils; import org.apache.kylin.common.util.HiveClient; import org.apache.kylin.metadata.MetadataConstants; @@ -35,6 +31,7 @@ import org.apache.kylin.rest.exception.InternalErrorException; import org.apache.kylin.rest.request.CardinalityRequest; import org.apache.kylin.rest.response.TableDescResponse; import org.apache.kylin.rest.service.CubeService; +import org.apache.kylin.rest.service.ProjectService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -57,6 +54,8 @@ public class TableController extends BasicController { @Autowired private CubeService cubeMgmtService; + @Autowired + private ProjectService projectService; /** * Get available table list of the input database @@ -126,10 +125,60 @@ public class TableController extends BasicController { cubeMgmtService.syncTableToProject(loaded, project); Map<String, String[]> result = new HashMap<String, String[]>(); result.put("result.loaded", loaded); - result.put("result.unloaded", new String[] {}); + result.put("result.unloaded", new String[]{}); + return result; + } + + /** + * table may referenced by several projects, and kylin only keep one copy of meta for each table. + * that's why we have two if statement here. + * @param tables + * @param project + * @throws IOException + */ + @RequestMapping(value = "{tables}/{project}", method = { RequestMethod.DELETE }) + @ResponseBody + public Map<String, String[]> unLoadHiveTables(@PathVariable String tables, @PathVariable String project) { + Set<String> unLoadSuccess = Sets.newHashSet(); + Set<String> unLoadFail = Sets.newHashSet(); + Map<String, String[]> result = new HashMap<String, String[]>(); + for (String tableName : tables.split(",")) { + if (unLoadHiveTable(tableName, project)) { + unLoadSuccess.add(tableName); + } else { + unLoadFail.add(tableName); + } + } + result.put("result.unload.success", (String[]) unLoadSuccess.toArray(new String[unLoadSuccess.size()])); + result.put("result.unload.fail", (String[]) unLoadFail.toArray(new String[unLoadFail.size()])); return result; } + private boolean unLoadHiveTable(String tableName, String project) { + boolean rtn = false; + if(!cubeMgmtService.isTableInCube(tableName, project)) { + try { + cubeMgmtService.removeTableFromProject(tableName, project); + rtn = true; + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + if(!projectService.isTableInAnyProject(tableName) && !cubeMgmtService.isTableInAnyCube(tableName)) { + try { + cubeMgmtService.unLoadHiveTable(tableName); + rtn = true; + } catch (IOException e) { + logger.error(e.getMessage(), e); + rtn = false; + } + } + + return rtn; + } + + + /** * Regenerate table cardinality * @@ -238,4 +287,8 @@ public class TableController extends BasicController { this.cubeMgmtService = cubeService; } + public void setProjectService(ProjectService projectService) { + this.projectService = projectService; + } + } http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/server/src/main/java/org/apache/kylin/rest/service/CubeService.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/kylin/rest/service/CubeService.java b/server/src/main/java/org/apache/kylin/rest/service/CubeService.java index 601814c..5020dc3 100644 --- a/server/src/main/java/org/apache/kylin/rest/service/CubeService.java +++ b/server/src/main/java/org/apache/kylin/rest/service/CubeService.java @@ -193,6 +193,18 @@ public class CubeService extends BasicService { return result; } + public boolean isTableInAnyCube(String tableName) { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + return getCubeManager().isTableInAnyCube(tableName); + } + + public boolean isTableInCube(String tableName, String projectName) { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + return getCubeManager().isTableInCube(tableName, projectName); + } + public boolean isCubeInProject(String projectName, CubeInstance target) { ProjectManager projectManager = getProjectManager(); ProjectInstance project = projectManager.getProject(projectName); @@ -334,7 +346,6 @@ public class CubeService extends BasicService { * Update a cube status from disable to ready. * * @return - * @throws CubeIntegrityException * @throws IOException * @throws JobException */ @@ -511,11 +522,25 @@ public class CubeService extends BasicService { return (String[]) loaded.toArray(new String[loaded.size()]); } + @PreAuthorize(Constant.ACCESS_HAS_ROLE_MODELER + " or " + Constant.ACCESS_HAS_ROLE_ADMIN) + public void unLoadHiveTable(String tableName) throws IOException { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + HiveSourceTableLoader.unLoadHiveTable(tableName.toUpperCase()); + } + @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) public void syncTableToProject(String[] tables, String project) throws IOException { getProjectManager().addTableDescToProject(tables, project); } + @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) + public void removeTableFromProject(String tableName, String project) throws IOException { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + getProjectManager().removeTableDescFromProject(tableName, project); + } + @PreAuthorize(Constant.ACCESS_HAS_ROLE_MODELER + " or " + Constant.ACCESS_HAS_ROLE_ADMIN) public void calculateCardinalityIfNotPresent(String[] tables, String submitter) throws IOException { MetadataManager metaMgr = getMetadataManager(); http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/server/src/main/java/org/apache/kylin/rest/service/ProjectService.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/kylin/rest/service/ProjectService.java b/server/src/main/java/org/apache/kylin/rest/service/ProjectService.java index 4059345..d6a8a07 100644 --- a/server/src/main/java/org/apache/kylin/rest/service/ProjectService.java +++ b/server/src/main/java/org/apache/kylin/rest/service/ProjectService.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.Collections; import java.util.List; +import org.apache.kylin.common.util.HadoopUtil; import org.apache.kylin.metadata.project.ProjectInstance; import org.apache.kylin.metadata.project.ProjectManager; import org.apache.kylin.rest.constant.Constant; @@ -108,6 +109,18 @@ public class ProjectService extends BasicService { accessService.clean(project, true); } + public boolean isTableInAnyProject(String tableName) { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + return getProjectManager().isTableInAnyProject(tableName); + } + + public boolean isTableInProject(String projectName, String tableName) { + String[] dbTableName = HadoopUtil.parseHiveTableName(tableName); + tableName = dbTableName[0] + "." + dbTableName[1]; + return getProjectManager().isTableInProject(projectName, tableName); + } + public void reloadProjectCache(String name) throws IOException { getProjectManager().reloadProject(name); } http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/server/src/test/java/org/apache/kylin/rest/controller/TableControllerTest.java ---------------------------------------------------------------------- diff --git a/server/src/test/java/org/apache/kylin/rest/controller/TableControllerTest.java b/server/src/test/java/org/apache/kylin/rest/controller/TableControllerTest.java index 4cbd544..4a48285 100644 --- a/server/src/test/java/org/apache/kylin/rest/controller/TableControllerTest.java +++ b/server/src/test/java/org/apache/kylin/rest/controller/TableControllerTest.java @@ -24,6 +24,7 @@ import java.util.Map; import org.apache.kylin.metadata.model.TableDesc; import org.apache.kylin.rest.service.CubeService; +import org.apache.kylin.rest.service.ProjectService; import org.apache.kylin.rest.service.ServiceTestBase; import org.junit.Assert; import org.junit.Before; @@ -36,10 +37,11 @@ import org.springframework.beans.factory.annotation.Autowired; public class TableControllerTest extends ServiceTestBase { private TableController tableController; - private CubeDescController cubeDescController; @Autowired CubeService cubeService; + @Autowired + ProjectService projectService; @Before public void setup() throws Exception { @@ -47,6 +49,7 @@ public class TableControllerTest extends ServiceTestBase { tableController = new TableController(); tableController.setCubeService(cubeService); + tableController.setProjectService(projectService); } @Test @@ -69,5 +72,8 @@ public class TableControllerTest extends ServiceTestBase { Assert.assertNotNull(loadResult); Assert.assertTrue(loadResult.get("result.loaded").length == 2); + + loadResult = tableController.unLoadHiveTables("TEST_CATEGORY_GROUPINGS","default"); + Assert.assertTrue(loadResult.get("result.unload.success")[0].equals("TEST_CATEGORY_GROUPINGS")); } } http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/webapp/app/js/controllers/sourceMeta.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/sourceMeta.js b/webapp/app/js/controllers/sourceMeta.js index 5c32f87..9c1fad2 100755 --- a/webapp/app/js/controllers/sourceMeta.js +++ b/webapp/app/js/controllers/sourceMeta.js @@ -119,6 +119,24 @@ KylinApp }); }; + $scope.openUnLoadModal = function () { + $modal.open({ + templateUrl: 'removeHiveTable.html', + controller: ModalInstanceCtrl, + resolve: { + tableNames: function () { + return $scope.tableNames; + }, + projectName: function () { + return $scope.projectModel.selectedProject; + }, + scope: function () { + return $scope; + } + } + }); + }; + var ModalInstanceCtrl = function ($scope, $location, $modalInstance, kylinConfig,tableNames, MessageService, projectName, scope) { $scope.tableNames = ""; $scope.projectName = projectName; @@ -327,6 +345,62 @@ KylinApp loadingRequest.hide(); }) } + + $scope.remove = function () { + + if($scope.tableNames.length === 0 && $scope.selectedNodes.length > 0) { + for(var i = 0; i < $scope.selectedNodes.length; i++){ + if($scope.selectedNodes[i].label.indexOf(".") >= 0){ + $scope.tableNames += ($scope.selectedNodes[i].label) += ','; + } + } + } + + if ($scope.tableNames.trim() === "") { + SweetAlert.swal('', 'Please input table(s) you want to synchronize.', 'info'); + return; + } + + if (!$scope.projectName) { + SweetAlert.swal('', 'Please choose your project first!.', 'info'); + return; + } + + $scope.cancel(); + loadingRequest.show(); + TableService.unLoadHiveTable({tableName: $scope.tableNames, action: projectName}, {}, function (result) { + var removedTableInfo = ""; + angular.forEach(result['result.unload.success'], function (table) { + removedTableInfo += "\n" + table; + }) + var unRemovedTableInfo = ""; + angular.forEach(result['result.unload.fail'], function (table) { + unRemovedTableInfo += "\n" + table; + }) + + if (result['result.unload.fail'].length != 0 && result['result.unload.success'].length == 0) { + SweetAlert.swal('Failed!', 'Failed to synchronize following table(s): ' + unRemovedTableInfo, 'error'); + } + if (result['result.unload.success'].length != 0 && result['result.unload.fail'].length == 0) { + SweetAlert.swal('Success!', 'The following table(s) have been successfully synchronized: ' + removedTableInfo, 'success'); + } + if (result['result.unload.success'].length != 0 && result['result.unload.fail'].length != 0) { + SweetAlert.swal('Partial unloaded!', 'The following table(s) have been successfully synchronized: ' + removedTableInfo + "\n\n Failed to synchronize following table(s):" + unRemovedTableInfo, 'warning'); + } + loadingRequest.hide(); + scope.aceSrcTbLoaded(true); + + }, function (e) { + if (e.data && e.data.exception) { + var message = e.data.exception; + var msg = !!(message) ? message : 'Failed to take action.'; + SweetAlert.swal('Oops...', msg, 'error'); + } else { + SweetAlert.swal('Oops...', "Failed to take action.", 'error'); + } + loadingRequest.hide(); + }) + } }; $scope.trimType = function (typeName) { if (typeName.match(/VARCHAR/i)) { http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/webapp/app/js/services/tables.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/services/tables.js b/webapp/app/js/services/tables.js index e98603b..ccc63c8 100755 --- a/webapp/app/js/services/tables.js +++ b/webapp/app/js/services/tables.js @@ -23,6 +23,7 @@ KylinApp.factory('TableService', ['$resource', function ($resource, config) { getExd: {method: 'GET', params: {action: 'exd-map'}, isArray: false}, reload: {method: 'PUT', params: {action: 'reload'}, isArray: false}, loadHiveTable: {method: 'POST', params: {}, isArray: false}, + unLoadHiveTable: {method: 'DELETE', params: {}, isArray: false}, genCardinality: {method: 'PUT', params: {action: 'cardinality'}, isArray: false}, showHiveDatabases: {method: 'GET', params: {action:'hive'}, cache: true, isArray: true}, showHiveTables: {method: 'GET', params: {action:'hive'}, cache: true, isArray: true} }); http://git-wip-us.apache.org/repos/asf/kylin/blob/6db101ed/webapp/app/partials/tables/source_table_tree.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/tables/source_table_tree.html b/webapp/app/partials/tables/source_table_tree.html index c048685..522fdbb 100755 --- a/webapp/app/partials/tables/source_table_tree.html +++ b/webapp/app/partials/tables/source_table_tree.html @@ -26,9 +26,9 @@ <div class="col-xs-5" style="padding-left: 0px;margin-top: 20px;"> <div class="pull-right"> <a class="btn btn-xs btn-primary" tooltip="Load Hive Table" ng-if="userService.hasRole('ROLE_ADMIN')" ng-click="openModal()"><i class="fa fa-download"></i></a> - <a class="btn btn-xs btn-info" tooltip="Load Hive Table From Tree" ng-if="userService.hasRole('ROLE_ADMIN')" ng-click="openTreeModal()"><i class="fa fa-download"></i></a> - + <a class="btn btn-xs btn-primary" tooltip="Load Hive Table From Tree" ng-if="userService.hasRole('ROLE_ADMIN')" ng-click="openTreeModal()"><i class="fa fa-download"></i></a> <a class="btn btn-xs btn-success" tooltip="Refresh Tables" ng-click="aceSrcTbChanged()"><i class="fa fa-refresh"></i></a> + <a class="btn btn-xs btn-info" tooltip="UnLoad Hive Table" ng-if="userService.hasRole('ROLE_ADMIN')" ng-click="openUnLoadModal()"><i class="fa fa-remove"></i></a> </div> </div> @@ -63,6 +63,22 @@ </div> </script> +<script type="text/ng-template" id="removeHiveTable.html"> + <div class="modal-header"> + <h4>UnLoad Hive Table Metadata</h4> + </div> + <div class="modal-body"> + <span><strong>Project: </strong>{{ $parent.projectName!=null?$parent.projectName:'NULL'}}</span> + <label for="tables"> Table Names:(Seperate with comma)</label> + <textarea ng-model="$parent.tableNames" class="form-control" id="removeTables" + placeholder="table1,table2 By default,system will choose 'Default' as database,you can specify database like this 'database.table'"></textarea> + </div> + <div class="modal-footer"> + <button class="btn btn-primary" ng-click="remove()">Sync</button> + <button class="btn btn-primary" ng-click="cancel()">Cancel</button> + </div> +</script> + <script type="text/ng-template" id="addHiveTableFromTree.html"> <div class="modal-header"><button class="close" type="button" data-dismiss="modal" ng-click="cancel()">Ã</button> <h4>Load Hive Table Metadata From Tree</h4>