CAY-2151 Migrate Database Schema: issue when no db is specified The problem is more complicated as simple catalog/schema selection. Some more problems still there see https://issues.apache.org/jira/browse/CAY-2156 Partial fix: - added catalogs select along with schema - skip AUTO_PK_SUPPORT creation if DbEntity has generated or custom PK generation strategy
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/1bbc93ed Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/1bbc93ed Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/1bbc93ed Branch: refs/heads/master Commit: 1bbc93ed8f52cc5fafa0dcc1ea1d2dcce3ce32e4 Parents: 66d44c2 Author: Nikita Timofeev <stari...@gmail.com> Authored: Mon Nov 28 12:04:50 2016 +0300 Committer: Savva Kolbachev <s.kolbac...@gmail.com> Committed: Tue Nov 29 18:30:28 2016 +0300 ---------------------------------------------------------------------- .../cayenne/dbsync/merge/CreateTableToDb.java | 30 ++++++++-- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + .../cayenne/modeler/action/MigrateAction.java | 20 +++++-- .../dialog/db/DbMigrateOptionsDialog.java | 61 +++++++++++++++----- .../modeler/dialog/db/MergerOptions.java | 25 ++------ 5 files changed, 91 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/1bbc93ed/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java index 9584aaf..b5d920c 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java @@ -21,6 +21,7 @@ package org.apache.cayenne.dbsync.merge; import org.apache.cayenne.access.DataNode; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory; +import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.validation.SimpleValidationFailure; @@ -37,8 +38,10 @@ public class CreateTableToDb extends AbstractToDbToken.Entity { @Override public List<String> createSql(DbAdapter adapter) { List<String> sqls = new ArrayList<String>(); - sqls.addAll(adapter.getPkGenerator().createAutoPkStatements( - Collections.singletonList(getEntity()))); + if(needAutoPkSupport()) { + sqls.addAll(adapter.getPkGenerator().createAutoPkStatements( + Collections.singletonList(getEntity()))); + } sqls.add(adapter.createTable(getEntity())); return sqls; } @@ -48,9 +51,11 @@ public class CreateTableToDb extends AbstractToDbToken.Entity { try { DataNode node = mergerContext.getDataNode(); DbAdapter adapter = node.getAdapter(); - adapter.getPkGenerator().createAutoPk( - node, - Collections.singletonList(getEntity())); + if(needAutoPkSupport()) { + adapter.getPkGenerator().createAutoPk( + node, + Collections.singletonList(getEntity())); + } executeSql(mergerContext, adapter.createTable(getEntity())); } catch (Exception e) { @@ -59,6 +64,21 @@ public class CreateTableToDb extends AbstractToDbToken.Entity { } } + private boolean needAutoPkSupport() { + DbEntity entity = getEntity(); + if(entity.getPrimaryKeyGenerator() != null) { + return false; + } + + for(DbAttribute attribute : entity.getPrimaryKeys()) { + if(attribute.isGenerated()) { + return false; + } + } + + return true; + } + public MergerToken createReverse(MergerTokenFactory factory) { return factory.createDropTableToModel(getEntity()); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/1bbc93ed/docs/doc/src/main/resources/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt index d472619..76d0283 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -73,6 +73,7 @@ CAY-2144 cdbimport always fails for databases which don't support catalogs CAY-2146 Vertical inheritance: record still inserted into parent db table when child validation fails CAY-2148 Failure upgrading from 3.1 to M4 CAY-2150 UI bug: PK generation custom sequence is getting reset +CAY-2151 Migrate Database Schema: issue when no db is specified CAY-2153 Modeler Exception in save action after reverse engineering some complex DB schema CAY-2154 Migrate db: queries order http://git-wip-us.apache.org/repos/asf/cayenne/blob/1bbc93ed/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java index f565cda..5f10f09 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/MigrateAction.java @@ -72,13 +72,18 @@ public class MigrateAction extends DBWizardAction { } //showOptions dialog String selectedSchema = null; + String selectedCatalog = null; try { List<String> schemas = getSchemas(connectWizard); - if (schemas != null && !schemas.isEmpty()) { - DbMigrateOptionsDialog optionsDialog = new DbMigrateOptionsDialog(schemas, connectWizard.getConnectionInfo().getUserName()); + List<String> catalogs = getCatalogs(connectWizard); + if (!catalogs.isEmpty() || !schemas.isEmpty()) { + DbMigrateOptionsDialog optionsDialog = new DbMigrateOptionsDialog(catalogs, schemas, connectWizard.getConnectionInfo().getUserName()); optionsDialog.showDialog(); if (optionsDialog.getChoice() == DbMigrateOptionsDialog.SELECT) { selectedSchema = optionsDialog.getSelectedSchema(); + selectedCatalog = optionsDialog.getSelectedCatalog(); + } else { + return; } } } catch (Exception ex) { @@ -97,12 +102,17 @@ public class MigrateAction extends DBWizardAction { getProjectController(), "Migrate DB Schema: Options", connectWizard.getConnectionInfo(), - map, selectedSchema, mergerTokenFactoryProvider).startupAction(); + map, selectedCatalog, selectedSchema, mergerTokenFactoryProvider).startupAction(); + } + + private List<String> getCatalogs(DataSourceController connectWizard) throws Exception { + DataSource dataSource = connectWizard.getConnectionInfo() + .makeDataSource(getApplication().getClassLoadingService()); + + return DbLoader.loadCatalogs(dataSource.getConnection()); } private List<String> getSchemas(DataSourceController connectWizard) throws Exception { - DbAdapter dbAdapter = connectWizard.getConnectionInfo() - .makeAdapter(getApplication().getClassLoadingService()); DataSource dataSource = connectWizard.getConnectionInfo() .makeDataSource(getApplication().getClassLoadingService()); http://git-wip-us.apache.org/repos/asf/cayenne/blob/1bbc93ed/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbMigrateOptionsDialog.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbMigrateOptionsDialog.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbMigrateOptionsDialog.java index f0ee8aa..f53bf9c 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbMigrateOptionsDialog.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/DbMigrateOptionsDialog.java @@ -43,16 +43,18 @@ public class DbMigrateOptionsDialog extends CayenneDialog { public static final int SELECT = 1; protected JLabel schemaLabel; - protected JComboBox schemaSelector; + protected JLabel catalogLabel; + protected JComboBox<String> catalogSelector; + protected JComboBox<String> schemaSelector; protected JButton selectButton; protected JButton cancelButton; protected int choice; - public DbMigrateOptionsDialog(Collection<String> schemas, String dbUserName) { - super(Application.getFrame(), "Migrate DB Schema: Select Schema"); + public DbMigrateOptionsDialog(Collection<String> catalogs, Collection<String> schemas, String dbUserName) { + super(Application.getFrame(), "Migrate DB Schema: Select Catalog and Schema"); init(); initController(); - initFromModel(schemas, dbUserName); + initFromModel(catalogs, schemas, dbUserName); pack(); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); @@ -63,13 +65,15 @@ public class DbMigrateOptionsDialog extends CayenneDialog { protected void init() { selectButton = new JButton("Continue"); cancelButton = new JButton("Cancel"); - schemaSelector = new JComboBox(); + catalogSelector = new JComboBox<>(); + schemaSelector = new JComboBox<>(); FormLayout layout = new FormLayout( "right:pref, 3dlu, fill:max(170dlu;pref):grow", ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); builder.setDefaultDialogBorder(); + catalogLabel = builder.append("Select Catalog:", catalogSelector, true); schemaLabel = builder.append("Select Schema:", schemaSelector); JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT)); @@ -108,21 +112,44 @@ public class DbMigrateOptionsDialog extends CayenneDialog { setVisible(false); } - protected void initFromModel(Collection<String> schemas, String dbUserName) { + protected void initFromModel(Collection<String> catalogs, Collection<String> schemas, String dbUserName) { this.choice = CANCEL; - schemaSelector.setVisible(true); - schemaLabel.setVisible(true); - schemaSelector.setModel(new DefaultComboBoxModel(schemas.toArray(new String[] {}))); + if(!schemas.isEmpty()) { + schemaLabel.setVisible(true); + schemaSelector.setModel(new DefaultComboBoxModel<>(schemas.toArray(new String[0]))); + schemaSelector.setVisible(true); + } else { + schemaLabel.setVisible(false); + schemaSelector.setVisible(false); + } + + if(!catalogs.isEmpty()) { + catalogLabel.setVisible(true); + catalogSelector.setModel(new DefaultComboBoxModel<>(catalogs.toArray(new String[0]))); + catalogSelector.setVisible(true); + } else { + catalogLabel.setVisible(false); + catalogSelector.setVisible(false); + } + + if (dbUserName == null) { + return; + } // select schema belonging to the user - if (dbUserName != null) { - for (String schema : schemas) { - if (dbUserName.equalsIgnoreCase(schema)) { - schemaSelector.setSelectedItem(schema); - break; - } + for (String schema : schemas) { + if (dbUserName.equalsIgnoreCase(schema)) { + schemaSelector.setSelectedItem(schema); + break; + } + } + + for(String catalog : catalogs) { + if(dbUserName.equalsIgnoreCase(catalog)) { + catalogSelector.setSelectedItem(catalog); + break; } } } @@ -133,6 +160,10 @@ public class DbMigrateOptionsDialog extends CayenneDialog { public String getSelectedSchema() { return (String) schemaSelector.getSelectedItem(); } + + public String getSelectedCatalog() { + return (String) catalogSelector.getSelectedItem(); + } public int getChoice() { return choice; http://git-wip-us.apache.org/repos/asf/cayenne/blob/1bbc93ed/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java index 3709aae..52a3666 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java @@ -85,6 +85,7 @@ public class MergerOptions extends CayenneController { protected String textForSQL; protected MergerTokenSelectorController tokens; + protected String defaultCatalog; protected String defaultSchema; private MergerTokenFactoryProvider mergerTokenFactoryProvider; @@ -92,6 +93,7 @@ public class MergerOptions extends CayenneController { String title, DBConnectionInfo connectionInfo, DataMap dataMap, + String defaultCatalog, String defaultSchema, MergerTokenFactoryProvider mergerTokenFactoryProvider) { super(parent); @@ -101,18 +103,12 @@ public class MergerOptions extends CayenneController { this.tokens = new MergerTokenSelectorController(parent); this.view = new MergerOptionsView(tokens.getView()); this.connectionInfo = connectionInfo; + this.defaultCatalog = defaultCatalog; this.defaultSchema = defaultSchema; - /* - * TODO:? this.generatorDefaults = (DBGeneratorDefaults) parent - * .getPreferenceDomainForProject() .getDetail("DbGenerator", - * DBGeneratorDefaults.class, true); - */ this.view.setTitle(title); initController(); - // tables.updateTables(dataMap); prepareMigrator(); - // generatorDefaults.configureGenerator(generator); createSQL(); refreshView(); } @@ -121,10 +117,6 @@ public class MergerOptions extends CayenneController { return view; } - /* - * public DBGeneratorDefaults getGeneratorDefaults() { return generatorDefaults; } - */ - public String getTextForSQL() { return textForSQL; } @@ -165,7 +157,7 @@ public class MergerOptions extends CayenneController { tokens.setMergerTokenFactory(mergerTokenFactory); - FiltersConfig filters = FiltersConfig.create(null, defaultSchema, TableFilter.everything(), + FiltersConfig filters = FiltersConfig.create(defaultCatalog, defaultSchema, TableFilter.everything(), PatternFilter.INCLUDE_NOTHING); DbMerger merger = DbMerger.builder(mergerTokenFactory) @@ -222,12 +214,6 @@ public class MergerOptions extends CayenneController { } protected void refreshView() { - - /* - * for (int i = 0; i < optionBindings.length; i++) { - * optionBindings[i].updateView(); } - */ - sqlBinding.updateView(); } @@ -248,7 +234,6 @@ public class MergerOptions extends CayenneController { } public void refreshGeneratorAction() { - // prepareMigrator(); refreshSQLAction(); } @@ -256,8 +241,6 @@ public class MergerOptions extends CayenneController { * Updates a text area showing generated SQL. */ public void refreshSQLAction() { - // sync generator with defaults, make SQL, then sync the view... - // generatorDefaults.configureGenerator(generator); createSQL(); sqlBinding.updateView(); }