CAY-2115 DbLoader - allow loading DataMap without Obj layer

* refactoring DbMerger... removing dependency on DbLoaderConfiguration
  using own builder instead


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/a811b44e
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/a811b44e
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/a811b44e

Branch: refs/heads/master
Commit: a811b44e5cfdc8b659f0f8a493150ff40a45a07a
Parents: d6aa914
Author: Andrus Adamchik <and...@objectstyle.com>
Authored: Mon Oct 3 18:49:03 2016 +0300
Committer: Andrus Adamchik <and...@objectstyle.com>
Committed: Mon Oct 3 20:09:05 2016 +0300

----------------------------------------------------------------------
 .../apache/cayenne/dbsync/merge/DbMerger.java   | 117 ++++++++++----
 .../cayenne/dbsync/merge/DbMergerConfig.java    |  63 --------
 .../dbsync/merge/DefaultModelMergeDelegate.java |  32 ++--
 .../dbsync/merge/EmptyValueForNullProvider.java |   4 +-
 .../dbsync/merge/ModelMergeDelegate.java        |  28 ++--
 .../cayenne/dbsync/merge/DbMergerTest.java      |  29 ++--
 .../apache/cayenne/dbsync/merge/MergeCase.java  |  19 ++-
 .../cayenne/dbsync/merge/ValueForNullIT.java    | 161 +++++++++----------
 .../tools/dbimport/DbImportConfiguration.java   |  14 +-
 .../tools/dbimport/DefaultDbImportAction.java   |  16 +-
 .../modeler/dialog/db/MergerOptions.java        |  15 +-
 11 files changed, 236 insertions(+), 262 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/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 605b6af..b3d7119 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
@@ -20,8 +20,9 @@ package org.apache.cayenne.dbsync.merge;
 
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
 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;
@@ -41,18 +42,26 @@ import java.util.Objects;
 import java.util.Set;
 
 /**
- * Traverse a {@link DataNode} and a {@link DataMap} and create a group of
- * {@link MergerToken}s to alter the {@link DataNode} data store to match the
- * {@link DataMap}.
+ * 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.
  */
 public class DbMerger {
 
-    private final MergerTokenFactory factory;
-    private final ValueForNullProvider valueForNull;
+    private MergerTokenFactory tokenFactory;
+    private ValueForNullProvider valueForNull;
+    private boolean skipRelationshipsTokens;
+    private boolean skipPKTokens;
+    private FiltersConfig filters;
 
-    public DbMerger(MergerTokenFactory factory, ValueForNullProvider 
valueForNull) {
-        this.factory = Objects.requireNonNull(factory);
-        this.valueForNull = Objects.requireNonNull(valueForNull);
+    private DbMerger() {
+    }
+
+    public static Builder builder(MergerTokenFactory tokenFactory) {
+        return new Builder(tokenFactory);
+    }
+
+    public static DbMerger build(MergerTokenFactory tokenFactory) {
+        return builder(tokenFactory).build();
     }
 
     /**
@@ -99,12 +108,11 @@ public class DbMerger {
      * Create and return a {@link List} of {@link MergerToken}s to alter the
      * given {@link DataNode} to match the given {@link DataMap}
      */
-    public List<MergerToken> createMergeTokens(DataMap existing, DataMap 
loadedFomDb, DbLoaderConfiguration config) {
+    public List<MergerToken> createMergeTokens(DataMap existing, DataMap 
loadedFomDb) {
 
         
loadedFomDb.setQuotingSQLIdentifiers(existing.isQuotingSQLIdentifiers());
 
-        List<MergerToken> tokens = createMergeTokens(filter(existing, 
config.getFiltersConfig()),
-                loadedFomDb.getDbEntities(), config);
+        List<MergerToken> tokens = createMergeTokens(filter(existing, 
filters), loadedFomDb.getDbEntities());
 
         // sort. use a custom Comparator since only toDb tokens are comparable
         // by now
@@ -123,7 +131,7 @@ public class DbMerger {
     }
 
     private Collection<DbEntity> filter(DataMap existing, FiltersConfig 
filtersConfig) {
-        Collection<DbEntity> existingFiltered = new LinkedList<DbEntity>();
+        Collection<DbEntity> existingFiltered = new LinkedList<>();
         for (DbEntity entity : existing.getDbEntities()) {
             if (filtersConfig.tableFilter(entity.getCatalog(), 
entity.getSchema()).isIncludeTable(entity.getName()) != null) {
                 existingFiltered.add(entity);
@@ -132,9 +140,7 @@ public class DbMerger {
         return existingFiltered;
     }
 
-    protected List<MergerToken> createMergeTokens(Collection<DbEntity> 
existing,
-                                                  Collection<DbEntity> 
loadedFromDb,
-                                                  DbLoaderConfiguration 
config) {
+    protected List<MergerToken> createMergeTokens(Collection<DbEntity> 
existing, Collection<DbEntity> loadedFromDb) {
         Collection<DbEntity> dbEntitiesToDrop = new LinkedList<>(loadedFromDb);
 
         List<MergerToken> tokens = new LinkedList<>();
@@ -144,10 +150,10 @@ public class DbMerger {
             // look for table
             DbEntity detectedEntity = findDbEntity(loadedFromDb, tableName);
             if (detectedEntity == null) {
-                tokens.add(factory.createCreateTableToDb(dbEntity));
+                tokens.add(tokenFactory.createCreateTableToDb(dbEntity));
                 // TODO: does this work properly with createReverse?
                 for (DbRelationship rel : dbEntity.getRelationships()) {
-                    tokens.add(factory.createAddRelationshipToDb(dbEntity, 
rel));
+                    
tokens.add(tokenFactory.createAddRelationshipToDb(dbEntity, rel));
                 }
                 continue;
             }
@@ -155,12 +161,12 @@ public class DbMerger {
             dbEntitiesToDrop.remove(detectedEntity);
 
             tokens.addAll(checkRelationshipsToDrop(dbEntity, detectedEntity));
-            if (!config.isSkipRelationshipsLoading()) {
+            if (!skipRelationshipsTokens) {
                 tokens.addAll(checkRelationshipsToAdd(dbEntity, 
detectedEntity));
             }
             tokens.addAll(checkRows(dbEntity, detectedEntity));
 
-            if (!config.isSkipPrimaryKeyLoading()) {
+            if (!skipPKTokens) {
                 MergerToken token = checkPrimaryKeyChange(dbEntity, 
detectedEntity);
                 if (token != null) {
                     tokens.add(token);
@@ -172,11 +178,11 @@ public class DbMerger {
         // TODO: support drop table. currently, too many tables are marked for
         // drop
         for (DbEntity e : dbEntitiesToDrop) {
-            tokens.add(factory.createDropTableToDb(e));
+            tokens.add(tokenFactory.createDropTableToDb(e));
             for (DbRelationship relationship : e.getRelationships()) {
                 DbEntity detectedEntity = findDbEntity(existing, 
relationship.getTargetEntityName());
                 if (detectedEntity != null) {
-                    
tokens.add(factory.createDropRelationshipToDb(detectedEntity, 
relationship.getReverseRelationship()));
+                    
tokens.add(tokenFactory.createDropRelationshipToDb(detectedEntity, 
relationship.getReverseRelationship()));
                 }
             }
         }
@@ -190,7 +196,7 @@ public class DbMerger {
         // columns to drop
         for (DbAttribute detected : loadedFromDb.getAttributes()) {
             if (findDbAttribute(existing, detected.getName()) == null) {
-                tokens.add(factory.createDropColumnToDb(existing, detected));
+                tokens.add(tokenFactory.createDropColumnToDb(existing, 
detected));
             }
         }
 
@@ -201,12 +207,12 @@ public class DbMerger {
             DbAttribute detected = findDbAttribute(loadedFromDb, columnName);
 
             if (detected == null) {
-                tokens.add(factory.createAddColumnToDb(existing, attr));
+                tokens.add(tokenFactory.createAddColumnToDb(existing, attr));
                 if (attr.isMandatory()) {
                     if (valueForNull.hasValueFor(existing, attr)) {
-                        tokens.add(factory.createSetValueForNullToDb(existing, 
attr, valueForNull));
+                        
tokens.add(tokenFactory.createSetValueForNullToDb(existing, attr, 
valueForNull));
                     }
-                    tokens.add(factory.createSetNotNullToDb(existing, attr));
+                    tokens.add(tokenFactory.createSetNotNullToDb(existing, 
attr));
                 }
                 continue;
             }
@@ -215,11 +221,11 @@ public class DbMerger {
             if (attr.isMandatory() != detected.isMandatory()) {
                 if (attr.isMandatory()) {
                     if (valueForNull.hasValueFor(existing, attr)) {
-                        tokens.add(factory.createSetValueForNullToDb(existing, 
attr, valueForNull));
+                        
tokens.add(tokenFactory.createSetValueForNullToDb(existing, attr, 
valueForNull));
                     }
-                    tokens.add(factory.createSetNotNullToDb(existing, attr));
+                    tokens.add(tokenFactory.createSetNotNullToDb(existing, 
attr));
                 } else {
-                    tokens.add(factory.createSetAllowNullToDb(existing, attr));
+                    tokens.add(tokenFactory.createSetAllowNullToDb(existing, 
attr));
                 }
             }
 
@@ -229,7 +235,7 @@ public class DbMerger {
                 case Types.VARCHAR:
                 case Types.CHAR:
                     if (attr.getMaxLength() != detected.getMaxLength()) {
-                        tokens.add(factory.createSetColumnTypeToDb(existing, 
detected, attr));
+                        
tokens.add(tokenFactory.createSetColumnTypeToDb(existing, detected, attr));
                     }
                     break;
             }
@@ -270,12 +276,12 @@ public class DbMerger {
                     }
                 }
 
-                MergerToken token = 
factory.createDropRelationshipToDb(dbEntity, detected);
+                MergerToken token = 
tokenFactory.createDropRelationshipToDb(dbEntity, detected);
                 if (detected.isToMany()) {
                     // default toModel as we can not do drop a toMany in the 
db.
                     // only
                     // toOne are represented using foreign key
-                    token = token.createReverse(factory);
+                    token = token.createReverse(tokenFactory);
                 }
                 tokens.add(token);
             }
@@ -290,7 +296,7 @@ public class DbMerger {
 
         for (DbRelationship rel : dbEntity.getRelationships()) {
             if (findDbRelationship(detectedEntity, rel) == null) {
-                AddRelationshipToDb token = (AddRelationshipToDb) 
factory.createAddRelationshipToDb(dbEntity, rel);
+                AddRelationshipToDb token = (AddRelationshipToDb) 
tokenFactory.createAddRelationshipToDb(dbEntity, rel);
 
                 if (token.shouldGenerateFkConstraint()) {
                     // TODO I guess we should add relationship always; in order
@@ -319,7 +325,7 @@ public class DbMerger {
             return null;
         }
 
-        return factory.createSetPrimaryKeyToDb(dbEntity, primaryKeyOriginal, 
primaryKeyNew, primaryKeyName);
+        return tokenFactory.createSetPrimaryKeyToDb(dbEntity, 
primaryKeyOriginal, primaryKeyNew, primaryKeyName);
     }
 
     private Set<String> upperCaseEntityNames(Collection<? extends Attribute> 
attrs) {
@@ -369,4 +375,47 @@ public class DbMerger {
         }
         return null;
     }
+
+    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/a811b44e/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMergerConfig.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMergerConfig.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMergerConfig.java
deleted file mode 100644
index 1cd80df..0000000
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/DbMergerConfig.java
+++ /dev/null
@@ -1,63 +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.reverse.filters.FiltersConfig;
-
-/**
- * @since 4.0
- */
-public class DbMergerConfig {
-
-    private FiltersConfig filtersConfig;
-
-    private boolean skipRelationships;
-
-    private boolean skipPrimaryKey;
-
-    public DbMergerConfig(FiltersConfig filtersConfig, boolean 
skipRelationships, boolean skipPrimaryKey) {
-        this.filtersConfig = filtersConfig;
-        this.skipRelationships = skipRelationships;
-        this.skipPrimaryKey = skipPrimaryKey;
-    }
-
-    public void setSkipRelationships(boolean skipRelationships) {
-        this.skipRelationships = skipRelationships;
-    }
-
-    public boolean isSkipRelationships() {
-        return skipRelationships;
-    }
-
-    public void setSkipPrimaryKey(boolean skipPrimaryKey) {
-        this.skipPrimaryKey = skipPrimaryKey;
-    }
-
-    public boolean isSkipPrimaryKey() {
-        return skipPrimaryKey;
-    }
-
-    public FiltersConfig getFiltersConfig() {
-        return filtersConfig;
-    }
-
-    public void setFiltersConfig(FiltersConfig filtersConfig) {
-        this.filtersConfig = filtersConfig;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/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
index 617aad2..816729d 100644
--- 
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
@@ -1,21 +1,21 @@
-/*****************************************************************
- *   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
+/*
+ * 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
+ *      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.
- ****************************************************************/
+ *    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;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EmptyValueForNullProvider.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EmptyValueForNullProvider.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EmptyValueForNullProvider.java
index 84a396b..ceaa7a3 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EmptyValueForNullProvider.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/EmptyValueForNullProvider.java
@@ -26,10 +26,8 @@ import java.util.List;
 
 /**
  * A dummy {@link ValueForNullProvider} that are not able to provide any 
values.
- *
- * @since 4.0
  */
-public class EmptyValueForNullProvider implements ValueForNullProvider {
+class EmptyValueForNullProvider implements ValueForNullProvider {
 
     public List<String> createSql(DbEntity entity, DbAttribute column) {
         return Collections.emptyList();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ModelMergeDelegate.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ModelMergeDelegate.java
 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ModelMergeDelegate.java
index 13f6ea5..ac63d93 100644
--- 
a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ModelMergeDelegate.java
+++ 
b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/ModelMergeDelegate.java
@@ -31,32 +31,32 @@ import org.apache.cayenne.map.ObjRelationship;
  */
 public interface ModelMergeDelegate {
 
-    public void dbEntityAdded(DbEntity ent);
+    void dbEntityAdded(DbEntity ent);
 
-    public void dbEntityRemoved(DbEntity ent);
+    void dbEntityRemoved(DbEntity ent);
 
-    public void objEntityAdded(ObjEntity ent);
+    void objEntityAdded(ObjEntity ent);
 
-    public void objEntityRemoved(ObjEntity ent);
+    void objEntityRemoved(ObjEntity ent);
 
-    public void dbAttributeAdded(DbAttribute att);
+    void dbAttributeAdded(DbAttribute att);
 
-    public void dbAttributeRemoved(DbAttribute att);
+    void dbAttributeRemoved(DbAttribute att);
 
-    public void dbAttributeModified(DbAttribute att);
+    void dbAttributeModified(DbAttribute att);
 
-    public void objAttributeAdded(ObjAttribute att);
+    void objAttributeAdded(ObjAttribute att);
 
-    public void objAttributeRemoved(ObjAttribute att);
+    void objAttributeRemoved(ObjAttribute att);
 
-    public void objAttributeModified(ObjAttribute att);
+    void objAttributeModified(ObjAttribute att);
 
-    public void dbRelationshipAdded(DbRelationship rel);
+    void dbRelationshipAdded(DbRelationship rel);
 
-    public void dbRelationshipRemoved(DbRelationship rel);
+    void dbRelationshipRemoved(DbRelationship rel);
 
-    public void objRelationshipAdded(ObjRelationship rel);
+    void objRelationshipAdded(ObjRelationship rel);
 
-    public void objRelationshipRemoved(ObjRelationship rel);
+    void objRelationshipRemoved(ObjRelationship rel);
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
index ea6be7d..62aa013 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/DbMergerTest.java
@@ -20,7 +20,6 @@ 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.reverse.db.DbLoaderConfiguration;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.junit.Test;
@@ -37,8 +36,7 @@ public class DbMergerTest {
 
     @Test
     public void testEmptyDataMap() throws Exception {
-        assertEquals(0, dbMerger().createMergeTokens(new 
ArrayList<DbEntity>(0),
-                new ArrayList<DbEntity>(0), new 
DbLoaderConfiguration()).size());
+        assertEquals(0, dbMerger().createMergeTokens(new 
ArrayList<DbEntity>(0), new ArrayList<DbEntity>(0)).size());
     }
 
     @Test
@@ -49,8 +47,7 @@ public class DbMergerTest {
         );
         DataMap existing = dataMap().with(dbEntity).build();
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(),
-                new ArrayList<DbEntity>(0), new DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), new 
ArrayList<DbEntity>(0));
 
         assertEquals(1, tokens.size());
         
assertEquals(factory().createCreateTableToDb(dbEntity.build()).getTokenValue(),
@@ -64,8 +61,7 @@ public class DbMergerTest {
                 dbAttr("attr01").typeInt()
         )).build();
 
-        List<MergerToken> tokens = dbMerger().createMergeTokens(new 
ArrayList<DbEntity>(0),
-                db.getDbEntities(), new DbLoaderConfiguration());
+        List<MergerToken> tokens = dbMerger().createMergeTokens(new 
ArrayList<DbEntity>(0), db.getDbEntities());
 
         assertEquals(1, tokens.size());
         
assertEquals(factory().createDropTableToDb(db.getDbEntity("table1")).getTokenValue(),
@@ -85,8 +81,7 @@ public class DbMergerTest {
                 dbAttr("attr01").typeInt()
         )).build();
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(),
-                db.getDbEntities(), new DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities());
 
         assertEquals(1, tokens.size());
 
@@ -120,8 +115,7 @@ public class DbMergerTest {
          .build();
 
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(),
-                db.getDbEntities(), new DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities());
 
         assertEquals(1, tokens.size());
 
@@ -159,8 +153,7 @@ public class DbMergerTest {
          .build();
 
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(),
-                db.getDbEntities(), new DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities());
 
         assertEquals(2, tokens.size());
 
@@ -198,7 +191,7 @@ public class DbMergerTest {
          .build();
 
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities(), new 
DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities());
 
         assertEquals(1, tokens.size());
 
@@ -220,8 +213,7 @@ public class DbMergerTest {
                 dbAttr("attr02").typeInt()
         )).build();
 
-        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(),
-                db.getDbEntities(), new DbLoaderConfiguration());
+        List<MergerToken> tokens = 
dbMerger().createMergeTokens(existing.getDbEntities(), db.getDbEntities());
 
         assertEquals(1, tokens.size());
 
@@ -247,12 +239,11 @@ public class DbMergerTest {
         )).build();
 
 
-        assertEquals(0, dbMerger().createMergeTokens(dataMap1.getDbEntities(),
-                dataMap2.getDbEntities(), new DbLoaderConfiguration()).size());
+        assertEquals(0, dbMerger().createMergeTokens(dataMap1.getDbEntities(), 
dataMap2.getDbEntities()).size());
     }
 
     private DbMerger dbMerger() {
-        return new DbMerger(factory(), new EmptyValueForNullProvider());
+        return DbMerger.build(factory());
     }
 
     private HSQLMergerTokenFactory factory() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java
index 7706c2f..afdcb01 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/MergeCase.java
@@ -95,22 +95,21 @@ public abstract class MergeCase extends DbSyncCase {
         assertTokensAndExecute(0, 0);
     }
 
-    protected DbMerger createMerger() {
-        return createMerger(null);
-    }
-
-    protected DbMerger createMerger(ValueForNullProvider valueForNullProvider) 
{
-        return new DbMerger(mergerFactory(), valueForNullProvider);
+    protected DbMerger.Builder merger() {
+        return DbMerger.builder(mergerFactory());
     }
 
     protected List<MergerToken> createMergeTokens() {
+
+        FiltersConfig filters = FiltersConfig.create(null, null,
+                TableFilter.include("ARTIST|GALLERY|PAINTING|NEW_TABLE2?"), 
PatternFilter.INCLUDE_NOTHING);
+
         DbLoaderConfiguration loaderConfiguration = new 
DbLoaderConfiguration();
-        loaderConfiguration.setFiltersConfig(FiltersConfig.create(null, null,
-                TableFilter.include("ARTIST|GALLERY|PAINTING|NEW_TABLE2?"), 
PatternFilter.INCLUDE_NOTHING));
+        loaderConfiguration.setFiltersConfig(filters);
 
         DataMap dbImport;
         try (Connection conn = node.getDataSource().getConnection();) {
-            dbImport =  new DbLoader(conn,
+            dbImport = new DbLoader(conn,
                     node.getAdapter(),
                     new 
LoggingDbLoaderDelegate(LogFactory.getLog(DbLoader.class)),
                     new EntityMergeSupport(new DefaultObjectNameGenerator(), 
true, true))
@@ -120,7 +119,7 @@ public abstract class MergeCase extends DbSyncCase {
             throw new CayenneRuntimeException("Can't doLoad dataMap from db.", 
e);
         }
 
-        return createMerger().createMergeTokens(map, dbImport, 
loaderConfiguration);
+        return merger().filters(filters).build().createMergeTokens(map, 
dbImport);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/ValueForNullIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/ValueForNullIT.java
 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/ValueForNullIT.java
index e9910fd..c88b601 100644
--- 
a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/ValueForNullIT.java
+++ 
b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/merge/ValueForNullIT.java
@@ -42,86 +42,85 @@ import static org.junit.Assert.assertTrue;
 
 public class ValueForNullIT extends MergeCase {
 
-       private static final String DEFAULT_VALUE_STRING = "DEFSTRING";
-
-       @Inject
-       private DataContext context;
-
-       @Test
-       public void test() throws Exception {
-               DbEntity dbEntity = map.getDbEntity("PAINTING");
-               assertNotNull(dbEntity);
-               ObjEntity objEntity = map.getObjEntity("Painting");
-               assertNotNull(objEntity);
-
-               // insert some rows before adding "not null" column
-               final int nrows = 10;
-               for (int i = 0; i < nrows; i++) {
-                       DataObject o = (DataObject) 
context.newObject("Painting");
-                       o.writeProperty("paintingTitle", "ptitle" + i);
-               }
-               context.commitChanges();
-
-               // create and add new column to model and db
-               DbAttribute column = new DbAttribute("NEWCOL2", Types.VARCHAR, 
dbEntity);
-
-               column.setMandatory(false);
-               column.setMaxLength(10);
-               dbEntity.addAttribute(column);
-               assertTrue(dbEntity.getAttributes().contains(column));
-               assertEquals(column, dbEntity.getAttribute(column.getName()));
-               assertTokensAndExecute(1, 0);
-
-               // need obj attr to be able to query
-               ObjAttribute objAttr = new ObjAttribute("newcol2");
-               objAttr.setDbAttributePath(column.getName());
-               objEntity.addAttribute(objAttr);
-
-               // check that is was merged
-               assertTokensAndExecute(0, 0);
-
-               // set not null
-               column.setMandatory(true);
-
-               // merge to db
-               assertTokensAndExecute(2, 0);
-
-               // check that is was merged
-               assertTokensAndExecute(0, 0);
-
-               // check values for null
-               Expression qual = ExpressionFactory.matchExp(objAttr.getName(), 
DEFAULT_VALUE_STRING);
-               SelectQuery query = new SelectQuery("Painting", qual);
-               List<Persistent> rows = context.performQuery(query);
-               assertEquals(nrows, rows.size());
-
-               // clean up
-               dbEntity.removeAttribute(column.getName());
-               assertTokensAndExecute(1, 0);
-               assertTokensAndExecute(0, 0);
-       }
-
-       @Override
-       protected DbMerger createMerger(final ValueForNullProvider 
valueForNullProvider) {
-               return super.createMerger(new DefaultValueForNullProvider() {
-
-                       @Override
-                       protected SQLParameterBinding get(DbEntity entity, 
DbAttribute column) {
-                               int type = column.getType();
-                               switch (type) {
-                               case Types.VARCHAR:
-                                       return new 
SQLParameterBinding(DEFAULT_VALUE_STRING, type, -1);
-                               default:
-                                       throw new AssertionFailedError("should 
not get here");
-                               }
-                       }
-
-                       @Override
-                       public boolean hasValueFor(DbEntity entity, DbAttribute 
column) {
-                               return true;
-                       }
-
-               });
-       }
+    private static final String DEFAULT_VALUE_STRING = "DEFSTRING";
+
+    @Inject
+    private DataContext context;
+
+    @Test
+    public void test() throws Exception {
+        DbEntity dbEntity = map.getDbEntity("PAINTING");
+        assertNotNull(dbEntity);
+        ObjEntity objEntity = map.getObjEntity("Painting");
+        assertNotNull(objEntity);
+
+        // insert some rows before adding "not null" column
+        final int nrows = 10;
+        for (int i = 0; i < nrows; i++) {
+            DataObject o = (DataObject) context.newObject("Painting");
+            o.writeProperty("paintingTitle", "ptitle" + i);
+        }
+        context.commitChanges();
+
+        // create and add new column to model and db
+        DbAttribute column = new DbAttribute("NEWCOL2", Types.VARCHAR, 
dbEntity);
+
+        column.setMandatory(false);
+        column.setMaxLength(10);
+        dbEntity.addAttribute(column);
+        assertTrue(dbEntity.getAttributes().contains(column));
+        assertEquals(column, dbEntity.getAttribute(column.getName()));
+        assertTokensAndExecute(1, 0);
+
+        // need obj attr to be able to query
+        ObjAttribute objAttr = new ObjAttribute("newcol2");
+        objAttr.setDbAttributePath(column.getName());
+        objEntity.addAttribute(objAttr);
+
+        // check that is was merged
+        assertTokensAndExecute(0, 0);
+
+        // set not null
+        column.setMandatory(true);
+
+        // merge to db
+        assertTokensAndExecute(2, 0);
+
+        // check that is was merged
+        assertTokensAndExecute(0, 0);
+
+        // check values for null
+        Expression qual = ExpressionFactory.matchExp(objAttr.getName(), 
DEFAULT_VALUE_STRING);
+        SelectQuery query = new SelectQuery("Painting", qual);
+        List<Persistent> rows = context.performQuery(query);
+        assertEquals(nrows, rows.size());
+
+        // clean up
+        dbEntity.removeAttribute(column.getName());
+        assertTokensAndExecute(1, 0);
+        assertTokensAndExecute(0, 0);
+    }
+
+    @Override
+    protected DbMerger.Builder merger() {
+        return super.merger().valueForNullProvider(new 
DefaultValueForNullProvider() {
+
+            @Override
+            protected SQLParameterBinding get(DbEntity entity, DbAttribute 
column) {
+                int type = column.getType();
+                switch (type) {
+                    case Types.VARCHAR:
+                        return new SQLParameterBinding(DEFAULT_VALUE_STRING, 
type, -1);
+                    default:
+                        throw new AssertionFailedError("should not get here");
+                }
+            }
+
+            @Override
+            public boolean hasValueFor(DbEntity entity, DbAttribute column) {
+                return true;
+            }
+        });
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
index c371ee6..eda833c 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportConfiguration.java
@@ -22,10 +22,11 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.conn.DataSourceInfo;
 import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dbsync.merge.DbMergerConfig;
 import org.apache.cayenne.dbsync.merge.DefaultModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
 import org.apache.cayenne.dbsync.merge.ModelMergeDelegate;
+import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
+import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
 import org.apache.cayenne.dbsync.reverse.NameFilter;
 import org.apache.cayenne.dbsync.reverse.NamePatternMatcher;
 import org.apache.cayenne.dbsync.reverse.db.DbLoader;
@@ -35,8 +36,6 @@ import 
org.apache.cayenne.dbsync.reverse.db.DefaultDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.db.LoggingDbLoaderDelegate;
 import org.apache.cayenne.dbsync.reverse.filters.CatalogFilter;
 import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
-import org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator;
-import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
@@ -49,7 +48,6 @@ import java.net.MalformedURLException;
 import java.sql.Connection;
 import java.util.Collections;
 
-
 /**
  * @since 4.0
  */
@@ -314,12 +312,4 @@ public class DbImportConfiguration {
     public void setTableTypes(String[] tableTypes) {
         dbLoaderConfiguration.setTableTypes(tableTypes);
     }
-
-    public DbMergerConfig getDbMergerConfig() {
-        return new DbMergerConfig(
-                getDbLoaderConfig().getFiltersConfig(),
-                getDbLoaderConfig().getSkipRelationshipsLoading(),
-                getDbLoaderConfig().getSkipPrimaryKeyLoading()
-        );
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
index fd40673..9118d34 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DefaultDbImportAction.java
@@ -26,15 +26,15 @@ import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dbsync.merge.AbstractToModelToken;
 import org.apache.cayenne.dbsync.merge.AddRelationshipToDb;
 import org.apache.cayenne.dbsync.merge.DbMerger;
-import org.apache.cayenne.dbsync.merge.EmptyValueForNullProvider;
 import org.apache.cayenne.dbsync.merge.MergerContext;
-import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.MergerToken;
 import org.apache.cayenne.dbsync.merge.ModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.ProxyModelMergeDelegate;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactory;
-import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.naming.ObjectNameGenerator;
+import org.apache.cayenne.dbsync.reverse.db.DbLoader;
+import org.apache.cayenne.dbsync.reverse.db.DbLoaderConfiguration;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.EntityResolver;
@@ -144,8 +144,14 @@ public class DefaultDbImportAction implements 
DbImportAction {
         } else {
             MergerTokenFactory mergerTokenFactory = 
mergerTokenFactoryProvider.get(adapter);
 
-            List<MergerToken> mergeTokens = new DbMerger(mergerTokenFactory, 
new EmptyValueForNullProvider())
-                    .createMergeTokens(existing, loadedFomDb, 
config.getDbLoaderConfig());
+            DbLoaderConfiguration loaderConfig = config.getDbLoaderConfig();
+            List<MergerToken> mergeTokens = 
DbMerger.builder(mergerTokenFactory)
+                    .filters(loaderConfig.getFiltersConfig())
+                    .skipPKTokens(loaderConfig.isSkipPrimaryKeyLoading())
+                    
.skipRelationshipsTokens(loaderConfig.isSkipRelationshipsLoading())
+                    .build()
+                    .createMergeTokens(existing, loadedFomDb);
+
             if (mergeTokens.isEmpty()) {
                 logger.info("");
                 logger.info("Detected changes: No changes to import.");

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a811b44e/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
index b00aed8..41a9e43 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/MergerOptions.java
@@ -25,7 +25,6 @@ import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dbsync.merge.AbstractToDbToken;
 import org.apache.cayenne.dbsync.merge.DbMerger;
-import org.apache.cayenne.dbsync.merge.EmptyValueForNullProvider;
 import org.apache.cayenne.dbsync.merge.EntityMergeSupport;
 import org.apache.cayenne.dbsync.merge.MergeDirection;
 import org.apache.cayenne.dbsync.merge.MergerContext;
@@ -165,12 +164,18 @@ public class MergerOptions extends CayenneController {
             adapter = (JdbcAdapter) 
connectionInfo.makeAdapter(getApplication().getClassLoadingService());
 
             MergerTokenFactory mergerTokenFactory = 
mergerTokenFactoryProvider.get(adapter);
-
             tokens.setMergerTokenFactory(mergerTokenFactory);
-            DbMerger merger = new DbMerger(mergerTokenFactory, new 
EmptyValueForNullProvider());
+
+
+            FiltersConfig filters = FiltersConfig.create(null, defaultSchema, 
TableFilter.everything(),
+                    PatternFilter.INCLUDE_NOTHING);
+
+            DbMerger merger = DbMerger.builder(mergerTokenFactory)
+                    .filters(filters)
+                    .build();
 
             DbLoaderConfiguration config = new DbLoaderConfiguration();
-            config.setFiltersConfig(FiltersConfig.create(null, defaultSchema, 
TableFilter.everything(), PatternFilter.INCLUDE_NOTHING));
+            config.setFiltersConfig(filters);
 
             DataSource dataSource  = 
connectionInfo.makeDataSource(getApplication().getClassLoadingService());
 
@@ -186,7 +191,7 @@ public class MergerOptions extends CayenneController {
                 throw new CayenneRuntimeException("Can't doLoad dataMap from 
db.", e);
             }
 
-            tokens.setTokens(merger.createMergeTokens(dataMap, dbImport, 
config));
+            tokens.setTokens(merger.createMergeTokens(dataMap, dbImport));
         } catch (Exception ex) {
             reportError("Error loading adapter", ex);
         }

Reply via email to