Repository: cayenne Updated Branches: refs/heads/master 6e92d71c3 -> ca0ef2824
CAY-2016 cdbimport: Rename table with toMany relationship causes migration error Real problem here is sort order of MergeTokens. - Improved sort on DbImportAction - Added sorting to DB migration Whole sorting need to be review and possibly rewritten. Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0c20dca5 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0c20dca5 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0c20dca5 Branch: refs/heads/master Commit: 0c20dca5173f8aa069fe7dbca193a9016065ddd5 Parents: 263ac1c Author: Nikita Timofeev <stari...@gmail.com> Authored: Mon Dec 5 17:18:13 2016 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Mon Dec 5 17:18:13 2016 +0300 ---------------------------------------------------------------------- .../apache/cayenne/dbsync/merge/DbMerger.java | 15 +-- .../cayenne/dbsync/merge/TokenComparator.java | 46 +++++++++ .../cayenne/dbsync/merge/DbMergerTest.java | 82 +++++++++++++++ .../apache/cayenne/dbsync/merge/MergeCase.java | 6 +- .../dbsync/merge/TokenComparatorTest.java | 101 +++++++++++++++++++ .../tools/dbimport/DefaultDbImportAction.java | 19 +--- .../dbimport/DefaultDbImportActionTest.java | 10 +- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + .../db/MergerTokenSelectorController.java | 2 + 9 files changed, 246 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java index e485a5e..7adb0e5 100644 --- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java @@ -33,7 +33,6 @@ import org.apache.cayenne.map.DetectedDbEntity; import java.sql.Types; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -112,18 +111,8 @@ public class DbMerger { List<MergerToken> tokens = createMergeTokens(filter(dataMap, filters), dbImport.getDbEntities()); - // sort. use a custom Comparator since only toDb tokens are comparable - // by now - Collections.sort(tokens, new Comparator<MergerToken>() { - - public int compare(MergerToken o1, MergerToken o2) { - if (o1 instanceof AbstractToDbToken && o2 instanceof AbstractToDbToken) { - - return ((AbstractToDbToken) o1).compareTo(o2); - } - return 0; - } - }); + // sort + Collections.sort(tokens, new TokenComparator()); return tokens; } http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/TokenComparator.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/TokenComparator.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/TokenComparator.java new file mode 100644 index 0000000..4cc312f --- /dev/null +++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/TokenComparator.java @@ -0,0 +1,46 @@ +/***************************************************************** + * 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 + * + * http://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.dbsync.merge; + +import java.util.Comparator; + +/** + * Simple sort of merge tokens. + * Just move all relationships creation tokens to the end of the list. + */ +public class TokenComparator implements Comparator<MergerToken> { + + @Override + public int compare(MergerToken o1, MergerToken o2) { + if (o1 instanceof AbstractToDbToken && o2 instanceof AbstractToDbToken) { + return ((AbstractToDbToken) o1).compareTo(o2); + } + + if (o1 instanceof AddRelationshipToModel && o2 instanceof AddRelationshipToModel) { + return 0; + } + + if (!(o1 instanceof AddRelationshipToModel || o2 instanceof AddRelationshipToModel)) { + return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); + } + + return o1 instanceof AddRelationshipToModel ? 1 : -1; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java index 62aa013..55e1e4a 100644 --- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java +++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java @@ -31,6 +31,7 @@ import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dataMap; import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbAttr; import static org.apache.cayenne.dbsync.merge.builders.ObjectMother.dbEntity; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class DbMergerTest { @@ -91,6 +92,87 @@ public class DbMergerTest { } @Test + public void testChangeColumnType() throws Exception { + DataMap existing = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeInt() + )).build(); + + DataMap db = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeVarchar(30) + )).build(); + + List<MergerToken> tokens = dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities()); + assertEquals(1, tokens.size()); + + DbEntity entity = existing.getDbEntity("table1"); + DbEntity entityDb = db.getDbEntity("table1"); + assertTrue(tokens.get(0) instanceof SetColumnTypeToDb); + + assertEquals( + factory() + .createSetColumnTypeToDb(entity, entityDb.getAttribute("attr01"), entity.getAttribute("attr01")) + .getTokenValue(), + tokens.get(0) + .getTokenValue() + ); + } + + @Test + public void testChangeColumnLength() throws Exception { + DataMap existing = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeVarchar(60) + )).build(); + + DataMap db = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeVarchar(30) + )).build(); + + List<MergerToken> tokens = dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities()); + assertEquals(1, tokens.size()); + + DbEntity entity = existing.getDbEntity("table1"); + DbEntity entityDb = db.getDbEntity("table1"); + assertTrue(tokens.get(0) instanceof SetColumnTypeToDb); + + assertEquals( + factory() + .createSetColumnTypeToDb(entity, entityDb.getAttribute("attr01"), entity.getAttribute("attr01")) + .getTokenValue(), + tokens.get(0) + .getTokenValue() + ); + } + + /** + * Test unsupported type changes + */ + @Test + public void testNotChangeColumnType() throws Exception { + DataMap existing = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeInt(), + dbAttr("attr02").type("DATE"), + dbAttr("attr03").type("BOOLEAN"), + dbAttr("attr04").type("FLOAT") + )).build(); + + DataMap db = dataMap().with( + dbEntity("table1").attributes( + dbAttr("attr01").typeBigInt(), + dbAttr("attr02").type("NUMERIC"), + dbAttr("attr03").type("BLOB"), + dbAttr("attr04").type("TIMESTAMP") + )).build(); + + List<MergerToken> tokens = dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities()); + assertEquals(0, tokens.size()); + } + + @Test public void testAddRelationship() throws Exception { DataMap existing = dataMap().with( dbEntity("table1").attributes( http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java index 279507d..63e7563 100644 --- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java +++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java @@ -101,9 +101,13 @@ public abstract class MergeCase extends DbSyncCase { } protected List<MergerToken> createMergeTokens() { + return createMergeTokens("ARTIST|GALLERY|PAINTING|NEW_TABLE2?"); + } + + protected List<MergerToken> createMergeTokens(String tableFilterInclude) { FiltersConfig filters = FiltersConfig.create(null, null, - TableFilter.include("ARTIST|GALLERY|PAINTING|NEW_TABLE2?"), PatternFilter.INCLUDE_NOTHING); + TableFilter.include(tableFilterInclude), PatternFilter.INCLUDE_NOTHING); DbLoaderConfiguration loaderConfiguration = new DbLoaderConfiguration(); loaderConfiguration.setFiltersConfig(filters); http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/TokenComparatorTest.java ---------------------------------------------------------------------- diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/TokenComparatorTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/TokenComparatorTest.java new file mode 100644 index 0000000..06adb75 --- /dev/null +++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/TokenComparatorTest.java @@ -0,0 +1,101 @@ +/***************************************************************** + * 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 + * + * http://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.dbsync.merge; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class TokenComparatorTest { + + TokenComparator comparator; + + @Before + public void setUp() { + comparator = new TokenComparator(); + } + + private List<String> toClassesNames(List<MergerToken> sort) { + List<String> res = new ArrayList<String>(sort.size()); + for (MergerToken mergerToken : sort) { + res.add(mergerToken.getClass().getSimpleName()); + } + return res; + } + + @Test + public void testToModelTokensCompare() throws Exception { + List<MergerToken> tokens = Arrays.<MergerToken>asList( + new DropColumnToModel(null, null), + new DropRelationshipToModel(null, null), + new DropTableToModel(null), + new AddColumnToDb(null, null), + new AddRelationshipToModel(null, null), + new AddColumnToModel(null, null), + new CreateTableToModel(null)); + Collections.sort(tokens, comparator); + + List<String> actual = toClassesNames(tokens); + List<String> expected = Arrays.asList( + "AddColumnToDb", + "AddColumnToModel", + "CreateTableToModel", + "DropColumnToModel", + "DropRelationshipToModel", + "DropTableToModel", + "AddRelationshipToModel" + ); + + assertEquals(expected, actual); + } + + @Test + public void testToDbTokensCompare() throws Exception { + List<MergerToken> tokens = Arrays.<MergerToken>asList( + new DropColumnToDb(null, null), + new DropRelationshipToDb(null, null), + new DropTableToDb(null), + new AddColumnToModel(null, null), + new AddRelationshipToDb(null, null), + new AddColumnToDb(null, null), + new CreateTableToDb(null)); + Collections.sort(tokens, comparator); + + List<String> actual = toClassesNames(tokens); + List<String> expected = Arrays.asList( + "AddColumnToModel", + "DropRelationshipToDb", + "DropColumnToDb", + "DropTableToDb", + "AddColumnToDb", + "AddRelationshipToDb", + "CreateTableToDb" + ); + + assertEquals(expected, actual); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java ---------------------------------------------------------------------- diff --git a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java index 7c2ed12..331a155 100644 --- a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java +++ b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java @@ -25,12 +25,12 @@ import org.apache.cayenne.configuration.server.DbAdapterFactory; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.dbsync.filter.NameFilter; import org.apache.cayenne.dbsync.merge.AbstractToModelToken; -import org.apache.cayenne.dbsync.merge.AddRelationshipToDb; import org.apache.cayenne.dbsync.merge.DbMerger; import org.apache.cayenne.dbsync.merge.MergerContext; import org.apache.cayenne.dbsync.merge.MergerToken; import org.apache.cayenne.dbsync.merge.ModelMergeDelegate; import org.apache.cayenne.dbsync.merge.ProxyModelMergeDelegate; +import org.apache.cayenne.dbsync.merge.TokenComparator; import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory; import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider; import org.apache.cayenne.dbsync.naming.ObjectNameGenerator; @@ -64,7 +64,6 @@ import java.io.IOException; import java.sql.Connection; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.LinkedList; import java.util.List; @@ -98,21 +97,7 @@ public class DefaultDbImportAction implements DbImportAction { } protected static List<MergerToken> sort(List<MergerToken> reverse) { - Collections.sort(reverse, new Comparator<MergerToken>() { - @Override - public int compare(MergerToken o1, MergerToken o2) { - if (o1 instanceof AddRelationshipToDb && o2 instanceof AddRelationshipToDb) { - return 0; - } - - if (!(o1 instanceof AddRelationshipToDb || o2 instanceof AddRelationshipToDb)) { - return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); - } - - return o1 instanceof AddRelationshipToDb ? 1 : -1; - } - }); - + Collections.sort(reverse, new TokenComparator()); return reverse; } http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java ---------------------------------------------------------------------- diff --git a/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java b/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java index 34365fc..aa635b2 100644 --- a/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java +++ b/cayenne-tools/src/test/java/org/apache/cayenne/tools/dbimport/DefaultDbImportActionTest.java @@ -25,8 +25,8 @@ import org.apache.cayenne.configuration.server.DbAdapterFactory; import org.apache.cayenne.dba.DbAdapter; import org.apache.cayenne.dbsync.DbSyncModule; import org.apache.cayenne.dbsync.filter.NamePatternMatcher; -import org.apache.cayenne.dbsync.merge.AddColumnToDb; -import org.apache.cayenne.dbsync.merge.AddRelationshipToDb; +import org.apache.cayenne.dbsync.merge.AddColumnToModel; +import org.apache.cayenne.dbsync.merge.AddRelationshipToModel; import org.apache.cayenne.dbsync.merge.CreateTableToDb; import org.apache.cayenne.dbsync.merge.CreateTableToModel; import org.apache.cayenne.dbsync.merge.DefaultModelMergeDelegate; @@ -330,12 +330,12 @@ public class DefaultDbImportActionTest { @Test public void testMergeTokensSorting() { LinkedList<MergerToken> tokens = new LinkedList<MergerToken>(); - tokens.add(new AddColumnToDb(null, null)); - tokens.add(new AddRelationshipToDb(null, null)); + tokens.add(new AddColumnToModel(null, null)); + tokens.add(new AddRelationshipToModel(null, null)); tokens.add(new CreateTableToDb(null)); tokens.add(new CreateTableToModel(null)); - assertEquals(asList("AddColumnToDb", "CreateTableToDb", "CreateTableToModel", "AddRelationshipToDb"), + assertEquals(asList("AddColumnToModel", "CreateTableToDb", "CreateTableToModel", "AddRelationshipToModel"), toClasses(DefaultDbImportAction.sort(tokens))); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/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 76d0283..8075caf 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -45,6 +45,7 @@ CAY-2136 Allow Ordering.orderedList(â¦) methods to accept a Collection rather t Bug Fixes: +CAY-2016 cdbimport: Rename table with toMany relationship causes migration error CAY-2064 Issue with BeanAccessor for classes with complex inheritance CAY-2066 Fixes for inner enums handling in ExtendedTypeMap CAY-2067 Cayenne 4.0 connection pool is occasionally running out of connections http://git-wip-us.apache.org/repos/asf/cayenne/blob/0c20dca5/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerTokenSelectorController.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerTokenSelectorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerTokenSelectorController.java index cfb1af1..666b113 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerTokenSelectorController.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerTokenSelectorController.java @@ -20,6 +20,7 @@ package org.apache.cayenne.modeler.dialog.db; import org.apache.cayenne.dbsync.merge.MergeDirection; import org.apache.cayenne.dbsync.merge.MergerToken; +import org.apache.cayenne.dbsync.merge.TokenComparator; import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.util.CayenneController; @@ -231,6 +232,7 @@ public class MergerTokenSelectorController extends CayenneController { } } + Collections.sort(selectableTokensList, new TokenComparator()); AbstractTableModel model = (AbstractTableModel) view.getTokens().getModel(); model.fireTableDataChanged(); }