You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by al...@apache.org on 2009/03/12 22:31:13 UTC

svn commit: r753024 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/

Author: allee8285
Date: Thu Mar 12 21:31:11 2009
New Revision: 753024

URL: http://svn.apache.org/viewvc?rev=753024&view=rev
Log:
OPENJPA-866 - Commit contributions by Tim McConnell.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java   (with props)
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java?rev=753024&r1=753023&r2=753024&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java Thu Mar 12 21:31:11 2009
@@ -90,6 +90,13 @@
         Schema schema = getSchema(schemaName);
         if (schema == null)
             schema = addSchema(schemaName);
+
+        // Ensure only valid table name(s) are added to the schema
+        if (tableName.length() > _dict.maxTableNameLength) {
+            return schema.addTable(tableName, 
+                _dict.getValidTableName(tableName, getSchema(schemaName)));
+        }
+
         return schema.addTable(tableName);
     }
 
@@ -104,7 +111,7 @@
     /**
      * Table type that adds columns when {@link #getColumn} is called.
      */
-    private static class DynamicTable
+    private class DynamicTable
         extends Table {
 
         public DynamicTable(String name, Schema schema) {
@@ -118,6 +125,13 @@
             Column col = super.getColumn(name);
             if (col != null)
                 return col;
+
+            // Ensure only valid column name(s) are added to the table
+            if (name.length() > _dict.maxColumnNameLength) {
+                return addColumn(name, 
+                    _dict.getValidColumnName(name, this));
+            }
+
             return addColumn(name);
         }
     }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java?rev=753024&r1=753023&r2=753024&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java Thu Mar 12 21:31:11 2009
@@ -134,6 +134,24 @@
     }
 
     /**
+     * Add a table with a shortened (i.e., validated) name to the schema
+     */
+    public Table addTable(String name, String validName) {
+        SchemaGroup group = getSchemaGroup();
+        Table tab;
+        if (group != null) {
+            group.addName(validName, true);
+            tab = group.newTable(validName, this);
+        } else
+            tab = new Table(validName, this);
+        if (_tableMap == null)
+            _tableMap = new TreeMap();
+        _tableMap.put(name.toUpperCase(), tab);
+        _tables = null;
+        return tab;
+    }
+
+    /**
      * Remove the given table from the schema.
      *
      * @return true if the table was removed, false if not in the schema

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java?rev=753024&r1=753023&r2=753024&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java Thu Mar 12 21:31:11 2009
@@ -297,6 +297,26 @@
         return col;
     }
 
+
+    /**
+     * Add a colum with a shortened (i.e., validated) name to the table
+     */
+    public Column addColumn(String name, String validName) {
+        addName(name, true);
+        Schema schema = getSchema();
+        Column col;
+        if (schema != null && schema.getSchemaGroup() != null)
+            col = schema.getSchemaGroup().newColumn(validName, this);
+        else
+            col = new Column(validName, this);
+        if (_colMap == null)
+            _colMap = new LinkedHashMap();
+        _colMap.put(name.toUpperCase(), col);
+        _cols = null;
+        return col;
+    }
+
+
     /**
      * Remove the given column from the table.
      *

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java?rev=753024&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java Thu Mar 12 21:31:11 2009
@@ -0,0 +1,149 @@
+/*
+ * 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.openjpa.persistence.dynamicschema;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+
+/**
+ * Entity with very long table and column names 
+ * 
+ * @author Tim McConnell
+ * @since 2.0.0
+ */
+@Entity
+@Table(name="Very______________________________________________" +
+            "Long______________________________________________" +
+            "Table_____________________________________________" +
+            "Name______________________________________________" )
+public class EntityVeryLongNames implements Serializable {
+
+    @Id
+    @Column(name="ID________________________________________________" +
+                 "Very______________________________________________" +
+                 "Long______________________________________________" +
+                 "Column____________________________________________" +
+                 "Name______________________________________________" )
+    private int id;
+
+    @Column(name="FirstName_________________________________________" +
+                 "Very______________________________________________" +
+                 "Long______________________________________________" +
+                 "Column____________________________________________" +
+                 "Name______________________________________________" )
+    private String firstName;
+
+    @Column(name="LastName__________________________________________" +
+                 "Very______________________________________________" +
+                 "Long______________________________________________" +
+                 "Column____________________________________________" +
+                 "Name______________________________________________" )
+    private String lastName;
+
+    public EntityVeryLongNames() {
+    }
+
+    public EntityVeryLongNames(String firstName, String lastName) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+
+    @Override
+    public String toString() {
+        return "EntityVeryLongNames: id: " + getId() + 
+               " firstName: " + getFirstName() +
+               " lastName: " + getLastName();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+            + ((getFirstName() == null) ? 0 : getFirstName().hashCode());
+        result = prime * result + getId();
+        result = prime * result
+            + ((getLastName() == null) ? 0 : getLastName().hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final EntityVeryLongNames other = (EntityVeryLongNames) obj;
+        if (getId() != other.getId()) {
+            return false;
+        }
+        if (getFirstName() == null) {
+            if (other.getFirstName() != null) {
+                return false;
+            }
+        }
+        else if (!getFirstName().equals(other.getFirstName())) {
+            return false;
+        }
+        if (getLastName() == null) {
+            if (other.getLastName() != null) {
+                return false;
+            }
+        }
+        else if (!getLastName().equals(other.getLastName())) {
+            return false;
+        }
+        return true;
+    } 
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/EntityVeryLongNames.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java?rev=753024&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java Thu Mar 12 21:31:11 2009
@@ -0,0 +1,179 @@
+/* 
+ * 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.openjpa.persistence.dynamicschema;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+
+/**
+ * <b>TestDynamicSchemas</b> is used to create dynamic schemas for the various 
+ * database dictionaries and validate them to ensure they are created 
+ * correctly as specified in their dictionary. The following variables of each 
+ * dictionary are used for validation:<p>
+ *
+ * <ol>
+ *     <li>maxTableNameLength           
+ *     <li>maxColumnNameLength          
+ * </ol>
+ * 
+ * <b>Note(s):</b> 
+ * <ul>
+ *     <li>To minimize the running time of these testcases there are no
+ *     connections made to any of the databases
+ *     <li>This is accomplished by passing the "export" SchemaAction to the
+ *     MappingTool, and using the RETAIN_DATA option to prevent SQL commands
+ *     from getting executed
+ * </ul>
+ * 
+ * @author Tim McConnell
+ * @since 2.0.0
+ */
+public class TestDynamicSchemas extends SingleEMFTestCase {
+
+    public void setUp() {
+    }
+
+
+    public void testDerbyDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI derbyEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:derby:net://host:1527/databaseName",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( derbyEMF );
+    }
+
+
+    public void testDB2DynamicSchema() {
+        OpenJPAEntityManagerFactorySPI db2EMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:db2://localhost:5000/db2",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( db2EMF );
+    }
+
+
+    public void testOracleDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI oracleEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:oracle:thin:@host:1234:database_sid",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( oracleEMF );
+    }
+
+
+    public void testAccessDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI accessEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:odbc:Driver=Microsoft Access Driver (*.mdb);DBQ=c:",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( accessEMF );
+    }
+
+
+    public void testSQLServerDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI sqlserverEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:microsoft:sqlserver:",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( sqlserverEMF );
+    }
+
+
+    public void testMySQLDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI mysqlEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:mysql://host1:1,host2:2/database?p1=v1&p2=v2",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( mysqlEMF );
+    }
+
+
+    public void testPostgresDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI postgresEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:postgresql:database",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( postgresEMF );
+    }
+
+
+    public void testInformixDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI informixEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:informix-sqli:",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( informixEMF );
+    }
+
+
+    public void testSybaseDynamicSchema() {
+        OpenJPAEntityManagerFactorySPI sybaseEMF = 
+            createEMF(EntityVeryLongNames.class,
+                "openjpa.ConnectionURL", 
+                "jdbc:sybase:Tds:host:1234?ServiceName=db",
+                "openjpa.jdbc.SynchronizeMappings", "export", 
+                "openjpa.jdbc.SchemaFactory", "dynamic", RETAIN_DATA);
+        validateTableName( sybaseEMF );
+    }
+
+
+    private void validateTableName(OpenJPAEntityManagerFactorySPI emf) {
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        DBDictionary dict = conf.getDBDictionaryInstance();
+        ClassMapping mapping =  (ClassMapping)conf.
+            getMetaDataRepositoryInstance().
+            getMetaData(EntityVeryLongNames.class,getClass().
+                getClassLoader(), true);
+        Table table = mapping.getTable();
+        assertTrue(table.getName().length() > 0);
+        assertTrue(table.getName().length() <= dict.maxTableNameLength);
+        validateColumnNames(table, dict);
+    }
+
+
+    private void validateColumnNames(Table table, DBDictionary dict) {
+        Column[] columns = table.getColumns();
+        for (Column column : columns) {
+            assertTrue(column.getName().length() > 0);
+            assertTrue(column.getName().length() <= dict.maxColumnNameLength);
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/dynamicschema/TestDynamicSchemas.java
------------------------------------------------------------------------------
    svn:eol-style = native