You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by to...@apache.org on 2009/09/09 09:04:22 UTC

svn commit: r812789 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne: access/ dba/hsqldb/ dba/postgres/ map/ merge/

Author: torehalset
Date: Wed Sep  9 07:04:21 2009
New Revision: 812789

URL: http://svn.apache.org/viewvc?rev=812789&view=rev
Log:
CAY-1270: merge primary key changes
 * tested on PostgreSQL, hsqldb, Derby and MS SQL Server
 * added DetectedDbEntity to hold primary key constraint name
 * proper quotation of table- and column names

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/DetectedDbEntity.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresMergerFactory.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/AbstractToDbToken.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToDb.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToModel.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DbLoader.java Wed Sep  9 07:04:21 2009
@@ -42,6 +42,7 @@
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.DbRelationshipDetected;
+import org.apache.cayenne.map.DetectedDbEntity;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.Procedure;
@@ -331,7 +332,7 @@
                     continue;
                 }
 
-                DbEntity table = new DbEntity(name);
+                DbEntity table = new DetectedDbEntity(name);
                 table.setCatalog(catalog);
                 table.setSchema(schema);
                 tables.add(table);
@@ -467,9 +468,9 @@
                         tableName);
                 try {
                     while (rs.next()) {
-                        String keyName = rs.getString(4);
+                        String columnName = rs.getString(4);
                         DbAttribute attribute = (DbAttribute) dbEntity
-                                .getAttribute(keyName);
+                                .getAttribute(columnName);
 
                         if (attribute != null) {
                             attribute.setPrimaryKey(true);
@@ -480,7 +481,12 @@
                             // possible
                             // so just print the warning, and ignore
                             logObj.warn("Can't locate attribute for primary key: "
-                                    + keyName);
+                                    + columnName);
+                        }
+                        
+                        String pkName = rs.getString(6);
+                        if ((pkName != null) && (dbEntity instanceof DetectedDbEntity)) {
+                            ((DetectedDbEntity) dbEntity).setPrimaryKeyName(pkName);
                         }
                     }
                 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java Wed Sep  9 07:04:21 2009
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.dba.hsqldb;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -29,6 +30,7 @@
 import org.apache.cayenne.merge.MergerToken;
 import org.apache.cayenne.merge.SetAllowNullToDb;
 import org.apache.cayenne.merge.SetColumnTypeToDb;
+import org.apache.cayenne.merge.SetPrimaryKeyToDb;
 
 public class HSQLMergerFactory extends MergerFactory {
 
@@ -73,4 +75,29 @@
         };
     }
 
+    @Override
+    public MergerToken createSetPrimaryKeyToDb(
+            DbEntity entity,
+            Collection<DbAttribute> primaryKeyOriginal,
+            Collection<DbAttribute> primaryKeyNew,
+            String detectedPrimaryKeyName) {
+        return new SetPrimaryKeyToDb(
+                entity,
+                primaryKeyOriginal,
+                primaryKeyNew,
+                detectedPrimaryKeyName) {
+
+            @Override
+            protected void appendDropOriginalPrimaryKeySQL(
+                    DbAdapter adapter,
+                    List<String> sqls) {
+                sqls.add("ALTER TABLE "
+                        + getQuotingStrategy(adapter)
+                                .quoteFullyQualifiedName(getEntity())
+                        + " DROP PRIMARY KEY");
+            }
+
+        };
+    }
+
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresMergerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresMergerFactory.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresMergerFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresMergerFactory.java Wed Sep  9 07:04:21 2009
@@ -18,16 +18,12 @@
  ****************************************************************/
 package org.apache.cayenne.dba.postgres;
 
-import java.util.Collection;
-import java.util.List;
-
 import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.merge.MergerToken;
 import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetPrimaryKeyToDb;
 
 public class PostgresMergerFactory extends MergerFactory {
 
@@ -51,26 +47,4 @@
         };
     }
 
-    @Override
-    public MergerToken createSetPrimaryKeyToDb(
-            DbEntity entity,
-            final Collection<DbAttribute> primaryKeyOriginal,
-            final Collection<DbAttribute> primaryKeyNew) {
-        return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, primaryKeyNew) {
-
-            @Override
-            protected void appendDropOriginalPrimaryKeySQL(List<String> sqls) {
-                sqls.add("ALTER TABLE "
-                        + getEntity().getFullyQualifiedName()
-                        + " DROP CONSTRAINT "
-                        + getConstraintName());
-            }
-
-            @Override
-            protected String getConstraintName() {
-                return getEntity().getName().toLowerCase() + "_pkey";
-            }
-        };
-    }
-
 }

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/DetectedDbEntity.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/DetectedDbEntity.java?rev=812789&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/DetectedDbEntity.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/DetectedDbEntity.java Wed Sep  9 07:04:21 2009
@@ -0,0 +1,48 @@
+/*****************************************************************
+ *   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.map;
+
+/**
+ * A {@link DbEntity} subclass used to hold extra JDBC metadata.
+ */
+public class DetectedDbEntity extends DbEntity {
+
+    protected String primaryKeyName;
+
+    public DetectedDbEntity(String name) {
+        super(name);
+    }
+
+    /**
+     * Sets the optional primary key name of this DbEntity. This is not the same as the
+     * name of the DbAttribute, but the name of the unique constraint.
+     */
+    public void setPrimaryKeyName(String primaryKeyName) {
+        this.primaryKeyName = primaryKeyName;
+    }
+
+    /**
+     * Returns the optional primary key name of this DbEntity. This is not the same as the
+     * name of the DbAttribute, but the name of the unique constraint.
+     */
+    public String getPrimaryKeyName() {
+        return primaryKeyName;
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/AbstractToDbToken.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/AbstractToDbToken.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/AbstractToDbToken.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/AbstractToDbToken.java Wed Sep  9 07:04:21 2009
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 
@@ -40,7 +41,7 @@
             mergerContext.executeSql(sql);
         }
     }
-
+    
     @Override
     public String toString() {
         StringBuilder ts = new StringBuilder();
@@ -70,6 +71,12 @@
             return getEntity().getName();
         }
         
+        protected QuotingStrategy getQuotingStrategy(DbAdapter adapter) {
+            return adapter.getQuotingStrategy(getEntity()
+                    .getDataMap()
+                    .isQuotingSQLIdentifiers());
+        }
+        
         public int compareTo(MergerToken o) {
             // default order as tokens are created
             return 0;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java Wed Sep  9 07:04:21 2009
@@ -46,6 +46,7 @@
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.DetectedDbEntity;
 import org.apache.cayenne.map.ObjEntity;
 
 /**
@@ -330,18 +331,29 @@
         }
     }
     
-    private void checkPrimaryKeyChange(DbAdapter adapter,
+    private void checkPrimaryKeyChange(
+            DbAdapter adapter,
             List<MergerToken> tokens,
             DbEntity dbEntity,
             DbEntity detectedEntity) {
         Collection<DbAttribute> primaryKeyOriginal = detectedEntity.getPrimaryKeys();
         Collection<DbAttribute> primaryKeyNew = dbEntity.getPrimaryKeys();
 
-        if (upperCaseEntityNames(primaryKeyOriginal).equals(upperCaseEntityNames(primaryKeyNew))) {
+        String primaryKeyName = null;
+        if ((detectedEntity instanceof DetectedDbEntity)) {
+            primaryKeyName = ((DetectedDbEntity) detectedEntity).getPrimaryKeyName();
+        }
+
+        if (upperCaseEntityNames(primaryKeyOriginal).equals(
+                upperCaseEntityNames(primaryKeyNew))) {
             return;
         }
-        
-        tokens.add(factory.createSetPrimaryKeyToDb(dbEntity, primaryKeyOriginal, primaryKeyNew));
+
+        tokens.add(factory.createSetPrimaryKeyToDb(
+                dbEntity,
+                primaryKeyOriginal,
+                primaryKeyNew,
+                primaryKeyName));
     }
     
     private Set<String> upperCaseEntityNames(Collection<? extends Attribute> attrs) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java Wed Sep  9 07:04:21 2009
@@ -119,14 +119,24 @@
     public MergerToken createSetPrimaryKeyToDb(
             DbEntity entity,
             Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew) {
-        return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, primaryKeyNew);
+            Collection<DbAttribute> primaryKeyNew,
+            String detectedPrimaryKeyName) {
+        return new SetPrimaryKeyToDb(
+                entity,
+                primaryKeyOriginal,
+                primaryKeyNew,
+                detectedPrimaryKeyName);
     }
 
     public MergerToken createSetPrimaryKeyToModel(
             DbEntity entity,
             Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew) {
-        return new SetPrimaryKeyToModel(entity, primaryKeyOriginal, primaryKeyNew);
+            Collection<DbAttribute> primaryKeyNew,
+            String detectedPrimaryKeyName) {
+        return new SetPrimaryKeyToModel(
+                entity,
+                primaryKeyOriginal,
+                primaryKeyNew,
+                detectedPrimaryKeyName);
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToDb.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToDb.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToDb.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToDb.java Wed Sep  9 07:04:21 2009
@@ -31,37 +31,45 @@
 
     private Collection<DbAttribute> primaryKeyOriginal;
     private Collection<DbAttribute> primaryKeyNew;
+    private String detectedPrimaryKeyName;
 
     public SetPrimaryKeyToDb(DbEntity entity, Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew) {
+            Collection<DbAttribute> primaryKeyNew, String detectedPrimaryKeyName) {
         super(entity);
+
         this.primaryKeyOriginal = primaryKeyOriginal;
         this.primaryKeyNew = primaryKeyNew;
+        this.detectedPrimaryKeyName = detectedPrimaryKeyName;
     }
 
     @Override
     public List<String> createSql(DbAdapter adapter) {
         List<String> sqls = new ArrayList<String>();
         if (!primaryKeyOriginal.isEmpty()) {
-            appendDropOriginalPrimaryKeySQL(sqls);
+            appendDropOriginalPrimaryKeySQL(adapter, sqls);
         }
-        appendAddNewPrimaryKeySQL(sqls);
+        appendAddNewPrimaryKeySQL(adapter, sqls);
         return sqls;
     }
 
-    protected void appendDropOriginalPrimaryKeySQL(List<String> sqls) {
+    protected void appendDropOriginalPrimaryKeySQL(DbAdapter adapter, List<String> sqls) {
+        if (detectedPrimaryKeyName == null) {
+            return;
+        }
         sqls.add("ALTER TABLE "
-                + getEntity().getFullyQualifiedName()
-                + " DROP PRIMARY KEY");
+                + getQuotingStrategy(adapter)
+                        .quoteFullyQualifiedName(getEntity())
+                + " DROP CONSTRAINT "
+                + detectedPrimaryKeyName);
     }
 
-    protected void appendAddNewPrimaryKeySQL(List<String> sqls) {
+    protected void appendAddNewPrimaryKeySQL(DbAdapter adapter, List<String> sqls) {
         StringBuilder sql = new StringBuilder();
         sql.append("ALTER TABLE ");
-        sql.append(getEntity().getFullyQualifiedName());
+        sql.append(getQuotingStrategy(adapter).quoteFullyQualifiedName(getEntity()));
         sql.append(" ADD PRIMARY KEY (");
         for (Iterator<DbAttribute> it = primaryKeyNew.iterator(); it.hasNext();) {
-            sql.append(it.next().getName());
+            sql.append(getQuotingStrategy(adapter).quoteString(it.next().getName()));
             if (it.hasNext()) {
                 sql.append(", ");
             }
@@ -74,11 +82,8 @@
         return factory.createSetPrimaryKeyToModel(
                 getEntity(),
                 primaryKeyNew,
-                primaryKeyOriginal);
-    }
-
-    protected String getConstraintName() {
-        return getEntity().getName() + "_PK";
+                primaryKeyOriginal,
+                detectedPrimaryKeyName);
     }
 
     public String getTokenName() {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToModel.java?rev=812789&r1=812788&r2=812789&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetPrimaryKeyToModel.java Wed Sep  9 07:04:21 2009
@@ -30,16 +30,20 @@
 
     private Collection<DbAttribute> primaryKeyOriginal;
     private Collection<DbAttribute> primaryKeyNew;
-    private Set<String> primaryKeyNewNames = new HashSet<String>();
+    private String detectedPrimaryKeyName;
+    private Set<String> primaryKeyNewAttributeNames = new HashSet<String>();
 
     public SetPrimaryKeyToModel(DbEntity entity,
             Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew) {
+            Collection<DbAttribute> primaryKeyNew, String detectedPrimaryKeyName) {
         super(entity);
+        
         this.primaryKeyOriginal = primaryKeyOriginal;
         this.primaryKeyNew = primaryKeyNew;
+        this.detectedPrimaryKeyName = detectedPrimaryKeyName;
+        
         for (DbAttribute attr : primaryKeyNew) {
-            primaryKeyNewNames.add(attr.getName().toUpperCase());
+            primaryKeyNewAttributeNames.add(attr.getName().toUpperCase());
         }
     }
 
@@ -47,7 +51,8 @@
         return factory.createSetPrimaryKeyToDb(
                 getEntity(),
                 primaryKeyNew,
-                primaryKeyOriginal);
+                primaryKeyOriginal,
+                detectedPrimaryKeyName);
     }
 
     public void execute(MergerContext mergerContext) {
@@ -56,7 +61,7 @@
         for (DbAttribute attr : e.getAttributes()) {
 
             boolean wasPrimaryKey = attr.isPrimaryKey();
-            boolean willBePrimaryKey = primaryKeyNewNames.contains(attr
+            boolean willBePrimaryKey = primaryKeyNewAttributeNames.contains(attr
                     .getName()
                     .toUpperCase());