This is an automated email from the ASF dual-hosted git repository. abulatski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 9fa986f437d0b257ce3ac853975bb1ec73c54a0b Author: Arseni Bulatski <ancars...@gmail.com> AuthorDate: Wed Aug 28 15:53:43 2019 +0300 CAY-2612 Modeler: add lazy-loading to dbImport tab --- RELEASE-NOTES.txt | 1 + .../org/apache/cayenne/dba/mysql/MySQLAdapter.java | 4 +- .../cayenne/dba/postgres/PostgresAdapter.java | 32 ++-- .../cayenne/dba/sqlserver/SQLServerAdapter.java | 5 +- .../cayenne/modeler/action/LoadDbSchemaAction.java | 69 +++++++-- .../editor/dbimport/DatabaseSchemaLoader.java | 167 ++++++++++++--------- .../modeler/editor/dbimport/DbImportTree.java | 60 ++++---- .../editor/dbimport/PrintColumnsBiFunction.java | 55 +++++++ .../editor/dbimport/PrintTablesBiFunction.java | 65 ++++++++ 9 files changed, 323 insertions(+), 135 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index b638050..2f57bc1 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -44,6 +44,7 @@ CAY-2593 Add tableTypes field to dbImport config in dataMap CAY-2602 Remove RTRIM of char columns in Sybase CAY-2610 Align methods in ObjectSelect and SQLSelect CAY-2611 Exclude system catalogs and schemas when run dbImport without config +CAY-2612 Modeler: add lazy-loading to dbImport tab Bug Fixes: diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java index 5129df5..b1792f4 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java @@ -80,12 +80,10 @@ import org.apache.cayenne.resource.ResourceLocator; public class MySQLAdapter extends JdbcAdapter { static final String DEFAULT_STORAGE_ENGINE = "InnoDB"; - static final String MYSQL_QUOTE_SQL_IDENTIFIERS_CHAR_START = "`"; - static final String MYSQL_QUOTE_SQL_IDENTIFIERS_CHAR_END = "`"; protected String storageEngine; - private String[] SYSTEM_CATALOGS = new String[]{"sys"}; + private String[] SYSTEM_CATALOGS = new String[]{"sys", "information_schema", "mysql", "performance_schema"}; public MySQLAdapter(@Inject RuntimeProperties runtimeProperties, @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes, diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java index b1b78a2..edf5e79 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java @@ -19,6 +19,16 @@ package org.apache.cayenne.dba.postgres; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; + import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.access.DataNode; import org.apache.cayenne.access.sqlbuilder.sqltree.Node; @@ -41,20 +51,11 @@ import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLAction; import org.apache.cayenne.resource.ResourceLocator; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - /** * DbAdapter implementation for <a href="http://www.postgresql.org">PostgreSQL * RDBMS </a>. Sample connection settings to use with PostgreSQL are shown * below: - * + * * <pre> * postgres.jdbc.username = test * postgres.jdbc.password = secret @@ -66,6 +67,8 @@ public class PostgresAdapter extends JdbcAdapter { public static final String BYTEA = "bytea"; + private String[] SYSTEM_SCHEMAS = new String[]{"information_schema", "pg_catalog"}; + public PostgresAdapter(@Inject RuntimeProperties runtimeProperties, @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes, @@ -87,7 +90,7 @@ public class PostgresAdapter extends JdbcAdapter { /** * Uses PostgresActionBuilder to create the right action. - * + * * @since 1.2 */ @Override @@ -156,7 +159,7 @@ public class PostgresAdapter extends JdbcAdapter { * Customizes table creating procedure for PostgreSQL. One difference with * generic implementation is that "bytea" type has no explicit length unlike * similar binary types in other databases. - * + * * @since 1.0.2 */ @Override @@ -267,4 +270,9 @@ public class PostgresAdapter extends JdbcAdapter { return false; } + @Override + public List<String> getSystemSchemas() { + return Arrays.asList(SYSTEM_SCHEMAS); + } + } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java index c15eb64..0da1518 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java @@ -81,7 +81,10 @@ public class SQLServerAdapter extends SybaseAdapter { @Deprecated public static final String TRIM_FUNCTION = "RTRIM"; - private String[] SYSTEM_SCHEMAS = new String[]{"dbo", "sys", "INFORMATION_SCHEMA"}; + private String[] SYSTEM_SCHEMAS = new String[]{"db_accessadmin", "db_backupoperator", + "db_datareader", "db_datawriter", "db_ddladmin", "db_denydatareader", + "db_denydatawriter","dbo", "sys", "db_owner", "db_securityadmin", "guest", + "INFORMATION_SCHEMA"}; public SQLServerAdapter(@Inject RuntimeProperties runtimeProperties, @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes, diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java index 3b6d773..871a502 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/LoadDbSchemaAction.java @@ -22,15 +22,22 @@ package org.apache.cayenne.modeler.action; import javax.swing.JOptionPane; import javax.swing.tree.TreePath; import java.awt.event.ActionEvent; +import java.sql.SQLException; import java.util.prefs.Preferences; +import org.apache.cayenne.dbsync.reverse.dbimport.Catalog; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable; import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering; +import org.apache.cayenne.dbsync.reverse.dbimport.Schema; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.dialog.db.DataSourceWizard; +import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode; import org.apache.cayenne.modeler.editor.dbimport.DatabaseSchemaLoader; import org.apache.cayenne.modeler.editor.dbimport.DbImportModel; import org.apache.cayenne.modeler.editor.dbimport.DbImportView; import org.apache.cayenne.modeler.editor.dbimport.DraggableTreePanel; +import org.apache.cayenne.modeler.editor.dbimport.PrintColumnsBiFunction; +import org.apache.cayenne.modeler.editor.dbimport.PrintTablesBiFunction; import org.apache.cayenne.modeler.pref.DBConnectionInfo; import org.apache.cayenne.modeler.pref.DataMapDefaults; import org.apache.cayenne.modeler.util.CayenneAction; @@ -86,24 +93,20 @@ public class LoadDbSchemaAction extends CayenneAction { } if (tablePath != null) { - ReverseEngineering databaseReverseEngineering = new DatabaseSchemaLoader() - .loadColumns(connectionInfo, getApplication().getClassLoadingService(), tablePath); - draggableTreePanel.getSourceTree().updateTableColumns(databaseReverseEngineering); + Object userObject = ((DbImportTreeNode) tablePath.getLastPathComponent()).getUserObject(); + if(userObject instanceof Catalog) { + Catalog catalog = (Catalog) userObject; + if(catalog.getSchemas().isEmpty()) { + loadTables(connectionInfo, tablePath, rootParent); + } + } else if(userObject instanceof Schema) { + loadTables(connectionInfo, tablePath, rootParent); + } else if(userObject instanceof IncludeTable) { + loadColumns(connectionInfo, tablePath); + } } else { - ReverseEngineering databaseReverseEngineering = new DatabaseSchemaLoader() - .load(connectionInfo, - getApplication().getClassLoadingService(), - rootParent.getTableTypes()); - draggableTreePanel.getSourceTree() - .setEnabled(true); - draggableTreePanel.getSourceTree() - .translateReverseEngineeringToTree(databaseReverseEngineering, true); - draggableTreePanel - .bindReverseEngineeringToDatamap(getProjectController().getCurrentDataMap(), databaseReverseEngineering); - ((DbImportModel) draggableTreePanel.getSourceTree().getModel()).reload(); + loadDataBase(connectionInfo); } - - } catch (Exception exception) { JOptionPane.showMessageDialog( Application.getFrame(), @@ -119,6 +122,40 @@ public class LoadDbSchemaAction extends CayenneAction { thread.start(); } + private void loadDataBase(DBConnectionInfo connectionInfo) throws Exception { + ReverseEngineering databaseReverseEngineering = new DatabaseSchemaLoader() + .load(connectionInfo, + getApplication().getClassLoadingService()); + draggableTreePanel.getSourceTree() + .setEnabled(true); + draggableTreePanel.getSourceTree() + .translateReverseEngineeringToTree(databaseReverseEngineering, true); + draggableTreePanel + .bindReverseEngineeringToDatamap(getProjectController().getCurrentDataMap(), databaseReverseEngineering); + ((DbImportModel) draggableTreePanel.getSourceTree().getModel()).reload(); + } + + private void loadTables(DBConnectionInfo connectionInfo, + TreePath tablePath, + DbImportView rootParent) throws SQLException { + ReverseEngineering databaseReverseEngineering = new DatabaseSchemaLoader() + .loadTables(connectionInfo, + getApplication().getClassLoadingService(), + tablePath, + rootParent.getTableTypes()); + draggableTreePanel.getSourceTree() + .update(databaseReverseEngineering, + new PrintTablesBiFunction(draggableTreePanel.getSourceTree())); + } + + private void loadColumns(DBConnectionInfo connectionInfo, TreePath tablePath) throws SQLException { + ReverseEngineering databaseReverseEngineering = new DatabaseSchemaLoader() + .loadColumns(connectionInfo, getApplication().getClassLoadingService(), tablePath); + draggableTreePanel.getSourceTree() + .update(databaseReverseEngineering, + new PrintColumnsBiFunction(draggableTreePanel.getSourceTree())); + } + private boolean datamapPrefNotExist() { Preferences dataMapPreference = getProjectController(). getDataMapPreferences(getProjectController().getCurrentDataMap()) diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java index 5f22e33..90166c3 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DatabaseSchemaLoader.java @@ -50,20 +50,15 @@ public class DatabaseSchemaLoader { } public ReverseEngineering load(DBConnectionInfo connectionInfo, - ClassLoadingService loadingService, - String[] tableTypesFromConfig) throws Exception { + ClassLoadingService loadingService) throws Exception { DbAdapter dbAdapter = connectionInfo.makeAdapter(loadingService); try (Connection connection = connectionInfo.makeDataSource(loadingService).getConnection()) { - String[] types = tableTypesFromConfig != null && tableTypesFromConfig.length != 0 ? - tableTypesFromConfig : - new String[]{"TABLE", "VIEW", "SYSTEM TABLE", - "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM"}; - processCatalogs(connection, types, dbAdapter); + processCatalogs(connection, dbAdapter); } return databaseReverseEngineering; } - private void processCatalogs(Connection connection, String[] types, DbAdapter dbAdapter) throws SQLException { + private void processCatalogs(Connection connection, DbAdapter dbAdapter) throws SQLException { try (ResultSet rsCatalog = connection.getMetaData().getCatalogs()) { boolean hasCatalogs = false; List<String> systemCatalogs = dbAdapter.getSystemCatalogs(); @@ -71,17 +66,16 @@ public class DatabaseSchemaLoader { hasCatalogs = true; String catalog = rsCatalog.getString("TABLE_CAT"); if(!systemCatalogs.contains(catalog)) { - processSchemas(connection, types, catalog, dbAdapter); + processSchemas(connection, catalog, dbAdapter); } } if(!hasCatalogs) { - processSchemas(connection, types, null, dbAdapter); + processSchemas(connection, null, dbAdapter); } } } private void processSchemas(Connection connection, - String[] types, String catalog, DbAdapter dbAdapter) throws SQLException { DatabaseMetaData metaData = connection.getMetaData(); @@ -92,17 +86,58 @@ public class DatabaseSchemaLoader { hasSchemas = true; String schema = rsSchema.getString("TABLE_SCHEM"); if(!systemSchemas.contains(schema)) { - ResultSet resultSet = metaData.getTables(catalog, schema, INCLUDE_ALL_PATTERN, types); - packTable(resultSet); - packProcedures(connection); + packFilterContainer(catalog, schema); } } if(!hasSchemas) { - ResultSet resultSet = metaData.getTables(catalog, null, INCLUDE_ALL_PATTERN, types); - packTable(resultSet); + packFilterContainer(catalog, null); + } + } + } + + public ReverseEngineering loadTables(DBConnectionInfo connectionInfo, + ClassLoadingService loadingService, + TreePath path, + String[] tableTypesFromConfig) throws SQLException { + int pathIndex = 1; + String catalogName = null, schemaName = null; + + Object userObject = getUserObject(path, pathIndex); + if(userObject instanceof Catalog) { + Catalog catalog = (Catalog) userObject; + catalogName = catalog.getName(); + if(!catalog.getSchemas().isEmpty()) { + userObject = getUserObject(path, ++pathIndex); + if (userObject instanceof Schema) { + schemaName = ((Schema) userObject).getName(); + } + } + } else if(userObject instanceof Schema) { + schemaName = ((Schema) userObject).getName(); + } + + try (Connection connection = connectionInfo.makeDataSource(loadingService).getConnection()) { + String[] types = tableTypesFromConfig != null && tableTypesFromConfig.length != 0 ? + tableTypesFromConfig : + new String[]{"TABLE", "VIEW", "SYSTEM TABLE", + "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM"}; + try (ResultSet resultSet = connection.getMetaData() + .getTables(catalogName, schemaName, INCLUDE_ALL_PATTERN, types)) { + boolean hasTables = false; + while (resultSet.next()) { + hasTables = true; + String table = resultSet.getString("TABLE_NAME"); + String schema = resultSet.getString("TABLE_SCHEM"); + String catalog = resultSet.getString("TABLE_CAT"); + packTable(table, catalog == null ? catalogName : catalog, schema, null); + } + if(!hasTables) { + packFilterContainer(catalogName, schemaName); + } packProcedures(connection); } } + return databaseReverseEngineering; } public ReverseEngineering loadColumns(DBConnectionInfo connectionInfo, @@ -136,6 +171,48 @@ public class DatabaseSchemaLoader { return databaseReverseEngineering; } + private FilterContainer packFilterContainer(String catalogName, String schemaName) { + if (catalogName != null && schemaName == null) { + Catalog parentCatalog = getCatalogByName(databaseReverseEngineering.getCatalogs(), catalogName); + + if(parentCatalog == null) { + parentCatalog = new Catalog(); + parentCatalog.setName(catalogName); + databaseReverseEngineering.addCatalog(parentCatalog); + } + + return parentCatalog; + } else if (catalogName == null) { + Schema parentSchema = getSchemaByName(databaseReverseEngineering.getSchemas(), schemaName); + + if(parentSchema == null) { + parentSchema = new Schema(); + parentSchema.setName(schemaName); + databaseReverseEngineering.addSchema(parentSchema); + } + return parentSchema; + } else { + Catalog parentCatalog = getCatalogByName(databaseReverseEngineering.getCatalogs(), catalogName); + Schema parentSchema; + if (parentCatalog != null) { + parentSchema = getSchemaByName(parentCatalog.getSchemas(), schemaName); + if(parentSchema == null) { + parentSchema = new Schema(); + parentSchema.setName(schemaName); + parentCatalog.addSchema(parentSchema); + } + } else { + parentCatalog = new Catalog(); + parentCatalog.setName(catalogName); + parentSchema = new Schema(); + parentSchema.setName(schemaName); + parentCatalog.addSchema(parentSchema); + databaseReverseEngineering.addCatalog(parentCatalog); + } + return parentSchema; + } + } + private Object getUserObject(TreePath path, int pathIndex) { return ((DbImportTreeNode)path.getPathComponent(pathIndex)).getUserObject(); } @@ -154,18 +231,18 @@ public class DatabaseSchemaLoader { if(!schemas.isEmpty()) { for(Schema schema : schemas) { ResultSet procResultSet = getProcedures(connection, catalog.getName(), schema.getName()); - packFunction(procResultSet, schema); + packProcedures(procResultSet, schema); } } else { ResultSet procResultSet = getProcedures(connection, catalog.getName(), null); - packFunction(procResultSet, catalog); + packProcedures(procResultSet, catalog); } } Collection<Schema> schemas = databaseReverseEngineering.getSchemas(); for(Schema schema : schemas) { ResultSet procResultSet = getProcedures(connection, null, schema.getName()); - packFunction(procResultSet, schema); + packProcedures(procResultSet, schema); } } @@ -173,7 +250,7 @@ public class DatabaseSchemaLoader { return connection.getMetaData().getProcedures(catalog, schema, "%"); } - private void packFunction(ResultSet resultSet, FilterContainer filterContainer) throws SQLException { + private void packProcedures(ResultSet resultSet, FilterContainer filterContainer) throws SQLException { while (resultSet.next()) { IncludeProcedure includeProcedure = new IncludeProcedure(resultSet.getString("PROCEDURE_NAME")); @@ -183,15 +260,6 @@ public class DatabaseSchemaLoader { } } - private void packTable(ResultSet resultSet) throws SQLException { - while (resultSet.next()) { - String tableName = resultSet.getString("TABLE_NAME"); - String schemaName = resultSet.getString("TABLE_SCHEM"); - String catalogName = resultSet.getString("TABLE_CAT"); - packTable(tableName, catalogName, schemaName, null); - } - } - private void packTable(String tableName, String catalogName, String schemaName, String columnName) { IncludeTable table = new IncludeTable(); table.setPattern(tableName); @@ -203,46 +271,7 @@ public class DatabaseSchemaLoader { return; } - FilterContainer filterContainer; - if (catalogName != null && schemaName == null) { - Catalog parentCatalog = getCatalogByName(databaseReverseEngineering.getCatalogs(), catalogName); - - if(parentCatalog == null) { - parentCatalog = new Catalog(); - parentCatalog.setName(catalogName); - databaseReverseEngineering.addCatalog(parentCatalog); - } - filterContainer = parentCatalog; - } else if (catalogName == null) { - Schema parentSchema = getSchemaByName(databaseReverseEngineering.getSchemas(), schemaName); - - if(parentSchema == null) { - parentSchema = new Schema(); - parentSchema.setName(schemaName); - databaseReverseEngineering.addSchema(parentSchema); - } - filterContainer = parentSchema; - } else { - Catalog parentCatalog = getCatalogByName(databaseReverseEngineering.getCatalogs(), catalogName); - Schema parentSchema; - if (parentCatalog != null) { - parentSchema = getSchemaByName(parentCatalog.getSchemas(), schemaName); - if(parentSchema == null) { - parentSchema = new Schema(); - parentSchema.setName(schemaName); - parentCatalog.addSchema(parentSchema); - } - } else { - parentCatalog = new Catalog(); - parentCatalog.setName(catalogName); - parentSchema = new Schema(); - parentSchema.setName(schemaName); - parentCatalog.addSchema(parentSchema); - databaseReverseEngineering.addCatalog(parentCatalog); - } - filterContainer = parentSchema; - } - + FilterContainer filterContainer = packFilterContainer(catalogName, schemaName); addTable(filterContainer, table); addColumn(filterContainer, table, columnName); } diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java index 86f49c7..f5e2053 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DbImportTree.java @@ -27,6 +27,7 @@ import javax.swing.tree.TreePath; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.function.BiFunction; import org.apache.cayenne.dbsync.reverse.dbimport.Catalog; import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable; @@ -73,7 +74,8 @@ public class DbImportTree extends JTree { model.reload(); } - public void updateTableColumns(ReverseEngineering reverseEngineering) { + public void update(ReverseEngineering reverseEngineering, + BiFunction<FilterContainer, DbImportTreeNode, Void> processor) { DbImportModel model = (DbImportModel) this.getModel(); DbImportTreeNode root = (DbImportTreeNode) model.getRoot(); Collection<Catalog> catalogs = reverseEngineering.getCatalogs(); @@ -82,55 +84,34 @@ public class DbImportTree extends JTree { Collection<Schema> schemas = catalog.getSchemas(); if(!schemas.isEmpty()) { DbImportTreeNode currentRoot = findNodeInParent(root, catalog); - schemas.forEach(schema -> packNextFilter(schema, currentRoot, model)); + schemas.forEach(schema -> packNextFilter(schema, currentRoot, processor)); } else { - packNextFilter(catalog, root, model); + packNextFilter(catalog, root, processor); } }); } else { - reverseEngineering.getSchemas().forEach(schema -> { - packNextFilter(schema, root, model); - }); + reverseEngineering.getSchemas().forEach(schema -> packNextFilter(schema, root, processor)); } } - private void packNextFilter(FilterContainer filterContainer, - DbImportTreeNode root, - DbImportModel model) { + private void packNextFilter(FilterContainer filterContainer, DbImportTreeNode root, + BiFunction<FilterContainer, DbImportTreeNode, Void> processor) { DbImportTreeNode container = findNodeInParent(root, filterContainer); if (container == null) { return; } - packTables(filterContainer, container, model); - } - - private void packTables(FilterContainer filterContainer, - DbImportTreeNode root, - DbImportModel model) { - filterContainer.getIncludeTables().forEach(tableFilter -> { - DbImportTreeNode container = findNodeInParent(root, tableFilter ); - if (container == null) { - return; - } - if (container.getChildCount() != 0) { - container.removeAllChildren(); - } - - packColumns(tableFilter , container); - - container.setLoaded(true); - model.reload(container); - }); + container.setLoaded(true); + processor.apply(filterContainer, container); } - private void packColumns(IncludeTable includeTable, DbImportTreeNode tableNode) { + void packColumns(IncludeTable includeTable, DbImportTreeNode tableNode) { includeTable.getIncludeColumns().forEach(column -> tableNode.add(new DbImportTreeNode(column))); } - private DbImportTreeNode findNodeInParent(DbImportTreeNode parent, Object object) { + DbImportTreeNode findNodeInParent(DbImportTreeNode parent, Object object) { for (int i = 0; i < parent.getChildCount(); i++) { DbImportTreeNode node = (DbImportTreeNode) parent.getChildAt(i); Object userObject = node.getUserObject(); @@ -258,7 +239,7 @@ public class DbImportTree extends JTree { expandBeginningWithNode(getRootNode(), expandIndexesList); } - private <T extends PatternParam> void printParams(Collection<T> collection, DbImportTreeNode parent) { + public <T extends PatternParam> void printParams(Collection<T> collection, DbImportTreeNode parent) { for (T element : collection) { DbImportTreeNode node = !isTransferable ? new DbImportTreeNode(element) : new TransferableNode(element); if (!node.getSimpleNodeName().equals("")) { @@ -296,6 +277,11 @@ public class DbImportTree extends JTree { for (Schema schema : schemas) { DbImportTreeNode node = !isTransferable ? new DbImportTreeNode(schema) : new TransferableNode(schema); if (!node.getSimpleNodeName().equals("")) { + + if (isTransferable && schema.getIncludeTables().isEmpty() && schema.getExcludeTables().isEmpty()) { + printParams(Collections.singletonList(new IncludeTable("Loading...")), node); + } + printChildren(schema, node); parent.add(node); } @@ -306,6 +292,12 @@ public class DbImportTree extends JTree { for (Catalog catalog : catalogs) { DbImportTreeNode node = !isTransferable ? new DbImportTreeNode(catalog) : new TransferableNode(catalog); if (!node.getSimpleNodeName().equals("")) { + + if (isTransferable && catalog.getSchemas().isEmpty() && + catalog.getIncludeTables().isEmpty() && catalog.getExcludeTables().isEmpty()) { + printParams(Collections.singletonList(new IncludeTable("Loading...")), node); + } + printSchemas(catalog.getSchemas(), node); printChildren(catalog, node); parent.add(node); @@ -325,8 +317,8 @@ public class DbImportTree extends JTree { } DbImportTreeNode node = (DbImportTreeNode) lastPathComponent; - if (node.isIncludeTable() && !node.isLoaded()) { - //reload columns action. + if ((node.isIncludeTable() || node.isSchema() || node.isCatalog()) && !node.isLoaded()) { + //reload tables and columns action. LoadDbSchemaAction action = Application.getInstance().getActionManager().getAction(LoadDbSchemaAction.class); action.performAction(null, path); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintColumnsBiFunction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintColumnsBiFunction.java new file mode 100644 index 0000000..b7003fe --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintColumnsBiFunction.java @@ -0,0 +1,55 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.modeler.editor.dbimport; + +import java.util.function.BiFunction; + +import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer; +import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode; + +public class PrintColumnsBiFunction implements BiFunction<FilterContainer, DbImportTreeNode, Void> { + + private DbImportTree dbImportTree; + + public PrintColumnsBiFunction(DbImportTree dbImportTree) { + this.dbImportTree = dbImportTree; + } + + @Override + public Void apply(FilterContainer filterContainer, DbImportTreeNode root) { + DbImportModel model = (DbImportModel) dbImportTree.getModel(); + filterContainer.getIncludeTables().forEach(tableFilter -> { + DbImportTreeNode container = dbImportTree + .findNodeInParent(root, tableFilter); + if (container == null) { + return; + } + if (container.getChildCount() != 0) { + container.removeAllChildren(); + } + + dbImportTree.packColumns(tableFilter , container); + + container.setLoaded(true); + model.reload(container); + }); + return null; + } +} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintTablesBiFunction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintTablesBiFunction.java new file mode 100644 index 0000000..b547fb9 --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/PrintTablesBiFunction.java @@ -0,0 +1,65 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.modeler.editor.dbimport; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.BiFunction; + +import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn; +import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable; +import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode; +import org.apache.cayenne.modeler.dialog.db.load.TransferableNode; + +public class PrintTablesBiFunction implements BiFunction<FilterContainer, DbImportTreeNode, Void> { + + private DbImportTree dbImportTree; + + public PrintTablesBiFunction(DbImportTree dbImportTree) { + this.dbImportTree = dbImportTree; + } + + @Override + public Void apply(FilterContainer filterContainer, DbImportTreeNode root) { + DbImportModel model = (DbImportModel) dbImportTree.getModel(); + boolean isTransferable = dbImportTree.isTransferable(); + if (root.getChildCount() != 0) { + root.removeAllChildren(); + } + Collection<IncludeTable> includeTables = filterContainer.getIncludeTables(); + for (IncludeTable includeTable : includeTables) { + DbImportTreeNode node = !isTransferable ? + new DbImportTreeNode(includeTable) : + new TransferableNode(includeTable); + if (isTransferable && + includeTable.getIncludeColumns().isEmpty() && + includeTable.getExcludeColumns().isEmpty()) { + dbImportTree.printParams(Collections.singletonList( + new IncludeColumn("Loading...")), node); + } + root.add(node); + dbImportTree.packColumns(includeTable, node); + } + model.reload(root); + + return null; + } +}