OPENJPA-866 - Commit contributions by Tim McConnell.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@753024 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Albert Lee 2009-03-12 21:31:11 +00:00
parent 272c584af2
commit 0e7c84ef81
5 changed files with 381 additions and 1 deletions

View File

@ -90,6 +90,13 @@ public class DynamicSchemaFactory
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 @@ public class DynamicSchemaFactory
/**
* 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 @@ public class DynamicSchemaFactory
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);
}
}

View File

@ -133,6 +133,24 @@ public class Schema
return tab;
}
/**
* 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.
*

View File

@ -297,6 +297,26 @@ public class Table
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.
*

View File

@ -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;
}
}

View File

@ -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);
}
}
}