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:41 UTC
[05/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)
First draft: no source filtering
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/46c8ded5
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/46c8ded5
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/46c8ded5
Branch: refs/heads/master
Commit: 46c8ded55629f1a91764491e6a9a255bd0ae783f
Parents: 1e01dc8
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Dec 9 18:17:39 2016 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Dec 9 18:17:40 2016 +0300
----------------------------------------------------------------------
.../cayenne/dbsync/merge/AbstractMerger.java | 89 ++++
.../cayenne/dbsync/merge/AbstractToDbToken.java | 130 -----
.../dbsync/merge/AbstractToModelToken.java | 125 -----
.../cayenne/dbsync/merge/AddColumnToDb.java | 74 ---
.../cayenne/dbsync/merge/AddColumnToModel.java | 52 --
.../dbsync/merge/AddRelationshipToDb.java | 87 ----
.../dbsync/merge/AddRelationshipToModel.java | 89 ----
.../cayenne/dbsync/merge/ChainMerger.java | 64 +++
.../cayenne/dbsync/merge/CreateTableToDb.java | 86 ----
.../dbsync/merge/CreateTableToModel.java | 98 ----
.../cayenne/dbsync/merge/DataMapMerger.java | 144 ++++++
.../dbsync/merge/DbAttributeDictionary.java | 44 ++
.../cayenne/dbsync/merge/DbAttributeMerger.java | 159 ++++++
.../dbsync/merge/DbEntityDictionary.java | 44 ++
.../cayenne/dbsync/merge/DbEntityMerger.java | 108 ++++
.../apache/cayenne/dbsync/merge/DbMerger.java | 12 +-
.../dbsync/merge/DbRelationshipDictionary.java | 83 +++
.../dbsync/merge/DbRelationshipMerger.java | 127 +++++
.../dbsync/merge/DefaultModelMergeDelegate.java | 89 ----
.../merge/DefaultValueForNullProvider.java | 62 ---
.../cayenne/dbsync/merge/DropColumnToDb.java | 61 ---
.../cayenne/dbsync/merge/DropColumnToModel.java | 77 ---
.../dbsync/merge/DropRelationshipToDb.java | 83 ---
.../dbsync/merge/DropRelationshipToModel.java | 49 --
.../cayenne/dbsync/merge/DropTableToDb.java | 51 --
.../cayenne/dbsync/merge/DropTableToModel.java | 51 --
.../cayenne/dbsync/merge/DummyReverseToken.java | 65 ---
.../dbsync/merge/EmptyValueForNullProvider.java | 40 --
.../dbsync/merge/EntityMergeSupport.java | 515 ------------------
.../cayenne/dbsync/merge/MergeDirection.java | 70 ---
.../org/apache/cayenne/dbsync/merge/Merger.java | 30 ++
.../cayenne/dbsync/merge/MergerContext.java | 170 ------
.../cayenne/dbsync/merge/MergerDictionary.java | 54 ++
.../dbsync/merge/MergerDictionaryDiff.java | 117 +++++
.../cayenne/dbsync/merge/MergerDiffPair.java | 39 ++
.../cayenne/dbsync/merge/MergerToken.java | 57 --
.../dbsync/merge/ModelMergeDelegate.java | 62 ---
.../dbsync/merge/ProxyModelMergeDelegate.java | 108 ----
.../cayenne/dbsync/merge/SetAllowNullToDb.java | 58 ---
.../dbsync/merge/SetAllowNullToModel.java | 45 --
.../cayenne/dbsync/merge/SetColumnTypeToDb.java | 111 ----
.../dbsync/merge/SetColumnTypeToModel.java | 95 ----
.../cayenne/dbsync/merge/SetNotNullToDb.java | 52 --
.../cayenne/dbsync/merge/SetNotNullToModel.java | 45 --
.../cayenne/dbsync/merge/SetPrimaryKeyToDb.java | 87 ----
.../dbsync/merge/SetPrimaryKeyToModel.java | 80 ---
.../dbsync/merge/SetValueForNullToDb.java | 48 --
.../cayenne/dbsync/merge/TokenComparator.java | 46 --
.../dbsync/merge/ValueForNullProvider.java | 41 --
.../merge/context/EntityMergeSupport.java | 516 +++++++++++++++++++
.../dbsync/merge/context/MergeDirection.java | 71 +++
.../dbsync/merge/context/MergerContext.java | 174 +++++++
.../merge/factory/DB2MergerTokenFactory.java | 4 +-
.../factory/DefaultMergerTokenFactory.java | 46 +-
.../merge/factory/DerbyMergerTokenFactory.java | 8 +-
.../factory/FirebirdMergerTokenFactory.java | 10 +-
.../merge/factory/H2MergerTokenFactory.java | 8 +-
.../merge/factory/HSQLMergerTokenFactory.java | 8 +-
.../merge/factory/IngresMergerTokenFactory.java | 14 +-
.../merge/factory/MergerTokenFactory.java | 4 +-
.../merge/factory/MySQLMergerTokenFactory.java | 12 +-
.../factory/OpenBaseMergerTokenFactory.java | 12 +-
.../merge/factory/OracleMergerTokenFactory.java | 10 +-
.../factory/PostgresMergerTokenFactory.java | 4 +-
.../factory/SQLServerMergerTokenFactory.java | 10 +-
.../merge/factory/SybaseMergerTokenFactory.java | 12 +-
.../dbsync/merge/token/AbstractToDbToken.java | 133 +++++
.../merge/token/AbstractToModelToken.java | 128 +++++
.../dbsync/merge/token/AddColumnToDb.java | 74 +++
.../dbsync/merge/token/AddColumnToModel.java | 55 ++
.../dbsync/merge/token/AddRelationshipToDb.java | 88 ++++
.../merge/token/AddRelationshipToModel.java | 91 ++++
.../dbsync/merge/token/CreateTableToDb.java | 88 ++++
.../dbsync/merge/token/CreateTableToModel.java | 100 ++++
.../token/DefaultValueForNullProvider.java | 63 +++
.../dbsync/merge/token/DropColumnToDb.java | 62 +++
.../dbsync/merge/token/DropColumnToModel.java | 79 +++
.../merge/token/DropRelationshipToDb.java | 84 +++
.../merge/token/DropRelationshipToModel.java | 51 ++
.../dbsync/merge/token/DropTableToDb.java | 52 ++
.../dbsync/merge/token/DropTableToModel.java | 53 ++
.../dbsync/merge/token/DummyReverseToken.java | 68 +++
.../merge/token/EmptyValueForNullProvider.java | 41 ++
.../cayenne/dbsync/merge/token/MergerToken.java | 58 +++
.../dbsync/merge/token/SetAllowNullToDb.java | 59 +++
.../dbsync/merge/token/SetAllowNullToModel.java | 47 ++
.../dbsync/merge/token/SetColumnTypeToDb.java | 112 ++++
.../merge/token/SetColumnTypeToModel.java | 97 ++++
.../dbsync/merge/token/SetNotNullToDb.java | 53 ++
.../dbsync/merge/token/SetNotNullToModel.java | 47 ++
.../dbsync/merge/token/SetPrimaryKeyToDb.java | 88 ++++
.../merge/token/SetPrimaryKeyToModel.java | 82 +++
.../dbsync/merge/token/SetValueForNullToDb.java | 49 ++
.../dbsync/merge/token/TokenComparator.java | 46 ++
.../merge/token/ValueForNullProvider.java | 42 ++
.../dbload/DefaultModelMergeDelegate.java | 90 ++++
.../reverse/dbload/ModelMergeDelegate.java | 65 +++
.../reverse/dbload/ProxyModelMergeDelegate.java | 109 ++++
.../dbsync/merge/AddColumnToModelIT.java | 2 +
.../dbsync/merge/CreateTableToModelIT.java | 3 +
.../cayenne/dbsync/merge/DbMergerTest.java | 35 +-
.../dbsync/merge/DropColumnToModelIT.java | 3 +
.../dbsync/merge/DropRelationshipToModelIT.java | 3 +
.../dbsync/merge/DropTableToModelIT.java | 2 +
.../dbsync/merge/EntityMergeSupportIT.java | 1 +
.../apache/cayenne/dbsync/merge/MergeCase.java | 3 +
.../dbsync/merge/TokenComparatorTest.java | 14 +
.../cayenne/dbsync/merge/TokensReverseTest.java | 3 +-
.../merge/TokensToModelExecutionTest.java | 1 +
.../cayenne/dbsync/merge/ValueForNullIT.java | 1 +
.../java/org/apache/cayenne/map/DbEntity.java | 4 +-
.../tools/dbimport/DbImportConfiguration.java | 4 +-
.../tools/dbimport/DefaultDbImportAction.java | 16 +-
.../dbimport/DefaultDbImportActionTest.java | 12 +-
.../modeler/action/CreateObjEntityAction.java | 2 +-
.../modeler/action/DbEntitySyncAction.java | 2 +-
.../modeler/action/ObjEntitySyncAction.java | 2 +-
.../modeler/dialog/db/MergerOptions.java | 18 +-
.../db/MergerTokenSelectorController.java | 6 +-
.../dialog/db/MergerTokenTableModel.java | 4 +-
.../dialog/objentity/EntitySyncController.java | 2 +-
121 files changed, 4398 insertions(+), 3195 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractMerger.java
new file mode 100644
index 0000000..c6772e1
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractMerger.java
@@ -0,0 +1,89 @@
+/*****************************************************************
+ * 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.Collection;
+import java.util.List;
+
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.DataMap;
+
+abstract class AbstractMerger<T, M> implements Merger<T> {
+
+ private MergerDictionaryDiff<M> diff;
+ private MergerTokenFactory tokenFactory;
+ DataMap originalDataMap;
+ DataMap importedDataMap;
+
+ AbstractMerger(MergerTokenFactory tokenFactory, DataMap original, DataMap imported) {
+ this.tokenFactory = tokenFactory;
+ this.originalDataMap = original;
+ this.importedDataMap = imported;
+ }
+
+ public List<MergerToken> createMergeTokens(T original, T imported) {
+ diff = createDiff(original, imported);
+
+ List<MergerToken> tokens = new ArrayList<>();
+
+ for(MergerDiffPair<M> pair : diff.getMissing()) {
+ Collection<MergerToken> tokensForMissing = createTokensForMissing(pair);
+ if(tokensForMissing != null) {
+ tokens.addAll(tokensForMissing);
+ }
+ }
+
+ for(MergerDiffPair<M> pair : diff.getSame()) {
+ Collection<MergerToken> tokensForSame = createTokensForSame(pair);
+ if(tokensForSame != null) {
+ tokens.addAll(tokensForSame);
+ }
+ }
+
+ return tokens;
+ }
+
+ MergerDictionaryDiff<M> getDiff() {
+ return diff;
+ }
+
+ MergerTokenFactory getTokenFactory() {
+ return tokenFactory;
+ }
+
+ private Collection<MergerToken> createTokensForMissing(MergerDiffPair<M> missing) {
+ if(missing.getOriginal() == null) {
+ return createTokensForMissingOriginal(missing.getImported());
+ } else {
+ return createTokensForMissingImported(missing.getOriginal());
+ }
+ }
+
+ abstract MergerDictionaryDiff<M> createDiff(T original, T imported);
+
+ abstract Collection<MergerToken> createTokensForMissingOriginal(M imported);
+
+ abstract Collection<MergerToken> createTokensForMissingImported(M original);
+
+ abstract Collection<MergerToken> createTokensForSame(MergerDiffPair<M> same);
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToDbToken.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToDbToken.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToDbToken.java
deleted file mode 100644
index 88e056f..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToDbToken.java
+++ /dev/null
@@ -1,130 +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.dba.DbAdapter;
-import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.validation.SimpleValidationFailure;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
-/**
- * Common abstract superclass for all {@link MergerToken}s going from the model
- * to the database.
- */
-public abstract class AbstractToDbToken implements MergerToken, Comparable<MergerToken> {
-
- private final String tokenName;
-
- protected AbstractToDbToken(String tokenName) {
- this.tokenName = tokenName;
- }
-
- @Override
- public final String getTokenName() {
- return tokenName;
- }
-
- @Override
- public final MergeDirection getDirection() {
- return MergeDirection.TO_DB;
- }
-
- @Override
- public void execute(MergerContext mergerContext) {
- for (String sql : createSql(mergerContext.getDataNode().getAdapter())) {
- executeSql(mergerContext, sql);
- }
- }
-
- protected void executeSql(MergerContext mergerContext, String sql) {
- JdbcEventLogger logger = mergerContext.getDataNode().getJdbcEventLogger();
- logger.log(sql);
-
- try (Connection conn = mergerContext.getDataNode().getDataSource().getConnection();) {
-
- try (Statement st = conn.createStatement();) {
- st.execute(sql);
- }
- } catch (SQLException e) {
- mergerContext.getValidationResult().addFailure(new SimpleValidationFailure(sql, e.getMessage()));
- logger.logQueryError(e);
- }
- }
-
- @Override
- public String toString() {
- return getTokenName() + ' ' + getTokenValue() + ' ' + getDirection();
- }
-
- public boolean isEmpty() {
- return false;
- }
-
- public abstract List<String> createSql(DbAdapter adapter);
-
- abstract static class Entity extends AbstractToDbToken {
-
- private DbEntity entity;
-
- public Entity(String tokenName, DbEntity entity) {
- super(tokenName);
- this.entity = entity;
- }
-
- public DbEntity getEntity() {
- return entity;
- }
-
- public String getTokenValue() {
- return getEntity().getName();
- }
-
- public int compareTo(MergerToken o) {
- // default order as tokens are created
- return 0;
- }
-
- }
-
- abstract static class EntityAndColumn extends Entity {
-
- private DbAttribute column;
-
- public EntityAndColumn(String tokenName, DbEntity entity, DbAttribute column) {
- super(tokenName, entity);
- this.column = column;
- }
-
- public DbAttribute getColumn() {
- return column;
- }
-
- @Override
- public String getTokenValue() {
- return getEntity().getName() + "." + getColumn().getName();
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToModelToken.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToModelToken.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToModelToken.java
deleted file mode 100644
index 24cee4a..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AbstractToModelToken.java
+++ /dev/null
@@ -1,125 +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.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-
-/**
- * Common abstract superclass for all {@link MergerToken}s going from the database to the
- * model.
- */
-public abstract class AbstractToModelToken implements MergerToken {
-
- private final String tokenName;
-
- protected AbstractToModelToken(String tokenName) {
- this.tokenName = tokenName;
- }
-
- protected static void remove(ModelMergeDelegate mergerContext, DbRelationship rel, boolean reverse) {
- if (rel == null) {
- return;
- }
- if (reverse) {
- remove(mergerContext, rel.getReverseRelationship(), false);
- }
-
- DbEntity dbEntity = rel.getSourceEntity();
- for (ObjEntity objEntity : dbEntity.mappedObjEntities()) {
- remove(mergerContext, objEntity.getRelationshipForDbRelationship(rel), true);
- }
-
- rel.getSourceEntity().removeRelationship(rel.getName());
- mergerContext.dbRelationshipRemoved(rel);
- }
-
- protected static void remove(ModelMergeDelegate mergerContext, ObjRelationship rel, boolean reverse) {
- if (rel == null) {
- return;
- }
- if (reverse) {
- remove(mergerContext, rel.getReverseRelationship(), false);
- }
- rel.getSourceEntity().removeRelationship(rel.getName());
- mergerContext.objRelationshipRemoved(rel);
- }
-
- @Override
- public final String getTokenName() {
- return tokenName;
- }
-
- @Override
- public final MergeDirection getDirection() {
- return MergeDirection.TO_MODEL;
- }
-
- @Override
- public String toString() {
- return getTokenName() + ' ' + getTokenValue() + ' ' + getDirection();
- }
-
- public boolean isEmpty() {
- return false;
- }
-
- abstract static class Entity extends AbstractToModelToken {
-
- private final DbEntity entity;
-
- protected Entity(String tokenName, DbEntity entity) {
- super(tokenName);
- this.entity = entity;
- }
-
- public DbEntity getEntity() {
- return entity;
- }
-
- public String getTokenValue() {
- return getEntity().getName();
- }
-
- }
-
- abstract static class EntityAndColumn extends Entity {
-
- private final DbAttribute column;
-
- protected EntityAndColumn(String tokenName, DbEntity entity, DbAttribute column) {
- super(tokenName, entity);
- this.column = column;
- }
-
- public DbAttribute getColumn() {
- return column;
- }
-
- @Override
- public String getTokenValue() {
- return getEntity().getName() + "." + getColumn().getName();
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToDb.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToDb.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToDb.java
deleted file mode 100644
index 6fdca2f..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToDb.java
+++ /dev/null
@@ -1,74 +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.dba.DbAdapter;
-import org.apache.cayenne.dba.JdbcAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-
-import java.util.Collections;
-import java.util.List;
-
-public class AddColumnToDb extends AbstractToDbToken.EntityAndColumn {
-
- public AddColumnToDb(DbEntity entity, DbAttribute column) {
- super("Add Column", entity, column);
- }
-
- /**
- * append the part of the token before the actual column data type
- */
- protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) {
-
- sqlBuffer.append("ALTER TABLE ");
- sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
- sqlBuffer.append(" ADD COLUMN ");
- sqlBuffer.append(context.quotedName(getColumn()));
- sqlBuffer.append(" ");
- }
-
- @Override
- public List<String> createSql(DbAdapter adapter) {
- StringBuffer sqlBuffer = new StringBuffer();
- QuotingStrategy context = adapter.getQuotingStrategy();
- appendPrefix(sqlBuffer, context);
-
- sqlBuffer.append(JdbcAdapter.getType(adapter, getColumn()));
- sqlBuffer.append(JdbcAdapter.sizeAndPrecision(adapter, getColumn()));
-
- return Collections.singletonList(sqlBuffer.toString());
- }
-
- @Override
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createDropColumnToModel(getEntity(), getColumn());
- }
-
- @Override
- public int compareTo(MergerToken o) {
- // add all AddRelationshipToDb to the end.
- if (o instanceof AddRelationshipToDb) {
- return -1;
- }
- return super.compareTo(o);
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToModel.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToModel.java
deleted file mode 100644
index 823a81d..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddColumnToModel.java
+++ /dev/null
@@ -1,52 +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.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjEntity;
-
-/**
- * A {@link MergerToken} to add a {@link DbAttribute} to a {@link DbEntity}. The
- * {@link EntityMergeSupport} will be used to update the mapped {@link ObjEntity}
- */
-public class AddColumnToModel extends AbstractToModelToken.EntityAndColumn {
-
- public AddColumnToModel(DbEntity entity, DbAttribute column) {
- super("Add Column", entity, column);
- }
-
- @Override
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createDropColumnToDb(getEntity(), getColumn());
- }
-
- @Override
- public void execute(MergerContext mergerContext) {
- getEntity().addAttribute(getColumn());
-
- for (ObjEntity e : getEntity().mappedObjEntities()) {
- mergerContext.getEntityMergeSupport().synchronizeOnDbAttributeAdded(e, getColumn());
- }
-
- mergerContext.getDelegate().dbAttributeAdded(getColumn());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToDb.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToDb.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToDb.java
deleted file mode 100644
index 8712613..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToDb.java
+++ /dev/null
@@ -1,87 +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.access.DbGenerator;
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-
-import java.util.Collections;
-import java.util.List;
-
-public class AddRelationshipToDb extends AbstractToDbToken.Entity {
-
- private DbRelationship relationship;
-
- public AddRelationshipToDb(DbEntity entity, DbRelationship relationship) {
- super("Add foreign key", entity);
- this.relationship = relationship;
- }
-
- /**
- * @see DbGenerator#createConstraintsQueries(org.apache.cayenne.map.DbEntity)
- */
- @Override
- public List<String> createSql(DbAdapter adapter) {
- // TODO: skip FK to a different DB
- if (!this.isEmpty()) {
- String fksql = adapter.createFkConstraint(relationship);
- if (fksql != null) {
- return Collections.singletonList(fksql);
- }
- }
- return Collections.emptyList();
- }
-
- @Override
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createDropRelationshipToModel(getEntity(), relationship);
- }
-
- @Override
- public String getTokenValue() {
- if (!this.isEmpty()) {
- return relationship.getSourceEntity().getName() + "->" + relationship.getTargetEntityName();
- } else {
- return "Skip. No sql representation.";
- }
- }
-
- @Override
- public boolean isEmpty() {
- // Method DbRelationship.isSourceIndependentFromTargetChange() looks same
- return relationship.isSourceIndependentFromTargetChange();
- /*return relationship.isToMany()
- || relationship.isToDependentPK()
- || !relationship.isToPK(); // TODO it is not necessary primary key it can be unique index
- */
- }
-
- @Override
- public int compareTo(MergerToken o) {
- // add all AddRelationshipToDb to the end.
- if (o instanceof AddRelationshipToDb) {
- return super.compareTo(o);
- }
- return 1;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToModel.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToModel.java
deleted file mode 100644
index 05a3d6c..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/AddRelationshipToModel.java
+++ /dev/null
@@ -1,89 +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.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjEntity;
-
-public class AddRelationshipToModel extends AbstractToModelToken.Entity {
-
- public static final String COMMA_SEPARATOR = ", ";
- public static final int COMMA_SEPARATOR_LENGTH = COMMA_SEPARATOR.length();
-
- private DbRelationship relationship;
-
- public AddRelationshipToModel(DbEntity entity, DbRelationship relationship) {
- super("Add Relationship", entity);
- this.relationship = relationship;
- }
-
- public static String getTokenValue(DbRelationship rel) {
- String attributes = "";
- if (rel.getJoins().size() == 1) {
- attributes = rel.getJoins().get(0).getTargetName();
- } else {
- for (DbJoin dbJoin : rel.getJoins()) {
- attributes += dbJoin.getTargetName() + COMMA_SEPARATOR;
- }
-
- attributes = "{" + attributes.substring(0, attributes.length() - COMMA_SEPARATOR_LENGTH) + "}";
- }
-
- return rel.getName() + " " + rel.getSourceEntity().getName() + "->" + rel.getTargetEntityName() + "." + attributes;
- }
-
- @Override
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createDropRelationshipToDb(getEntity(), relationship);
- }
-
- @Override
- public void execute(MergerContext context) {
- // Set name to relationship if it was created without it, e.g. in createReverse() action
- if(relationship.getName() == null) {
- relationship.setName(context.getNameGenerator().relationshipName(relationship));
- }
-
- getEntity().addRelationship(relationship);
- for (ObjEntity e : getEntity().mappedObjEntities()) {
- context.getEntityMergeSupport().synchronizeOnDbRelationshipAdded(e, relationship);
- }
-
- context.getDelegate().dbRelationshipAdded(relationship);
- }
-
- @Override
- public String getTokenValue() {
- String attributes = "";
- if (relationship.getJoins().size() == 1) {
- attributes = relationship.getJoins().get(0).getTargetName();
- } else {
- for (DbJoin dbJoin : relationship.getJoins()) {
- attributes += dbJoin.getTargetName() + COMMA_SEPARATOR;
- }
-
- attributes = "{" + attributes.substring(0, attributes.length() - COMMA_SEPARATOR_LENGTH) + "}";
- }
-
- return relationship.getName() + " " + relationship.getSourceEntity().getName() + "->" + relationship.getTargetEntityName() + "." + attributes;
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ChainMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ChainMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ChainMerger.java
new file mode 100644
index 0000000..04583d6
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ChainMerger.java
@@ -0,0 +1,64 @@
+/*****************************************************************
+ * 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.Collection;
+
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.DataMap;
+
+class ChainMerger<T, M> extends AbstractMerger<T, M> {
+
+ private final AbstractMerger<T, M> merger;
+
+ private final AbstractMerger<?, T> parentMerger;
+
+ ChainMerger(MergerTokenFactory tokenFactory, DataMap original, DataMap imported, AbstractMerger<T, M> merger, AbstractMerger<?, T> parentMerger) {
+ super(tokenFactory, original, imported);
+ this.merger = merger;
+ this.parentMerger = parentMerger;
+ }
+
+ @Override
+ MergerDictionaryDiff<M> createDiff(T original, T imported) {
+ MergerDictionaryDiff<M> diff = new MergerDictionaryDiff<M>();
+ MergerDictionaryDiff<T> parentDiff = parentMerger.getDiff();
+ for(MergerDiffPair<T> pair : parentDiff.getSame()) {
+ diff.addAll(merger.createDiff(pair.getOriginal(), pair.getImported()));
+ }
+ return diff;
+ }
+
+ @Override
+ Collection<MergerToken> createTokensForMissingOriginal(M imported) {
+ return merger.createTokensForMissingOriginal(imported);
+ }
+
+ @Override
+ Collection<MergerToken> createTokensForMissingImported(M original) {
+ return merger.createTokensForMissingImported(original);
+ }
+
+ @Override
+ Collection<MergerToken> createTokensForSame(MergerDiffPair<M> same) {
+ return merger.createTokensForSame(same);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/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
deleted file mode 100644
index b5d920c..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToDb.java
+++ /dev/null
@@ -1,86 +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.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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class CreateTableToDb extends AbstractToDbToken.Entity {
-
- public CreateTableToDb(DbEntity entity) {
- super("Create Table", entity);
- }
-
- @Override
- public List<String> createSql(DbAdapter adapter) {
- List<String> sqls = new ArrayList<String>();
- if(needAutoPkSupport()) {
- sqls.addAll(adapter.getPkGenerator().createAutoPkStatements(
- Collections.singletonList(getEntity())));
- }
- sqls.add(adapter.createTable(getEntity()));
- return sqls;
- }
-
- @Override
- public void execute(MergerContext mergerContext) {
- try {
- DataNode node = mergerContext.getDataNode();
- DbAdapter adapter = node.getAdapter();
- if(needAutoPkSupport()) {
- adapter.getPkGenerator().createAutoPk(
- node,
- Collections.singletonList(getEntity()));
- }
- executeSql(mergerContext, adapter.createTable(getEntity()));
- }
- catch (Exception e) {
- mergerContext.getValidationResult().addFailure(
- new SimpleValidationFailure(this, e.getMessage()));
- }
- }
-
- 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/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
deleted file mode 100644
index 8352a27..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/CreateTableToModel.java
+++ /dev/null
@@ -1,98 +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.naming.NameBuilder;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjEntity;
-
-/**
- * A {@link MergerToken} to add a {@link DbEntity} to a {@link DataMap}
- */
-public class CreateTableToModel extends AbstractToModelToken.Entity {
-
- /**
- * className if {@link ObjEntity} should be generated with a
- * special class name.
- * Setting this to <code>null</code>, because by default class name should be generated
- */
- private String objEntityClassName;
-
- public CreateTableToModel(DbEntity entity) {
- super("Create Table", entity);
- }
-
- /**
- * Set the {@link ObjEntity} className if {@link ObjEntity} should be generated with a
- * special class name. Set to null if the {@link ObjEntity} should be created with a
- * name based on {@link DataMap#getDefaultPackage()} and {@link ObjEntity#getName()}
- * <p>
- * The default value is <code>null</code>
- */
- public void setObjEntityClassName(String n) {
- objEntityClassName = n;
- }
-
- @Override
- public void execute(MergerContext context) {
- DbEntity dbEntity = getEntity();
-
- DataMap map = context.getDataMap();
- map.addDbEntity(dbEntity);
-
- // create a ObjEntity
- ObjEntity objEntity = new ObjEntity();
-
- objEntity.setName(NameBuilder
- .builder(objEntity, dbEntity.getDataMap())
- .baseName(context.getNameGenerator().objEntityName(dbEntity))
- .name());
- objEntity.setDbEntity(getEntity());
-
- // try to find a class name for the ObjEntity
- String className = objEntityClassName;
- if (className == null) {
- // generate a className based on the objEntityName
- className = map.getNameWithDefaultPackage(objEntity.getName());
- }
-
- objEntity.setClassName(className);
- objEntity.setSuperClassName(map.getDefaultSuperclass());
-
- if (map.isClientSupported()) {
- objEntity.setClientClassName(map.getNameWithDefaultClientPackage(objEntity.getName()));
- objEntity.setClientSuperClassName(map.getDefaultClientSuperclass());
- }
-
- map.addObjEntity(objEntity);
-
- // presumably there are no other ObjEntities pointing to this DbEntity, so syncing just this one...
- context.getEntityMergeSupport().synchronizeWithDbEntity(objEntity);
-
- context.getDelegate().dbEntityAdded(getEntity());
- context.getDelegate().objEntityAdded(objEntity);
- }
-
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createDropTableToDb(getEntity());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
new file mode 100644
index 0000000..51bea0d
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DataMapMerger.java
@@ -0,0 +1,144 @@
+/*****************************************************************
+ * 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.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.cayenne.dbsync.merge.token.EmptyValueForNullProvider;
+import org.apache.cayenne.dbsync.merge.token.ValueForNullProvider;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.dbsync.merge.token.TokenComparator;
+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.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+
+/**
+ * Synchronization data base store and Cayenne model.
+ */
+public class DataMapMerger implements Merger<DataMap> {
+
+ private MergerTokenFactory tokenFactory;
+ private ValueForNullProvider valueForNull;
+ private boolean skipRelationshipsTokens;
+ private boolean skipPKTokens;
+ private FiltersConfig filters;
+
+ private DataMapMerger() {
+ }
+
+ /**
+ * Create List of MergerToken that represent the difference between two {@link DataMap} objects.
+ */
+ public List<MergerToken> createMergeTokens(DataMap original, DataMap importedFromDb) {
+ List<MergerToken> tokens = new ArrayList<>();
+
+ DbEntityMerger dbEntityMerger = mergeDbEntities(tokens, original, importedFromDb);
+ mergeAttributes(tokens, dbEntityMerger, original, importedFromDb);
+ mergeRelationships(tokens, dbEntityMerger, original, importedFromDb);
+
+ Collections.sort(tokens, new TokenComparator());
+
+ return tokens;
+ }
+
+ private DbEntityMerger mergeDbEntities(List<MergerToken> tokens, DataMap original, DataMap importedFromDb) {
+ DbEntityMerger dbEntityMerger = new DbEntityMerger(tokenFactory, skipPKTokens, original, importedFromDb);
+ tokens.addAll(dbEntityMerger.createMergeTokens(original, importedFromDb));
+ return dbEntityMerger;
+ }
+
+ private void mergeAttributes(List<MergerToken> tokens, DbEntityMerger dbEntityMerger, DataMap original, DataMap importedFromDb) {
+ ChainMerger<DbEntity, DbAttribute> dbAttributeMerger = new ChainMerger<>(
+ tokenFactory, original, importedFromDb,
+ new DbAttributeMerger(tokenFactory, original, importedFromDb, valueForNull),
+ dbEntityMerger
+ );
+ tokens.addAll(dbAttributeMerger.createMergeTokens(null, null));
+ }
+
+ private void mergeRelationships(List<MergerToken> tokens, DbEntityMerger dbEntityMerger, DataMap original, DataMap importedFromDb) {
+ ChainMerger<DbEntity, DbRelationship> dbRelationshipMerger = new ChainMerger<>(
+ tokenFactory, original, importedFromDb,
+ new DbRelationshipMerger(tokenFactory, original, importedFromDb, skipRelationshipsTokens),
+ dbEntityMerger
+ );
+ tokens.addAll(dbRelationshipMerger.createMergeTokens(null, null));
+ }
+
+
+ public static Builder builder(MergerTokenFactory tokenFactory) {
+ return new Builder(tokenFactory);
+ }
+
+ public static DataMapMerger build(MergerTokenFactory tokenFactory) {
+ return builder(tokenFactory).build();
+ }
+
+ public static class Builder {
+ private DataMapMerger merger;
+
+ private Builder(MergerTokenFactory tokenFactory) {
+ this.merger = new DataMapMerger();
+ this.merger.tokenFactory = Objects.requireNonNull(tokenFactory);
+ }
+
+ public DataMapMerger 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/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeDictionary.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeDictionary.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeDictionary.java
new file mode 100644
index 0000000..1fc17da
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeDictionary.java
@@ -0,0 +1,44 @@
+/*****************************************************************
+ * 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.Collection;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+class DbAttributeDictionary extends MergerDictionary<DbAttribute> {
+
+ private final DbEntity container;
+
+ DbAttributeDictionary(DbEntity container) {
+ this.container = container;
+ }
+
+ @Override
+ String getName(DbAttribute entity) {
+ return entity.getName();
+ }
+
+ @Override
+ Collection<DbAttribute> getAll() {
+ return container.getAttributes();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeMerger.java
new file mode 100644
index 0000000..cf26201
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbAttributeMerger.java
@@ -0,0 +1,159 @@
+/*****************************************************************
+ * 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.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.cayenne.dbsync.merge.token.ValueForNullProvider;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+class DbAttributeMerger extends AbstractMerger<DbEntity, DbAttribute> {
+
+ private final ValueForNullProvider valueForNull;
+
+ DbAttributeMerger(MergerTokenFactory tokenFactory, DataMap original, DataMap imported, ValueForNullProvider valueForNull) {
+ super(tokenFactory, original, imported);
+ this.valueForNull = valueForNull;
+ }
+
+ @Override
+ MergerDictionaryDiff<DbAttribute> createDiff(DbEntity original, DbEntity imported) {
+ return new MergerDictionaryDiff.Builder<DbAttribute>()
+ .originalDictionary(new DbAttributeDictionary(original))
+ .importedDictionary(new DbAttributeDictionary(imported))
+ .build();
+ }
+
+ /**
+ * Add column to db
+ * @param original attribute found in model but missing in db
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingImported(DbAttribute original) {
+ DbEntity originalDbEntity = original.getEntity();
+ List<MergerToken> tokens = new LinkedList<>();
+ tokens.add(getTokenFactory().createAddColumnToDb(originalDbEntity, original));
+
+ // Create not null check
+ if (original.isMandatory()) {
+ if (valueForNull.hasValueFor(originalDbEntity, original)) {
+ tokens.add(getTokenFactory().createSetValueForNullToDb(originalDbEntity, original, valueForNull));
+ }
+ tokens.add(getTokenFactory().createSetNotNullToDb(originalDbEntity, original));
+ }
+
+ return tokens;
+ }
+
+ /**
+ * Drop column in db
+ * @param imported attribute found in db but missing in model
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingOriginal(DbAttribute imported) {
+ DbEntity originalDbEntity = originalDataMap.getDbEntity(imported.getEntity().getName());
+ return Collections.singleton(getTokenFactory().createDropColumnToDb(originalDbEntity, imported));
+ }
+
+ /**
+ * Compare same attributes in model and db
+ */
+ @Override
+ Collection<MergerToken> createTokensForSame(MergerDiffPair<DbAttribute> same) {
+ List<MergerToken> tokens = new LinkedList<>();
+
+ // isMandatory flag
+ checkMandatory(same.getOriginal(), same.getImported(), tokens);
+ // check type (including max length, scale and precision)
+ checkType(same.getOriginal(), same.getImported(), tokens);
+
+ // not implemented yet
+ // isGenerated flag
+ //checkIsGenerated(same.getOriginal(), same.getImported(), tokens);
+
+
+ return tokens;
+ }
+
+ private void checkMandatory(DbAttribute original, DbAttribute imported, List<MergerToken> tokens) {
+ if(original.isMandatory() == imported.isMandatory()) {
+ return;
+ }
+
+ DbEntity originalDbEntity = original.getEntity();
+ if (original.isMandatory()) {
+ if (valueForNull.hasValueFor(originalDbEntity, original)) {
+ tokens.add(getTokenFactory().createSetValueForNullToDb(originalDbEntity, original, valueForNull));
+ }
+ tokens.add(getTokenFactory().createSetNotNullToDb(originalDbEntity, original));
+ } else {
+ tokens.add(getTokenFactory().createSetAllowNullToDb(originalDbEntity, original));
+ }
+ }
+
+ /**
+ * Check whether attributes have same type, max length, scale and precision
+ * @param original attribute in model
+ * @param imported attribute from db
+ * @return true if attributes not same
+ */
+ private boolean needUpdate(DbAttribute original, DbAttribute imported) {
+ if(original.getType() != imported.getType()) {
+ return true;
+ }
+
+ if(original.getMaxLength() != imported.getMaxLength()) {
+ return true;
+ }
+
+ if(original.getScale() != imported.getScale()) {
+ return true;
+ }
+
+ if(original.getAttributePrecision() != imported.getAttributePrecision()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private void checkType(DbAttribute original, DbAttribute imported, List<MergerToken> tokens) {
+ if(!needUpdate(original, imported)) {
+ return;
+ }
+ DbEntity originalDbEntity = original.getEntity();
+ tokens.add(getTokenFactory().createSetColumnTypeToDb(originalDbEntity, original, imported));
+ }
+
+ private void checkIsGenerated(DbAttribute original, DbAttribute imported, List<MergerToken> tokens) {
+ if(original.isGenerated() == imported.isGenerated()) {
+ return;
+ }
+
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityDictionary.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityDictionary.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityDictionary.java
new file mode 100644
index 0000000..9114711
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityDictionary.java
@@ -0,0 +1,44 @@
+/*****************************************************************
+ * 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.Collection;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+
+class DbEntityDictionary extends MergerDictionary<DbEntity> {
+
+ private final DataMap container;
+
+ DbEntityDictionary(DataMap container) {
+ this.container = container;
+ }
+
+ @Override
+ String getName(DbEntity entity) {
+ return entity.getFullyQualifiedName();
+ }
+
+ @Override
+ Collection<DbEntity> getAll() {
+ return container.getDbEntities();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityMerger.java
new file mode 100644
index 0000000..b718005
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbEntityMerger.java
@@ -0,0 +1,108 @@
+/*****************************************************************
+ * 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.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+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.DetectedDbEntity;
+
+class DbEntityMerger extends AbstractMerger<DataMap, DbEntity> {
+
+ private final boolean skipPKTokens;
+
+ DbEntityMerger(MergerTokenFactory tokenFactory, boolean skipPKTokens, DataMap original, DataMap imported) {
+ super(tokenFactory, original, imported);
+ this.skipPKTokens = skipPKTokens;
+ }
+
+ @Override
+ MergerDictionaryDiff<DbEntity> createDiff(DataMap original, DataMap imported) {
+ return new MergerDictionaryDiff.Builder<DbEntity>()
+ .originalDictionary(new DbEntityDictionary(original))
+ .importedDictionary(new DbEntityDictionary(imported))
+ .build();
+ }
+
+ /**
+ * Generate Drop Table in DB token
+ * @param imported DbEntity not found in model but found in DB
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingOriginal(DbEntity imported) {
+ return Collections.singleton(getTokenFactory().createDropTableToDb(imported));
+ }
+
+ /**
+ * Generate Create Table in model token
+ * @param original DbEntity found in model but not found in DB
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingImported(DbEntity original) {
+ return Collections.singleton(getTokenFactory().createCreateTableToDb(original));
+ }
+
+ /**
+ * Compare same entities. For now we check primary keys.
+ * @param same found DbEntities in model and db
+ */
+ @Override
+ Collection<MergerToken> createTokensForSame(MergerDiffPair<DbEntity> same) {
+ if(skipPKTokens) {
+ return null;
+ }
+ return checkPrimaryKeyChange(same.getOriginal(), same.getImported());
+ }
+
+ private Collection<MergerToken> checkPrimaryKeyChange(DbEntity original, DbEntity imported) {
+ Collection<DbAttribute> primaryKeyOriginal = imported.getPrimaryKeys();
+ Collection<DbAttribute> primaryKeyNew = original.getPrimaryKeys();
+
+ String primaryKeyName = null;
+ if (imported instanceof DetectedDbEntity) {
+ primaryKeyName = ((DetectedDbEntity) imported).getPrimaryKeyName();
+ }
+
+ if (upperCaseEntityNames(primaryKeyOriginal).equals(upperCaseEntityNames(primaryKeyNew))) {
+ return null;
+ }
+ return Collections.singleton(
+ getTokenFactory().createSetPrimaryKeyToDb(
+ original, primaryKeyOriginal, primaryKeyNew, primaryKeyName
+ )
+ );
+ }
+
+ private Set<String> upperCaseEntityNames(Collection<? extends Attribute> attributes) {
+ Set<String> names = new HashSet<String>();
+ for (Attribute attr : attributes) {
+ names.add(attr.getName().toUpperCase());
+ }
+ return names;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/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 7adb0e5..9da71b5 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
@@ -19,6 +19,11 @@
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;
@@ -42,6 +47,7 @@ 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 {
@@ -85,13 +91,12 @@ public class DbMerger {
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())
+ 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;
}
}
@@ -351,6 +356,7 @@ public class DbMerger {
return null;
}
+ @Deprecated
public static class Builder {
private DbMerger merger;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipDictionary.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipDictionary.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipDictionary.java
new file mode 100644
index 0000000..4d5d74c
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipDictionary.java
@@ -0,0 +1,83 @@
+/*****************************************************************
+ * 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.Collection;
+import java.util.TreeSet;
+
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+
+class DbRelationshipDictionary extends MergerDictionary<DbRelationship> {
+
+ private final DbEntity container;
+
+ DbRelationshipDictionary(DbEntity container) {
+ this.container = container;
+ }
+
+ @Override
+ String getName(DbRelationship entity) {
+ return new Signature(entity).getName();
+ }
+
+ @Override
+ Collection<DbRelationship> getAll() {
+ return container.getRelationships();
+ }
+
+ /**
+ * Signature of DbRelationship is sorted strings generated from its DbJoins
+ */
+ private static class Signature {
+ private final DbRelationship relationship;
+
+ private String[] joinSignature;
+
+ private Signature(DbRelationship relationship) {
+ this.relationship = relationship;
+ build();
+ }
+
+ public String getName() {
+ if(joinSignature.length == 0) {
+ return "";
+ }
+ String name = joinSignature[0];
+ for(int i=1; i<joinSignature.length; i++) {
+ name += "|" + joinSignature[i];
+ }
+ return name;
+ }
+
+ private void build() {
+ TreeSet<String> joins = new TreeSet<>();
+ for(DbJoin join : relationship.getJoins()) {
+ joins.add(
+ (join.getSource() == null ? "~" : join.getSource().getName()) + "." + join.getSourceName()
+ + ">" +
+ (join.getTarget() == null ? "~" : join.getTarget().getName()) + "." + join.getTargetName()
+ );
+ }
+ joinSignature = joins.toArray(new String[0]);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipMerger.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipMerger.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipMerger.java
new file mode 100644
index 0000000..a094cb2
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbRelationshipMerger.java
@@ -0,0 +1,127 @@
+/*****************************************************************
+ * 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.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
+import org.apache.cayenne.dbsync.merge.token.MergerToken;
+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;
+
+/**
+ * Merger of relationships.
+ * Scoped to single DbEntity and it's counterpart.
+ */
+public class DbRelationshipMerger extends AbstractMerger<DbEntity, DbRelationship> {
+
+ private final boolean skipRelationshipsTokens;
+
+ DbRelationshipMerger(MergerTokenFactory tokenFactory,
+ DataMap original, DataMap imported, boolean skipRelationshipsTokens) {
+ super(tokenFactory, original, imported);
+ this.skipRelationshipsTokens = skipRelationshipsTokens;
+ }
+
+ @Override
+ MergerDictionaryDiff<DbRelationship> createDiff(DbEntity original, DbEntity imported) {
+ return new MergerDictionaryDiff.Builder<DbRelationship>()
+ .originalDictionary(new DbRelationshipDictionary(original))
+ .importedDictionary(new DbRelationshipDictionary(imported))
+ .build();
+ }
+
+ private DbEntity getOriginalDbEntity(DbRelationship relationship) {
+ return originalDataMap.getDbEntity(relationship.getSourceEntity().getName());
+ }
+
+ /**
+ * @param imported DbRelationship that is in db but not in model
+ * @return generated tokens
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingOriginal(DbRelationship imported) {
+ DbEntity originalDbEntity = getOriginalDbEntity(imported);
+ DbEntity targetEntity = originalDataMap.getDbEntity(imported.getTargetEntityName());
+
+ if (targetEntity == null) {
+ return null;
+ }
+
+ imported.setSourceEntity(originalDbEntity);
+ imported.setTargetEntityName(targetEntity);
+
+ // manipulate the joins to match the DbAttributes in the model
+ for (DbJoin join : imported.getJoins()) {
+ DbAttribute sourceAttr = findDbAttribute(originalDbEntity, join.getSourceName());
+ if (sourceAttr != null) {
+ join.setSourceName(sourceAttr.getName());
+ }
+ DbAttribute targetAttr = findDbAttribute(targetEntity, join.getTargetName());
+ if (targetAttr != null) {
+ join.setTargetName(targetAttr.getName());
+ }
+ }
+ // Add all relationships. Tokens will decide whether or not to execute
+ MergerToken token = getTokenFactory().createDropRelationshipToDb(originalDbEntity, imported);
+ return Collections.singleton(token);
+ }
+
+ /**
+ * @param original DbRelationship that is in model but not in db
+ * @return generated tokens
+ */
+ @Override
+ Collection<MergerToken> createTokensForMissingImported(DbRelationship original) {
+ if(skipRelationshipsTokens) {
+ return null;
+ }
+ DbEntity originalDbEntity = getOriginalDbEntity(original);
+ MergerToken token = getTokenFactory().createAddRelationshipToDb(originalDbEntity, original);
+ return Collections.singleton(token);
+ }
+
+ /**
+ *
+ * @param same pair of found in model and in db DbRelationships
+ * @return generated tokens
+ */
+ @Override
+ Collection<MergerToken> createTokensForSame(MergerDiffPair<DbRelationship> same) {
+ 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultModelMergeDelegate.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultModelMergeDelegate.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultModelMergeDelegate.java
deleted file mode 100644
index 816729d..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultModelMergeDelegate.java
+++ /dev/null
@@ -1,89 +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.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-
-/**
- * A default noop implementation of {@link ModelMergeDelegate}.
- */
-public class DefaultModelMergeDelegate implements ModelMergeDelegate {
-
- @Override
- public void dbAttributeAdded(DbAttribute att) {
- }
-
- @Override
- public void dbAttributeModified(DbAttribute att) {
- }
-
- @Override
- public void dbAttributeRemoved(DbAttribute att) {
- }
-
- @Override
- public void dbEntityAdded(DbEntity ent) {
- }
-
- @Override
- public void dbEntityRemoved(DbEntity ent) {
- }
-
- @Override
- public void dbRelationshipAdded(DbRelationship rel) {
- }
-
- @Override
- public void dbRelationshipRemoved(DbRelationship rel) {
- }
-
- @Override
- public void objAttributeAdded(ObjAttribute att) {
- }
-
- @Override
- public void objAttributeModified(ObjAttribute att) {
- }
-
- @Override
- public void objAttributeRemoved(ObjAttribute att) {
- }
-
- @Override
- public void objEntityAdded(ObjEntity ent) {
- }
-
- @Override
- public void objEntityRemoved(ObjEntity ent) {
- }
-
- @Override
- public void objRelationshipAdded(ObjRelationship rel) {
- }
-
- @Override
- public void objRelationshipRemoved(ObjRelationship rel) {
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultValueForNullProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultValueForNullProvider.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultValueForNullProvider.java
deleted file mode 100644
index 9d4e0cd..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DefaultValueForNullProvider.java
+++ /dev/null
@@ -1,62 +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 java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.access.jdbc.SQLParameterBinding;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-
-public class DefaultValueForNullProvider implements ValueForNullProvider {
-
- private Map<String, SQLParameterBinding> values = new HashMap<>();
-
- public void set(DbEntity entity, DbAttribute column, Object value, int type) {
- values.put(createKey(entity, column), new SQLParameterBinding(value, type, column
- .getAttributePrecision()));
- }
-
- protected SQLParameterBinding get(DbEntity entity, DbAttribute column) {
- return values.get(createKey(entity, column));
- }
-
- public List<String> createSql(DbEntity entity, DbAttribute column) {
- SQLParameterBinding value = get(entity, column);
- if (value == null) {
- return Collections.emptyList();
- }
-
- // TODO: change things so it is possible to use prepared statements here
- return Collections.singletonList("UPDATE " + entity.getFullyQualifiedName()
- + " SET " + column.getName() + "='" + value.getValue() + "' WHERE " + column.getName() + " IS NULL");
- }
-
- public boolean hasValueFor(DbEntity entity, DbAttribute column) {
- return values.containsKey(createKey(entity, column));
- }
-
- private String createKey(DbEntity entity, DbAttribute attribute) {
- return (entity.getFullyQualifiedName() + "." + attribute.getName()).toUpperCase();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/46c8ded5/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropColumnToDb.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropColumnToDb.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropColumnToDb.java
deleted file mode 100644
index dec3297..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DropColumnToDb.java
+++ /dev/null
@@ -1,61 +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 java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-
-public class DropColumnToDb extends AbstractToDbToken.EntityAndColumn {
-
- public DropColumnToDb(DbEntity entity, DbAttribute column) {
- super("Drop Column", entity, column);
- }
-
- @Override
- public List<String> createSql(DbAdapter adapter) {
- StringBuilder sqlBuffer = new StringBuilder();
- QuotingStrategy context = adapter.getQuotingStrategy();
- sqlBuffer.append("ALTER TABLE ");
- sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
- sqlBuffer.append(" DROP COLUMN ");
- sqlBuffer.append(context.quotedName(getColumn()));
-
- return Collections.singletonList(sqlBuffer.toString());
- }
-
- public MergerToken createReverse(MergerTokenFactory factory) {
- return factory.createAddColumnToModel(getEntity(), getColumn());
- }
-
- @Override
- public int compareTo(MergerToken o) {
- // add all AddRelationshipToDb to the end.
- if (o instanceof DropRelationshipToDb) {
- return 1;
- }
- return super.compareTo(o);
- }
-
-}