Repository: cayenne
Updated Branches:
  refs/heads/master 44642ea58 -> c8ff4355f


fix relationships loading


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

Branch: refs/heads/master
Commit: aaafe117143e256a7b48692485b22c9d10538477
Parents: 44642ea
Author: alexkolonitsky <alex.kolonit...@gmail.com>
Authored: Thu Jan 8 20:49:26 2015 +0300
Committer: alexkolonitsky <alex.kolonit...@gmail.com>
Committed: Thu Jan 8 20:49:26 2015 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/access/DbLoader.java     |  69 ++++-----
 .../access/loader/LoggingDbLoaderDelegate.java  |  20 +--
 .../org/apache/cayenne/map/DbRelationship.java  |  40 ++++--
 .../org/apache/cayenne/map/Relationship.java    |   6 +-
 .../apache/cayenne/map/naming/ExportedKey.java  |  18 ++-
 .../merge/DropRelationshipToModelIT.java        |   7 +-
 .../apache/cayenne/merge/MergerFactoryIT.java   |  13 +-
 cayenne-tools/pom.xml                           |   5 +
 .../cayenne/tools/CayenneGeneratorTask.java     |  11 +-
 .../cayenne/tools/dbimport/DbImportAction.java  |  30 ++--
 .../dbimport/DbImportDbLoaderDelegate.java      |   1 -
 .../src/main/resources/reverseEngineering.xsd   | 139 +++++++++++++++++++
 .../cayenne/tools/DbImporterMojoTest.java       |   4 +
 .../cayenne/tools/dbimport/testOneToOne-pom.xml |  39 ++++++
 .../tools/dbimport/testOneToOne.map.xml-result  |  58 ++++++++
 .../cayenne/tools/dbimport/testOneToOne.sql     |  24 ++++
 16 files changed, 400 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
index 864e4f0..f86692f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DbLoader.java
@@ -49,14 +49,12 @@ import org.apache.commons.logging.LogFactory;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -325,9 +323,8 @@ public class DbLoader {
 
             loadDbAttributes(config.getFiltersConfig(), tablesMap.getKey(), 
tablesMap.getValue());
 
-            if (!config.isSkipPrimaryKeyLoading()) {
-                getPrimaryKeyForTable(tablesMap.getValue());
-            }
+            // get primary keys for each table and store it in dbEntity
+            getPrimaryKeyForTable(tablesMap.getValue());
         }
 
         return dbEntityList;
@@ -366,8 +363,6 @@ public class DbLoader {
         ResultSet rs = getMetaData().getColumns(path.catalog, path.schema, 
WILDCARD, WILDCARD);
 
         try {
-            Set<String> columns = new HashSet<String>();
-
             while (rs.next()) {
                 // for a reason not quiet apparent to me, Oracle sometimes
                 // returns duplicate record sets for the same table, messing 
up table
@@ -382,7 +377,7 @@ public class DbLoader {
                     continue;
                 }
 
-                DbAttribute attr = loadDbAttribute(columns, rs);
+                DbAttribute attr = loadDbAttribute(rs);
                 attr.setEntity(dbEntity);
                 Filter<DbAttribute> filter = filters.filter(new 
DbPath(dbEntity.getCatalog(), dbEntity.getSchema(), 
dbEntity.getName())).columnFilter();
                 if (!filter.isInclude(attr)) {
@@ -404,14 +399,7 @@ public class DbLoader {
         }
     }
 
-    private DbAttribute loadDbAttribute(Set<String> columns, ResultSet rs) 
throws SQLException {
-        if (columns.isEmpty()) {
-            ResultSetMetaData rsMetaData = rs.getMetaData();
-            for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
-                columns.add(rsMetaData.getColumnLabel(i));
-            }
-        }
-
+    private DbAttribute loadDbAttribute(ResultSet rs) throws SQLException {
         // gets attribute's (column's) information
         int columnType = rs.getInt("DATA_TYPE");
 
@@ -433,7 +421,11 @@ public class DbLoader {
                 decimalDigits,
                 rs.getBoolean("NULLABLE"));
 
-        if (columns.contains("IS_AUTOINCREMENT")) {
+        if (adapter.supportsGeneratedKeys()) {
+
+            // TODO: this actually throws on some drivers... need to
+            // ensure that 'supportsGeneratedKeys' check is enough
+            // to prevent an exception here.
             String autoIncrement = rs.getString("IS_AUTOINCREMENT");
             if ("YES".equals(autoIncrement)) {
                 attr.setGenerated(true);
@@ -443,7 +435,8 @@ public class DbLoader {
     }
 
     /**
-     * Creates an ObjEntity for each DbEntity in the map.
+     * Creates an ObjEntity for each DbEntity in the map. ObjEntities are
+     * created empty without
      */
     protected Collection<ObjEntity> loadObjEntities(DataMap map, 
DbLoaderConfiguration config, Collection<DbEntity> entities) {
         if (entities.isEmpty()) {
@@ -518,28 +511,29 @@ public class DbLoader {
                     continue;
                 }
 
+                // forwardRelationship is a reference from table with primary 
key
                 DbRelationship forwardRelationship = new 
DbRelationship(generateName(pkEntity, key, true));
                 forwardRelationship.setSourceEntity(pkEntity);
                 forwardRelationship.setTargetEntity(fkEntity);
 
+                // forwardRelationship is a reference from table with foreign 
key, it is what exactly we load from db
                 DbRelationshipDetected reverseRelationship = new 
DbRelationshipDetected(generateName(fkEntity, key, false));
                 reverseRelationship.setFkName(key.getFKName());
                 reverseRelationship.setSourceEntity(fkEntity);
                 reverseRelationship.setTargetEntity(pkEntity);
                 reverseRelationship.setToMany(false);
-                if (delegate.dbRelationshipLoaded(fkEntity, 
reverseRelationship)) {
-                    fkEntity.addRelationship(reverseRelationship);
-                }
 
-                boolean toPK = createAndAppendJoins(exportedKeys, pkEntity, 
fkEntity, forwardRelationship, reverseRelationship);
+                createAndAppendJoins(exportedKeys, pkEntity, fkEntity, 
forwardRelationship, reverseRelationship);
 
-                forwardRelationship.setToDependentPK(toPK);
-
-                boolean isOneToOne = toPK && fkEntity.getPrimaryKeys().size()
-                        == forwardRelationship.getJoins().size();
+                boolean isOneToOne = isOneToOne(fkEntity, forwardRelationship);
 
+                forwardRelationship.setToDependentPK(isOneToOne);
                 forwardRelationship.setToMany(!isOneToOne);
                 forwardRelationship.setName(generateName(pkEntity, key, 
!isOneToOne));
+
+                if (delegate.dbRelationshipLoaded(fkEntity, 
reverseRelationship)) {
+                    fkEntity.addRelationship(reverseRelationship);
+                }
                 if (delegate.dbRelationshipLoaded(pkEntity, 
forwardRelationship)) {
                     pkEntity.addRelationship(forwardRelationship);
                 }
@@ -547,8 +541,21 @@ public class DbLoader {
         }
     }
 
-    private boolean createAndAppendJoins(Set<ExportedKey> exportedKeys, 
DbEntity pkEntity, DbEntity fkEntity, DbRelationship forwardRelationship, 
DbRelationshipDetected reverseRelationship) {
-        boolean toPK = true;
+    private boolean isOneToOne(DbEntity fkEntity, DbRelationship 
forwardRelationship) {
+        if (fkEntity.getPrimaryKeys().size() != 
forwardRelationship.getJoins().size()) {
+            return false;
+        }
+
+        for (DbJoin dbJoin : forwardRelationship.getJoins()) {
+            if (!dbJoin.getTarget().isPrimaryKey()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void createAndAppendJoins(Set<ExportedKey> exportedKeys, DbEntity 
pkEntity, DbEntity fkEntity, DbRelationship forwardRelationship, 
DbRelationshipDetected reverseRelationship) {
         for (ExportedKey exportedKey : exportedKeys) {
             // Create and append joins
             String pkName = exportedKey.getPKColumnName();
@@ -569,12 +576,7 @@ public class DbLoader {
 
             forwardRelationship.addJoin(new DbJoin(forwardRelationship, 
pkName, fkName));
             reverseRelationship.addJoin(new DbJoin(reverseRelationship, 
fkName, pkName));
-
-            if (!pkAtt.isPrimaryKey()) {
-                toPK = false;
-            }
         }
-        return toPK;
     }
 
     private Map<String, Set<ExportedKey>> 
loadExportedKeys(DbLoaderConfiguration config, DbPath dbPath, Map<String, 
DbEntity> tables) throws SQLException {
@@ -760,6 +762,7 @@ public class DbLoader {
      * @since 4.0
      */
     public void load(DataMap dataMap, DbLoaderConfiguration config) throws 
SQLException {
+        LOGGER.info("Schema loading...");
 
         Map<DbPath, Map<String, DbEntity>> tables = getTables(config, 
config.getTableTypes());
         List<DbEntity> entities = loadDbEntities(dataMap, config, tables);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/main/java/org/apache/cayenne/access/loader/LoggingDbLoaderDelegate.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/LoggingDbLoaderDelegate.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/LoggingDbLoaderDelegate.java
index d5e69f4..8c77a87 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/LoggingDbLoaderDelegate.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/LoggingDbLoaderDelegate.java
@@ -36,37 +36,41 @@ public class LoggingDbLoaderDelegate extends 
DefaultDbLoaderDelegate {
 
     @Override
     public void dbEntityAdded(DbEntity entity) {
-        logger.info("Add dbEntity: " + entity.getFullyQualifiedName());
+        logger.info("  Table: " + entity.getFullyQualifiedName());
     }
 
     @Override
     public void dbEntityRemoved(DbEntity entity) {
-        logger.info("Del dbEntity: " + entity.getFullyQualifiedName());
+        logger.info("  Table removed: " + entity.getFullyQualifiedName());
     }
 
     @Override
     public boolean dbRelationship(DbEntity entity) {
-        logger.info("    Relationships for " + entity.getFullyQualifiedName());
+        if (logger.isDebugEnabled()) {
+            logger.debug("    Relationships for " + 
entity.getFullyQualifiedName());
+        }
 
         return true;
     }
 
     @Override
     public boolean dbRelationshipLoaded(DbEntity entity, DbRelationship 
relationship) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("    Relationship : " + entity.getName() + "; " + 
relationship.toString());
-        }
+        logger.info("    " + relationship);
 
         return true;
     }
 
     @Override
     public void objEntityAdded(ObjEntity entity) {
-        logger.info("Add objEntity: " + entity.getName());
+        if (logger.isDebugEnabled()) {
+            logger.debug("  Class: " + entity.getName());
+        }
     }
 
     @Override
     public void objEntityRemoved(ObjEntity entity) {
-        logger.info("Del objEntity: " + entity.getName());
+        if (logger.isDebugEnabled()) {
+            logger.debug("  Class removed: " + entity.getName());
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java 
b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
index 5234ff4..12bfbf9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/DbRelationship.java
@@ -33,6 +33,7 @@ import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.Transformer;
+import org.apache.commons.lang.StringUtils;
 
 /**
  * A DbRelationship is a descriptor of a database inter-table relationship 
based
@@ -40,17 +41,18 @@ import org.apache.commons.collections.Transformer;
  */
 public class DbRelationship extends Relationship implements ConfigurationNode {
 
-    // The columns through which the join is implemented.
+    /**
+     * The columns through which the join is implemented.
+     */
     protected List<DbJoin> joins = new ArrayList<DbJoin>(2);
 
-    // Is relationship from source to target points to dependent primary
-    // key (primary key column of destination table that is also a FK to the
-    // source
-    // column)
+    /**
+     * Is relationship from source to target points to dependent primary key 
(primary key column of destination table
+     * that is also a FK to the source column)
+     */
     protected boolean toDependentPK;
 
     public DbRelationship() {
-        super();
     }
 
     public DbRelationship(String name) {
@@ -122,7 +124,7 @@ public class DbRelationship extends Relationship implements 
ConfigurationNode {
      */
     public Collection<DbAttribute> getTargetAttributes() {
         if (joins.size() == 0) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
         return CollectionUtils.collect(joins, 
JoinTransformers.targetExtractor);
@@ -135,7 +137,7 @@ public class DbRelationship extends Relationship implements 
ConfigurationNode {
      */
     public Collection<DbAttribute> getSourceAttributes() {
         if (joins.size() == 0) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
         return CollectionUtils.collect(joins, 
JoinTransformers.sourceExtractor);
@@ -148,7 +150,7 @@ public class DbRelationship extends Relationship implements 
ConfigurationNode {
      * @since 1.0.5
      */
     public DbRelationship createReverseRelationship() {
-        DbEntity targetEntity = (DbEntity) getTargetEntity();
+        DbEntity targetEntity = getTargetEntity();
 
         DbRelationship reverse = new DbRelationship();
         reverse.setSourceEntity(targetEntity);
@@ -535,4 +537,24 @@ public class DbRelationship extends Relationship 
implements ConfigurationNode {
                     && Util.nullSafeEquals(j.targetName, this.targetName);
         }
     }
+
+    @Override
+    public String toString() {
+        String res = "Db Relationship : " + (toMany ? "toMany" : "toOne ");
+
+        String sourceEntityName = getSourceEntityName();
+        String targetEntityName = getTargetEntityName();
+        for (DbJoin join : joins) {
+            res += " (" + sourceEntityName + "." + join.getSourceName() + ", " 
+ targetEntityName + "." + join.getTargetName() + ")";
+        }
+
+        return res;
+    }
+
+    public String getSourceEntityName() {
+        if (this.sourceEntity == null) {
+            return null;
+        }
+        return this.sourceEntity.name;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java 
b/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
index 1c34172..ecc0f80 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/Relationship.java
@@ -159,9 +159,9 @@ public abstract class Relationship implements 
CayenneMapEntry, XMLSerializable,
      */
     @Override
     public String toString() {
-        return new ToStringBuilder(this).append("name", getName()).append(
-                "toMany",
-                isToMany()).toString();
+        return new ToStringBuilder(this)
+                .append("name", getName())
+                .append("toMany", isToMany()).toString();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ExportedKey.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ExportedKey.java 
b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ExportedKey.java
index 42697fe..ab8229f 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ExportedKey.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/map/naming/ExportedKey.java
@@ -28,6 +28,19 @@ import java.sql.SQLException;
 /**
  * ExportedKey is an representation of relationship between two tables 
  * in database. It can be used for creating names for relationships
+ *
+ * Example:
+ *  Table A with primary key ID
+ *  Table B with primary key ID and foreign key A_ID
+ *
+ *  In that case ExportedKey will be:
+ *      pkTable:  A
+ *      pkColumn: A.ID
+ *      fkTable:  B
+ *      fkColumn: B.A_ID
+ *      fkName:   name of foreign key
+ *      pkName:
+ *      keySeq: TODO
  * 
  */
 public class ExportedKey implements Comparable {
@@ -200,11 +213,10 @@ public class ExportedKey implements Comparable {
 
     @Override
     public String toString() {
-        return getStrKey() + " # " + keySeq
-                + "(" + pkColumn + " <- " + fkColumn + ")";
+        return getStrKey() + " # " + keySeq;
     }
 
     public String getStrKey() {
-        return pkTable + "." + pkName + " <- " + fkTable + "." + fkName;
+        return pkTable + "." + pkColumn + " <- " + fkTable + "." + fkColumn;
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
index e235109..3505971 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/merge/DropRelationshipToModelIT.java
@@ -130,7 +130,12 @@ public class DropRelationshipToModelIT extends MergeCase {
         dbEntity1.removeRelationship(rel1To2.getName());
         dbEntity2.removeAttribute(e2col2.getName());
         List<MergerToken> tokens = createMergeTokens();
-        assertTokens(tokens, 3, 0);
+        /**
+         * Add Relationship NEW_TABLE->NEW_TABLE2 To Model
+         * Drop Relationship NEW_TABLE2->NEW_TABLE To DB
+         * Drop Column NEW_TABLE2.FK To DB
+         * */
+        assertTokens(tokens, 2, 1);
         for (MergerToken token : tokens) {
             if (token.getDirection().isToDb()) {
                 execute(token);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
index 409f1c9..e1db050 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/merge/MergerFactoryIT.java
@@ -219,8 +219,11 @@ public class MergerFactoryIT extends MergeCase {
         dbEntity.removeRelationship(r1.getName());
         artistDbEntity.removeRelationship(r2.getName());
         resolver.refreshMappingCache();
-        assertTokensAndExecute(2, 0);
-//        assertTokensAndExecute(1, 1);
+        /*
+         * Db -Rel 'toArtistR1' - NEW_TABLE 1 -> 1 ARTIST"
+r2 =     * Db -Rel 'toNewTableR2' - ARTIST 1 -> * NEW_TABLE"
+         * */
+        assertTokensAndExecute(1, 1);
         assertTokensAndExecute(0, 0);
 
         // clear up
@@ -277,7 +280,11 @@ public class MergerFactoryIT extends MergeCase {
         dbEntity.removeRelationship(r1.getName());
         artistDbEntity.removeRelationship(r2.getName());
         resolver.refreshMappingCache();
-        assertTokensAndExecute(2, 0);
+        /*
+        * Add Relationship ARTIST->NEW_TABLE To Model
+        * Drop Relationship NEW_TABLE->ARTIST To DB
+        * */
+        assertTokensAndExecute(1, 1);
         assertTokensAndExecute(0, 0);
 
         // clear up

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-tools/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-tools/pom.xml b/cayenne-tools/pom.xml
index a97dd13..630c92d 100644
--- a/cayenne-tools/pom.xml
+++ b/cayenne-tools/pom.xml
@@ -165,6 +165,11 @@
             <plugin>
                 <artifactId>maven-pmd-plugin</artifactId>
             </plugin>
+            <plugin>
+                <groupId>xsddoc</groupId>
+                <artifactId>maven-xsddoc-plugin</artifactId>
+                <version>1.0</version>
+            </plugin>
         </plugins>
        </build>
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-tools/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java
index dcd36e6..26ae00d 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/CayenneGeneratorTask.java
@@ -73,16 +73,9 @@ public class CayenneGeneratorTask extends CayenneTask {
     }
 
     protected ClassGenerationAction createGeneratorAction() {
-        ClassGenerationAction action;
-        if (client) {
-            action = new ClientClassGenerationAction();
-            action.setContext(getVppContext());
-        }
-        else {
-            action = new ClassGenerationAction();
-            action.setContext(getVppContext());
-        }
+        ClassGenerationAction action = client ? new 
ClientClassGenerationAction() : new ClassGenerationAction();
 
+        action.setContext(getVppContext());
         action.setDestDir(destDir);
         action.setEncoding(encoding);
         action.setMakePairs(makepairs);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
index bf981ee..3ff9278 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportAction.java
@@ -110,7 +110,8 @@ public class DbImportAction {
             List<MergerToken> mergeTokens = new DbMerger(mergerFactory)
                     .createMergeTokens(existing, loadedFomDb, 
config.getDbLoaderConfig());
             if (mergeTokens.isEmpty()) {
-                logger.info("No changes to import.");
+                logger.info("");
+                logger.info("Detected changes: No changes to import.");
                 return;
             }
 
@@ -122,6 +123,7 @@ public class DbImportAction {
     }
 
     private Collection<MergerToken> log(List<MergerToken> tokens) {
+        logger.info("");
         logger.info("Detected changes: ");
         for (MergerToken token : tokens) {
             logger.info(String.format("    %-20s %s", token.getTokenName(), 
token.getTokenValue()));
@@ -154,7 +156,7 @@ public class DbImportAction {
     /**
      * Performs configured schema operations via DbGenerator.
      */
-    public DataMap execute(ModelMergeDelegate mergeDelegate, DataMap dataMap, 
Collection<MergerToken> tokens) {
+    private DataMap execute(ModelMergeDelegate mergeDelegate, DataMap dataMap, 
Collection<MergerToken> tokens) {
         MergerContext mergerContext = new ExecutingMergerContext(
                 dataMap, null, null, mergeDelegate);
 
@@ -190,18 +192,18 @@ public class DbImportAction {
         projectSaver.save(project);
     }
 
-       private DataMap load(DbImportConfiguration config, DbAdapter adapter, 
Connection connection) throws Exception {
-               DataMap dataMap = config.createDataMap();
+    private DataMap load(DbImportConfiguration config, DbAdapter adapter, 
Connection connection) throws Exception {
+        DataMap dataMap = config.createDataMap();
 
-               try {
-                       DbLoader loader = config.createLoader(adapter, 
connection, config.createLoaderDelegate());
-                       loader.load(dataMap, config.getDbLoaderConfig());
-               } finally {
-                       if (connection != null) {
-                               connection.close();
-                       }
-               }
+        try {
+            DbLoader loader = config.createLoader(adapter, connection, 
config.createLoaderDelegate());
+            loader.load(dataMap, config.getDbLoaderConfig());
+        } finally {
+            if (connection != null) {
+                connection.close();
+            }
+        }
 
-               return dataMap;
-       }
+        return dataMap;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
----------------------------------------------------------------------
diff --git 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
index a97fd03..e3fbc01 100644
--- 
a/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
+++ 
b/cayenne-tools/src/main/java/org/apache/cayenne/tools/dbimport/DbImportDbLoaderDelegate.java
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.tools.dbimport;
 
-import org.apache.cayenne.access.DbLoaderDelegate;
 import org.apache.cayenne.access.loader.DefaultDbLoaderDelegate;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.ObjEntity;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/cayenne-tools/src/main/resources/reverseEngineering.xsd
----------------------------------------------------------------------
diff --git a/cayenne-tools/src/main/resources/reverseEngineering.xsd 
b/cayenne-tools/src/main/resources/reverseEngineering.xsd
new file mode 100644
index 0000000..6905386
--- /dev/null
+++ b/cayenne-tools/src/main/resources/reverseEngineering.xsd
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<xs:schema attributeFormDefault="unqualified"
+           elementFormDefault="qualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema";>
+
+    <xs:complexType name="PatternParamType" mixed="true">
+        <xs:annotation>
+            <xs:documentation>
+                At least one of 3 options ot fill pattern information should 
be used
+                1) &lt;tag>pattarn&lt;tag>
+                2) &lt;tag pattern="pattern" />
+                3) &lt;tag>
+                      &lt;pattern>pattern&lt;/pattern>
+                   &lt;/tag>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element type="xs:string" name="pattern" minOccurs="0"/>
+        </xs:sequence>
+        <xs:attribute type="xs:string" name="pattern" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="IncludeTableType" mixed="true">
+        <xs:complexContent>
+            <xs:extension base="PatternParamType">
+                <xs:sequence>
+                    <xs:choice minOccurs="0" maxOccurs="unbounded">
+                        <xs:element name="includeColumn" 
type="PatternParamType" />
+                        <xs:element name="excludeColumn" 
type="PatternParamType" />
+                    </xs:choice>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:complexType name="FilterContainerType">
+        <xs:sequence>
+            <xs:choice minOccurs="1" maxOccurs="unbounded">
+                <xs:element name="includeTable" type="IncludeTableType" />
+                <xs:element name="excludeTable" type="PatternParamType" />
+                <xs:element name="includeColumn" type="PatternParamType" />
+                <xs:element name="excludeColumn" type="PatternParamType" />
+                <xs:element name="includeProcedure" type="PatternParamType" />
+                <xs:element name="excludeProcedure" type="PatternParamType" />
+            </xs:choice>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="SchemaType" mixed="true">
+        <xs:annotation>
+            <xs:documentation>
+                At least one of 3 options to provide schema name can be used:
+                1) &lt;schema>name&lt;schema>
+                2) &lt;schema name="name" />
+                3) &lt;schema>
+                &lt;name>name&lt;/name>
+                &lt;/schema>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexContent>
+            <xs:extension base="FilterContainerType">
+                <xs:sequence>
+                    <xs:element name="name" type="xs:string" minOccurs="0" 
maxOccurs="1" />
+                </xs:sequence>
+                <xs:attribute type="xs:string" name="name" use="optional" />
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:complexType name="CatalogType" mixed="true">
+        <xs:annotation>
+            <xs:documentation>
+                At least one of 3 options to provide schema name can be used:
+                1) &lt;catalog>name&lt;catalog>
+                2) &lt;catalog name="name" />
+                3) &lt;catalog>
+                &lt;name>name&lt;/name>
+                &lt;/catalog>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexContent>
+            <xs:extension base="FilterContainerType">
+                <xs:sequence>
+                    <xs:element name="name" type="xs:string" minOccurs="0" 
maxOccurs="1" />
+                    <xs:choice minOccurs="0" maxOccurs="unbounded">
+                        <xs:element name="schema" type="SchemaType" />
+                    </xs:choice>
+                </xs:sequence>
+                <xs:attribute type="xs:string" name="name" use="optional" />
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:complexType name="ReverseEngineeringType">
+        <xs:annotation>
+            <xs:documentation>
+                <!-- TODO -->
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexContent>
+            <xs:extension base="FilterContainerType">
+                <xs:sequence>
+                    <xs:element name="name" type="xs:string" minOccurs="0" 
maxOccurs="1" />
+                    <xs:choice minOccurs="0" maxOccurs="unbounded">
+                        <xs:element name="catalog" type="CatalogType" />
+                        <xs:element name="schema" type="SchemaType" />
+                    </xs:choice>
+                </xs:sequence>
+                <xs:attribute type="xs:string" name="name" use="optional" />
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="reverseEngineering" type="ReverseEngineeringType">
+        <xs:annotation>
+            <!-- TODO -->
+            <xs:documentation> </xs:documentation>
+        </xs:annotation>
+    </xs:element>
+
+</xs:schema>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
----------------------------------------------------------------------
diff --git 
a/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
 
b/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
index cf17a84..e7fc592 100644
--- 
a/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
+++ 
b/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
@@ -153,6 +153,10 @@ public class DbImporterMojoTest extends 
AbstractMojoTestCase {
                test("testSkipPrimaryKeyLoading");
        }
 
+       public void testOneToOne() throws Exception {
+               test("testOneToOne");
+       }
+
     /**
      * Q: what happens if a relationship existed over a column that was later 
deleted? and ‘skipRelLoading’ is true
      * A: it should remove relationship and column

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne-pom.xml
----------------------------------------------------------------------
diff --git 
a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne-pom.xml
 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne-pom.xml
new file mode 100644
index 0000000..bee8671
--- /dev/null
+++ 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne-pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+       http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+       <name>DbImporterMojo Test1</name>       
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-cayenne-plugin</artifactId>
+                               <configuration>
+                                       
<map>target/test-classes/org/apache/cayenne/tools/dbimport/testOneToOne.map.xml</map>
+                    <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
+                    <url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.map.xml-result
----------------------------------------------------------------------
diff --git 
a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.map.xml-result
 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.map.xml-result
new file mode 100644
index 0000000..557423d
--- /dev/null
+++ 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.map.xml-result
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+       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.
+-->
+<data-map xmlns="http://cayenne.apache.org/schema/7/modelMap";
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          xsi:schemaLocation="http://cayenne.apache.org/schema/7/modelMap 
http://cayenne.apache.org/schema/7/modelMap.xsd";
+          project-version="7">
+       <db-entity name="PICK_SCHEDULE" schema="APP">
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+               <db-attribute name="OWNER_ID" type="INTEGER" length="10"/>
+               <db-attribute name="SELECTED_PLAYER_ID" type="INTEGER" 
length="10"/>
+       </db-entity>
+       <db-entity name="PLAYER" schema="APP">
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true" length="10"/>
+       </db-entity>
+       <db-entity name="PLAYER_INFO" schema="APP">
+               <db-attribute name="PLAYER_ID" type="INTEGER" 
isPrimaryKey="true" isMandatory="true" length="10"/>
+       </db-entity>
+       <obj-entity name="PickSchedule" className="PickSchedule" 
dbEntityName="PICK_SCHEDULE">
+               <obj-attribute name="ownerId" type="java.lang.Integer" 
db-attribute-path="OWNER_ID"/>
+       </obj-entity>
+       <obj-entity name="Player" className="Player" dbEntityName="PLAYER">
+       </obj-entity>
+       <obj-entity name="PlayerInfo" className="PlayerInfo" 
dbEntityName="PLAYER_INFO">
+       </obj-entity>
+       <db-relationship name="toPlayer" source="PICK_SCHEDULE" target="PLAYER" 
toMany="false">
+               <db-attribute-pair source="SELECTED_PLAYER_ID" target="ID"/>
+       </db-relationship>
+       <db-relationship name="pickScheduleArray" source="PLAYER" 
target="PICK_SCHEDULE" toMany="true">
+               <db-attribute-pair source="ID" target="SELECTED_PLAYER_ID"/>
+       </db-relationship>
+       <db-relationship name="toPlayer" source="PLAYER" target="PLAYER_INFO" 
toDependentPK="true" toMany="false">
+               <db-attribute-pair source="ID" target="PLAYER_ID"/>
+       </db-relationship>
+       <db-relationship name="toPlayer" source="PLAYER_INFO" target="PLAYER" 
toMany="false">
+               <db-attribute-pair source="PLAYER_ID" target="ID"/>
+       </db-relationship>
+       <obj-relationship name="toPlayer" source="PickSchedule" target="Player" 
deleteRule="Nullify" db-relationship-path="toPlayer"/>
+       <obj-relationship name="pickScheduleArray" source="Player" 
target="PickSchedule" deleteRule="Deny" 
db-relationship-path="pickScheduleArray"/>
+       <obj-relationship name="toPlayer" source="Player" target="PlayerInfo" 
deleteRule="Nullify" db-relationship-path="toPlayer"/>
+       <obj-relationship name="toPlayer" source="PlayerInfo" target="Player" 
deleteRule="Nullify" db-relationship-path="toPlayer"/>
+</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/aaafe117/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.sql
----------------------------------------------------------------------
diff --git 
a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.sql
 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.sql
new file mode 100644
index 0000000..a279c65
--- /dev/null
+++ 
b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testOneToOne.sql
@@ -0,0 +1,24 @@
+CREATE TABLE player (
+  id INTEGER NOT NULL,
+
+  PRIMARY KEY (id)
+);
+
+
+-- one-to-one relationship
+CREATE TABLE player_info (
+  player_id INTEGER NOT NULL,
+
+  PRIMARY KEY (player_id),
+  CONSTRAINT fk_player_info FOREIGN KEY (player_id) REFERENCES player (id)
+);
+
+-- one-to-many relationship
+CREATE TABLE pick_schedule (
+  id INTEGER NOT NULL,
+  owner_id INTEGER,
+  selected_player_id INTEGER,
+  PRIMARY KEY (id),
+
+  CONSTRAINT fk_pick_schedule_player1 FOREIGN KEY (selected_player_id) 
REFERENCES player (id)
+)

Reply via email to