You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/12/14 19:12:44 UTC
[08/16] cayenne git commit: New DbMerger for dbsync utils - merger
process split in independent steps - new attributes compared (full type
comparision of DbAttribute)
New DbMerger for dbsync utils
- merger process split in independent steps
- new attributes compared (full type comparision of DbAttribute)
Clean up and tests
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/d5707c75
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/d5707c75
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/d5707c75
Branch: refs/heads/master
Commit: d5707c75203cae33c7c0580b59effd7dcb1b6f66
Parents: c86094f
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Dec 12 12:59:58 2016 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Dec 12 12:59:58 2016 +0300
----------------------------------------------------------------------
.../apache/cayenne/dbsync/merge/DbMerger.java | 402 -------------------
.../cayenne/dbsync/merge/DataMapMergerTest.java | 387 ++++++++++++++++++
.../cayenne/dbsync/merge/DbMergerTest.java | 387 ------------------
3 files changed, 387 insertions(+), 789 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d5707c75/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
deleted file mode 100644
index 9da71b5..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMerger.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * 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 org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.merge.token.AddRelationshipToDb;
-import org.apache.cayenne.dbsync.merge.token.EmptyValueForNullProvider;
-import org.apache.cayenne.dbsync.merge.token.MergerToken;
-import org.apache.cayenne.dbsync.merge.token.TokenComparator;
-import org.apache.cayenne.dbsync.merge.token.ValueForNullProvider;
-import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
-import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
-import org.apache.cayenne.dbsync.reverse.filters.TableFilter;
-import org.apache.cayenne.map.Attribute;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.DetectedDbEntity;
-
-import java.sql.Types;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Wraps an algorithm to traverse a {@link DataMap} and create a group of {@link MergerToken}s that can be used to
- * synchronize data store and Cayenne model.
- * @deprecated
- */
-public class DbMerger {
-
- private MergerTokenFactory tokenFactory;
- private ValueForNullProvider valueForNull;
- private boolean skipRelationshipsTokens;
- private boolean skipPKTokens;
- private FiltersConfig filters;
-
- private DbMerger() {
- }
-
- public static Builder builder(MergerTokenFactory tokenFactory) {
- return new Builder(tokenFactory);
- }
-
- public static DbMerger build(MergerTokenFactory tokenFactory) {
- return builder(tokenFactory).build();
- }
-
- /**
- * Return true if the two unordered {@link Collection}s of {@link DbJoin}s
- * are equal. Entity and Attribute names are compared case insensitively.
- * <p>
- * TODO complexity n^2; sort both collection and go through them to compare
- * = 2*n*log(n) + n
- */
- private static boolean equalDbJoinCollections(Collection<DbJoin> j1s, Collection<DbJoin> j2s) {
- if (j1s.size() != j2s.size()) {
- return false;
- }
-
- for (DbJoin j1 : j1s) {
- if (!havePair(j2s, j1)) {
- return false;
- }
- }
-
- return true;
- }
-
- private static boolean havePair(Collection<DbJoin> j2s, DbJoin j1) {
- for (DbJoin j2 : j2s) {
- if ( !isNull(j1.getSource()) && !isNull(j1.getTarget())
- && !isNull(j2.getSource()) && !isNull(j2.getTarget())
- && j1.getSource().getEntity().getName().equalsIgnoreCase(j2.getSource().getEntity().getName())
- && j1.getTarget().getEntity().getName().equalsIgnoreCase(j2.getTarget().getEntity().getName())
- && j1.getSourceName().equalsIgnoreCase(j2.getSourceName())
- && j1.getTargetName().equalsIgnoreCase(j2.getTargetName())) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isNull(DbAttribute attribute) {
- return attribute == null || attribute.getEntity() == null;
- }
-
- /**
- * Create MergerTokens that represent the difference between two {@link DataMap} objects.
- */
- public List<MergerToken> createMergeTokens(DataMap dataMap, DataMap dbImport) {
-
- dbImport.setQuotingSQLIdentifiers(dataMap.isQuotingSQLIdentifiers());
-
- List<MergerToken> tokens = createMergeTokens(filter(dataMap, filters), dbImport.getDbEntities());
-
- // sort
- Collections.sort(tokens, new TokenComparator());
-
- return tokens;
- }
-
- private Collection<DbEntity> filter(DataMap existing, FiltersConfig filtersConfig) {
- Collection<DbEntity> existingFiltered = new LinkedList<>();
- for (DbEntity entity : existing.getDbEntities()) {
- TableFilter tableFilter = filtersConfig.tableFilter(entity.getCatalog(), entity.getSchema());
- if (tableFilter != null && tableFilter.isIncludeTable(entity.getName()) != null) {
- existingFiltered.add(entity);
- }
- }
- return existingFiltered;
- }
-
- protected List<MergerToken> createMergeTokens(Collection<DbEntity> entities, Collection<DbEntity> dbImportedEntities) {
- Collection<DbEntity> dbEntitiesToDrop = new LinkedList<>(dbImportedEntities);
-
- List<MergerToken> tokens = new LinkedList<>();
- for (DbEntity dbEntity : entities) {
- String tableName = dbEntity.getName();
-
- // look for table
- DbEntity detectedEntity = findDbEntity(dbImportedEntities, tableName);
- if (detectedEntity == null) {
- tokens.add(tokenFactory.createCreateTableToDb(dbEntity));
- // TODO: does this work properly with createReverse?
- for (DbRelationship rel : dbEntity.getRelationships()) {
- tokens.add(tokenFactory.createAddRelationshipToDb(dbEntity, rel));
- }
- continue;
- }
-
- dbEntitiesToDrop.remove(detectedEntity);
-
- tokens.addAll(checkRelationshipsToDrop(dbEntity, detectedEntity));
- if (!skipRelationshipsTokens) {
- tokens.addAll(checkRelationshipsToAdd(dbEntity, detectedEntity));
- }
- tokens.addAll(checkRows(dbEntity, detectedEntity));
-
- if (!skipPKTokens) {
- MergerToken token = checkPrimaryKeyChange(dbEntity, detectedEntity);
- if (token != null) {
- tokens.add(token);
- }
- }
- }
-
- // drop table
- // TODO: support drop table. currently, too many tables are marked for
- // drop
- for (DbEntity e : dbEntitiesToDrop) {
- tokens.add(tokenFactory.createDropTableToDb(e));
- for (DbRelationship relationship : e.getRelationships()) {
- DbEntity detectedEntity = findDbEntity(entities, relationship.getTargetEntityName());
- if (detectedEntity != null) {
- tokens.add(tokenFactory.createDropRelationshipToDb(detectedEntity, relationship.getReverseRelationship()));
- }
- }
- }
-
- return tokens;
- }
-
- private List<MergerToken> checkRows(DbEntity existing, DbEntity loadedFromDb) {
- List<MergerToken> tokens = new LinkedList<MergerToken>();
-
- // columns to drop
- for (DbAttribute detected : loadedFromDb.getAttributes()) {
- if (findDbAttribute(existing, detected.getName()) == null) {
- tokens.add(tokenFactory.createDropColumnToDb(existing, detected));
- }
- }
-
- // columns to add or modify
- for (DbAttribute attr : existing.getAttributes()) {
- String columnName = attr.getName().toUpperCase();
-
- DbAttribute detected = findDbAttribute(loadedFromDb, columnName);
-
- if (detected == null) {
- tokens.add(tokenFactory.createAddColumnToDb(existing, attr));
- if (attr.isMandatory()) {
- if (valueForNull.hasValueFor(existing, attr)) {
- tokens.add(tokenFactory.createSetValueForNullToDb(existing, attr, valueForNull));
- }
- tokens.add(tokenFactory.createSetNotNullToDb(existing, attr));
- }
- continue;
- }
-
- // check for not null
- if (attr.isMandatory() != detected.isMandatory()) {
- if (attr.isMandatory()) {
- if (valueForNull.hasValueFor(existing, attr)) {
- tokens.add(tokenFactory.createSetValueForNullToDb(existing, attr, valueForNull));
- }
- tokens.add(tokenFactory.createSetNotNullToDb(existing, attr));
- } else {
- tokens.add(tokenFactory.createSetAllowNullToDb(existing, attr));
- }
- }
-
- // TODO: check more types than char/varchar
- // TODO: psql report VARCHAR for text column, not clob
- switch (detected.getType()) {
- case Types.VARCHAR:
- case Types.CHAR:
- if (attr.getMaxLength() != detected.getMaxLength()) {
- tokens.add(tokenFactory.createSetColumnTypeToDb(existing, detected, attr));
- }
- break;
- }
- }
-
- return tokens;
- }
-
- private List<MergerToken> checkRelationshipsToDrop(DbEntity dbEntity, DbEntity detectedEntity) {
- List<MergerToken> tokens = new LinkedList<MergerToken>();
-
- // relationships to drop
- for (DbRelationship detected : detectedEntity.getRelationships()) {
- if (findDbRelationship(dbEntity, detected) == null) {
-
- // alter detected relationship to match entity and attribute names.
- // (case sensitively)
-
- DbEntity targetEntity = findDbEntity(dbEntity.getDataMap().getDbEntities(),
- detected.getTargetEntityName());
- if (targetEntity == null) {
- continue;
- }
-
- detected.setSourceEntity(dbEntity);
- detected.setTargetEntityName(targetEntity);
-
- // manipulate the joins to match the DbAttributes in the model
- for (DbJoin join : detected.getJoins()) {
- DbAttribute sattr = findDbAttribute(dbEntity, join.getSourceName());
- if (sattr != null) {
- join.setSourceName(sattr.getName());
- }
- DbAttribute tattr = findDbAttribute(targetEntity, join.getTargetName());
- if (tattr != null) {
- join.setTargetName(tattr.getName());
- }
- }
-
- // Add all relationships. Tokens will decide whether or not to execute
- MergerToken token = tokenFactory.createDropRelationshipToDb(dbEntity, detected);
- tokens.add(token);
- }
- }
-
- return tokens;
- }
-
- private List<MergerToken> checkRelationshipsToAdd(DbEntity dbEntity, DbEntity detectedEntity) {
-
- List<MergerToken> tokens = new LinkedList<MergerToken>();
-
- for (DbRelationship rel : dbEntity.getRelationships()) {
- if (findDbRelationship(detectedEntity, rel) == null) {
- // Add all relationships. Tokens will decide whether or not to execute
- AddRelationshipToDb token = (AddRelationshipToDb) tokenFactory.createAddRelationshipToDb(dbEntity, rel);
- tokens.add(token);
- }
- }
-
- return tokens;
- }
-
- private MergerToken checkPrimaryKeyChange(DbEntity dbEntity, DbEntity detectedEntity) {
- Collection<DbAttribute> primaryKeyOriginal = detectedEntity.getPrimaryKeys();
- Collection<DbAttribute> primaryKeyNew = dbEntity.getPrimaryKeys();
-
- String primaryKeyName = null;
- if (detectedEntity instanceof DetectedDbEntity) {
- primaryKeyName = ((DetectedDbEntity) detectedEntity).getPrimaryKeyName();
- }
-
- if (upperCaseEntityNames(primaryKeyOriginal).equals(upperCaseEntityNames(primaryKeyNew))) {
- return null;
- }
-
- return tokenFactory.createSetPrimaryKeyToDb(dbEntity, primaryKeyOriginal, primaryKeyNew, primaryKeyName);
- }
-
- private Set<String> upperCaseEntityNames(Collection<? extends Attribute> attrs) {
- Set<String> names = new HashSet<String>();
- for (Attribute attr : attrs) {
- names.add(attr.getName().toUpperCase());
- }
- return names;
- }
-
- /**
- * case insensitive search for a {@link DbEntity} in a {@link DataMap} by
- * name
- */
- private DbEntity findDbEntity(Collection<DbEntity> dbEntities, String caseInsensitiveName) {
- // TODO: create a Map with upper case keys?
- for (DbEntity e : dbEntities) {
- if (e.getName().equalsIgnoreCase(caseInsensitiveName)) {
- return e;
- }
- }
- return null;
- }
-
- /**
- * case insensitive search for a {@link DbAttribute} in a {@link DbEntity}
- * by name
- */
- private DbAttribute findDbAttribute(DbEntity entity, String caseInsensitiveName) {
- for (DbAttribute a : entity.getAttributes()) {
- if (a.getName().equalsIgnoreCase(caseInsensitiveName)) {
- return a;
- }
- }
- return null;
- }
-
- /**
- * search for a {@link DbRelationship} like rel in the given
- * {@link DbEntity}
- */
- private DbRelationship findDbRelationship(DbEntity entity, DbRelationship rel) {
- for (DbRelationship candidate : entity.getRelationships()) {
- if (equalDbJoinCollections(candidate.getJoins(), rel.getJoins())) {
- return candidate;
- }
- }
- return null;
- }
-
- @Deprecated
- public static class Builder {
- private DbMerger merger;
-
- private Builder(MergerTokenFactory tokenFactory) {
- this.merger = new DbMerger();
- this.merger.tokenFactory = Objects.requireNonNull(tokenFactory);
- }
-
- public DbMerger build() {
-
- if (merger.valueForNull == null) {
- merger.valueForNull = new EmptyValueForNullProvider();
- }
-
- if (merger.filters == null) {
- // default: match all tables, no stored procedures
- merger.filters = FiltersConfig.create(null, null, TableFilter.everything(), PatternFilter.INCLUDE_NOTHING);
- }
-
- return merger;
- }
-
- public Builder valueForNullProvider(ValueForNullProvider provider) {
- merger.valueForNull = provider;
- return this;
- }
-
- public Builder skipRelationshipsTokens(boolean flag) {
- merger.skipRelationshipsTokens = flag;
- return this;
- }
-
- public Builder skipPKTokens(boolean flag) {
- merger.skipPKTokens = flag;
- return this;
- }
-
- public Builder filters(FiltersConfig filters) {
- merger.filters = Objects.requireNonNull(filters);
- return this;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d5707c75/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
new file mode 100644
index 0000000..c70752a
--- /dev/null
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DataMapMergerTest.java
@@ -0,0 +1,387 @@
+/*****************************************************************
+ * 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 org.apache.cayenne.dbsync.merge.builders.DbEntityBuilder;
+import org.apache.cayenne.dbsync.merge.factory.HSQLMergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.dbsync.merge.token.SetColumnTypeToDb;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+import org.junit.Test;
+
+import java.util.List;
+
+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 DataMapMergerTest {
+
+ @Test
+ public void testEmptyDataMap() throws Exception {
+ DataMap existing = dataMap().build();
+ DataMap db = dataMap().build();
+ assertEquals(0, dbMerger().createMergeTokens(existing, db).size());
+ }
+
+ @Test
+ public void testAddTable() throws Exception {
+ DbEntityBuilder dbEntity =
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ );
+ DataMap existing = dataMap().with(dbEntity).build();
+ DataMap db = dataMap().build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+ assertEquals(factory().createCreateTableToDb(dbEntity.build()).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testRemoveTable() throws Exception {
+ DataMap existing = dataMap().build();
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ )).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+ assertEquals(factory().createDropTableToDb(db.getDbEntity("table1")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testAddColumn() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()
+ )).build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ )).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+
+ DbEntity entity = existing.getDbEntity("table1");
+ assertEquals(factory().createAddColumnToDb(entity, entity.getAttribute("attr02")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testChangeColumnTypeSimple() 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, db);
+ 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, db);
+ 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 testChangeColumnType() throws Exception {
+ DbEntity fromModel = dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").type("DATE"),
+ dbAttr("attr03").type("BOOLEAN"),
+ dbAttr("attr04").type("FLOAT")
+ ).build();
+ DataMap existing = dataMap().with(fromModel).build();
+
+ DbEntity fromDb = dbEntity("table1").attributes(
+ dbAttr("attr01").typeBigInt(),
+ dbAttr("attr02").type("NUMERIC"),
+ dbAttr("attr03").type("BLOB"),
+ dbAttr("attr04").type("TIMESTAMP")
+ ).build();
+ DataMap db = dataMap().with(fromDb).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+ assertEquals(4, tokens.size());
+
+ assertEquals(
+ factory()
+ .createSetColumnTypeToDb(fromModel, fromDb.getAttribute("attr02"), fromModel.getAttribute("attr02"))
+ .getTokenValue(),
+ tokens.get(1)
+ .getTokenValue()
+ );
+
+ for(MergerToken token : tokens) {
+ assertTrue(token instanceof SetColumnTypeToDb);
+ }
+ }
+
+ @Test
+ public void testDropPrimaryKey() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ )
+ ).build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt().primaryKey()
+ )
+ ).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+ assertEquals(1, tokens.size());
+ }
+
+ @Test
+ public void testAddPrimaryKey() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt().primaryKey()
+ )
+ ).build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ )
+ ).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+ assertEquals(1, tokens.size());
+ }
+
+ @Test
+ public void testAddRelationship() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt())
+ ).join("rel", "table1.attr01", "table2.attr01")
+ .build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt())
+ )//.join("table1.attr01", "table2.attr01")
+ .build();
+
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+
+ DbEntity entity = existing.getDbEntity("table1");
+ assertEquals(factory().createAddRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testAddRelationship1() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt().primaryKey(),
+ dbAttr("attr03").typeInt().primaryKey())
+ ).join("rel", "table1.attr01", "table2.attr01")
+ .join("rel1", "table1.attr01", "table2.attr03")
+ .build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt().primaryKey(),
+ dbAttr("attr03").typeInt().primaryKey())
+ ).join("rel", "table1.attr01", "table2.attr02")
+ .join("rel1", "table1.attr01", "table2.attr03")
+ .build();
+
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(2, tokens.size());
+
+ DbEntity entity = existing.getDbEntity("table1");
+ assertEquals(factory().createDropRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+
+ entity = db.getDbEntity("table1");
+ assertEquals(factory().createAddRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testRemoveRelationship() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt())
+ )
+ .build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()),
+
+ dbEntity("table2").attributes(
+ dbAttr("attr01").typeInt().primaryKey(),
+ dbAttr("attr02").typeInt())
+ ).join("rel", "table1.attr01", "table2.attr01")
+ .build();
+
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+
+ DbEntity entity = db.getDbEntity("table1");
+ assertEquals(factory().createDropRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testRemoveColumn() throws Exception {
+ DataMap existing = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt()
+ )).build();
+
+ DataMap db = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt()
+ )).build();
+
+ List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
+
+ assertEquals(1, tokens.size());
+
+ DbEntity entity = db.getDbEntity("table1");
+ assertEquals(factory().createDropColumnToModel(entity, entity.getAttribute("attr02")).getTokenValue(),
+ tokens.get(0).getTokenValue());
+ }
+
+ @Test
+ public void testNoChanges() throws Exception {
+ DataMap dataMap1 = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt(),
+ dbAttr("attr03").typeInt()
+ )).build();
+
+ DataMap dataMap2 = dataMap().with(
+ dbEntity("table1").attributes(
+ dbAttr("attr01").typeInt(),
+ dbAttr("attr02").typeInt(),
+ dbAttr("attr03").typeInt()
+ )).build();
+
+
+ assertEquals(0, dbMerger().createMergeTokens(dataMap1, dataMap2).size());
+ }
+
+ private DataMapMerger dbMerger() {
+ return DataMapMerger.build(factory());
+ }
+
+ private HSQLMergerTokenFactory factory() {
+ return new HSQLMergerTokenFactory();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d5707c75/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
deleted file mode 100644
index 55097e2..0000000
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*****************************************************************
- * 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 org.apache.cayenne.dbsync.merge.builders.DbEntityBuilder;
-import org.apache.cayenne.dbsync.merge.factory.HSQLMergerTokenFactory;
-import org.apache.cayenne.dbsync.merge.token.MergerToken;
-import org.apache.cayenne.dbsync.merge.token.SetColumnTypeToDb;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.junit.Test;
-
-import java.util.List;
-
-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 {
-
- @Test
- public void testEmptyDataMap() throws Exception {
- DataMap existing = dataMap().build();
- DataMap db = dataMap().build();
- assertEquals(0, dbMerger().createMergeTokens(existing, db).size());
- }
-
- @Test
- public void testAddTable() throws Exception {
- DbEntityBuilder dbEntity =
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- );
- DataMap existing = dataMap().with(dbEntity).build();
- DataMap db = dataMap().build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
- assertEquals(factory().createCreateTableToDb(dbEntity.build()).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testRemoveTable() throws Exception {
- DataMap existing = dataMap().build();
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- )).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
- assertEquals(factory().createDropTableToDb(db.getDbEntity("table1")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testAddColumn() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()
- )).build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- )).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
-
- DbEntity entity = existing.getDbEntity("table1");
- assertEquals(factory().createAddColumnToDb(entity, entity.getAttribute("attr02")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testChangeColumnTypeSimple() 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, db);
- 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, db);
- 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 testChangeColumnType() throws Exception {
- DbEntity fromModel = dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").type("DATE"),
- dbAttr("attr03").type("BOOLEAN"),
- dbAttr("attr04").type("FLOAT")
- ).build();
- DataMap existing = dataMap().with(fromModel).build();
-
- DbEntity fromDb = dbEntity("table1").attributes(
- dbAttr("attr01").typeBigInt(),
- dbAttr("attr02").type("NUMERIC"),
- dbAttr("attr03").type("BLOB"),
- dbAttr("attr04").type("TIMESTAMP")
- ).build();
- DataMap db = dataMap().with(fromDb).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
- assertEquals(4, tokens.size());
-
- assertEquals(
- factory()
- .createSetColumnTypeToDb(fromModel, fromDb.getAttribute("attr02"), fromModel.getAttribute("attr02"))
- .getTokenValue(),
- tokens.get(1)
- .getTokenValue()
- );
-
- for(MergerToken token : tokens) {
- assertTrue(token instanceof SetColumnTypeToDb);
- }
- }
-
- @Test
- public void testDropPrimaryKey() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- )
- ).build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt().primaryKey()
- )
- ).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
- assertEquals(1, tokens.size());
- }
-
- @Test
- public void testAddPrimaryKey() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt().primaryKey()
- )
- ).build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- )
- ).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
- assertEquals(1, tokens.size());
- }
-
- @Test
- public void testAddRelationship() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt())
- ).join("rel", "table1.attr01", "table2.attr01")
- .build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt())
- )//.join("table1.attr01", "table2.attr01")
- .build();
-
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
-
- DbEntity entity = existing.getDbEntity("table1");
- assertEquals(factory().createAddRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testAddRelationship1() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt().primaryKey(),
- dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr01")
- .join("rel1", "table1.attr01", "table2.attr03")
- .build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt().primaryKey(),
- dbAttr("attr03").typeInt().primaryKey())
- ).join("rel", "table1.attr01", "table2.attr02")
- .join("rel1", "table1.attr01", "table2.attr03")
- .build();
-
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(2, tokens.size());
-
- DbEntity entity = existing.getDbEntity("table1");
- assertEquals(factory().createDropRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
- tokens.get(0).getTokenValue());
-
- entity = db.getDbEntity("table1");
- assertEquals(factory().createAddRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testRemoveRelationship() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt())
- )
- .build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()),
-
- dbEntity("table2").attributes(
- dbAttr("attr01").typeInt().primaryKey(),
- dbAttr("attr02").typeInt())
- ).join("rel", "table1.attr01", "table2.attr01")
- .build();
-
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
-
- DbEntity entity = db.getDbEntity("table1");
- assertEquals(factory().createDropRelationshipToDb(entity, entity.getRelationship("rel")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testRemoveColumn() throws Exception {
- DataMap existing = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt()
- )).build();
-
- DataMap db = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt()
- )).build();
-
- List<MergerToken> tokens = dbMerger().createMergeTokens(existing, db);
-
- assertEquals(1, tokens.size());
-
- DbEntity entity = db.getDbEntity("table1");
- assertEquals(factory().createDropColumnToModel(entity, entity.getAttribute("attr02")).getTokenValue(),
- tokens.get(0).getTokenValue());
- }
-
- @Test
- public void testNoChanges() throws Exception {
- DataMap dataMap1 = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt(),
- dbAttr("attr03").typeInt()
- )).build();
-
- DataMap dataMap2 = dataMap().with(
- dbEntity("table1").attributes(
- dbAttr("attr01").typeInt(),
- dbAttr("attr02").typeInt(),
- dbAttr("attr03").typeInt()
- )).build();
-
-
- assertEquals(0, dbMerger().createMergeTokens(dataMap1, dataMap2).size());
- }
-
- private DataMapMerger dbMerger() {
- return DataMapMerger.build(factory());
- }
-
- private HSQLMergerTokenFactory factory() {
- return new HSQLMergerTokenFactory();
- }
-}
\ No newline at end of file