mirror of https://github.com/apache/openjpa.git
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:
parent
272c584af2
commit
0e7c84ef81
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue